Only in uClinux-dist/config: config.tk
Only in uClinux-dist: linux-2.0.x
Only in uClinux-dist/linux-2.4.x/arch: alpha
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/boot/Makefile uClinux-dist-20040408/linux-2.4.x/arch/armnommu/boot/Makefile
--- uClinux-dist/linux-2.4.x/arch/armnommu/boot/Makefile	2004-04-08 08:14:58.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/boot/Makefile	2004-09-07 16:59:31.000000000 +0800
@@ -108,6 +108,11 @@
 ZRELADDR	= 0x1000000
 endif
 
+ifeq ($(CONFIG_ARCH_STR710),y)
+ZRELADDR	 = 0x62000000
+ZTEXTADDR	 = 0x62200000
+endif
+
 ifeq ($(CONFIG_BOARD_SNDS100),y)
 ZRELADDR	 = 0x00008000
 ifeq ($(CONFIG_ZYXEL_BOOTEXT),y)
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/config.in uClinux-dist-20040408/linux-2.4.x/arch/armnommu/config.in
--- uClinux-dist/linux-2.4.x/arch/armnommu/config.in	2004-04-08 08:15:01.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/config.in	2004-09-07 17:21:54.000000000 +0800
@@ -56,6 +56,7 @@
 	  Triscend-A7V		CONFIG_ARCH_TA7V \
 	  SWARM			CONFIG_ARCH_SWARM \
 	  Samsung		CONFIG_ARCH_SAMSUNG \
+	  STR710		CONFIG_ARCH_STR710 \
 	  Atmel			CONFIG_ARCH_ATMEL" TI-DSC21
 
 if [ "$CONFIG_ARCH_TA7V" = "y" ]; then
@@ -359,6 +360,18 @@
        define_hex FLASH_SIZE     0x00200000
     fi
 fi
+if [ "$CONFIG_ARCH_STR710" = "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       n
+    define_bool CONFIG_CPU_WITH_MCR_INSTRUCTION n
+    define_hex DRAM_BASE 0x62000000
+    define_hex DRAM_SIZE 0x00400000
+    define_hex FLASH_MEM_BASE 0x60000000
+    define_hex FLASH_SIZE 0x00400000
+fi
 
 if [ "$CONFIG_BOARD_EVS3C4530HEI" = "y" ]; then
     define_bool CONFIG_ARCTURUS		y
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/kernel/entry-armv.S uClinux-dist-20040408/linux-2.4.x/arch/armnommu/kernel/entry-armv.S
--- uClinux-dist/linux-2.4.x/arch/armnommu/kernel/entry-armv.S	2004-04-08 08:15:02.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/kernel/entry-armv.S	2004-09-07 16:53:07.000000000 +0800
@@ -949,6 +949,25 @@
 
 		.macro irq_prio_table
 		.endm
+#elif defined(CONFIG_ARCH_STR710)
+
+		.macro disable_fiq
+		.endm
+
+		.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =EIC_BASE 	@ EIC base
+		ldr	\tmp, [\base,#0x18]	@ Read IVR(offset 0x18)to deassert IRQ signal
+		@ after reading IVR, CICR (offset 4)is updated,
+		@ Which tells which IRQ channel is serviced now...
+		ldr \irqnr, [\base,#4]	
+		
+		@to ensure Z flag not set if there is pending bit
+		ldr \tmp, [\base,#0x40]		@pending bit
+		teq \tmp, #0
+       		.endm
+
+		.macro irq_prio_table
+		.endm
 
 #elif defined(CONFIG_ARCH_SWARM)
 
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/kernel/head-armv.S uClinux-dist-20040408/linux-2.4.x/arch/armnommu/kernel/head-armv.S
--- uClinux-dist/linux-2.4.x/arch/armnommu/kernel/head-armv.S	2004-04-08 08:15:03.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/kernel/head-armv.S	2004-09-15 12:05:08.000000000 +0800
@@ -164,6 +164,8 @@
 		mov     r1, #MACH_TYPE_SMDK2500
 #elif defined(CONFIG_BOARD_S3C2500REFRGP)
 		mov	r1, #MACH_TYPE_S3C2500REFRGP
+#elif defined(CONFIG_ARCH_STR710)
+		ldr	r1, MACH_ID_STR710
 #endif
 
 		mov	r0, #F_BIT | I_BIT | MODE_SVC	@ make sure svc mode
@@ -220,6 +222,43 @@
         .long	init_task_union+8192
 #endif
 
+#if defined(CONFIG_ARCH_STR710)
+        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, STR710_PROCESSOR_TYPE
+
+	str     r2, [r6]
+	ldr     r2, MACH_ID_STR710
+	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
+	
+STR710_PROCESSOR_TYPE:
+	.long	0x07100000
+MACH_ID_STR710:	
+	.long	MACH_TYPE_STR710
+		
+#endif
+
 #if defined(CONFIG_BOARD_SNDS100)
 
         adr	r5, LC0
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/arch.c uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/arch.c
--- uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/arch.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/arch.c	2004-09-01 10:14:38.000000000 +0800
@@ -0,0 +1,25 @@
+/*
+ *  linux/arch/arm/mach-STR710/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(STR710, "STR710")
+       MAINTAINER("ST MMCC")
+	   BOOT_PARAMS(0x00000100)
+       INITIRQ(genarch_init_irq)
+MACHINE_END
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/irq.c uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/irq.c
--- uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/irq.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/irq.c	2004-08-26 16:23:52.000000000 +0800
@@ -0,0 +1,40 @@
+/*
+*  linux/arch/armnommu/mach-STR710/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>
+
+
+void str710_mask_irq(unsigned int irq)
+{
+	//INT_DISABLE(irq);
+	EIC->IER &= ~(1<<irq);
+}
+
+void str710_unmask_irq(unsigned int irq)
+{
+	//INT_ENABLE(irq);
+	EIC->IER |= (1<<irq);
+}
+
+void str710_mask_ack_irq(unsigned int irq)
+{
+	//INT_DISABLE(irq);
+	EIC->IER &= ~(1<<irq);
+}
+
+void str710_int_init()
+{
+	EIC->IPR = 0xFFFFFFFF;	//Clear all Int pending bits
+	EIC->ICR = 0x1;			//Global IRQ enabled, FIQ disabled
+	EIC->IER = 0x00000000;	//all int disabled
+	EIC->FIR = 0x0000000C; // Disable all FIQ channels interrupts and clear FIQ channels pending bits
+	EIC->CIPR = 0x00000000; // Set the current priority level to zero
+	EIC->IVR  = 0xE59F0000; // IVR = high half of load PC instruction.Does not care!
+	
+}
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/linux.lds uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/linux.lds
--- uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/linux.lds	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/linux.lds	2004-08-18 15:03:50.000000000 +0800
@@ -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>
+ */
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+SECTIONS
+{
+	. = 0x62000000;
+	.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		*/
+		
+		romfs_data = .;
+		romfs.o
+		romfs_data_end = .;
+		
+		_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 --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/Makefile uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/Makefile
--- uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/Makefile	2004-08-18 11:49:34.000000000 +0800
@@ -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		:= STR710.o
+
+# Object file lists.
+
+obj-y			:= $(patsubst %.c, %.o, $(wildcard *.c))
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+include $(TOPDIR)/Rules.make
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/time.c uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/time.c
--- uClinux-dist/linux-2.4.x/arch/armnommu/mach-STR710/time.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mach-STR710/time.c	2004-08-27 11:13:20.000000000 +0800
@@ -0,0 +1,31 @@
+/*
+ * time.c  Timer functions for STR710
+ */
+
+#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>
+
+static unsigned int i=0;
+static int light = 7;
+
+unsigned long str710_gettimeoffset (void)
+{
+	return 0;
+}
+
+void str710_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+		i++;
+		if (i % 100 == 0)
+		{
+			light = (light+1) % 8;
+			GPIO2->PD &= ~0x7000;
+			GPIO2->PD |= (light << 12);
+		}
+		WDG->SR = 0;	//Clear End-of-Count Pending bit
+        do_timer(regs);
+}
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/Makefile uClinux-dist-20040408/linux-2.4.x/arch/armnommu/Makefile
--- uClinux-dist/linux-2.4.x/arch/armnommu/Makefile	2004-04-08 08:15:01.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/Makefile	2004-09-07 16:56:23.000000000 +0800
@@ -161,6 +161,12 @@
 MACHINE		= atmel
 endif
 
+ifeq ($(CONFIG_ARCH_STR710), y)
+#TEXTADDR	 = 0x62000000
+MACHINE		 = STR710
+LINKFLAGS	=-p -X -T arch/armnommu/mach-$(MACHINE)/linux.lds
+endif
+
 ifeq ($(CONFIG_ARCH_NETARM),y)
 MACHINE 	 = netarm
 # This allows it to use the internal bootloader.
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/mm/proc-arm6,7.S uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mm/proc-arm6,7.S
--- uClinux-dist/linux-2.4.x/arch/armnommu/mm/proc-arm6,7.S	2004-04-08 08:15:08.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/mm/proc-arm6,7.S	2004-09-08 10:43:38.000000000 +0800
@@ -430,6 +430,8 @@
 cpu_s3c4530_manu_name:
 cpu_s3c44b0x_manu_name:
 		.asciz	"Samsung"
+cpu_str710_manu_name:
+		.asciz	"STMicro"
 cpu_s3c3410_name:
 		.asciz	"S3C3410X"
 cpu_s3c4510b_name:
@@ -438,6 +440,9 @@
 		.asciz  "S3C4530A01"
 cpu_s3c44b0x_name:
 		.asciz  "S3C44B0X"
+cpu_str710_name:
+		.asciz  "STR71x"
+
                 .align
 
 		.section ".text.init", #alloc, #execinstr
@@ -638,6 +643,12 @@
 		.long	cpu_s3c44b0x_name
 		.size	cpu_s3c44b0x_info, . - cpu_s3c44b0x_info
 
+		.type   cpu_str710_info, #object
+cpu_str710_info:
+		.long   cpu_str710_manu_name
+		.long   cpu_str710_name
+		.size	cpu_str710_info, . - cpu_str710_info
+
 		.type	cpu_s3c4510b_info, #object
 cpu_s3c4510b_info:
 		.long	cpu_s3c4510b_manu_name
@@ -803,6 +814,19 @@
 		.long	arm7_processor_functions	@ info
 		.size	__s3c3410_proc_info, . - __s3c3410_proc_info
 
+		.type   __str710_proc_info, #object
+__str710_proc_info:
+		.long	0x07100000			@ 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_str710_info			@ info
+		.long	arm7_processor_functions	@ info
+		.size	__str710_proc_info, . - __str710_proc_info
+
 		.type   __s3c44b0x_proc_info, #object
 __s3c44b0x_proc_info:
 		.long	0x44b00000			@ cpu_val
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/arch/armnommu/tools/mach-types uClinux-dist-20040408/linux-2.4.x/arch/armnommu/tools/mach-types
--- uClinux-dist/linux-2.4.x/arch/armnommu/tools/mach-types	2004-04-08 08:15:08.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/arch/armnommu/tools/mach-types	2004-09-15 11:49:50.000000000 +0800
@@ -99,6 +99,7 @@
 atmel			ARCH_ATMEL		ATMEL			224
 ta7s			ARCH_TA7S		TA7S			334
 ta7v			ARCH_TA7V		TA7V			335
+str710			ARCH_STR710		STR710			603
 
 # The following are unallocated
 
@@ -110,4 +111,4 @@
 S3C3410X		BOARD_SMDK40100		S3C3410			165
 smdk2500		BOARD_SMDK2500		SMDK2500		166
 S3C2500REFRGP		BOARD_S3C2500REFRGP	S3C2500REFRGP		167
-S3C44B0X		BOARD_MBA44		S3C44B0X		168
+S3C44B0X		BOARD_MBA44		S3C44B0X		168
\ No newline at end of file
Only in uClinux-dist/linux-2.4.x/arch: blackfin
Only in uClinux-dist/linux-2.4.x/arch: cris
Only in uClinux-dist/linux-2.4.x/arch: e1nommu
Only in uClinux-dist/linux-2.4.x/arch: h8300
Only in uClinux-dist/linux-2.4.x/arch: i386
Only in uClinux-dist/linux-2.4.x/arch: ia64
Only in uClinux-dist/linux-2.4.x/arch: m68k
Only in uClinux-dist/linux-2.4.x/arch: m68knommu
Only in uClinux-dist/linux-2.4.x/arch: microblaze
Only in uClinux-dist/linux-2.4.x/arch: mips
Only in uClinux-dist/linux-2.4.x/arch: mips64
Only in uClinux-dist/linux-2.4.x/arch: niosnommu
Only in uClinux-dist/linux-2.4.x/arch: parisc
Only in uClinux-dist/linux-2.4.x/arch: ppc
Only in uClinux-dist/linux-2.4.x/arch: ppc64
Only in uClinux-dist/linux-2.4.x/arch: s390
Only in uClinux-dist/linux-2.4.x/arch: s390x
Only in uClinux-dist/linux-2.4.x/arch: sh
Only in uClinux-dist/linux-2.4.x/arch: sh64
Only in uClinux-dist/linux-2.4.x/arch: sparc
Only in uClinux-dist/linux-2.4.x/arch: sparc64
Only in uClinux-dist/linux-2.4.x/arch: v850
Only in uClinux-dist/linux-2.4.x/arch: x86_64
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/block/blkmem.c uClinux-dist-20040408/linux-2.4.x/drivers/block/blkmem.c
--- uClinux-dist/linux-2.4.x/drivers/block/blkmem.c	2004-04-08 08:16:15.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/block/blkmem.c	2004-09-07 17:33:59.000000000 +0800
@@ -85,7 +85,7 @@
 
 
 /* Samsung S3C4510-SNDS100 arch */
-#ifdef CONFIG_BOARD_SNDS100
+#if defined(CONFIG_BOARD_SNDS100) || defined(CONFIG_ARCH_STR710)
 extern char romfs_data[];
 extern char romfs_data_end[];
 #endif
@@ -380,7 +380,7 @@
 	{0, (unsigned long) FIXED_ROMARRAY, -1},
 #endif
 
-#ifdef CONFIG_BOARD_SNDS100
+#if defined(CONFIG_BOARD_SNDS100) || defined(CONFIG_ARCH_STR710)
 	{0, romfs_data, -1},
 #endif
 
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/block/Makefile uClinux-dist-20040408/linux-2.4.x/drivers/block/Makefile
--- uClinux-dist/linux-2.4.x/drivers/block/Makefile	2004-04-08 08:16:15.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/block/Makefile	2004-09-07 17:51:59.000000000 +0800
@@ -35,9 +35,11 @@
 
 subdir-$(CONFIG_PARIDE) += paride
 
-mod-subdirs			+= xilinx_sysace
+ifeq ($(CONFIG_XILINX_SYSACE),y)
+mod-subdirs += xilinx_sysace
 subdir-$(CONFIG_XILINX_SYSACE)	+= xilinx_sysace
 obj-$(CONFIG_XILINX_SYSACE)	+= xilinx_sysace/xilinx_sysace.o
+endif
 
 ifeq ($(CONFIG_ARCH_ACORN),y)
 mod-subdirs	+= ../acorn/block
Only in uClinux-dist/linux-2.4.x/drivers/block: xilinx_sysace
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/char/Config.in uClinux-dist-20040408/linux-2.4.x/drivers/char/Config.in
--- uClinux-dist/linux-2.4.x/drivers/char/Config.in	2004-04-08 08:16:16.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/char/Config.in	2004-09-07 17:23:50.000000000 +0800
@@ -150,6 +150,12 @@
       fi
    fi
 fi
+if [ "$CONFIG_ARCH_STR710" = "y" ]; then
+   bool 'STR710 serial port support' CONFIG_SERIAL_STR710
+   if [ "$CONFIG_SERIAL_STR710" = 'y' ]; then
+      bool ' Support for console on STR710 serial port' CONFIG_SERIAL_STR710_CONSOLE
+   fi
+fi
 
 if [ "$CONFIG_CPU_S3C4530" = "y" ]; then
    bool 'Samsung S3C4530a serial ports support' CONFIG_SERIAL_S3C4530
Only in uClinux-dist/linux-2.4.x/drivers/char: digiFep1.h
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/char/Makefile uClinux-dist-20040408/linux-2.4.x/drivers/char/Makefile
--- uClinux-dist/linux-2.4.x/drivers/char/Makefile	2004-04-08 08:16:16.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/char/Makefile	2004-09-08 10:09:14.000000000 +0800
@@ -239,6 +239,7 @@
 obj-$(CONFIG_SERIAL_S3C3410) += serial_s3c3410.o
 obj-$(CONFIG_SERIAL_S3C44B0X) += serial_s3c44b0x.o
 obj-$(CONFIG_SERIAL_S3C4530) += serial_s3c4530.o
+obj-$(CONFIG_SERIAL_STR710) += serial_str710.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
@@ -398,9 +399,11 @@
 obj-$(CONFIG_C5471_WDT) += wdt_c5471.o
 
 # Support for Xilinx GPIO driver
+ifeq ($(CONFIG_XILINX_GPIO),y)
 mod-subdirs += xilinx_gpio
 subdir-$(CONFIG_XILINX_GPIO) += xilinx_gpio
 obj-$(CONFIG_XILINX_GPIO) += xilinx_gpio/xilinx_gpio.o
+endif
 
 subdir-$(CONFIG_MWAVE) += mwave
 ifeq ($(CONFIG_MWAVE),y)
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/char/serial_str710.c uClinux-dist-20040408/linux-2.4.x/drivers/char/serial_str710.c
--- uClinux-dist/linux-2.4.x/drivers/char/serial_str710.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/char/serial_str710.c	2004-09-15 17:15:34.000000000 +0800
@@ -0,0 +1,2101 @@
+/*
+ * serial_str710.c: Serial port driver for the STR710 builtin UART
+ *
+ * Copyright (c) 2004 STMicroelectronics Corp.
+ *      by Kevin Zhu <kevin.zhu@st.com>
+ *
+ * Based on: drivers/char/Serial_s3c44b0x.c
+ * 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_str710.h"
+
+#if defined(CONFIG_UCBOOTSTRAP)
+#include <asm/uCbootstrap.h>
+extern  char *getbenv (char *a);
+#endif
+
+/* the max num of USART_CNT is 3 */
+#define USART_CNT		3
+
+#define UART_IRQ_OFF        9
+
+#define FIFO_ENABLE             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		(16) 	/* maximum transmit FIFO length */
+#define RX_FIFO_DEPTH		(16) 	/* 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_INT_OPEN
+#undef SERIAL_DEBUG_OPEN
+#define SERIAL_DEBUG_FLOW
+#define SERIAL_DEBUG_THROTTLE
+
+#define _INLINE_ inline
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+static struct str710_serial aStr710_info[USART_CNT];
+
+#if  USART_CNT == 1
+static UART_TypeDef * paUART[USART_CNT] = {UART0};
+static u8 aUART_IRQ[USART_CNT] = {IRQ_UART0};
+#elif USART_CNT == 2
+static UART_TypeDef * paUART[USART_CNT] = {UART0, UART1};
+static u8 aUART_IRQ[USART_CNT] = {IRQ_UART0, IRQ_UART1};
+#else
+static UART_TypeDef * paUART[USART_CNT] = {UART0, UART1, UART2};
+static u8 aUART_IRQ[USART_CNT] = {IRQ_UART0, IRQ_UART1, IRQ_UART2};
+#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 */
+static DECLARE_MUTEX (tmp_buf_sem);
+
+/* Console hooks... */
+static str_baud_table_t default_console_baud = { 115200, B115200 };
+
+#if defined(CONFIG_SERIAL_STR710_CONSOLE)
+static int console_number =  0;
+#endif
+	
+DECLARE_TASK_QUEUE(tq_str710_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 str710_serial *info);
+
+static _INLINE_ void tx_stop(int nLine);
+static _INLINE_ void tx_start(int nLine);
+static _INLINE_ void rx_stop(int nLine);
+static _INLINE_ void rx_start(int nLine);
+static _INLINE_ void xmit_char		(struct str710_serial *info, char ch);
+static _INLINE_ void rs_sched_event	(struct str710_serial *info, int event);
+static _INLINE_ void handle_status 	(struct str710_serial *info, unsigned int status);
+static _INLINE_ void fifo_reset(int nLine);
+static _INLINE_ void fifo_init(int nLine);
+
+static void set_ints_mode	(struct str710_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 rs_interrupt_act    (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 str710_serial *pinfo);
+
+void GPIO_Config (GPIO_TypeDef *GPIOx, u16 Port_Pins, GpioPinMode_TypeDef GPIO_Mode);
+
+
+/******************************************************************************/
+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 nLine)
+{
+        if((nLine < 0) || (nLine > USART_CNT))
+        {
+            printk("nLine = %d, which num is error!\n", nLine);
+            return;
+        }
+
+	paUART[nLine]->IER |= (UART_TxEmpty_IE | UART_TxHalfEmpty_IE);
+}
+
+static _INLINE_ void tx_stop(int nLine)
+{
+        if((nLine < 0) || (nLine > USART_CNT))
+        {
+            printk("nLine = %d, which num is error!\n", nLine);
+            return;
+        }
+
+	paUART[nLine]->IER &= ~(UART_TxEmpty_IE | UART_TxHalfEmpty_IE);
+}
+
+static _INLINE_ void rx_start(int nLine)
+{
+        if((nLine < 0) || (nLine > USART_CNT))
+        {
+            printk("nLine = %d, which num is error!\n", nLine);
+            return;
+        }
+
+        paUART[nLine]->IER |= (UART_RxBufFull_IE | UART_RxHalfFull_IE);
+}
+
+static _INLINE_ void rx_stop(int nLine)
+{
+        if((nLine < 0) || (nLine > USART_CNT))
+        {
+            printk("nLine = %d, which num is error!\n", nLine);
+            return;
+        }
+
+        paUART[nLine]->IER &= ~(UART_RxBufFull_IE | UART_RxHalfFull_IE);
+}
+
+static void set_ints_mode(struct str710_serial *info, int yes)
+{
+	info->use_ints = yes;
+	if (yes)
+        {
+	    str710_unmask_irq(aUART_IRQ[info->line]);
+	}
+        else
+        {
+	    str710_mask_irq(aUART_IRQ[info->line]);
+	}
+}
+
+static void hw_flow_control (int cmd)
+{
+	/* the STR710 board does not have hw flow control */
+}
+
+static _INLINE_ void fifo_reset(int nLine)
+{
+	paUART[nLine]->RRR = 0xFFFF;
+        paUART[nLine]->TRR = 0xFFFF;
+}
+
+static _INLINE_ void fifo_init(int nLine)
+{
+        if(FIFO_ENABLE)
+        {
+            paUART[nLine]->CR |= (0x0001<<UART_FIFOEnableBit);
+        }
+        else
+        {
+            paUART[nLine]->CR &= ~(0x0001<<UART_FIFOEnableBit);
+        }
+}
+
+static inline int serial_paranoia_check(struct str710_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 str710_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 str710_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 str710_serial *info, int set)
+{
+	/* we do not need hw flow control */
+}
+
+/* Reads value of serial status signals */
+static unsigned int get_status(struct str710_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 str710_serial *info = (struct str710_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->line);
+    rx_stop(info->line);
+    restore_flags(flags);
+}
+
+static void rs_put_char(struct str710_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 str710_serial *info = (struct str710_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->line);
+    tx_start(info->line);
+    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("str710_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 str710_serial *info, int event)
+{
+	info->event |= 1 << event;
+	queue_task_irq_off(&info->tqueue, &tq_str710_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;
+	struct str710_serial *info = &aStr710_info[irq - UART_IRQ_OFF];
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+	printk("--- Tx INT ---\n");
+#endif
+
+	if  (info->x_char) {
+		tx_delay();
+                paUART[info->line]->TBR = info->x_char;
+		info->x_char = 0;
+		return;
+	}
+
+	if  ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped ) {
+		tx_stop(info->line);
+		return;
+	}
+
+	for (count = TX_FIFO_DEPTH; count > 0; --count) {
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+        printk("(rs_interruptTx 1) paUART[%d]->SR = %d\n", info->line, paUART[info->line]->SR);
+#endif
+
+		if (paUART[info->line]->SR & UART_TxFull) {
+			handle_status (info, UART_TxFull);
+			break;
+		} else {
+			tx_delay();
+                        paUART[info->line]->TBR = info->xmit_buf[info->xmit_tail++];
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+	printk("(rs_interruptTx 2) paUART[%d]->TBR = %c\n", info->line, info->xmit_buf[info->xmit_tail - 1]);
+	printk("(rs_interruptTx 3) info->xmit_cnt = %d\n", info->xmit_cnt);
+#endif
+
+			info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+			if (--info->xmit_cnt <= 0) 
+				break;
+		}
+	}
+
+	if (info->xmit_cnt < WAKEUP_CHARS)
+	{
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+	printk("(rs_interruptTx 4) info->xmit_cnt = %d\n", info->xmit_cnt);
+#endif
+
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+	}
+
+	if (info->xmit_cnt <= 0)
+	{
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+	printk("(rs_interruptTx 5) info->xmit_cnt = %d\n", info->xmit_cnt);
+#endif
+
+		tx_stop(info->line);
+	}
+	return;
+}
+
+static void rs_interruptRx(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct str710_serial *info = &aStr710_info[irq - UART_IRQ_OFF];
+	struct tty_struct *tty = info->tty;
+	unsigned int count;
+	volatile u_int16_t status;
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+	printk("--- Rx INT ---\n");
+#endif
+	
+	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 */
+		status = paUART[info->line]->SR;
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+	printk("(rs_interruptRx 1) paUART[%d]->SR = %d\n", info->line, status);
+#endif
+
+		if (!(status & (UART_RxBufFull | UART_RxHalfFull | UART_TimeOutNotEmpty)))
+			break;  //if RxFIFO empty, exit
+
+		if (!(status & (UART_OverrunError | UART_FrameError | UART_ParityError)) )
+			*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		else {
+			if (status & UART_OverrunError) {
+				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				handle_status (info, UART_OverrunError);
+			}
+			if	(status & UART_ParityError) {
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+				handle_status (info, UART_ParityError);
+			}
+			if 	(status & UART_FrameError) {
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+				handle_status (info, UART_FrameError);
+			}
+		}
+		*(tty->flip.char_buf_ptr++) = (u_int8_t)(paUART[info->line]->RBR);
+		tty->flip.flag_buf_ptr++;
+		tty->flip.count++;
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+	printk("(rs_interruptRx 2) paUART[%d]->RBR = %c\n", info->line, *(tty->flip.char_buf_ptr - 1));
+        printk("(rs_interruptRx 3) count = %d\n", count);
+#endif
+	} while ((--count > 0) && !(status & (UART_OverrunError | UART_FrameError | UART_ParityError)) );
+
+	queue_task_irq_off(&tty->flip.tqueue, &tq_timer);	
+}
+
+static void rs_interruptErr(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+#ifdef SERIAL_DEBUG_INT_OPEN
+	printk("--- Err INT ---\n");
+#endif
+
+	rs_interruptRx(irq, dev_id, regs);
+}
+
+static void rs_interrupt_act(int irq, void *dev_id, struct pt_regs *regs)
+{
+    volatile u_int16_t status, intEnable;
+
+    status = paUART[aStr710_info[irq - UART_IRQ_OFF].line]->SR;
+    intEnable = paUART[aStr710_info[irq - UART_IRQ_OFF].line]->IER;
+
+    if (((status & UART_TxEmpty) && (intEnable & UART_TxEmpty_IE))
+        || ((status & UART_TxHalfEmpty) && (intEnable & UART_TxHalfEmpty_IE)))
+    {
+        rs_interruptTx(irq, dev_id, regs);
+    }
+    else if (((status & UART_RxBufFull) && (intEnable & UART_RxBufFull_IE))
+                || ((status & UART_RxHalfFull) && (intEnable & UART_RxHalfFull_IE))
+                //no need to check it
+                //|| ((status & UART_TimeOutIdle) && (intEnable & UART_TimeOutIdle_IE))
+                || ((status & UART_TimeOutNotEmpty) && (intEnable & UART_TimeOutNotEmpty_IE)))
+    {
+        rs_interruptRx(irq, dev_id, regs);
+    }
+    else if (((status & UART_OverrunError) && (intEnable & UART_OverrunError_IE))
+                || ((status & UART_FrameError) && (intEnable & UART_FrameError_IE))
+                || ((status & UART_ParityError) && (intEnable & UART_ParityError_IE)))
+    {
+        rs_interruptErr(irq, dev_id, regs);
+    }
+    else
+    {
+#ifdef SERIAL_DEBUG_INT_OPEN
+        printk("Interrupt reason cann't be identified!\n");
+#endif
+    }
+}
+
+static _INLINE_ void handle_status ( struct str710_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_str710_serial);
+}
+
+static void do_softint(void *private_)
+{
+	struct str710_serial *info = (struct str710_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 str710_serial *info = (struct str710_serial *) private_;
+	struct tty_struct *tty;
+	
+	tty = info->tty;
+	if (!tty)	return;
+	tty_hangup(tty);
+}
+
+static int startup(struct str710_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->line);
+
+	/*
+	 * 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;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("startup 1: old paUART[info->line]->IER = 0x%X\n", paUART[info->line]->IER);
+	printk("startup 2: old paUART[info->line]->CR = 0x%X\n", paUART[info->line]->CR);
+#endif
+
+        /* Interupt enabled */
+        paUART[info->line]->IER = ( UART_RxBufFull_IE 
+                                                        | UART_TxEmpty_IE 
+                                                        | UART_TxHalfEmpty_IE 
+                                                        | UART_RxHalfFull_IE 
+                                                        | UART_ParityError_IE 
+                                                        | UART_FrameError_IE 
+                                                        | UART_OverrunError_IE 
+                                                        | UART_TimeOutNotEmpty_IE );
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("startup 3: new paUART[info->line]->IER = 0x%X\n", paUART[info->line]->IER);
+#endif
+        /* SmartCard mode disabled */
+        paUART[info->line]->CR &= ~(0x0001 << UART_SCEnableBit);
+
+        /* Receiver enabled */
+        paUART[info->line]->CR |= (0x0001 << UART_RxEnableBit);
+
+        /* Standard transmit/receive mode */
+        paUART[info->line]->CR &= ~(0x0001 << UART_LoopBackBit);
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("startup 4: before call func change_speed\n");
+#endif
+
+	/*
+	 * and set the speed of the serial port
+	 */
+	change_speed(info);
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("startup 5: after call func change_speed\n");
+#endif
+
+	info->flags |= S_INITIALIZED;
+	restore_flags(flags);
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("startup 6: startup will be successful!\n");
+#endif
+
+	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 str710_serial *info)
+{
+	unsigned long flags;
+	
+	tx_stop(info->line);
+	rx_stop(info->line);	/* 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 str_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 str710_serial *info)
+{
+	unsigned cflag;
+	int      table_index;
+	u_int16_t uart_cr;
+	
+	if (!info->tty || !info->tty->termios)
+	{
+#ifdef SERIAL_DEBUG_OPEN
+        	printk("change_speed: (!info->tty || !info->tty->termios) is true\n");
+#endif
+		return;
+	}
+	cflag = info->tty->termios->c_cflag;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("change_speed: info->tty->termios->c_iflag = 0x%X\n", info->tty->termios->c_iflag);
+	printk("change_speed: info->tty->termios->c_oflag = 0x%X\n", info->tty->termios->c_oflag);
+	printk("change_speed: info->tty->termios->c_cflag = 0x%X\n", info->tty->termios->c_cflag);
+	printk("change_speed: info->tty->termios->c_lflag = 0x%X\n", info->tty->termios->c_lflag);
+	printk("change_speed: info->tty->termios->c_line = 0x%X\n", info->tty->termios->c_line);
+#endif
+
+	tx_stop(info->line);
+	rx_stop(info->line);
+
+        /* init fifo buffer */
+        fifo_init(info->line);
+
+        /* Baud rate generator enabled */
+        paUART[info->line]->CR |= (0x0001 << UART_RunBit);
+
+	/* 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;
+
+#ifdef SERIAL_DEBUG_OPEN
+        printk("paUART[info->line]->BRR will be set as 0x%x\n", (u16)(fPCLK1_MHz / (16 * info->baud)));
+#endif
+        paUART[info->line]->BRR = (u16)(fPCLK1_MHz / (16 * info->baud));
+
+	/* UART control register: Mode/Stop Bits/ParityOdd */
+	uart_cr = paUART[info->line]->CR & 0xFFC0;
+	switch  (cflag & CSIZE) {
+		case CS5:
+		case CS6:
+                    printk("Don't support the configuration of 5 or 6 bits data per frame!\n");
+                    return;
+		case CS7:
+                    uart_cr |= UART_7BitsData;
+                    break;
+		case CS8:
+                    if (cflag & PARENB)
+                    {
+                        uart_cr |= UART_8BitsDataParity;
+                    }
+                    else
+                    {
+                        uart_cr |= UART_8BitsData;
+                    }
+                    break;
+                default:
+                    printk("Don't support the unknown configuration of frame!\n");
+                    return;
+	}
+
+	if (cflag & PARENB)
+	{
+	    uart_cr |= (cflag & PARODD) ? UART_ODD_PARITY : UART_EVEN_PARITY;
+	}
+        else
+        {
+            /* don't care this bit */
+	    uart_cr |= UART_ODD_PARITY;
+        }
+
+	if (cflag & CSTOPB)
+	{
+	    uart_cr |= UART_2_StopBits;
+	}
+        else
+        {
+	    uart_cr |= UART_1_StopBits;
+        }
+
+        paUART[info->line]->CR = uart_cr;
+#ifdef SERIAL_DEBUG_OPEN
+	printk("change_speed: new paUART[info->line]->CR = 0x%X\n", paUART[info->line]->CR);
+#endif
+
+	tx_start(info->line);
+	rx_start(info->line);
+
+#ifdef SERIAL_DEBUG_OPEN
+        printk("change_speed is successful!\n");
+#endif
+
+	return;
+}
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct str710_serial *info)
+{
+	volatile unsigned int tmout = 100000;
+
+        // if FIFO ENABLED
+        if (paUART[info->line]->CR & (0x0001<<UART_FIFOEnableBit))
+        {
+        // while the UART_TxFIFO contain 16 characters.
+            while((paUART[info->line]->SR & UART_TxFull))
+            {
+                if(--tmout == 0)
+                    break;
+            }
+        }
+        // if FIFO DISABLED
+        else
+        {
+        // while the transmit shift register not empty
+            while (!(paUART[info->line]->SR & UART_TxEmpty))
+            {
+                if(--tmout == 0)
+                    break;
+            }
+        }
+}
+
+static _INLINE_ void xmit_char(struct str710_serial *info, char ch)
+{
+	wait_for_xmitr(info);	
+	tx_delay();
+        paUART[info->line]->TBR = ch;
+}
+
+static void rs_set_ldisc(struct tty_struct *tty)
+{
+	struct str710_serial *info = (struct str710_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 str710_serial *info = (struct str710_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->line);
+		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->line);
+		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 str710_serial *info = (struct str710_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->line);
+		}
+	} 
+	restore_flags(flags);
+	
+	return total;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct str710_serial *info = (struct str710_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 str710_serial *info = (struct str710_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 str710_serial *info = (struct str710_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 str710_serial *info = (struct str710_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 str710_serial *info = (struct str710_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 str710_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 str710_serial *info,
+			   struct serial_struct *new_info)
+{
+	struct serial_struct new_serial;
+	struct str710_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 str710_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 str710_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 str710_serial *info = (struct str710_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 str710_serial));
+		if (error)
+			return error;
+		memcpy_tofs((struct str710_serial *) arg, info,
+			sizeof(struct str710_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 str710_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 str710_serial *info = (struct str710_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 str710_serial *info = (struct str710_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 != 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;
+/*			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 str710_serial *info = (struct str710_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 str710_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 str710_serial *info;
+	int retval, line;
+
+	line = MINOR(tty->device) - tty->driver.minor_start;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open 1: MINOR(tty->device) = %d, tty->driver.minor_start = %d\n", MINOR(tty->device), tty->driver.minor_start);
+        printk("rs_open 2: line = %d\n", line);
+#endif
+
+	/* check if line is sane */
+	if (line < 0 || line >= USART_CNT)
+		return -ENODEV;
+
+         info = &aStr710_info[line];
+
+         if(info->line != line)
+         {
+                printk("rs_open: line != info->line , line = %d, info->line = %d\n", line, info->line);
+                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)
+	{
+#ifdef SERIAL_DEBUG_OPEN
+        	printk("rs_open 3: startup proc failed! retval = %d\n", retval);
+#endif
+		return retval;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+        	printk("rs_open 4: startup proc successful!\n");
+#endif
+
+	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;
+	}
+
+#ifdef SERIAL_DEBUG_OPEN
+        	printk("rs_open 5: block_til_ready proc successful!\n");
+#endif
+
+	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;
+
+#ifdef SERIAL_DEBUG_OPEN
+        	printk("rs_open 6: block_til_ready proc successful!\n");
+#endif
+		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_uart_action =
+	{ rs_interrupt_act,  0, 0, "STR710_UART",  NULL, NULL };
+	
+extern int setup_arm_irq(int, struct irqaction *);
+
+static void interrupts_init(void)
+{
+        int nLoop;
+        for(nLoop = 0; nLoop < USART_CNT; nLoop++)
+        {
+	        EIC->SIR[aUART_IRQ[nLoop]] = (aUART_IRQ[nLoop]<<16) || 12;
+	        setup_arm_irq(aUART_IRQ[nLoop],  &irq_uart_action);
+        }
+}
+
+static void show_serial_version(void)
+{
+	printk("STMicroelectronics STR710 UART driver version 0.1\n");
+}
+
+/* rs_init inits the driver */
+static int __init rs_str710_init(void)
+{
+	int flags, i;
+	struct str710_serial *info;
+
+        do {
+                if(0 == USART_CNT) break;
+
+                // Configure the GPIO pins as alternate function push pull
+                GPIO_Config(GPIO0, UART0_Rx_Pin, GPIO_IN_TRI_CMOS);
+                GPIO_Config(GPIO0, UART0_Tx_Pin, GPIO_AF_PP);
+                if(1 == USART_CNT) break;
+
+                // Configure the GPIO pins as alternate function push pull
+                GPIO_Config(GPIO0, UART1_Rx_Pin, GPIO_IN_TRI_CMOS);
+                GPIO_Config(GPIO0, UART1_Tx_Pin, GPIO_AF_PP);
+                if(2 == USART_CNT) break;
+
+                // Configure the GPIO pins as alternate function push pull
+                GPIO_Config(GPIO0, UART2_Rx_Pin, GPIO_IN_TRI_CMOS);
+                GPIO_Config(GPIO0, UART2_Tx_Pin, GPIO_AF_PP);
+        } while(0);
+
+	/* 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 = USART_CNT;
+	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.init_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
+	ECHOKE | IEXTEN;
+
+	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 = &aStr710_info[i];
+		info->magic = SERIAL_MAGIC;
+		info->tty = 0;
+		info->irqmask = aUART_IRQ[i];
+		info->irq = aUART_IRQ[i];
+		info->port = i + 1;
+
+                /* line has been initialized in str710_console_setup */
+		//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 STMicroelectronics STR710 UART\n");
+	}
+	
+	interrupts_init();
+	
+	restore_flags(flags);
+	return 0;
+}
+
+module_init(rs_str710_init);
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+
+#ifdef CONFIG_SERIAL_STR710_CONSOLE
+
+static kdev_t str710_console_device(struct console *);
+static int    str710_console_setup(struct console *, char *);
+static void   str710_console_write (struct console *, const char *, unsigned int );
+
+static int    aStr710_console_initialized[USART_CNT];
+
+static struct console aStr710_console_driver[USART_CNT];
+
+/* static void init_console(struct str710_serial *info) */
+static int str710_console_setup(struct console *c, char *p)
+{
+	struct str710_serial *info = &aStr710_info[c->index];
+	
+	memset(info, 0, sizeof(struct str710_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);
+        info->line = c->index;
+	fifo_init(info->line);
+	info->baud = B115200;
+	
+//     info->usart->brgr = calcCD(info->baud);
+//     info->usart->ier = 0;
+	
+	aStr710_console_initialized[c->index] = 1;
+	return 0;
+}
+
+static kdev_t str710_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static void str710_console_write (struct console *c, const char *str,
+			   unsigned int count)
+{
+#if defined(CONFIG_CONSOLE_NULL)
+	return;
+#else
+	struct str710_serial *info = &aStr710_info[c->index];
+	
+	if (!aStr710_console_initialized[c->index])
+		printk ("WARNING: Console used unintialized\n");
+	
+	while (count--) {
+		if  (*str == '\n')
+			rs_put_char(info,'\r');
+        	rs_put_char(info, *str++ );
+	}
+#endif
+}
+
+void __init str710_console_init(void)
+{
+	int i;
+#ifdef SERIAL_DEBUG_OPEN
+	extern struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
+#endif
+
+        do {
+                if(0 == USART_CNT) break;
+
+                // Configure the GPIO pins as alternate function push pull
+                GPIO_Config(GPIO0, UART0_Rx_Pin, GPIO_IN_TRI_CMOS);
+                GPIO_Config(GPIO0, UART0_Tx_Pin, GPIO_AF_PP);
+                if(1 == USART_CNT) break;
+
+                // Configure the GPIO pins as alternate function push pull
+                GPIO_Config(GPIO0, UART1_Rx_Pin, GPIO_IN_TRI_CMOS);
+                GPIO_Config(GPIO0, UART1_Tx_Pin, GPIO_AF_PP);
+                if(2 == USART_CNT) break;
+
+                // Configure the GPIO pins as alternate function push pull
+                GPIO_Config(GPIO0, UART2_Rx_Pin, GPIO_IN_TRI_CMOS);
+                GPIO_Config(GPIO0, UART2_Tx_Pin, GPIO_AF_PP);
+        } while(0);
+
+        for(i = 0; i < USART_CNT; i++)
+        {
+                aStr710_console_initialized[i] = 0;
+                aStr710_console_driver[i].name[0] = 't';
+		aStr710_console_driver[i].name[1] = 't';
+		aStr710_console_driver[i].name[2] = 'y';
+		aStr710_console_driver[i].name[3] = 'S';
+		aStr710_console_driver[i].name[4] = '\0';
+                aStr710_console_driver[i].write = str710_console_write;
+                aStr710_console_driver[i].device = str710_console_device;
+                aStr710_console_driver[i].setup = str710_console_setup;
+                aStr710_console_driver[i].flags = CON_PRINTBUFFER;
+                aStr710_console_driver[i].index = i;
+
+	        register_console(&aStr710_console_driver[i]);
+        }
+
+#ifdef SERIAL_DEBUG_OPEN
+	for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
+        {
+                printk("console_cmdline[%d].name = %s\n", i, console_cmdline[i].name);
+                printk("console_cmdline[%d].index = %d\n", i, console_cmdline[i].index);
+	}
+#endif
+
+}
+
+#endif 
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
+
+/******************** (C) COPYRIGHT 2003 STMicroelectronics ********************
+* File Name          : gpio.c
+* Author             : MCD Application Team
+* Date First Issued  : 08/06/2003
+* Description        : This file provides all the GPIO software functions
+********************************************************************************
+* History:
+*  08/06/2003 : Created
+*******************************************************************************/
+
+/*******************************************************************************
+* Function Name  : GPIO_Config
+* Description    : Configure the GPIO port pins
+* Input 1        : GPIOx (x can be 0,1 or 2) the desired port
+* Input 2        : Port_Pins : pins placements
+* Input 3        : Pins Mode
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void GPIO_Config (GPIO_TypeDef *GPIOx, u16 Port_Pins, GpioPinMode_TypeDef GPIO_Mode)
+{
+  switch (GPIO_Mode)
+  {
+    case GPIO_HI_AIN_TRI:
+      GPIOx->PC0&=~Port_Pins;
+      GPIOx->PC1&=~Port_Pins;
+      GPIOx->PC2&=~Port_Pins;
+      break;
+
+    case GPIO_IN_TRI_TTL:
+      GPIOx->PC0|=Port_Pins;
+      GPIOx->PC1&=~Port_Pins;
+      GPIOx->PC2&=~Port_Pins;
+      break;
+
+    case GPIO_IN_TRI_CMOS:
+      GPIOx->PC0&=~Port_Pins;
+      GPIOx->PC1|=Port_Pins;
+      GPIOx->PC2&=~Port_Pins;
+      break;
+
+    case GPIO_INOUT_WP:
+      GPIOx->PC0|=Port_Pins;
+      GPIOx->PC1|=Port_Pins;
+      GPIOx->PC2&=~Port_Pins;
+      break;
+
+    case GPIO_OUT_OD:
+      GPIOx->PC0&=~Port_Pins;
+      GPIOx->PC1&=~Port_Pins;
+      GPIOx->PC2|=Port_Pins;
+      break;
+
+    case GPIO_OUT_PP:
+      GPIOx->PC0|=Port_Pins;
+      GPIOx->PC1&=~Port_Pins;
+      GPIOx->PC2|=Port_Pins;
+      break;
+
+    case GPIO_AF_OD:
+      GPIOx->PC0&=~Port_Pins;
+      GPIOx->PC1|=Port_Pins;
+      GPIOx->PC2|=Port_Pins;
+      break;
+
+    case GPIO_AF_PP:
+      GPIOx->PC0|=Port_Pins;
+      GPIOx->PC1|=Port_Pins;
+      GPIOx->PC2|=Port_Pins;
+      break;
+  }
+}
+
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/char/serial_str710.h uClinux-dist-20040408/linux-2.4.x/drivers/char/serial_str710.h
--- uClinux-dist/linux-2.4.x/drivers/char/serial_str710.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/char/serial_str710.h	2004-09-16 10:32:50.000000000 +0800
@@ -0,0 +1,180 @@
+/*
+ * drivers/char/serial_str710.h
+ * 
+ * Serial port driver for the STR710 builtin UART
+ *
+ * Copyright (c) 2004 STMicroelectronics Corp.
+ *      by Kevin Zhu <kevin.zhu@st.com>
+ *
+ * Based on: drivers/char/serial_s3c3410.h
+ * 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 _STR710_SERIAL_H
+#define _STR710_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 str710_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;
+} str_baud_table_t;
+
+#define RS_EVENT_WRITE_WAKEUP   0
+#define SERIAL_MAGIC 0x5301
+
+#endif 
+
+
+/******************** (C) COPYRIGHT 2003 STMicroelectronics ********************
+* File Name          : gpio.h
+* Author             : MCD Application Team
+* Date First Issued  : 08/06/2003
+* Description        : This file contains all the functions prototypes for the
+*                      GPIO software library.
+************************************************************************/
+#ifndef _STR710_GPIO_H
+#define _STR710_GPIO_H
+
+typedef enum
+{
+  GPIO_HI_AIN_TRI,
+  GPIO_IN_TRI_TTL,
+  GPIO_IN_TRI_CMOS,
+  GPIO_INOUT_WP,
+  GPIO_OUT_OD,
+  GPIO_OUT_PP,
+  GPIO_AF_OD,
+  GPIO_AF_PP
+} GpioPinMode_TypeDef;
+
+#define UART0_Rx_Pin (0x0001<<8)
+#define UART0_Tx_Pin (0x0001<<9)
+
+#define UART1_Rx_Pin (0x0001<<10)
+#define UART1_Tx_Pin (0x0001<<11)
+
+#define UART2_Rx_Pin (0x0001<<13)
+#define UART2_Tx_Pin (0x0001<<14)
+
+#endif
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/char/tty_io.c uClinux-dist-20040408/linux-2.4.x/drivers/char/tty_io.c
--- uClinux-dist/linux-2.4.x/drivers/char/tty_io.c	2004-04-08 08:16:18.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/char/tty_io.c	2004-09-08 09:51:45.000000000 +0800
@@ -175,6 +175,7 @@
 extern void c5471_console_init(void);
 extern void bf535_console_init(void);
 extern void bf533_console_init(void);
+extern void str710_console_init(void);
 
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
@@ -2340,6 +2341,9 @@
 #ifdef CONFIG_SERIAL_S3C44B0X_CONSOLE
 	s3c44b0x_console_init();
 #endif
+#ifdef CONFIG_SERIAL_STR710_CONSOLE
+	str710_console_init();
+#endif
 #ifdef CONFIG_SERIAL_S3C4530_CONSOLE
 	s3c4530_console_init();
 #endif
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/i2c/Config.in uClinux-dist-20040408/linux-2.4.x/drivers/i2c/Config.in
--- uClinux-dist/linux-2.4.x/drivers/i2c/Config.in	2004-04-08 08:16:20.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/i2c/Config.in	2004-09-14 16:39:05.000000000 +0800
@@ -311,6 +310,8 @@
       dep_tristate 'SiByte SMBus interface' CONFIG_I2C_ALGO_SIBYTE $CONFIG_I2C
       dep_tristate '  MAX1617 Temperature Sensor' CONFIG_I2C_MAX1617 $CONFIG_I2C_ALGO_SIBYTE
    fi
+  
+   dep_tristate 'STR710 I2C Controller support' CONFIG_I2C_STR710 $CONFIG_I2C
 
 # This is needed for automatic patch generation: sensors code starts here
 # This is needed for automatic patch generation: sensors code ends here
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/i2c/i2c-adap-str71x.c uClinux-dist-20040408/linux-2.4.x/drivers/i2c/i2c-adap-str71x.c
--- uClinux-dist/linux-2.4.x/drivers/i2c/i2c-adap-str71x.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/i2c/i2c-adap-str71x.c	2004-09-14 17:33:30.000000000 +0800
@@ -0,0 +1,177 @@
+/*
+   -------------------------------------------------------------------------
+   i2c-adap-str71x.c i2c-hw access for the I2C Contorller on STR71x
+   -------------------------------------------------------------------------
+  
+	MMCC China, STMicroelectronics
+
+   ----------------------------------------------------------------------------
+   This file was highly leveraged from i2c-elektor.c, which was created
+   by Simon G. Vogl and Hans Berglund:
+
+ 
+     Copyright (C) 1995-97 Simon G. Vogl
+                   1998-99 Hans Berglund
+
+   With some changes from Ky�ti M�kki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+   ----------------------------------------------------------------------------
+
+   Revision History: 
+   =================================================================
+   14/Sep/04	xinghua Li			Create this file.
+
+*/
+
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include "i2c-str71x.h"
+#include <asm/irq.h>
+#include <asm/io.h>
+
+/*
+ * This next section is configurable, and it is used to set the number
+ * of i2c controllers in the system.  The default number of instances is 1,
+ * however, this should be changed to reflect your system's configuration.
+ */ 
+
+/*
+ * The STR71X has two i2c controllers.
+ */
+
+#define IIC_NUMS 2
+
+const unsigned int IIC_BASEADDR[2] = {I2C0_BASE,I2C1_BASE};
+
+static struct i2c_str71x_algo_data *iic_str71x_data[IIC_NUMS];
+static struct i2c_adapter *iic_str71x_ops[IIC_NUMS];
+
+/* module parameters:
+ */
+static int i2c_debug=2;
+
+/* ----- 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 				*/
+
+/* ----- local functions ----------------------------------------------	*/
+
+
+//
+// Description: Called when the module is loaded.  This function starts the
+// cascade of calls up through the heirarchy of i2c modules (i.e. up to the
+//  algorithm layer and into to the core layer)
+//
+static int __init iic_str71x_init(void) 
+{
+   int i;
+   GPIO_TypeDef * gpio_reg;
+
+   printk(KERN_INFO "iic_str71x_init: STR71x on-chip I2C adapter module\n");
+ 
+   for(i=0; i<IIC_NUMS; i++) {
+      iic_str71x_data[i] = kmalloc(sizeof(struct i2c_str71x_algo_data),GFP_KERNEL);
+      if(iic_str71x_data[i] == NULL) {
+         return -ENOMEM;
+      }
+      memset(iic_str71x_data[i], 0, sizeof(struct i2c_str71x_algo_data));
+
+      iic_str71x_data[i]->iic_base = (u32)ioremap((unsigned long)IIC_BASEADDR[i],PAGE_SIZE);
+
+      iic_str71x_ops[i] = kmalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+      if(iic_str71x_ops[i] == NULL) {
+         return -ENOMEM;
+      }
+      memset(iic_str71x_ops[i], 0, sizeof(struct i2c_adapter));
+      sprintf(iic_str71x_ops[i]->name, "STR71x IIC adapter %d",i);
+      //iic_str71x_ops[i]->owner = THIS_MODULE;
+      iic_str71x_ops[i]->id = I2C_HW_STR71X;
+      iic_str71x_ops[i]->algo = NULL;
+      iic_str71x_ops[i]->algo_data = iic_str71x_data[i];
+       
+	switch(i)
+	{
+		case 0:
+		//Config P1.13/P1.14 as I2C0 SCL/SDA open-drain
+		//to do....
+		    gpio_reg = (GPIO_TypeDef *)ioremap((unsigned long)GPIO1_BASE,PAGE_SIZE);
+			gpio_reg->PC0 &= ~(3<<13);
+			gpio_reg->PC1 |= (3<<13);
+			gpio_reg->PC2 |= (3<<13);
+
+			break;
+		case 1:
+		//Config P0.2/P0.3 as I2C1 SCL/SDA open drain
+		//to do...
+		    gpio_reg = (GPIO_TypeDef *)ioremap((unsigned long)GPIO0_BASE,PAGE_SIZE);
+			gpio_reg->PC0 &= ~(3<<2);
+			gpio_reg->PC1 |= (3<<2);
+			gpio_reg->PC2 |= (3<<2);
+			break;
+		default:
+			break;
+	}
+	iounmap((void *)gpio_reg);
+
+	  
+	 if (i2c_str71x_add_bus(iic_str71x_ops[i]) < 0)
+	 return -ENODEV;
+
+	 DEB(printk(KERN_INFO "iic_str71x_init: found device at %#x.\n\n", iic_str71x_data[i]->iic_base));
+   }
+   return 0;
+}
+
+
+static void __exit iic_str71x_exit(void)
+{
+   int i;
+
+   for(i=0; i<IIC_NUMS; i++) {
+      i2c_str71x_del_bus(iic_str71x_ops[i]);
+
+      //free allocated memory space
+	  iounmap((void *)(iic_str71x_data[i]->iic_base));
+	  kfree(iic_str71x_data[i]);
+      kfree(iic_str71x_ops[i]);
+   }
+
+}
+
+//
+// If modules is NOT defined when this file is compiled, then the MODULE_*
+// macros will resolve to nothing
+//
+MODULE_AUTHOR("STMicro <www.st.com>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for STR71x I2C Module");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(i2c_debug,"i");
+
+
+module_init(iic_str71x_init);
+module_exit(iic_str71x_exit); 
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/i2c/i2c-algo-str71x.c uClinux-dist-20040408/linux-2.4.x/drivers/i2c/i2c-algo-str71x.c
--- uClinux-dist/linux-2.4.x/drivers/i2c/i2c-algo-str71x.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/i2c/i2c-algo-str71x.c	2004-09-20 17:11:47.000000000 +0800
@@ -0,0 +1,435 @@
+/*
+   -------------------------------------------------------------------------
+   i2c-algo-str71x.c i2c driver algorithms for STR71x I2C adapters	    
+	
+	MMCC China, STMicroelectronics
+
+   -------------------------------------------------------------------------
+      
+   This file was highly leveraged from 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
+
+   With some changes from Ky�ti M�kki <kmalkki@cc.hut.fi> and 
+   Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
+   <mbailey@littlefeet-inc.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.
+   ---------------------------------------------------------------------------
+
+   REVISION HISTORY: 
+	=========================================================================
+   14/Sep/04	Xinghua	Li	Initial version
+
+*/
+
+
+#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/i2c.h>
+#include <linux/i2c-id.h>
+#include <asm/delay.h>
+#include "i2c-str71x.h"
+#include "asm/arch/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 /* print several statistical values*/
+#define DEBPROTO(x) if (i2c_debug>=9) x;
+
+
+/* module parameters:
+ */
+static int i2c_debug=2;
+
+
+//
+// Description: This performs the IIC initialization sequence
+// as described in the STR710 processor data book.
+//
+static int iic_init (struct i2c_str71x_algo_data *iic_algodata)
+{
+	I2C_TypeDef *iic = (I2C_TypeDef *)iic_algodata->iic_base;	
+	unsigned short clkdiv = (fPCLK1_MHz/(2*100000))-7;
+	
+	//init regs
+	iic->CR=0x0;
+	iic->OAR1=0x0;
+	iic->OAR2=0x20;
+	(void)iic->SR1;
+	(void)iic->SR2;
+	iic->DR=0x0;
+	//Peripheral enable
+	iic->CR |= 0x20;	//bit5 PE
+	iic->CR |= 0x20;	//set TWICE
+	//config speed 100K
+	iic->CCR = clkdiv & 0x7f;
+	iic->ECCR = clkdiv >> 7;
+
+    //DEB2(printk(KERN_DEBUG "iic_init: Initialized I2C on STR710x\n"));
+    return 0;
+}
+
+static void I2C_AddressSend (I2C_TypeDef *I2Cx, unsigned short Address, int Mode, int Direction)
+{
+	int to = 500;
+  if (Mode == 1 )
+  //10 bit addressing mode
+  {
+
+    // Update the DR register by generated header
+    I2Cx->DR = ((Address>>7)|0xf0)&0xfe;
+    //Wait till I2C_ADD10 flag is set
+	while ((I2Cx->SR1&0x40)==0);
+    //clear I2C_ADD10 flag
+    (void)I2Cx->SR2;
+    I2Cx->DR=(u8)Address;
+    //Test on the direction to define the read/write bit
+    if (Direction == 1)//Receive
+    {
+      //Wait till I2C_ENDAD flag is set
+      while ((I2Cx->SR2&0x20)==0);
+      I2Cx->CR|=0x20;
+      //Repeated START Generate
+      I2Cx->CR|=0x08;
+      //Test on SB flag status
+      while ((I2Cx->SR1&0x01)==0);
+      I2Cx->DR = ((Address>>7)|0xf1);
+    }
+
+  }
+  else
+  // 7 bit addressing mode
+  {
+  	Address <<= 1;
+    if (Direction == 1) Address|=0x01; //Receive
+	else Address&=~0x01;
+    I2Cx->DR=(u8)Address;
+  }
+}
+
+
+//
+//Master Transmit
+//return the transmission status
+
+static int I2C_BufferSend (I2C_TypeDef *I2Cx,unsigned char *PtrToBuffer, unsigned char NbOfBytes, int genstop)
+{
+  unsigned char SentBytes;
+  unsigned char error;
+  int I2C_TXTMP,to;
+
+  to = 500;	//timeout 3000us
+  //Wait till I2C_BTF bit is set
+  while ((I2Cx->SR1 & 0x08)==0 && to--)	udelay(10);
+  //while ((I2Cx->SR1 & 0x08)==0);
+  
+  if (to <= 0)	return I2C_EVENTTO;
+  
+  SentBytes=0;
+  while (SentBytes<NbOfBytes)
+  {
+    I2Cx->DR= *(PtrToBuffer+SentBytes);
+
+	//Wait till I2C_BTF bit is set or error detected
+    to = 500;	
+    do
+	{
+		udelay(10);
+      	error = I2Cx->SR2 & 0x16;
+    }while ((I2Cx->SR1 & 0x08)==0 && error==0 && to--);
+	//while  ((I2Cx->SR1 & 0x08)==0 && error==0 );
+	
+	if (to<=0) return I2C_EVENTTO;
+	//STOP after writing the last byte
+	
+	if ((SentBytes == NbOfBytes-1) && genstop)
+	{
+		I2Cx->CR |= 0x02;
+	}
+
+    // In case of error exit
+    if (error) break;
+    // increment SentBytes counter
+    SentBytes++;
+  }
+  if (error)
+  {
+    if (error & 0x10)
+      // I2C_TX_AF if Acknowledge failure is detected
+      I2C_TXTMP = I2C_ERR_AF;
+    if (error & 0x04)
+      //I2C_TX_ARLO if the ARLO bit is set in the SR2 register
+      I2C_TXTMP = I2C_ERR_ARLO;
+    if (error & 0x02)
+      // I2C_TX_BERR if the BERR bit is set in the SR2 register
+      I2C_TXTMP=  I2C_ERR_BERR;
+  }
+  else
+    //I2C_DATA_OK to show that the buffer is well sent
+    I2C_TXTMP= I2C_DATA_OK;
+
+  return I2C_TXTMP;
+}
+
+// Master Receive
+// return the receiving status
+static int I2C_BufferReceive (I2C_TypeDef *I2Cx, unsigned char*PtrToBuffer, unsigned char NbOfBytes)
+{
+  u8 ReceivedBytes;
+  u8 error;
+  int I2C_RXTMP,to;
+
+  ReceivedBytes=0;
+
+  if (NbOfBytes > 1)
+  {
+	  I2Cx->CR  |= 0x04;	//Enable  ACK (CR.2)
+  }
+
+  while (ReceivedBytes<NbOfBytes)
+  {
+	to = 500;
+    do
+	{
+	 udelay(10);
+      error = I2Cx->SR2 & 0x16;
+    }while ((I2Cx->SR1 & 0x08)==0 && !error && to--);
+	//while ((I2Cx->SR1 & 0x08)==0 && !error);
+	if(to <= 0)	return I2C_EVENTTO;	
+    
+	if (error==0)
+    // No error detected
+    {
+		//STOP(CR.1) before reading the last byte
+		if (ReceivedBytes == NbOfBytes-1)
+		{
+			I2Cx->CR |= 0x02;
+		}
+		
+		else //NAK before reading the second last data byte
+		if (ReceivedBytes == NbOfBytes-2)
+		{
+			I2Cx->CR &= ~0x04;
+		}
+      *(PtrToBuffer+ReceivedBytes) = I2Cx->DR;
+      ReceivedBytes++;
+    }
+    else break;
+  }
+  if (error)
+  {
+    if (error & 0x10)
+      // I2C_RX_AF if Acknowledge failure is detected
+      I2C_RXTMP= I2C_ERR_AF;
+    else if (error & 0x04)
+      // I2C_RX_ARLO if the ARLO bit is set in the SR2 register
+      I2C_RXTMP=  I2C_ERR_ARLO;
+    else if (error & 0x02)
+      // I2C_RX_BERR if the BERR bit is set in the SR2 register
+      I2C_RXTMP=  I2C_ERR_BERR;
+  }
+  else
+    //I2C_DATA_OK to show that the buffer is well sent
+    I2C_RXTMP= I2C_DATA_OK;
+
+  return I2C_RXTMP;
+}
+
+
+// Transfer a single message as Master.
+// return the error code.
+//
+
+static int iic_single_xfer(I2C_TypeDef *iic,struct i2c_msg *msg,int genstop)
+{
+	int ret = 0,to = 500;
+	
+	//step 1, generate START (CR.3) ,then wait for EV5
+	iic->CR |= 0x08;	
+	//EV5: EVF(SR1.7)=1 SB(SR1.0)=1 cleared by reading SR1 followed by writing DR
+	//while ((iic->SR1 & 0x81) != 0x81);
+	while ((iic->SR1 & 0x81) != 0x81	&& to--) udelay(10);
+	if (to <=0)	return I2C_EVENTTO;
+	
+	//step 2, send slave address , and then wait for EV6
+	I2C_AddressSend(iic,msg->addr,(msg->flags & I2C_M_TEN),(msg->flags & I2C_M_RD));
+	//wait EV6: EVF =1 ENDAD=1(SR2.5) , cleared by reading SR2 followed by writing CR
+	while ((iic->SR2 & 0x20) != 0x20 && to--)	udelay(10);
+	//while ((iic->SR2 & 0x20) != 0x20);
+	iic->CR |= 0x20;	//set PE to clear ENDAD bit
+	if (to <=0)	return I2C_EVENTTO;
+
+	//step 3,transmit or receive
+	if (msg->flags & I2C_M_RD)
+	{
+		ret = I2C_BufferReceive(iic,msg->buf,msg->len);
+	}
+	else
+	{
+		ret = I2C_BufferSend(iic,msg->buf,msg->len,genstop);
+	}
+		
+	return ret;
+}
+
+
+//
+// Description: Transfer multiple messages as Master.
+// return : the number of msgs successfully transferred.
+
+static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+	int i = 0;
+	int ret;
+
+	I2C_TypeDef *iic = (I2C_TypeDef *)(((struct i2c_str71x_algo_data *)(adap->algo_data))->iic_base);
+	
+	if (num == 0) return 0;
+
+	//basic initialization......
+	iic->CR=0x0;
+	(void)iic->SR1;
+	(void)iic->SR2;
+	iic->DR=0x0;
+	//Peripheral Enable(CR.5)
+	iic->CR |= 0x20;	//bit5 PE
+	iic->CR |= 0x20;	//set TWICE
+	
+	if (num == 1)
+	{
+		if (iic_single_xfer(iic,&msgs[0],1) == I2C_DATA_OK) ret = msgs[0].len;
+		else
+		{
+		 ret = -1;
+		}
+	}
+	else{
+
+		for (i=0; i<num; i++ )
+		{
+			if (iic_single_xfer(iic,&msgs[i],i== (num-1)) != I2C_DATA_OK) 
+			{
+				ret = -1 ;
+				break;
+			}
+		}
+		ret = msgs[num-1].len;
+	}
+	
+	//wait until go back to Slave mode
+	while(iic->SR1 & 0x02) ;
+	//disable i2c finally
+	iic->CR &= ~0x20;
+	
+	return ret;
+
+}
+
+//
+// Description: Implements device specific ioctls.  Higher level ioctls can
+// be found in i2c-core.c and are typical of any i2c controller (specifying
+// slave address, timeouts, etc).  These ioctls take advantage of any hardware
+// features built into the controller for which this algorithm-adapter set
+// was written.
+//
+static int algo_control(struct i2c_adapter *adapter, 
+	unsigned int cmd, unsigned long arg)
+{
+	//do nothing right now.
+	return 0;
+}
+
+
+static u32 iic_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
+	       I2C_FUNC_PROTOCOL_MANGLING; 
+}
+
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static struct i2c_algorithm iic_algo = {
+//	.owner		= THIS_MODULE,
+	.name		= "STR71x on-chip IIC algorithm",
+	.id		= I2C_ALGO_STR71X,	
+	.master_xfer	= iic_xfer, 
+	.algo_control	= algo_control,
+	.functionality	= iic_func,
+};
+
+/* 
+ * registering functions to load algorithms at runtime 
+ */
+
+
+//
+// Description: Register bus structure
+//
+int i2c_str71x_add_bus(struct i2c_adapter *adap)
+{
+	DEB2(printk(KERN_DEBUG "i2c-algo-str71x.o: hw routines for %s registered.\n",
+	            adap->name));
+
+	/* register new adapter to i2c module... */
+
+	adap->id |= iic_algo.id;
+	adap->algo = &iic_algo;
+
+	adap->timeout = 100;	/* default values, should	*/
+	adap->retries = 3;		/* be replaced by defines	*/
+
+	iic_init((struct i2c_str71x_algo_data *)(adap->algo_data));
+	i2c_add_adapter(adap);
+	return 0;
+}
+
+
+//
+// Done
+//
+int i2c_str71x_del_bus(struct i2c_adapter *adap)
+{
+	return i2c_del_adapter(adap);
+}
+
+
+EXPORT_SYMBOL(i2c_str71x_add_bus);
+EXPORT_SYMBOL(i2c_str71x_del_bus);
+
+//
+// The MODULE_* macros resolve to nothing if MODULES is not defined
+// when this file is compiled.
+//
+MODULE_AUTHOR("STMicro <www.st.com>");
+MODULE_DESCRIPTION("STR71x iic algorithm");
+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 --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/i2c/i2c-str71x.h uClinux-dist-20040408/linux-2.4.x/drivers/i2c/i2c-str71x.h
--- uClinux-dist/linux-2.4.x/drivers/i2c/i2c-str71x.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/i2c/i2c-str71x.h	2004-09-20 10:37:30.000000000 +0800
@@ -0,0 +1,49 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-str71x.h 	internal head files										*/
+/* 	MMCC China, STMicroelectronics											*/
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-97 Simon G. Vogl
+                   1998-99 Hans Berglund
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU 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.                */
+/* ------------------------------------------------------------------------- */
+/*
+	REVISION HISTORY:
+	========================================================================
+	14/Sep/04	Xinghua LI		Create this file.
+
+*/
+
+#ifndef _LINUX_I2C_ALGO_STR71X_H
+#define _LINUX_I2C_ALGO_STR71X_H
+
+//transfer Status
+#define  I2C_ERR_AF			-1	//Acknowledge Failure
+#define  I2C_ERR_ARLO		-2	//Arbitration Lost
+#define  I2C_ERR_BERR		-3	//Bus error
+#define  I2C_ADD_OK		0	//add sent OK
+#define  I2C_DATA_OK	0	//data transferred OK
+#define  I2C_EVENTTO	-5	//Timeout waiting for some event
+
+struct i2c_str71x_algo_data {
+
+	unsigned int iic_base;	//base address of register(ioremap)
+};
+
+
+int i2c_str71x_add_bus(struct i2c_adapter *);
+int i2c_str71x_del_bus(struct i2c_adapter *);
+
+#endif /* _LINUX_I2C_ALGO_STR71X_H */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/i2c/Makefile uClinux-dist-20040408/linux-2.4.x/drivers/i2c/Makefile
--- uClinux-dist/linux-2.4.x/drivers/i2c/Makefile	2004-04-08 08:16:20.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/i2c/Makefile	2004-09-14 17:28:42.000000000 +0800
@@ -37,6 +37,10 @@
 obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 
+ifeq ($(CONFIG_I2C_STR710),y)
+obj-y	+= i2c-algo-str71x.o i2c-adap-str71x.o
+endif
+
 # This is needed for automatic patch generation: sensors code starts here
 # This is needed for automatic patch generation: sensors code ends here
 
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/mtd/chips/cfi_cmdset_0001.c uClinux-dist-20040408/linux-2.4.x/drivers/mtd/chips/cfi_cmdset_0001.c
--- uClinux-dist/linux-2.4.x/drivers/mtd/chips/cfi_cmdset_0001.c	2004-04-08 08:16:26.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/mtd/chips/cfi_cmdset_0001.c	2004-09-21 12:08:32.000000000 +0800
@@ -267,16 +267,24 @@
 	}
 
 #ifndef FORCE_WORD_WRITE
-	if ( cfi->cfiq->BufWriteTimeoutTyp ) {
-		printk("Using buffer write method\n" );
+
+#ifdef CONFIG_ARCH_STR710
+	/*FIXME: ST710 has a M28W320CB chip that does not support buffer write*/
+	if (cfi->cfiq->MaxBufWriteSize > 3) 
+#else
+	if ( cfi->cfiq->BufWriteTimeoutTyp )
+#endif	
+	{
+		printk("Using buffer write method\n");
 		mtd->write = cfi_intelext_write_buffers;
 	} else {
 #else
 	{
 #endif
-		printk("Using word write method\n" );
+		printk("Using word write method\n");
 		mtd->write = cfi_intelext_write_words;
 	}
+
 	mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
 	mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
 	mtd->sync = cfi_intelext_sync;
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/mtd/maps/Config.in uClinux-dist-20040408/linux-2.4.x/drivers/mtd/maps/Config.in
--- uClinux-dist/linux-2.4.x/drivers/mtd/maps/Config.in	2004-04-08 08:16:26.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/mtd/maps/Config.in	2004-09-13 16:26:50.000000000 +0800
@@ -119,6 +119,7 @@
    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 EDB7312' CONFIG_MTD_EDB7312 $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on STR710' CONFIG_MTD_STR710 $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
 fi
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/mtd/maps/Makefile uClinux-dist-20040408/linux-2.4.x/drivers/mtd/maps/Makefile
--- uClinux-dist/linux-2.4.x/drivers/mtd/maps/Makefile	2004-04-08 08:16:26.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/mtd/maps/Makefile	2004-09-13 16:28:31.000000000 +0800
@@ -28,6 +28,7 @@
 obj-$(CONFIG_MTD_NORA)		+= nora.o
 obj-$(CONFIG_MTD_CEIVA)		+= ceiva.o
 obj-$(CONFIG_MTD_OCTAGON)	+= octagon-5066.o
+obj-$(CONFIG_MTD_STR710)	+= str71x_map.o
 ifneq ($(CONFIG_MTD_PHYSMAP),n)
   ifeq ($(CONFIG_MTD_PHYSMAP_BUSWIDTH),8)
     obj-$(CONFIG_MTD_PHYSMAP)	+= physmap64.o 
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/mtd/maps/str71x_map.c uClinux-dist-20040408/linux-2.4.x/drivers/mtd/maps/str71x_map.c
--- uClinux-dist/linux-2.4.x/drivers/mtd/maps/str71x_map.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/mtd/maps/str71x_map.c	2004-09-14 12:25:44.000000000 +0800
@@ -0,0 +1,256 @@
+#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 0x60000000
+#define WINDOW_SIZE 0x00400000
+#define BUSWIDTH    2
+
+#define EXT_FLASH_BASE      ((volatile unsigned short *)0x60000000)
+#define EXT_FLASH_BLKNUM    (71)
+
+static struct mtd_info *mymtd;
+
+const unsigned int M28W320B_Blk_Off[] =
+{
+      0x000000,  /* Start offset of block 0  */
+      0x001000,  /* Start offset of block 1  */
+      0x002000,  /* Start offset of block 2  */
+      0x003000,  /* Start offset of block 3  */
+      0x004000,  /* Start offset of block 4  */
+      0x005000,  /* Start offset of block 5  */
+      0x006000,  /* Start offset of block 6  */
+      0x007000,  /* Start offset of block 7  */
+      0x008000,  /* Start offset of block 8  */
+      0x010000,  /* Start offset of block 9  */
+      0x018000,  /* Start offset of block 10 */
+      0x020000,  /* Start offset of block 11 */
+      0x028000,  /* Start offset of block 12 */
+      0x030000,  /* Start offset of block 13 */
+      0x038000,  /* Start offset of block 14 */
+      0x040000,  /* Start offset of block 15 */
+      0x048000,  /* Start offset of block 16 */
+      0x050000,  /* Start offset of block 17 */
+      0x058000,  /* Start offset of block 18 */
+      0x060000,  /* Start offset of block 19 */
+      0x068000,  /* Start offset of block 20 */
+      0x070000,  /* Start offset of block 21 */
+      0x078000,  /* Start offset of block 22 */
+      0x080000,  /* Start offset of block 23 */
+      0x088000,  /* Start offset of block 24 */
+      0x090000,  /* Start offset of block 25 */
+      0x098000,  /* Start offset of block 26 */
+      0x0A0000,  /* Start offset of block 27 */
+      0x0A8000,  /* Start offset of block 28 */
+      0x0B0000,  /* Start offset of block 29 */
+      0x0B8000,  /* Start offset of block 30 */
+      0x0C0000,  /* Start offset of block 31 */
+      0x0C8000,  /* Start offset of block 32 */
+      0x0D0000,  /* Start offset of block 33 */
+      0x0D8000,  /* Start offset of block 34 */
+      0x0E0000,  /* Start offset of block 35 */
+      0x0E8000,  /* Start offset of block 36 */
+      0x0F0000,  /* Start offset of block 37 */
+      0x0F8000,  /* Start offset of block 38 */
+      0x100000,  /* Start offset of block 39 */
+      0x108000,  /* Start offset of block 40 */
+      0x110000,  /* Start offset of block 41 */
+      0x118000,  /* Start offset of block 42 */
+      0x120000,  /* Start offset of block 43 */
+      0x128000,  /* Start offset of block 44 */
+      0x130000,  /* Start offset of block 45 */
+      0x138000,  /* Start offset of block 46 */
+      0x140000,  /* Start offset of block 47 */
+      0x148000,  /* Start offset of block 48 */
+      0x150000,  /* Start offset of block 49 */
+      0x158000,  /* Start offset of block 50 */
+      0x160000,  /* Start offset of block 51 */
+      0x168000,  /* Start offset of block 52 */
+      0x170000,  /* Start offset of block 53 */
+      0x178000,  /* Start offset of block 54 */
+      0x180000,  /* Start offset of block 55 */
+      0x188000,  /* Start offset of block 56 */
+      0x190000,  /* Start offset of block 57 */
+      0x198000,  /* Start offset of block 58 */
+      0x1A0000,  /* Start offset of block 59 */
+      0x1A8000,  /* Start offset of block 60 */
+      0x1B0000,  /* Start offset of block 61 */
+      0x1B8000,  /* Start offset of block 62 */
+      0x1C0000,  /* Start offset of block 63 */
+      0x1C8000,  /* Start offset of block 64 */
+      0x1D0000,  /* Start offset of block 65 */
+      0x1D8000,  /* Start offset of block 66 */
+      0x1E0000,  /* Start offset of block 67 */
+      0x1E8000,  /* Start offset of block 68 */
+      0x1F0000,  /* Start offset of block 69 */
+      0x1F8000   /* Start offset of block 70 */
+};
+
+int ExtFlashBlockUnlock (unsigned int u32BlkNum)
+{
+    int iRetVal = 0;
+    unsigned short u16ProtStat;
+
+    /* check the block number */
+    if (u32BlkNum >= EXT_FLASH_BLKNUM)
+    {
+        return -1;
+    }
+
+    /* unlock the block */
+    EXT_FLASH_BASE[0] = 0x0060;
+    EXT_FLASH_BASE[M28W320B_Blk_Off[u32BlkNum]] = 0x00D0;
+
+    /* check the block protection status */
+    EXT_FLASH_BASE[0] = 0x0090;
+    u16ProtStat = EXT_FLASH_BASE[M28W320B_Blk_Off[u32BlkNum] + 0x00000002];
+    if (u16ProtStat & 0x0001)
+    {
+        /* failed */
+        iRetVal = -1;
+    }
+
+    /* reset the flash */
+    EXT_FLASH_BASE[0] = 0x00FF;
+    return iRetVal;
+}
+
+int ExtFlashAllUnlock (void)
+{
+    unsigned int i;
+
+    for (i=0; i<EXT_FLASH_BLKNUM; i++)
+    {
+        if (ExtFlashBlockUnlock(i) != 0)
+        {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+__u8 str71x_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 str71x_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 str71x_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void str71x_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+void str71x_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void str71x_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void str71x_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void str71x_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 str71x_map = {
+	name: "STR71x External Flash",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: str71x_read8,
+	read16: str71x_read16,
+	read32: str71x_read32,
+	copy_from: str71x_copy_from,
+	write8: str71x_write8,
+	write16: str71x_write16,
+	write32: str71x_write32,
+	copy_to: str71x_copy_to
+};
+
+static struct mtd_partition str71x_partitions[] = {
+        {
+                name:   "Boot Loader",
+                size:   0x00010000,
+                offset: 0x00000000,
+                mask_flags: MTD_WRITEABLE
+        },
+        {
+                name:   "uCLinux Image",
+                size:   0x001f0000,
+                offset: 0x00010000,
+                mask_flags: MTD_WRITEABLE
+        },
+        {
+                name:   "JFFS2 Disk",
+                size:   0x00200000,
+                offset: 0x00200000
+        }
+};
+
+int __init init_str71x(void)
+{
+    printk(KERN_NOTICE "str71x external flash: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	str71x_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+	if (!str71x_map.map_priv_1)
+	{
+		printk("Failed to ioremap!\n");
+		return -EIO;
+	}
+
+	mymtd = do_map_probe("cfi_probe", &str71x_map);
+	if (!mymtd) {
+		mymtd = do_map_probe("jedec_probe", &str71x_map);
+	}
+	if (mymtd) {
+		if (ExtFlashAllUnlock() == 0)
+			printk("Flash Unlocked.\n");
+		else
+			printk("Flash Unlock Failed!\n");
+		mymtd->module = THIS_MODULE;
+		mymtd->erasesize = 0x10000;
+		return add_mtd_partitions(mymtd, str71x_partitions, sizeof(str71x_partitions) / sizeof(struct mtd_partition));
+	}
+
+	iounmap((void *)str71x_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_str71x(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+	}
+	if (str71x_map.map_priv_1) {
+		iounmap((void *)str71x_map.map_priv_1);
+		str71x_map.map_priv_1 = 0;
+	}
+}
+
+module_init(init_str71x);
+module_exit(cleanup_str71x);
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/drivers/net/Makefile uClinux-dist-20040408/linux-2.4.x/drivers/net/Makefile
--- uClinux-dist/linux-2.4.x/drivers/net/Makefile	2004-04-08 08:16:27.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/drivers/net/Makefile	2004-09-07 17:56:28.000000000 +0800
@@ -101,9 +101,11 @@
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_TIGON3) += tg3.o
 
+ifeq ($(CONFIG_XILINX_ENET),y)
 mod-subdirs     +=	xilinx_enet
 subdir-$(CONFIG_XILINX_ENET) += xilinx_enet
 obj-$(CONFIG_XILINX_ENET) += xilinx_enet/xilinx_enet.o
+endif
 
 ifeq ($(CONFIG_E100),y)
   obj-y += e100/e100.o
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/fs/jffs2/zlib.c uClinux-dist-20040408/linux-2.4.x/fs/jffs2/zlib.c
--- uClinux-dist/linux-2.4.x/fs/jffs2/zlib.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/fs/jffs2/zlib.c	2004-09-13 16:56:25.000000000 +0800
@@ -0,0 +1,5371 @@
+/*
+ * This file is derived from various .h and .c files from the zlib-1.0.4
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets.  See zlib.h for conditions of
+ * distribution and use.
+ *
+ * Changes that have been made include:
+ * - added Z_PACKET_FLUSH (see zlib.h for details)
+ * - added inflateIncomp and deflateOutputPending
+ * - allow strm->next_out to be NULL, meaning discard the output
+ *
+ * $Id: zlib.c,v 1.3 1997/12/23 10:47:42 paulus Exp $
+ */
+
+/* 
+ *  ==FILEVERSION 971210==
+ *
+ * This marker is used by the Linux installation script to determine
+ * whether an up-to-date version of this file is already installed.
+ */
+
+#define NO_DUMMY_DECL
+#define NO_ZCFUNCS
+#define MY_ZCALLOC
+
+#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
+#define inflate	inflate_ppp	/* FreeBSD already has an inflate :-( */
+#endif
+
+
+/* +++ zutil.h */
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#if defined(KERNEL) || defined(_KERNEL)
+/* Assume this is a *BSD or SVR4 kernel */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/systm.h>
+#  define HAVE_MEMCPY
+#  define memcpy(d, s, n)	bcopy((s), (d), (n))
+#  define memset(d, v, n)	bzero((d), (n))
+#  define memcmp		bcmp
+
+#else
+#if defined(__KERNEL__)
+/* Assume this is a Linux kernel */
+#include <linux/string.h>
+#define HAVE_MEMCPY
+
+#else /* not kernel */
+
+#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS)
+#   include <stddef.h>
+#   include <errno.h>
+#else
+    extern int errno;
+#endif
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#endif /* __KERNEL__ */
+#endif /* _KERNEL || KERNEL */
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#ifdef MSDOS
+#  define OS_CODE  0x00
+#  ifdef __TURBOC__
+#    include <alloc.h>
+#  else /* MSC or DJGPP */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#endif
+
+#ifdef WIN32 /* Window 95 & Windows NT */
+#  define OS_CODE  0x0b
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define FOPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef MACOS
+#  define OS_CODE  0x07
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0F
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+        /* Common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef FOPEN
+#  define FOPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#ifdef HAVE_STRERROR
+   extern char *strerror OF((int));
+#  define zstrerror(errnum) strerror(errnum)
+#else
+#  define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+#  define NO_MEMCPY
+#endif
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   extern void zmemcpy  OF((Bytef* dest, Bytef* source, uInt len));
+   extern int  zmemcmp  OF((Bytef* s1,   Bytef* s2, uInt len));
+   extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG_ZLIB
+#  include <stdio.h>
+#  ifndef verbose
+#    define verbose 0
+#  endif
+   extern void z_error    OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_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
+
+
+typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len));
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void   zcfree  OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* _Z_UTIL_H */
+/* --- zutil.h */
+
+/* +++ deflate.h */
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-1996 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */
+
+#ifndef _DEFLATE_H
+#define _DEFLATE_H
+
+/* #include "zutil.h" */
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct deflate_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    int   pending;       /* nb of bytes in the pending buffer */
+    int   noheader;      /* suppress zlib header and adler32 */
+    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    ulg compressed_len; /* total bit length of compressed file */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG_ZLIB
+    ulg bits_sent;      /* bit length of the compressed data */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+        /* in trees.c */
+void _tr_init         OF((deflate_state *s));
+int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
+ulg  _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
+			  int eof));
+void _tr_align        OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+void _tr_stored_type_only OF((deflate_state *));
+
+#endif
+/* --- deflate.h */
+
+/* +++ deflate.c */
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */
+
+/* #include "deflate.h" */
+
+char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, charf *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG_ZLIB
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+local config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+			 Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+		  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int noheader = 0;
+    static char* my_version = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+	return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+#ifndef NO_ZCFUNCS
+    if (strm->zalloc == Z_NULL) {
+	strm->zalloc = zcalloc;
+	strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == Z_NULL) strm->zfree = zcfree;
+#endif
+
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+
+    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+        noheader = 1;
+        windowBits = -windowBits;
+    }
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+        return Z_STREAM_ERROR;
+    }
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->noheader = noheader;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
+	return Z_STREAM_ERROR;
+
+    s = (deflate_state *) strm->state;
+    if (s->status != INIT_STATE) return Z_STREAM_ERROR;
+
+    strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > MAX_DIST(s)) {
+	length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+	dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+    }
+    zmemcpy((charf *)s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+	INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+    
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->noheader < 0) {
+        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
+    }
+    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+    strm->adler = 1;
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = (deflate_state *) strm->state;
+
+    if (level == Z_DEFAULT_COMPRESSION) {
+	level = 6;
+    }
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+	return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if (func != configuration_table[level].func && strm->total_in != 0) {
+	/* Flush the last buffer: */
+	err = deflate(strm, Z_PARTIAL_FLUSH);
+    }
+    if (s->level != level) {
+	s->level = level;
+	s->max_lazy_match   = configuration_table[level].max_lazy;
+	s->good_match       = configuration_table[level].good_length;
+	s->nice_match       = configuration_table[level].nice_length;
+	s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}   
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    deflate_state *s = (deflate_state *) strm->state;
+    unsigned len = s->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    if (strm->next_out != Z_NULL) {
+	zmemcpy(strm->next_out, s->pending_out, len);
+	strm->next_out += len;
+    }
+    s->pending_out += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    s->pending -= len;
+    if (s->pending == 0) {
+        s->pending_out = s->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+	flush > Z_FINISH || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = (deflate_state *) strm->state;
+
+    if ((strm->next_in == Z_NULL && strm->avail_in != 0) ||
+	(s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the zlib header */
+    if (s->status == INIT_STATE) {
+
+        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+        uInt level_flags = (s->level-1) >> 1;
+
+        if (level_flags > 3) level_flags = 3;
+        header |= (level_flags << 6);
+	if (s->strstart != 0) header |= PRESET_DICT;
+        header += 31 - (header % 31);
+
+        s->status = BUSY_STATE;
+        putShortMSB(s, header);
+
+	/* Save the adler32 of the preset dictionary: */
+	if (s->strstart != 0) {
+	    putShortMSB(s, (uInt)(strm->adler >> 16));
+	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+	}
+	strm->adler = 1L;
+    }
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+	    /* Since avail_out is 0, deflate will be called again with
+	     * more output space, but possibly with both pending and
+	     * avail_in equal to zero. There won't be anything to do,
+	     * but this is not an error situation so make sure we
+	     * return OK instead of BUF_ERROR at next call of deflate:
+             */
+	    s->last_flush = -1;
+	    return Z_OK;
+	}
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+	       flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+	bstate = (*(configuration_table[s->level].func))(s, flush);
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+	    if (strm->avail_out == 0) {
+	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+	    }
+	    return Z_OK;
+	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+	     * of deflate should use the same flush parameter to make sure
+	     * that the flush is complete. So we don't have to output an
+	     * empty block here, this will be done at next call. This also
+	     * ensures that for a very small output buffer, we emit at most
+	     * one empty block.
+	     */
+	}
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+	    } else if (flush == Z_PACKET_FLUSH) {
+		/* Output just the 3-bit `stored' block type value,
+		   but not a zero length. */
+		_tr_stored_type_only(s);
+            } else { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                }
+            }
+            flush_pending(strm);
+	    if (strm->avail_out == 0) {
+	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+	      return Z_OK;
+	    }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->noheader) return Z_STREAM_END;
+
+    /* Write the zlib trailer (adler32) */
+    putShortMSB(s, (uInt)(strm->adler >> 16));
+    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    s->noheader = -1; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = (deflate_state *) strm->state;
+
+    status = s->status;
+    if (status != INIT_STATE && status != BUSY_STATE &&
+	status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, s->pending_buf);
+    TRY_FREE(strm, s->head);
+    TRY_FREE(strm, s->prev);
+    TRY_FREE(strm, s->window);
+
+    ZFREE(strm, s);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ */
+int deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    ss = (deflate_state *) source->state;
+
+    *dest = *source;
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    *ds = *ss;
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* ??? following zmemcpy doesn't work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+}
+
+/* ===========================================================================
+ * Return the number of bytes of output which are immediately available
+ * for output from the decompressor.
+ */
+int deflateOutputPending (strm)
+    z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return 0;
+    
+    return ((deflate_state *)(strm->state))->pending;
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    charf *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (!((deflate_state *)(strm->state))->noheader) {
+        strm->adler = adler32(strm->adler, strm->next_in, len);
+    }
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+}
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2:
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+
+#ifdef DEBUG_ZLIB
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp((charf *)s->window + match,
+                (charf *)s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+		start, match, length);
+        do {
+	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+	} while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+            more = wsize;
+
+        } else if (more == (unsigned)(-1)) {
+            /* Very unlikely, but possible on 16 bit machine if strstart == 0
+             * and lookahead == 1 (input done one byte at time)
+             */
+            more--;
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy((charf *)s->window, (charf *)s->window+wsize,
+                   (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead,
+                     more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+		(ulg)((long)s->strstart - s->block_start), \
+		(eof)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+   FLUSH_BLOCK_ONLY(s, eof); \
+   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+		   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+	Assert(s->block_start >= 0L, "block gone");
+
+	s->strstart += s->lookahead;
+	s->lookahead = 0;
+
+	/* Emit a stored block if pending_buf will be full: */
+ 	max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+	    /* strstart == 0 is possible when wraparound on 16-bit machine */
+	    s->lookahead = (uInt)(s->strstart - max_start);
+	    s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+	}
+	/* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+	}
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL; /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            bflush = _tr_tally(s, s->strstart - s->match_start,
+                               s->match_length - MIN_MATCH);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in hash table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++; 
+            } else {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            bflush = _tr_tally (s, 0, s->window[s->strstart]);
+            s->lookahead--;
+            s->strstart++; 
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL;    /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+                 (s->match_length == MIN_MATCH &&
+                  s->strstart - s->match_start > TOO_FAR))) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            bflush = _tr_tally(s, s->strstart -1 - s->prev_match,
+                               s->prev_length - MIN_MATCH);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            if (_tr_tally (s, 0, s->window[s->strstart-1])) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally (s, 0, s->window[s->strstart-1]);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+/* --- deflate.c */
+
+/* +++ trees.c */
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-1996 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */
+
+/* #include "deflate.h" */
+
+#ifdef DEBUG_ZLIB
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {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};
+
+local int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {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};
+
+local int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+local uch dist_code[512];
+/* distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+local uch length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+struct static_tree_desc_s {
+    ct_data *static_tree;        /* static tree or NULL */
+    intf    *extra_bits;         /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(ct_data *)0, extra_blbits, 0,      BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local void set_data_type  OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifndef DEBUG_ZLIB
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG_ZLIB */
+#  define send_code(s, c, tree) \
+     { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+#define d_code(dist) \
+   ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. dist_code[256] and dist_code[257] are never
+ * used.
+ */
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG_ZLIB
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (value << s->bi_valid);
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG_ZLIB */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (val << s->bi_valid);\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG_ZLIB */
+
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables. In a multi-threaded environment,
+ * this function may be called by two threads concurrently, but this is
+ * harmless since both invocations do exactly the same thing.
+ */
+local void tr_static_init()
+{
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+}
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->compressed_len = 0L;
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG_ZLIB
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree  = desc->dyn_tree;
+    int max_code   = desc->max_code;
+    ct_data *stree = desc->stat_desc->static_tree;
+    intf *extra    = desc->stat_desc->extra_bits;
+    int base       = desc->stat_desc->extra_base;
+    int max_length = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if (tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree   = desc->dyn_tree;
+    ct_data *stree  = desc->stat_desc->static_tree;
+    int elems       = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* Send just the `stored block' type code without any length bytes or data.
+ */
+void _tr_stored_type_only(s)
+    deflate_state *s;
+{
+    send_bits(s, (STORED_BLOCK << 1), 3);
+    bi_windup(s);
+    s->compressed_len = (s->compressed_len + 3) & ~7L;
+}
+
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+        s->compressed_len += 10L;
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file. This function
+ * returns the total compressed length for the file so far.
+ */
+ulg _tr_flush_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+	 /* Check if the file is ascii or binary */
+	if (s->data_type == Z_UNKNOWN) set_data_type(s);
+
+	/* Construct the literal and distance trees */
+	build_tree(s, (tree_desc *)(&(s->l_desc)));
+	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+
+	build_tree(s, (tree_desc *)(&(s->d_desc)));
+	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+	/* At this point, opt_len and static_len are the total bit lengths of
+	 * the compressed block data, excluding the tree representations.
+	 */
+
+	/* Build the bit length tree for the above two trees, and get the index
+	 * in bl_order of the last bit length code to send.
+	 */
+	max_blindex = build_bl_tree(s);
+
+	/* Determine the best encoding. Compute first the block length in bytes*/
+	opt_lenb = (s->opt_len+3+7)>>3;
+	static_lenb = (s->static_len+3+7)>>3;
+
+	Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+		opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+		s->last_lit));
+
+	if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+    /* If compression failed and this is the first and last block,
+     * and if the .zip file can be seeked (to rewrite the local header),
+     * the whole file is transformed into a stored file:
+     */
+#ifdef STORED_FILE_OK
+#  ifdef FORCE_STORED_FILE
+    if (eof && s->compressed_len == 0L) { /* force stored file */
+#  else
+    if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
+#  endif
+        /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
+        if (buf == (charf*)0) error ("block vanished");
+
+        copy_block(s, buf, (unsigned)stored_len, 0); /* without header */
+        s->compressed_len = stored_len << 3;
+        s->method = STORED;
+    } else
+#endif /* STORED_FILE_OK */
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+eof, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+        s->compressed_len += 3 + s->static_len;
+    } else {
+        send_bits(s, (DYN_TREES<<1)+eof, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+        s->compressed_len += 3 + s->opt_len;
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    init_block(s);
+
+    if (eof) {
+        bi_windup(s);
+        s->compressed_len += 7;  /* align on byte boundary */
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*eof));
+
+    return s->compressed_len >> 3;
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+    /* Try to guess if it is profitable to stop the current block here */
+    if (s->level > 2 && (s->last_lit & 0xfff) == 0) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+    deflate_state *s;
+{
+    int n = 0;
+    unsigned ascii_freq = 0;
+    unsigned bin_freq = 0;
+    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
+    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
+    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG_ZLIB
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);   
+        put_short(s, (ush)~len);
+#ifdef DEBUG_ZLIB
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG_ZLIB
+    s->bits_sent += (ulg)len<<3;
+#endif
+    /* bundle up the put_byte(s, *buf++) calls */
+    zmemcpy(&s->pending_buf[s->pending], buf, len);
+    s->pending += len;
+}
+/* --- trees.c */
+
+/* +++ inflate.c */
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* #include "zutil.h" */
+
+/* +++ infblock.h */
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+extern inflate_blocks_statef * inflate_blocks_new OF((
+    z_streamp z,
+    check_func c,               /* check function */
+    uInt w));                   /* window size */
+
+extern int inflate_blocks OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));                      /* initial return code */
+
+extern void inflate_blocks_reset OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    uLongf *));                  /* check value on output */
+
+extern int inflate_blocks_free OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    uLongf *));                  /* check value on output */
+
+extern void inflate_set_dictionary OF((
+    inflate_blocks_statef *s,
+    const Bytef *d,  /* dictionary */
+    uInt  n));       /* dictionary length */
+
+extern int inflate_addhistory OF((
+    inflate_blocks_statef *,
+    z_streamp));
+
+extern int inflate_packet_flush OF((
+    inflate_blocks_statef *));
+/* --- infblock.h */
+
+#ifndef NO_DUMMY_DECL
+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
+#endif
+
+/* inflate private state */
+struct internal_state {
+
+  /* mode */
+  enum {
+      METHOD,   /* waiting for method byte */
+      FLAG,     /* waiting for flag byte */
+      DICT4,    /* four dictionary check bytes to go */
+      DICT3,    /* three dictionary check bytes to go */
+      DICT2,    /* two dictionary check bytes to go */
+      DICT1,    /* one dictionary check byte to go */
+      DICT0,    /* waiting for inflateSetDictionary */
+      BLOCKS,   /* decompressing blocks */
+      CHECK4,   /* four check bytes to go */
+      CHECK3,   /* three check bytes to go */
+      CHECK2,   /* two check bytes to go */
+      CHECK1,   /* one check byte to go */
+      DONE,     /* finished check, done */
+      BAD}      /* got an error--stay here */
+    mode;               /* current inflate mode */
+
+  /* mode dependent information */
+  union {
+    uInt method;        /* if FLAGS, method byte */
+    struct {
+      uLong was;                /* computed check value */
+      uLong need;               /* stream check value */
+    } check;            /* if CHECK, check values to compare */
+    uInt marker;        /* if BAD, inflateSync's marker bytes count */
+  } sub;        /* submode */
+
+  /* mode independent information */
+  int  nowrap;          /* flag for no wrapper */
+  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
+  inflate_blocks_statef 
+    *blocks;            /* current inflate_blocks state */
+
+};
+
+
+int inflateReset(z)
+z_streamp z;
+{
+  uLong c;
+
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->total_in = z->total_out = 0;
+  z->msg = Z_NULL;
+  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+  inflate_blocks_reset(z->state->blocks, z, &c);
+  Trace((stderr, "inflate: reset\n"));
+  return Z_OK;
+}
+
+
+int inflateEnd(z)
+z_streamp z;
+{
+  uLong c;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->blocks != Z_NULL)
+    inflate_blocks_free(z->state->blocks, z, &c);
+  ZFREE(z, z->state);
+  z->state = Z_NULL;
+  Trace((stderr, "inflate: end\n"));
+  return Z_OK;
+}
+
+
+int inflateInit2_(z, w, version, stream_size)
+z_streamp z;
+int w;
+const char *version;
+int stream_size;
+{
+  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+      stream_size != sizeof(z_stream))
+      return Z_VERSION_ERROR;
+
+  /* initialize state */
+  if (z == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->msg = Z_NULL;
+#ifndef NO_ZCFUNCS
+  if (z->zalloc == Z_NULL)
+  {
+    z->zalloc = zcalloc;
+    z->opaque = (voidpf)0;
+  }
+  if (z->zfree == Z_NULL) z->zfree = zcfree;
+#endif
+  if ((z->state = (struct internal_state FAR *)
+       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+    return Z_MEM_ERROR;
+  z->state->blocks = Z_NULL;
+
+  /* handle undocumented nowrap option (no zlib header or check) */
+  z->state->nowrap = 0;
+  if (w < 0)
+  {
+    w = - w;
+    z->state->nowrap = 1;
+  }
+
+  /* set window size */
+  if (w < 8 || w > 15)
+  {
+    inflateEnd(z);
+    return Z_STREAM_ERROR;
+  }
+  z->state->wbits = (uInt)w;
+
+  /* create inflate_blocks state */
+  if ((z->state->blocks =
+      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
+      == Z_NULL)
+  {
+    inflateEnd(z);
+    return Z_MEM_ERROR;
+  }
+  Trace((stderr, "inflate: allocated\n"));
+
+  /* reset state */
+  inflateReset(z);
+  return Z_OK;
+}
+
+
+int inflateInit_(z, version, stream_size)
+z_streamp z;
+const char *version;
+int stream_size;
+{
+  return inflateInit2_(z, DEF_WBITS, version, stream_size);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int inflate(z, f)
+z_streamp z;
+int f;
+{
+  int r;
+  uInt b;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0)
+    return Z_STREAM_ERROR;
+  r = Z_BUF_ERROR;
+  while (1) switch (z->state->mode)
+  {
+    case METHOD:
+      NEEDBYTE
+      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"unknown compression method";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"invalid window size";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      z->state->mode = FLAG;
+    case FLAG:
+      NEEDBYTE
+      b = NEXTBYTE;
+      if (((z->state->sub.method << 8) + b) % 31)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"incorrect header check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Trace((stderr, "inflate: zlib header ok\n"));
+      if (!(b & PRESET_DICT))
+      {
+        z->state->mode = BLOCKS;
+	break;
+      }
+      z->state->mode = DICT4;
+    case DICT4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = DICT3;
+    case DICT3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = DICT2;
+    case DICT2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = DICT1;
+    case DICT1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+      z->adler = z->state->sub.check.need;
+      z->state->mode = DICT0;
+      return Z_NEED_DICT;
+    case DICT0:
+      z->state->mode = BAD;
+      z->msg = (char*)"need dictionary";
+      z->state->sub.marker = 0;       /* can try inflateSync */
+      return Z_STREAM_ERROR;
+    case BLOCKS:
+      r = inflate_blocks(z->state->blocks, z, r);
+      if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
+	  r = inflate_packet_flush(z->state->blocks);
+      if (r == Z_DATA_ERROR)
+      {
+        z->state->mode = BAD;
+        z->state->sub.marker = 0;       /* can try inflateSync */
+        break;
+      }
+      if (r != Z_STREAM_END)
+        return r;
+      r = Z_OK;
+      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+      if (z->state->nowrap)
+      {
+        z->state->mode = DONE;
+        break;
+      }
+      z->state->mode = CHECK4;
+    case CHECK4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = CHECK3;
+    case CHECK3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = CHECK2;
+    case CHECK2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = CHECK1;
+    case CHECK1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+
+      if (z->state->sub.check.was != z->state->sub.check.need)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"incorrect data check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Trace((stderr, "inflate: zlib check ok\n"));
+      z->state->mode = DONE;
+    case DONE:
+      return Z_STREAM_END;
+    case BAD:
+      return Z_DATA_ERROR;
+    default:
+      return Z_STREAM_ERROR;
+  }
+
+ empty:
+  if (f != Z_PACKET_FLUSH)
+    return r;
+  z->state->mode = BAD;
+  z->msg = (char *)"need more for packet flush";
+  z->state->sub.marker = 0;       /* can try inflateSync */
+  return Z_DATA_ERROR;
+}
+
+
+int inflateSetDictionary(z, dictionary, dictLength)
+z_streamp z;
+const Bytef *dictionary;
+uInt  dictLength;
+{
+  uInt length = dictLength;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
+    return Z_STREAM_ERROR;
+
+  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
+  z->adler = 1L;
+
+  if (length >= ((uInt)1<<z->state->wbits))
+  {
+    length = (1<<z->state->wbits)-1;
+    dictionary += dictLength - length;
+  }
+  inflate_set_dictionary(z->state->blocks, dictionary, length);
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output.  The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS).  On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+
+int inflateIncomp(z)
+z_stream *z;
+{
+    if (z->state->mode != BLOCKS)
+	return Z_DATA_ERROR;
+    return inflate_addhistory(z->state->blocks, z);
+}
+
+
+int inflateSync(z)
+z_streamp z;
+{
+  uInt n;       /* number of bytes to look at */
+  Bytef *p;     /* pointer to bytes */
+  uInt m;       /* number of marker bytes found in a row */
+  uLong r, w;   /* temporaries to save total_in and total_out */
+
+  /* set up */
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->mode != BAD)
+  {
+    z->state->mode = BAD;
+    z->state->sub.marker = 0;
+  }
+  if ((n = z->avail_in) == 0)
+    return Z_BUF_ERROR;
+  p = z->next_in;
+  m = z->state->sub.marker;
+
+  /* search */
+  while (n && m < 4)
+  {
+    if (*p == (Byte)(m < 2 ? 0 : 0xff))
+      m++;
+    else if (*p)
+      m = 0;
+    else
+      m = 4 - m;
+    p++, n--;
+  }
+
+  /* restore */
+  z->total_in += p - z->next_in;
+  z->next_in = p;
+  z->avail_in = n;
+  z->state->sub.marker = m;
+
+  /* return no joy or set up to restart on a new block */
+  if (m != 4)
+    return Z_DATA_ERROR;
+  r = z->total_in;  w = z->total_out;
+  inflateReset(z);
+  z->total_in = r;  z->total_out = w;
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+#undef NEEDBYTE
+#undef NEXTBYTE
+/* --- inflate.c */
+
+/* +++ infblock.c */
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* #include "zutil.h" */
+/* #include "infblock.h" */
+
+/* +++ inftrees.h */
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* 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). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+  union {
+    struct {
+      Byte Exop;        /* number of extra bits or operation */
+      Byte Bits;        /* number of bits in this code or subcode */
+    } what;
+    Bytef *pad;         /* pad structure to a power of 2 (4 bytes for */
+  } word;               /*  16-bit, 8 bytes for 32-bit machines) */
+  union {
+    uInt Base;          /* literal, length base, or distance base */
+    inflate_huft *Next; /* pointer to next level of table */
+  } more;
+};
+
+#ifdef DEBUG_ZLIB
+  extern uInt inflate_hufts;
+#endif
+
+extern int inflate_trees_bits OF((
+    uIntf *,                    /* 19 code lengths */
+    uIntf *,                    /* bits tree desired/actual depth */
+    inflate_huft * FAR *,       /* bits tree result */
+    z_streamp ));               /* for zalloc, zfree functions */
+
+extern int inflate_trees_dynamic OF((
+    uInt,                       /* number of literal/length codes */
+    uInt,                       /* number of distance codes */
+    uIntf *,                    /* that many (total) code lengths */
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    z_streamp ));               /* for zalloc, zfree functions */
+
+extern int inflate_trees_fixed OF((
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *));     /* distance tree result */
+
+extern int inflate_trees_free OF((
+    inflate_huft *,             /* tables to free */
+    z_streamp ));               /* for zfree function */
+
+/* --- inftrees.h */
+
+/* +++ infcodes.h */
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+extern inflate_codes_statef *inflate_codes_new OF((
+    uInt, uInt,
+    inflate_huft *, inflate_huft *,
+    z_streamp ));
+
+extern int inflate_codes OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+extern void inflate_codes_free OF((
+    inflate_codes_statef *,
+    z_streamp ));
+
+/* --- infcodes.h */
+
+/* +++ infutil.h */
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFUTIL_H
+#define _INFUTIL_H
+
+typedef enum {
+      TYPE,     /* get type bits (3, including end bit) */
+      LENS,     /* get lengths for stored */
+      STORED,   /* processing stored block */
+      TABLE,    /* get table lengths */
+      BTREE,    /* get bit lengths tree for a dynamic block */
+      DTREE,    /* get length, distance trees for a dynamic block */
+      CODES,    /* processing fixed or dynamic block */
+      DRY,      /* output remaining window bytes */
+      DONEB,    /* finished last block, done */
+      BADB}     /* got a data error--stuck here */
+inflate_block_mode;
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+  /* mode */
+  inflate_block_mode  mode;     /* current inflate_block mode */
+
+  /* mode dependent information */
+  union {
+    uInt left;          /* if STORED, bytes left to copy */
+    struct {
+      uInt table;               /* table lengths (14 bits) */
+      uInt index;               /* index into blens (or border) */
+      uIntf *blens;             /* bit lengths of codes */
+      uInt bb;                  /* bit length tree depth */
+      inflate_huft *tb;         /* bit length decoding tree */
+    } trees;            /* if DTREE, decoding info for trees */
+    struct {
+      inflate_huft *tl;
+      inflate_huft *td;         /* trees to free */
+      inflate_codes_statef 
+         *codes;
+    } decode;           /* if CODES, current state */
+  } sub;                /* submode */
+  uInt last;            /* true if this block is the last block */
+
+  /* mode independent information */
+  uInt bitk;            /* bits in bit buffer */
+  uLong bitb;           /* bit buffer */
+  Bytef *window;        /* sliding window */
+  Bytef *end;           /* one byte after sliding window */
+  Bytef *read;          /* window read pointer */
+  Bytef *write;         /* window write pointer */
+  check_func checkfn;   /* check function */
+  uLong check;          /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/*   update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/*   get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/*   output bytes */
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WWRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WWRAP if(m==0){FLUSH WWRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/*   load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
+extern uInt inflate_mask[17];
+
+/* copy as much as possible from the sliding window to the output area */
+extern int inflate_flush OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+#endif
+/* --- infutil.h */
+
+#ifndef NO_DUMMY_DECL
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+#endif
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local const uInt 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};
+
+/*
+   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.  Similarily, 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.
+ */
+
+
+void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_streamp z;
+uLongf *c;
+{
+  if (s->checkfn != Z_NULL)
+    *c = s->check;
+  if (s->mode == BTREE || s->mode == DTREE)
+    ZFREE(z, s->sub.trees.blens);
+  if (s->mode == CODES)
+  {
+    inflate_codes_free(s->sub.decode.codes, z);
+    inflate_trees_free(s->sub.decode.td, z);
+    inflate_trees_free(s->sub.decode.tl, z);
+  }
+  s->mode = TYPE;
+  s->bitk = 0;
+  s->bitb = 0;
+  s->read = s->write = s->window;
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0);
+  Trace((stderr, "inflate:   blocks reset\n"));
+}
+
+
+inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_streamp z;
+check_func c;
+uInt w;
+{
+  inflate_blocks_statef *s;
+
+  if ((s = (inflate_blocks_statef *)ZALLOC
+       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+    return s;
+  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+  {
+    ZFREE(z, s);
+    return Z_NULL;
+  }
+  s->end = s->window + w;
+  s->checkfn = c;
+  s->mode = TYPE;
+  Trace((stderr, "inflate:   blocks allocated\n"));
+  inflate_blocks_reset(s, z, &s->check);
+  return s;
+}
+
+
+#ifdef DEBUG_ZLIB
+  extern uInt inflate_hufts;
+#endif
+int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt t;               /* temporary storage */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input based on current state */
+  while (1) switch (s->mode)
+  {
+    case TYPE:
+      NEEDBITS(3)
+      t = (uInt)b & 7;
+      s->last = t & 1;
+      switch (t >> 1)
+      {
+        case 0:                         /* stored */
+          Trace((stderr, "inflate:     stored block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          t = k & 7;                    /* go to byte boundary */
+          DUMPBITS(t)
+          s->mode = LENS;               /* get length of stored block */
+          break;
+        case 1:                         /* fixed */
+          Trace((stderr, "inflate:     fixed codes block%s\n",
+                 s->last ? " (last)" : ""));
+          {
+            uInt bl, bd;
+            inflate_huft *tl, *td;
+
+            inflate_trees_fixed(&bl, &bd, &tl, &td);
+            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+            if (s->sub.decode.codes == Z_NULL)
+            {
+              r = Z_MEM_ERROR;
+              LEAVE
+            }
+            s->sub.decode.tl = Z_NULL;  /* don't try to free these */
+            s->sub.decode.td = Z_NULL;
+          }
+          DUMPBITS(3)
+          s->mode = CODES;
+          break;
+        case 2:                         /* dynamic */
+          Trace((stderr, "inflate:     dynamic codes block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          s->mode = TABLE;
+          break;
+        case 3:                         /* illegal */
+          DUMPBITS(3)
+          s->mode = BADB;
+          z->msg = (char*)"invalid block type";
+          r = Z_DATA_ERROR;
+          LEAVE
+      }
+      break;
+    case LENS:
+      NEEDBITS(32)
+      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
+      {
+        s->mode = BADB;
+        z->msg = (char*)"invalid stored block lengths";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+      s->sub.left = (uInt)b & 0xffff;
+      b = k = 0;                      /* dump bits */
+      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
+      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
+      break;
+    case STORED:
+      if (n == 0)
+        LEAVE
+      NEEDOUT
+      t = s->sub.left;
+      if (t > n) t = n;
+      if (t > m) t = m;
+      zmemcpy(q, p, t);
+      p += t;  n -= t;
+      q += t;  m -= t;
+      if ((s->sub.left -= t) != 0)
+        break;
+      Tracev((stderr, "inflate:       stored end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      s->mode = s->last ? DRY : TYPE;
+      break;
+    case TABLE:
+      NEEDBITS(14)
+      s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+      {
+        s->mode = BADB;
+        z->msg = (char*)"too many length or distance symbols";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+#endif
+      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+      if (t < 19)
+        t = 19;
+      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+      {
+        r = Z_MEM_ERROR;
+        LEAVE
+      }
+      DUMPBITS(14)
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       table sizes ok\n"));
+      s->mode = BTREE;
+    case BTREE:
+      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+      {
+        NEEDBITS(3)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+        DUMPBITS(3)
+      }
+      while (s->sub.trees.index < 19)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+      s->sub.trees.bb = 7;
+      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+                             &s->sub.trees.tb, z);
+      if (t != Z_OK)
+      {
+        ZFREE(z, s->sub.trees.blens);
+        r = t;
+        if (r == Z_DATA_ERROR)
+          s->mode = BADB;
+        LEAVE
+      }
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       bits tree ok\n"));
+      s->mode = DTREE;
+    case DTREE:
+      while (t = s->sub.trees.table,
+             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+      {
+        inflate_huft *h;
+        uInt i, j, c;
+
+        t = s->sub.trees.bb;
+        NEEDBITS(t)
+        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+        t = h->word.what.Bits;
+        c = h->more.Base;
+        if (c < 16)
+        {
+          DUMPBITS(t)
+          s->sub.trees.blens[s->sub.trees.index++] = c;
+        }
+        else /* c == 16..18 */
+        {
+          i = c == 18 ? 7 : c - 14;
+          j = c == 18 ? 11 : 3;
+          NEEDBITS(t + i)
+          DUMPBITS(t)
+          j += (uInt)b & inflate_mask[i];
+          DUMPBITS(i)
+          i = s->sub.trees.index;
+          t = s->sub.trees.table;
+          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+              (c == 16 && i < 1))
+          {
+            inflate_trees_free(s->sub.trees.tb, z);
+            ZFREE(z, s->sub.trees.blens);
+            s->mode = BADB;
+            z->msg = (char*)"invalid bit length repeat";
+            r = Z_DATA_ERROR;
+            LEAVE
+          }
+          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+          do {
+            s->sub.trees.blens[i++] = c;
+          } while (--j);
+          s->sub.trees.index = i;
+        }
+      }
+      inflate_trees_free(s->sub.trees.tb, z);
+      s->sub.trees.tb = Z_NULL;
+      {
+        uInt bl, bd;
+        inflate_huft *tl, *td;
+        inflate_codes_statef *c;
+
+        bl = 9;         /* must be <= 9 for lookahead assumptions */
+        bd = 6;         /* must be <= 9 for lookahead assumptions */
+        t = s->sub.trees.table;
+#ifdef DEBUG_ZLIB
+      inflate_hufts = 0;
+#endif
+        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+                                  s->sub.trees.blens, &bl, &bd, &tl, &td, z);
+        ZFREE(z, s->sub.trees.blens);
+        if (t != Z_OK)
+        {
+          if (t == (uInt)Z_DATA_ERROR)
+            s->mode = BADB;
+          r = t;
+          LEAVE
+        }
+        Tracev((stderr, "inflate:       trees ok, %d * %d bytes used\n",
+              inflate_hufts, sizeof(inflate_huft)));
+        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+        {
+          inflate_trees_free(td, z);
+          inflate_trees_free(tl, z);
+          r = Z_MEM_ERROR;
+          LEAVE
+        }
+        s->sub.decode.codes = c;
+        s->sub.decode.tl = tl;
+        s->sub.decode.td = td;
+      }
+      s->mode = CODES;
+    case CODES:
+      UPDATE
+      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+        return inflate_flush(s, z, r);
+      r = Z_OK;
+      inflate_codes_free(s->sub.decode.codes, z);
+      inflate_trees_free(s->sub.decode.td, z);
+      inflate_trees_free(s->sub.decode.tl, z);
+      LOAD
+      Tracev((stderr, "inflate:       codes end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      if (!s->last)
+      {
+        s->mode = TYPE;
+        break;
+      }
+      if (k > 7)              /* return unused byte, if any */
+      {
+        Assert(k < 16, "inflate_codes grabbed too many bytes")
+        k -= 8;
+        n++;
+        p--;                    /* can always return one */
+      }
+      s->mode = DRY;
+    case DRY:
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      s->mode = DONEB;
+    case DONEB:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADB:
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+int inflate_blocks_free(s, z, c)
+inflate_blocks_statef *s;
+z_streamp z;
+uLongf *c;
+{
+  inflate_blocks_reset(s, z, c);
+  ZFREE(z, s->window);
+  ZFREE(z, s);
+  Trace((stderr, "inflate:   blocks freed\n"));
+  return Z_OK;
+}
+
+
+void inflate_set_dictionary(s, d, n)
+inflate_blocks_statef *s;
+const Bytef *d;
+uInt  n;
+{
+  zmemcpy((charf *)s->window, d, n);
+  s->read = s->write = s->window + n;
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output.  The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS).  On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+int inflate_addhistory(s, z)
+inflate_blocks_statef *s;
+z_stream *z;
+{
+    uLong b;              /* bit buffer */  /* NOT USED HERE */
+    uInt k;               /* bits in bit buffer */ /* NOT USED HERE */
+    uInt t;               /* temporary storage */
+    Bytef *p;             /* input data pointer */
+    uInt n;               /* bytes available there */
+    Bytef *q;             /* output window write pointer */
+    uInt m;               /* bytes to end of window or read pointer */
+
+    if (s->read != s->write)
+	return Z_STREAM_ERROR;
+    if (s->mode != TYPE)
+	return Z_DATA_ERROR;
+
+    /* we're ready to rock */
+    LOAD
+    /* while there is input ready, copy to output buffer, moving
+     * pointers as needed.
+     */
+    while (n) {
+	t = n;  /* how many to do */
+	/* is there room until end of buffer? */
+	if (t > m) t = m;
+	/* update check information */
+	if (s->checkfn != Z_NULL)
+	    s->check = (*s->checkfn)(s->check, q, t);
+	zmemcpy(q, p, t);
+	q += t;
+	p += t;
+	n -= t;
+	z->total_out += t;
+	s->read = q;    /* drag read pointer forward */
+/*      WWRAP  */ 	/* expand WWRAP macro by hand to handle s->read */
+	if (q == s->end) {
+	    s->read = q = s->window;
+	    m = WAVAIL;
+	}
+    }
+    UPDATE
+    return Z_OK;
+}
+
+
+/*
+ * At the end of a Deflate-compressed PPP packet, we expect to have seen
+ * a `stored' block type value but not the (zero) length bytes.
+ */
+int inflate_packet_flush(s)
+    inflate_blocks_statef *s;
+{
+    if (s->mode != LENS)
+	return Z_DATA_ERROR;
+    s->mode = TYPE;
+    return Z_OK;
+}
+/* --- infblock.c */
+
+/* +++ inftrees.c */
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* #include "zutil.h" */
+/* #include "inftrees.h" */
+
+char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+#ifndef NO_DUMMY_DECL
+struct internal_state  {int dummy;}; /* for buggy compilers */
+#endif
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+    uIntf *,            /* code lengths in bits */
+    uInt,               /* number of codes */
+    uInt,               /* number of "simple" codes */
+    const uIntf *,      /* list of base values for non-simple codes */
+    const uIntf *,      /* list of extra bits for non-simple codes */
+    inflate_huft * FAR*,/* result: starting table */
+    uIntf *,            /* maximum lookup bits (returns actual) */
+    z_streamp ));       /* for zalloc function */
+
+local voidpf falloc OF((
+    voidpf,             /* opaque pointer (not used) */
+    uInt,               /* number of items */
+    uInt));             /* size of item */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local const uInt cplens[31] = { /* 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};
+        /* see note #13 above about 258 */
+local const uInt cplext[31] = { /* 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, 112, 112}; /* 112==invalid */
+local const uInt cpdist[30] = { /* 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};
+local const uInt cpdext[30] = { /* 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};
+
+/*
+   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.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15         /* maximum bit length of any code */
+#define N_MAX 288       /* maximum number of codes in any set */
+
+#ifdef DEBUG_ZLIB
+  uInt inflate_hufts;
+#endif
+
+local int huft_build(b, n, s, d, e, t, m, zs)
+uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
+uInt n;                 /* number of codes (assumed <= N_MAX) */
+uInt s;                 /* number of simple-valued codes (0..s-1) */
+const uIntf *d;         /* list of base values for non-simple codes */
+const uIntf *e;         /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t;  /* result: starting table */
+uIntf *m;               /* maximum lookup bits, returns actual */
+z_streamp zs;           /* for zalloc function */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
+   if the given code set is incomplete (the tables are still built in this
+   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
+   lengths), or Z_MEM_ERROR if not enough memory. */
+{
+
+  uInt a;                       /* counter for codes of length k */
+  uInt c[BMAX+1];               /* bit length count table */
+  uInt f;                       /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register uInt i;              /* counter, current code */
+  register uInt j;              /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  register uIntf *p;            /* pointer into c[], b[], or v[] */
+  inflate_huft *q;              /* points to current table */
+  struct inflate_huft_s r;      /* table entry for structure assignment */
+  inflate_huft *u[BMAX];        /* table stack */
+  uInt v[N_MAX];                /* values in order of bit length */
+  register int w;               /* bits before this table == (l * h) */
+  uInt x[BMAX+1];               /* bit offsets, then code stack */
+  uIntf *xp;                    /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  uInt z;                       /* number of entries in current table */
+
+
+  /* Generate counts for each bit length */
+  p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+  C4                            /* clear c[]--assume BMAX+1 is 16 */
+  p = b;  i = n;
+  do {
+    c[*p++]++;                  /* assume all entries <= BMAX */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (inflate_huft *)Z_NULL;
+    *m = 0;
+    return Z_OK;
+  }
+
+
+  /* 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 ((uInt)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((uInt)l > i)
+    l = i;
+  *m = l;
+
+
+  /* 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 Z_DATA_ERROR;
+  if ((y -= c[i]) < 0)
+    return Z_DATA_ERROR;
+  c[i] += y;
+
+
+  /* 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++);
+  }
+
+
+  /* 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);
+  n = x[g];                   /* set n to length of v */
+
+
+  /* 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] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
+  q = (inflate_huft *)Z_NULL;   /* ditto */
+  z = 0;                        /* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+    a = c[k];
+    while (a--)
+    {
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = g - w;
+        z = z > (uInt)l ? l : z;        /* table size upper limit */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          if (j < z)
+            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 */
+            }
+        }
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate and link in new table */
+        if ((q = (inflate_huft *)ZALLOC
+             (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
+        {
+          if (h)
+            inflate_trees_free(u[0], zs);
+          return Z_MEM_ERROR;   /* not enough memory */
+        }
+#ifdef DEBUG_ZLIB
+        inflate_hufts += z + 1;
+#endif
+        *t = q + 1;             /* link to list for huft_free() */
+        *(t = &(q->next)) = Z_NULL;
+        u[h] = ++q;             /* table starts after link */
+
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.bits = (Byte)l;     /* bits to dump before this table */
+          r.exop = (Byte)j;     /* bits in this table */
+          r.next = q;           /* pointer to this table */
+          j = i >> (w - l);     /* (get around Turbo C bug) */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+      }
+
+      /* set up table entry in r */
+      r.bits = (Byte)(k - w);
+      if (p >= v + n)
+        r.exop = 128 + 64;      /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
+        r.base = *p++;          /* simple code is just the value */
+      }
+      else
+      {
+        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
+        r.base = d[*p++ - s];
+      }
+
+      /* 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;
+      }
+    }
+  }
+
+
+  /* Return Z_BUF_ERROR if we were given an incomplete table */
+  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+int inflate_trees_bits(c, bb, tb, z)
+uIntf *c;               /* 19 code lengths */
+uIntf *bb;              /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+z_streamp z;            /* for zfree function */
+{
+  int r;
+
+  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
+  if (r == Z_DATA_ERROR)
+    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
+  else if (r == Z_BUF_ERROR || *bb == 0)
+  {
+    inflate_trees_free(*tb, z);
+    z->msg = (char*)"incomplete dynamic bit lengths tree";
+    r = Z_DATA_ERROR;
+  }
+  return r;
+}
+
+
+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
+uInt nl;                /* number of literal/length codes */
+uInt nd;                /* number of distance codes */
+uIntf *c;               /* that many (total) code lengths */
+uIntf *bl;              /* literal desired/actual bit depth */
+uIntf *bd;              /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+z_streamp z;            /* for zfree function */
+{
+  int r;
+
+  /* build literal/length tree */
+  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z);
+  if (r != Z_OK || *bl == 0)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed literal/length tree";
+    else if (r != Z_MEM_ERROR)
+    {
+      inflate_trees_free(*tl, z);
+      z->msg = (char*)"incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    return r;
+  }
+
+  /* build distance tree */
+  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z);
+  if (r != Z_OK || (*bd == 0 && nl > 257))
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed distance tree";
+    else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+      r = Z_OK;
+    }
+#else
+      inflate_trees_free(*td, z);
+      z->msg = (char*)"incomplete distance tree";
+      r = Z_DATA_ERROR;
+    }
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"empty distance tree with lengths";
+      r = Z_DATA_ERROR;
+    }
+    inflate_trees_free(*tl, z);
+    return r;
+#endif
+  }
+
+  /* done */
+  return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+local int fixed_built = 0;
+#define FIXEDH 530      /* number of hufts used by fixed tables */
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+
+
+local voidpf falloc(q, n, s)
+voidpf q;       /* opaque pointer */
+uInt n;         /* number of items */
+uInt s;         /* size of item */
+{
+  Assert(s == sizeof(inflate_huft) && n <= *(intf *)q,
+         "inflate_trees falloc overflow");
+  *(intf *)q -= n+s-s; /* s-s to avoid warning */
+  return (voidpf)(fixed_mem + *(intf *)q);
+}
+
+
+int inflate_trees_fixed(bl, bd, tl, td)
+uIntf *bl;               /* literal desired/actual bit depth */
+uIntf *bd;               /* distance desired/actual bit depth */
+inflate_huft * FAR *tl;  /* literal/length tree result */
+inflate_huft * FAR *td;  /* distance tree result */
+{
+  /* build fixed tables if not already (multiple overlapped executions ok) */
+  if (!fixed_built)
+  {
+    int k;              /* temporary variable */
+    unsigned c[288];    /* length list for huft_build */
+    z_stream z;         /* for falloc function */
+    int f = FIXEDH;     /* number of hufts left in fixed_mem */
+
+    /* set up fake z_stream for memory routines */
+    z.zalloc = falloc;
+    z.zfree = Z_NULL;
+    z.opaque = (voidpf)&f;
+
+    /* literal table */
+    for (k = 0; k < 144; k++)
+      c[k] = 8;
+    for (; k < 256; k++)
+      c[k] = 9;
+    for (; k < 280; k++)
+      c[k] = 7;
+    for (; k < 288; k++)
+      c[k] = 8;
+    fixed_bl = 7;
+    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
+
+    /* distance table */
+    for (k = 0; k < 30; k++)
+      c[k] = 5;
+    fixed_bd = 5;
+    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
+
+    /* done */
+    Assert(f == 0, "invalid build of fixed tables");
+    fixed_built = 1;
+  }
+  *bl = fixed_bl;
+  *bd = fixed_bd;
+  *tl = fixed_tl;
+  *td = fixed_td;
+  return Z_OK;
+}
+
+
+int inflate_trees_free(t, z)
+inflate_huft *t;        /* table to free */
+z_streamp z;            /* for zfree function */
+/* 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 inflate_huft *p, *q, *r;
+
+  /* Reverse linked list */
+  p = Z_NULL;
+  q = t;
+  while (q != Z_NULL)
+  {
+    r = (q - 1)->next;
+    (q - 1)->next = p;
+    p = q;
+    q = r;
+  }
+  /* Go through linked list, freeing from the malloced (t[-1]) address. */
+  while (p != Z_NULL)
+  {
+    q = (--p)->next;
+    ZFREE(z,p);
+    p = q;
+  } 
+  return Z_OK;
+}
+/* --- inftrees.c */
+
+/* +++ infcodes.c */
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* #include "zutil.h" */
+/* #include "inftrees.h" */
+/* #include "infblock.h" */
+/* #include "infcodes.h" */
+/* #include "infutil.h" */
+
+/* +++ inffast.h */
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+extern int inflate_fast OF((
+    uInt,
+    uInt,
+    inflate_huft *,
+    inflate_huft *,
+    inflate_blocks_statef *,
+    z_streamp ));
+/* --- inffast.h */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+  /* mode */
+  enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+      START,    /* x: set up for LEN */
+      LEN,      /* i: get length/literal/eob next */
+      LENEXT,   /* i: getting length extra (have base) */
+      DIST,     /* i: get distance next */
+      DISTEXT,  /* i: getting distance extra */
+      COPY,     /* o: copying bytes in window, waiting for space */
+      LIT,      /* o: got literal, waiting for output space */
+      WASH,     /* o: got eob, possibly still output waiting */
+      END,      /* x: got eob and all data flushed */
+      BADCODE}  /* x: got error */
+    mode;               /* current inflate_codes mode */
+
+  /* mode dependent information */
+  uInt len;
+  union {
+    struct {
+      inflate_huft *tree;       /* pointer into tree */
+      uInt need;                /* bits needed */
+    } code;             /* if LEN or DIST, where in tree */
+    uInt lit;           /* if LIT, literal */
+    struct {
+      uInt get;                 /* bits to get for extra */
+      uInt dist;                /* distance back to copy from */
+    } copy;             /* if EXT or COPY, where and how much */
+  } sub;                /* submode */
+
+  /* mode independent information */
+  Byte lbits;           /* ltree bits decoded per branch */
+  Byte dbits;           /* dtree bits decoder per branch */
+  inflate_huft *ltree;          /* literal/length/eob tree */
+  inflate_huft *dtree;          /* distance tree */
+
+};
+
+
+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+z_streamp z;
+{
+  inflate_codes_statef *c;
+
+  if ((c = (inflate_codes_statef *)
+       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+  {
+    c->mode = START;
+    c->lbits = (Byte)bl;
+    c->dbits = (Byte)bd;
+    c->ltree = tl;
+    c->dtree = td;
+    Tracev((stderr, "inflate:       codes new\n"));
+  }
+  return c;
+}
+
+
+int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt j;               /* temporary storage */
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  Bytef *f;             /* pointer to copy strings from */
+  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input and output based on current state */
+  while (1) switch (c->mode)
+  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+    case START:         /* x: set up for LEN */
+#ifndef SLOW
+      if (m >= 258 && n >= 10)
+      {
+        UPDATE
+        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+        LOAD
+        if (r != Z_OK)
+        {
+          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+          break;
+        }
+      }
+#endif /* !SLOW */
+      c->sub.code.need = c->lbits;
+      c->sub.code.tree = c->ltree;
+      c->mode = LEN;
+    case LEN:           /* i: get length/literal/eob next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e == 0)               /* literal */
+      {
+        c->sub.lit = t->base;
+        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                 "inflate:         literal '%c'\n" :
+                 "inflate:         literal 0x%02x\n", t->base));
+        c->mode = LIT;
+        break;
+      }
+      if (e & 16)               /* length */
+      {
+        c->sub.copy.get = e & 15;
+        c->len = t->base;
+        c->mode = LENEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t->next;
+        break;
+      }
+      if (e & 32)               /* end of block */
+      {
+        Tracevv((stderr, "inflate:         end of block\n"));
+        c->mode = WASH;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid literal/length code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case LENEXT:        /* i: getting length extra (have base) */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->len += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      c->sub.code.need = c->dbits;
+      c->sub.code.tree = c->dtree;
+      Tracevv((stderr, "inflate:         length %u\n", c->len));
+      c->mode = DIST;
+    case DIST:          /* i: get distance next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e & 16)               /* distance */
+      {
+        c->sub.copy.get = e & 15;
+        c->sub.copy.dist = t->base;
+        c->mode = DISTEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t->next;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid distance code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case DISTEXT:       /* i: getting distance extra */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->sub.copy.dist += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
+      c->mode = COPY;
+    case COPY:          /* o: copying bytes in window, waiting for space */
+#ifndef __TURBOC__ /* Turbo C bug for following expression */
+      f = (uInt)(q - s->window) < c->sub.copy.dist ?
+          s->end - (c->sub.copy.dist - (q - s->window)) :
+          q - c->sub.copy.dist;
+#else
+      f = q - c->sub.copy.dist;
+      if ((uInt)(q - s->window) < c->sub.copy.dist)
+        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
+#endif
+      while (c->len)
+      {
+        NEEDOUT
+        OUTBYTE(*f++)
+        if (f == s->end)
+          f = s->window;
+        c->len--;
+      }
+      c->mode = START;
+      break;
+    case LIT:           /* o: got literal, waiting for output space */
+      NEEDOUT
+      OUTBYTE(c->sub.lit)
+      c->mode = START;
+      break;
+    case WASH:          /* o: got eob, possibly more output */
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      c->mode = END;
+    case END:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADCODE:       /* x: got error */
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_streamp z;
+{
+  ZFREE(z, c);
+  Tracev((stderr, "inflate:       codes free\n"));
+}
+/* --- infcodes.c */
+
+/* +++ infutil.c */
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* #include "zutil.h" */
+/* #include "infblock.h" */
+/* #include "inftrees.h" */
+/* #include "infcodes.h" */
+/* #include "infutil.h" */
+
+#ifndef NO_DUMMY_DECL
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+#endif
+
+/* And'ing with mask[n] masks the lower n bits */
+uInt inflate_mask[17] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+
+/* copy as much as possible from the sliding window to the output area */
+int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt n;
+  Bytef *p;
+  Bytef *q;
+
+  /* local copies of source and destination pointers */
+  p = z->next_out;
+  q = s->read;
+
+  /* compute number of bytes to copy as far as end of window */
+  n = (uInt)((q <= s->write ? s->write : s->end) - q);
+  if (n > z->avail_out) n = z->avail_out;
+  if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+  /* update counters */
+  z->avail_out -= n;
+  z->total_out += n;
+
+  /* update check information */
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+  /* copy as far as end of window */
+  if (p != Z_NULL) {
+    zmemcpy(p, q, n);
+    p += n;
+  }
+  q += n;
+
+  /* see if more to copy at beginning of window */
+  if (q == s->end)
+  {
+    /* wrap pointers */
+    q = s->window;
+    if (s->write == s->end)
+      s->write = s->window;
+
+    /* compute bytes to copy */
+    n = (uInt)(s->write - q);
+    if (n > z->avail_out) n = z->avail_out;
+    if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+    /* update counters */
+    z->avail_out -= n;
+    z->total_out += n;
+
+    /* update check information */
+    if (s->checkfn != Z_NULL)
+      z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+    /* copy */
+    if (p != Z_NULL) {
+      zmemcpy(p, q, n);
+      p += n;
+    }
+    q += n;
+  }
+
+  /* update pointers */
+  z->next_out = p;
+  s->read = q;
+
+  /* done */
+  return r;
+}
+/* --- infutil.c */
+
+/* +++ inffast.c */
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* #include "zutil.h" */
+/* #include "inftrees.h" */
+/* #include "infblock.h" */
+/* #include "infcodes.h" */
+/* #include "infutil.h" */
+/* #include "inffast.h" */
+
+#ifndef NO_DUMMY_DECL
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+#endif
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
+
+/* Called with number of bytes left to write in window at least 258
+   (the maximum string length) and number of input bytes available
+   at least ten.  The ten bytes are six bytes for the longest length/
+   distance pair plus four bytes for overloading the bit buffer. */
+
+int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  uInt ml;              /* mask for literal/length tree */
+  uInt md;              /* mask for distance tree */
+  uInt c;               /* bytes to copy */
+  uInt d;               /* distance back to copy from */
+  Bytef *r;             /* copy source pointer */
+
+  /* load input, output, bit values */
+  LOAD
+
+  /* initialize masks */
+  ml = inflate_mask[bl];
+  md = inflate_mask[bd];
+
+  /* do until not enough input or output space for fast loop */
+  do {                          /* assume called with m >= 258 && n >= 10 */
+    /* get literal/length code */
+    GRABBITS(20)                /* max bits for literal/length code */
+    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+    {
+      DUMPBITS(t->bits)
+      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                "inflate:         * literal '%c'\n" :
+                "inflate:         * literal 0x%02x\n", t->base));
+      *q++ = (Byte)t->base;
+      m--;
+      continue;
+    }
+    do {
+      DUMPBITS(t->bits)
+      if (e & 16)
+      {
+        /* get extra bits for length */
+        e &= 15;
+        c = t->base + ((uInt)b & inflate_mask[e]);
+        DUMPBITS(e)
+        Tracevv((stderr, "inflate:         * length %u\n", c));
+
+        /* decode distance base of block to copy */
+        GRABBITS(15);           /* max bits for distance code */
+        e = (t = td + ((uInt)b & md))->exop;
+        do {
+          DUMPBITS(t->bits)
+          if (e & 16)
+          {
+            /* get extra bits to add to distance base */
+            e &= 15;
+            GRABBITS(e)         /* get extra bits (up to 13) */
+            d = t->base + ((uInt)b & inflate_mask[e]);
+            DUMPBITS(e)
+            Tracevv((stderr, "inflate:         * distance %u\n", d));
+
+            /* do the copy */
+            m -= c;
+            if ((uInt)(q - s->window) >= d)     /* offset before dest */
+            {                                   /*  just copy */
+              r = q - d;
+              *q++ = *r++;  c--;        /* minimum count is three, */
+              *q++ = *r++;  c--;        /*  so unroll loop a little */
+            }
+            else                        /* else offset after destination */
+            {
+              e = d - (uInt)(q - s->window); /* bytes from offset to end */
+              r = s->end - e;           /* pointer to offset */
+              if (c > e)                /* if source crosses, */
+              {
+                c -= e;                 /* copy to end of window */
+                do {
+                  *q++ = *r++;
+                } while (--e);
+                r = s->window;          /* copy rest from start of window */
+              }
+            }
+            do {                        /* copy all or what's left */
+              *q++ = *r++;
+            } while (--c);
+            break;
+          }
+          else if ((e & 64) == 0)
+            e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
+          else
+          {
+            z->msg = (char*)"invalid distance code";
+            UNGRAB
+            UPDATE
+            return Z_DATA_ERROR;
+          }
+        } while (1);
+        break;
+      }
+      if ((e & 64) == 0)
+      {
+        if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
+        {
+          DUMPBITS(t->bits)
+          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                    "inflate:         * literal '%c'\n" :
+                    "inflate:         * literal 0x%02x\n", t->base));
+          *q++ = (Byte)t->base;
+          m--;
+          break;
+        }
+      }
+      else if (e & 32)
+      {
+        Tracevv((stderr, "inflate:         * end of block\n"));
+        UNGRAB
+        UPDATE
+        return Z_STREAM_END;
+      }
+      else
+      {
+        z->msg = (char*)"invalid literal/length code";
+        UNGRAB
+        UPDATE
+        return Z_DATA_ERROR;
+      }
+    } while (1);
+  } while (m >= 258 && n >= 10);
+
+  /* not enough input or output--restore pointers and return */
+  UNGRAB
+  UPDATE
+  return Z_OK;
+}
+/* --- inffast.c */
+
+/* +++ zutil.c */
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */
+
+/* #include "zutil.h" */
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char *z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char *zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+#ifdef DEBUG_ZLIB
+void z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+    Bytef* dest;
+    Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+    Bytef* s1;
+    Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#ifdef __TURBOC__
+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
+/* Small and medium model in Turbo C are for now limited to near allocation
+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
+ */
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+#endif
+#endif /* __TURBOC__ */
+
+
+#if defined(M_I86) && !defined(__32BIT__)
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER < 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* MSC */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return (voidpf)calloc(items, size);
+}
+
+void  zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
+/* --- zutil.c */
+
+/* +++ adler32.c */
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-1996 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */
+
+/* #include "zlib.h" */
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* ========================================================================= */
+uLong adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long s1 = adler & 0xffff;
+    unsigned long s2 = (adler >> 16) & 0xffff;
+    int k;
+
+    if (buf == Z_NULL) return 1L;
+
+    while (len > 0) {
+        k = len < NMAX ? len : NMAX;
+        len -= k;
+        while (k >= 16) {
+            DO16(buf);
+	    buf += 16;
+            k -= 16;
+        }
+        if (k != 0) do {
+            s1 += *buf++;
+	    s2 += s1;
+        } while (--k);
+        s1 %= BASE;
+        s2 %= BASE;
+    }
+    return (s2 << 16) | s1;
+}
+/* --- adler32.c */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/fs/jffs2/zlib.h uClinux-dist-20040408/linux-2.4.x/fs/jffs2/zlib.h
--- uClinux-dist/linux-2.4.x/fs/jffs2/zlib.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/fs/jffs2/zlib.h	2004-09-13 16:56:25.000000000 +0800
@@ -0,0 +1,1010 @@
+/*	$Id: zlib.h,v 1.2 1997/12/23 10:47:44 paulus Exp $	*/
+
+/*
+ * This file is derived from zlib.h and zconf.h from the zlib-1.0.4
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets.
+ */
+
+/*
+ *  ==FILEVERSION 971127==
+ *
+ * This marker is used by the Linux installation script to determine
+ * whether an up-to-date version of this file is already installed.
+ */
+
+
+/* +++ zlib.h */
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.0.4, Jul 24th, 1996.
+
+  Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  gzip@prep.ai.mit.edu    madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* +++ zconf.h */
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* From: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_	z_deflateInit_
+#  define deflate	z_deflate
+#  define deflateEnd	z_deflateEnd
+#  define inflateInit_ 	z_inflateInit_
+#  define inflate	z_inflate
+#  define inflateEnd	z_inflateEnd
+#  define deflateInit2_	z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy	z_deflateCopy
+#  define deflateReset	z_deflateReset
+#  define deflateParams	z_deflateParams
+#  define inflateInit2_	z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync	z_inflateSync
+#  define inflateReset	z_inflateReset
+#  define compress	z_compress
+#  define uncompress	z_uncompress
+#  define adler32	z_adler32
+#  define crc32		z_crc32
+#  define get_crc_table z_get_crc_table
+
+#  define Byte		z_Byte
+#  define uInt		z_uInt
+#  define uLong		z_uLong
+#  define Bytef	        z_Bytef
+#  define charf		z_charf
+#  define intf		z_intf
+#  define uIntf		z_uIntf
+#  define uLongf	z_uLongf
+#  define voidpf	z_voidpf
+#  define voidp		z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+#  ifndef __32BIT__
+#    define __32BIT__
+#  endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
+#  define STDC
+#endif
+#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            1 << (windowBits+2)   +  1 << (memLevel+9)
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+   /* MSC small or medium model */
+#  define SMALL_MEDIUM
+#  ifdef _MSC_VER
+#    define FAR __far
+#  else
+#    define FAR far
+#  endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+#  ifndef __32BIT__
+#    define SMALL_MEDIUM
+#    define FAR __far
+#  endif
+#endif
+#ifndef FAR
+#   define FAR
+#endif
+
+typedef unsigned char  Byte;  /* 8 bits */
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#if defined(__BORLANDC__) && defined(SMALL_MEDIUM)
+   /* Borland C/C++ ignores FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void FAR *voidpf;
+   typedef void     *voidp;
+#else
+   typedef Byte FAR *voidpf;
+   typedef Byte     *voidp;
+#endif
+
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
+#  include <windows.h>
+#  define EXPORT  WINAPI
+#else
+#  define EXPORT
+#endif
+
+#endif /* _ZCONF_H */
+/* --- zconf.h */
+
+#define ZLIB_VERSION "1.0.4P"
+
+/* 
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms may be added later and will have the same
+  stream interface.
+
+     For compression the application must provide the output buffer and
+  may optionally provide the input buffer for optimization. For decompression,
+  the application must provide the input buffer and may optionally provide
+  the output buffer for optimization.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The library does not install any signal handler. It is recommended to
+  add at least a handler for SIGSEGV when decompressing; the library checks
+  the consistency of the input data whenever possible but may go nuts
+  for some forms of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: ascii or binary */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_PACKET_FLUSH	2
+#define Z_SYNC_FLUSH    3
+#define Z_FULL_FLUSH    4
+#define Z_FINISH        5
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+                        /* basic functions */
+
+extern const char * EXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+/* 
+extern int EXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+extern int EXPORT deflate OF((z_streamp strm, int flush));
+/*
+  Performs one or both of the following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression
+  block is terminated and flushed to the output buffer so that the
+  decompressor can get all input data available so far. For method 9, a future
+  variant on method 8, the current block will be flushed but not terminated.
+  Z_SYNC_FLUSH has the same effect as partial flush except that the compressed
+  output is byte aligned (the compressor can clear its internal bit buffer)
+  and the current block is always terminated; this can be useful if the
+  compressor has to be restarted from scratch after an interruption (in which
+  case the internal state of the compressor may be lost).
+    If flush is set to Z_FULL_FLUSH, the compression block is terminated, a
+  special marker is output and the compression dictionary is discarded; this
+  is useful to allow the decompressor to synchronize if one compressed block
+  has been damaged (see inflateSync below).  Flushing degrades compression and
+  so should be used only when necessary.  Using Z_FULL_FLUSH too often can
+  seriously degrade the compression. If deflate returns with avail_out == 0,
+  this function must be called again with the same value of the flush
+  parameter and more output space (updated avail_out), until the flush is
+  complete (deflate returns with non-zero avail_out).
+
+    If the parameter flush is set to Z_PACKET_FLUSH, the compression
+  block is terminated, and a zero-length stored block is output,
+  omitting the length bytes (the effect of this is that the 3-bit type
+  code 000 for a stored block is output, and the output is then
+  byte-aligned).  This is designed for use at the end of a PPP packet.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+  
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() may update data_type if it can make a good guess about
+  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
+*/
+
+
+extern int EXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/* 
+extern int EXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.  If
+   zalloc and zfree are set to Z_NULL, inflateInit updates them to use default
+   allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
+   with the version assumed by the caller.  msg is set to null if there is no
+   error message. inflateInit does not perform any decompression: this will be
+   done by inflate().
+*/
+
+
+extern int EXPORT inflate OF((z_streamp strm, int flush));
+/*
+  Performs one or both of the following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
+  inflate flushes as much output as possible to the output buffer. The
+  flushing behavior of inflate is not specified for values of the flush
+  parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
+  current implementation actually flushes as much output as possible
+  anyway.  For Z_PACKET_FLUSH, inflate checks that once all the input data
+  has been consumed, it is expecting to see the length field of a stored
+  block; if not, it returns Z_DATA_ERROR.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster routine
+  may be used for the single inflate() call.
+
+    inflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if the end of the
+  compressed data has been reached and all uncompressed output has been
+  produced, Z_NEED_DICT if a preset dictionary is needed at this point (see
+  inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted,
+  Z_STREAM_ERROR if the stream structure was inconsistent (for example if
+  next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in
+  the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the
+  application may then call inflateSync to look for a good compression block.
+  In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the
+  dictionary chosen by the compressor.
+*/
+
+
+extern int EXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*   
+extern int EXPORT deflateInit2 OF((z_streamp strm,
+                                   int  level,
+                                   int  method,
+                                   int  windowBits,
+                                   int  memLevel,
+                                   int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library. (Method 9 will allow a 64K history buffer and
+   partial block flushes.)
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library (the value 16 will be allowed for method 9). Larger
+   values of this parameter result in better compression at the expense of
+   memory usage. The default value is 15 if deflateInit is used instead.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match).  Filtered data consists mostly of small values with a
+   somewhat random distribution. In this case, the compression algorithm is
+   tuned to compress them better. The effect of Z_FILTERED is to force more
+   Huffman coding and less string matching; it is somewhat intermediate
+   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+   the compression ratio but not the correctness of the compressed output even
+   if it is not set appropriately.
+
+     If next_in is not null, the library will use this buffer to hold also
+   some history information; the buffer must either hold the entire input
+   data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in
+   is null, the library will allocate its own history buffer (and leave next_in
+   null). next_out need not be provided here but must be provided by the
+   application for the next call of deflate().
+
+     If the history buffer is provided by the application, next_in must
+   must never be changed by the application since the compressor maintains
+   information inside this buffer from call to call; the application
+   must provide more input only by increasing avail_in. next_in is always
+   reset by the library in this case.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
+   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
+   an invalid method). msg is set to null if there is no error message.
+   deflateInit2 does not perform any compression: this will be done by
+   deflate(). 
+*/
+                            
+extern int EXPORT deflateSetDictionary OF((z_streamp strm,
+                                           const Bytef *dictionary,
+				           uInt  dictLength));
+/*
+     Initializes the compression dictionary (history buffer) from the given
+   byte sequence without producing any compressed output. This function must
+   be called immediately after deflateInit or deflateInit2, before any call
+   of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and
+   can be predicted with good accuracy; the data can then be compressed better
+   than with the default empty dictionary. In this version of the library,
+   only the last 32K bytes of the dictionary are used.
+     Upon return of this function, strm->adler is set to the Adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The Adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.)
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state
+   is inconsistent (for example if deflate has already been called for this
+   stream). deflateSetDictionary does not perform any compression: this will
+   be done by deflate(). 
+*/
+
+extern int EXPORT deflateCopy OF((z_streamp dest,
+                                  z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.  If
+   the source stream is using an application-supplied history buffer, a new
+   buffer is allocated for the destination stream.  The compressed output
+   buffer is always application-supplied. It's the responsibility of the
+   application to provide the correct values of next_out and avail_out for the
+   next call of deflate.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+extern int EXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy));
+/*
+     Dynamically update the compression level and compression strategy.
+   This can be used to switch between compression and straight copy of
+   the input data, or to switch to a different kind of input data requiring
+   a different strategy. If the compression level is changed, the input
+   available so far is compressed with the old level (and may be flushed);
+   the new level will take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+extern int EXPORT deflateOutputPending OF((z_streamp strm));
+/*
+     Returns the number of bytes of output which are immediately
+   available from the compressor (i.e. without any further input
+   or flush).
+*/
+
+/*   
+extern int EXPORT inflateInit2 OF((z_streamp strm,
+                                   int  windowBits));
+
+     This is another version of inflateInit with more compression options. The
+   fields next_out, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library (the value 16 will be allowed soon). The
+   default value is 15 if inflateInit is used instead. If a compressed stream
+   with a larger window size is given as input, inflate() will return with
+   the error code Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     If next_out is not null, the library will use this buffer for the history
+   buffer; the buffer must either be large enough to hold the entire output
+   data, or have at least 1<<windowBits bytes.  If next_out is null, the
+   library will allocate its own buffer (and leave next_out null). next_in
+   need not be provided here but must be provided by the application for the
+   next call of inflate().
+
+     If the history buffer is provided by the application, next_out must
+   never be changed by the application since the decompressor maintains
+   history information inside this buffer from call to call; the application
+   can only reset next_out to the beginning of the history buffer when
+   avail_out is zero and all output has been consumed.
+
+      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
+   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
+   windowBits < 8). msg is set to null if there is no error message.
+   inflateInit2 does not perform any decompression: this will be done by
+   inflate().
+*/
+
+extern int EXPORT inflateSetDictionary OF((z_streamp strm,
+				           const Bytef *dictionary,
+					   uInt  dictLength));
+/*
+     Initializes the decompression dictionary (history buffer) from the given
+   uncompressed byte sequence. This function must be called immediately after
+   a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen
+   by the compressor can be determined from the Adler32 value returned by this
+   call of inflate. The compressor and decompressor must use exactly the same
+   dictionary (see deflateSetDictionary).
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect Adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+extern int EXPORT inflateSync OF((z_streamp strm));
+/* 
+    Skips invalid compressed data until the special marker (see deflate()
+  above) can be found, or until all available input is skipped. No output
+  is provided.
+
+    inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no marker has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+extern int EXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+extern int inflateIncomp OF((z_stream *strm));
+/*
+     This function adds the data at next_in (avail_in bytes) to the output
+   history without performing any output.  There must be no pending output,
+   and the decompressor must be expecting to see the start of a block.
+   Calling this function is equivalent to decompressing a stored block
+   containing the data at next_in (except that the data is not output).
+*/
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level, window size,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+extern int EXPORT compress OF((Bytef *dest,   uLongf *destLen,
+			       const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least 0.1% larger than
+   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+extern int EXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+				 const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+
+
+typedef voidp gzFile;
+
+extern gzFile EXPORT gzopen  OF((const char *path, const char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb") but can also include a compression level
+   ("wb9").  gzopen can be used to read a file which is not in gzip format;
+   in this case gzread will directly read from the file without decompression.
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).
+*/
+
+extern gzFile EXPORT gzdopen  OF((int fd, const char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, pipe or
+   fileno (in the file has been previously opened with fopen).
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+extern int EXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+extern int EXPORT    gzwrite OF((gzFile file, const voidp buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+extern int EXPORT    gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+extern int EXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+extern uLong EXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running crc with the bytes buf[0..len-1] and return the updated
+   crc. If buf is NULL, this function returns the required initial value
+   for the crc. Pre- and post-conditioning (one's complement) is performed
+   within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+extern int EXPORT deflateInit_ OF((z_streamp strm, int level,
+			           const char *version, int stream_size));
+extern int EXPORT inflateInit_ OF((z_streamp strm,
+				   const char *version, int stream_size));
+extern int EXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+				    int windowBits, int memLevel, int strategy,
+				    const char *version, int stream_size));
+extern int EXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+				    const char *version, int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+		      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
+/* --- zlib.h */
Only in uClinux-dist/linux-2.4.x/include: asm-alpha
Only in uClinux-dist/linux-2.4.x/include/asm-armnommu: arch
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/71x_map.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/71x_map.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/71x_map.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/71x_map.h	2004-08-18 11:46:42.000000000 +0800
@@ -0,0 +1,477 @@
+/******************** (C) COPYRIGHT 2003 STMicroelectronics ********************
+* File Name          : 71x_map.h
+* Description        : Peripherals memory mapping and registers structures
+
+*******************************************************************************/
+
+#ifndef __ASM_ARCH_71XMAP_H
+#define __ASM_ARCH_71XMAP_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+
+
+/* IP registers structures */
+
+typedef volatile struct
+{
+  u16 DATA0;
+  u16 EMPTY1[3];
+  u16 DATA1;
+  u16 EMPTY2[3];
+  u16 DATA2;
+  u16 EMPTY3[3];
+  u16 DATA3;
+  u16 EMPTY4[3];
+  u16 CSR;
+  u16 EMPTY5[7];
+  u16 PRES;
+} ADC12_TypeDef;
+
+typedef volatile struct
+{
+  u32 BSR;
+  u32 TOR;
+  u32 OMR;
+  u32 TOER;
+  u32 CKDIS;
+  u32 SWRES;
+} APB_TypeDef;
+
+typedef volatile struct
+{
+  u16 RXR;
+  u16 EMPTY1;
+  u16 TXR;
+  u16 EMPTY2;
+  u16 CSR1;
+  u16 EMPTY3;
+  u16 CSR2;
+  u16 EMPTY4;
+  u16 CLK;
+} BSPI_TypeDef;
+
+typedef volatile struct
+{
+  u16 COMR;
+  u16 EMPTY1;
+  u16 COMM;
+  u16 EMPTY2;
+  u16 MASK1;
+  u16 EMPTY3;
+  u16 MASK2;
+  u16 EMPTY4;
+  u16 ARB1;
+  u16 EMPTY5;
+  u16 ARB2;
+  u16 EMPTY6;
+  u16 MSGC;
+  u16 EMPTY7;
+  u16 DA1;
+  u16 EMPTY8;
+  u16 DA2;
+  u16 EMPTY9;
+  u16 DB1;
+  u16 EMPTY10;
+  u16 DB2;
+  u16 EMPTY11[27];
+} CAN_MsgObj_TypeDef;
+
+typedef volatile struct
+{
+  u16 CR;
+  u16 EMPTY1;
+  u16 SR;
+  u16 EMPTY2;
+  u16 ERR;
+  u16 EMPTY3;
+  u16 BTR;
+  u16 EMPTY4;
+  u16 INTR;
+  u16 EMPTY5;
+  u16 TESTR;
+  u16 EMPTY6;
+  u16 BRPR;
+  u16 EMPTY7[3];
+  CAN_MsgObj_TypeDef sMsgObj[2];
+  u16 EMPTY8[16];
+  u16 TR1;
+  u16 EMPTY9;
+  u16 TR2;
+  u16 EMPTY10[13];
+  u16 NEWD1;
+  u16 EMPTY11;
+  u16 NEWD2;
+  u16 EMPTY12[13];
+  u16 INTP1;
+  u16 EMPTY13;
+  u16 INTP2;
+  u16 EMPTY14[13];
+  u16 MSGV1;
+  u16 EMPTY15;
+  u16 MSGV2;
+  u16 EMPTY16;
+} CAN_TypeDef;
+
+typedef volatile struct
+{
+  u32 ICR;
+  u32 CICR;
+  u32 CIPR;
+  u32 EMPTY1[3];
+  u32 IVR;
+  u32 FIR;
+  u32 IER;
+  u32 EMPTY2[7];
+  u32 IPR;
+  u32 EMPTY3[7];
+  u32 SIR[32];
+} EIC_TypeDef;
+
+typedef volatile struct
+{
+  u16 BCR0;
+  u16 EMPTY1;
+  u16 BCR1;
+  u16 EMPTY2;
+  u16 BCR2;
+  u16 EMPTY3;
+  u16 BCR3;
+  u16 EMPTY4;
+} EMI_TypeDef;
+
+typedef volatile struct
+{
+  u32 FCR0;
+  u32 FCR1;
+  u32 FDR0;
+  u32 FDR1;
+  u32 FAR;
+  u32 FER;
+} FLASHR_TypeDef;
+
+typedef volatile struct
+{
+  u32 FNVWPAR;
+  u32 EMPTY;
+  u32 FNVAPR0;
+  u32 FNVAPR1;
+} FLASHPR_TypeDef;
+
+typedef volatile struct
+{
+  u16 PC0;
+  u16 EMPTY1;
+  u16 PC1;
+  u16 EMPTY2;
+  u16 PC2;
+  u16 EMPTY3;
+  u16 PD;
+  u16 EMPTY4;
+} GPIO_TypeDef;
+
+typedef volatile struct
+{
+  u8  CR;
+  u8  EMPTY1[3];
+  u8  SR1;
+  u8  EMPTY2[3];
+  u8  SR2;
+  u8  EMPTY3[3];
+  u8  CCR;
+  u8  EMPTY4[3];
+  u8  OAR1;
+  u8  EMPTY5[3];
+  u8  OAR2;
+  u8  EMPTY6[3];
+  u8  DR;
+  u8  EMPTY7[3];
+  u8  ECCR;
+} I2C_TypeDef;
+
+typedef volatile struct
+{
+  u16 CPUDIV;
+  u16 EMPTY1;
+  u16 APBDIV;
+  u16 EMPTY2;
+  u16 PH_RST;
+  u16 EMPTY3;
+  u16 PLL2CTL;
+  u16 EMPTY4;
+  u16 BOOTCONF;
+  u16 EMPTY5;
+  u16 PWRCTRL;
+} PCU_TypeDef;
+
+typedef volatile struct
+{
+  u32 CLKCTL;
+  u32 EMPTY1;
+  u32 CLK_FLAG;
+  u32 EMPTY2;
+  u32 EMPTY3;
+  u32 EMPTY4;
+  u32 PLLCONF;
+  u32 PH_CLOCK_EN;
+  u32 SYSMODE;
+} RCCU_TypeDef;
+
+typedef volatile struct
+{
+  u16 CRH;
+  u16 EMPTY1;
+  u16 CRL;
+  u16 EMPTY2;
+  u16 LHI;
+  u16 EMPTY3;
+  u16 LLO;
+  u16 EMPTY4;
+  u16 DHI;
+  u16 EMPTY5;
+  u16 DLO;
+  u16 EMPTY6;
+  u16 CNT_H;
+  u16 EMPTY7;
+  u16 CNT_L;
+  u16 EMPTY8;
+  u16 AHI;
+  u16 EMPTY9;
+  u16 ALO;
+} RTC_TypeDef;
+
+typedef volatile struct
+{
+  u16 ICAR;
+  u16 EMPTY1;
+  u16 ICBR;
+  u16 EMPTY2;
+  u16 OCAR;
+  u16 EMPTY3;
+  u16 OCBR;
+  u16 EMPTY4;
+  u16 CNTR;
+  u16 EMPTY5;
+  u16 CTR1;
+  u16 EMPTY6;
+  u16 CTR2;
+  u16 EMPTY7;
+  u16 SR;
+} TIM_TypeDef;
+
+typedef volatile struct
+{
+  u16 BRR;
+  u16 EMPTY1;
+  u16 TBR;
+  u16 EMPTY2;
+  u16 RBR;
+  u16 EMPTY3;
+  u16 CR;
+  u16 EMPTY4;
+  u16 IER;
+  u16 EMPTY5;
+  u16 SR;
+  u16 EMPTY6;
+  u16 GTR;
+  u16 EMPTY7;
+  u16 TOR;
+  u16 EMPTY8;
+  u16 TRR;
+  u16 EMPTY9;
+  u16 RRR;
+} UART_TypeDef;
+
+typedef volatile struct
+{
+  u32 ENDP_0;
+  u32 ENDP_1;
+  u32 ENDP_2;
+  u32 ENDP_3;
+  u32 ENDP_4;
+  u32 ENDP_5;
+  u32 ENDP_6;
+  u32 ENDP_7;
+  u32 ENDP_8;
+  u32 ENDP_9;
+  u32 ENDP_10;
+  u32 ENDP_11;
+  u32 ENDP_12;
+  u32 ENDP_13;
+  u32 ENDP_14;
+  u32 ENDP_15;
+  u32 CNTR_;
+  u32 ISTR_;
+  u32 FNR_;
+  u32 DADDR_;
+  u32 BTABLE_;
+} USB_TypeDef;
+
+typedef volatile struct
+{
+  u16 CR;
+  u16 EMPTY1;
+  u16 PR;
+  u16 EMPTY2;
+  u16 VR;
+  u16 EMPTY3;
+  u16 CNT;
+  u16 EMPTY4;
+  u16 SR;
+  u16 EMPTY5;
+  u16 MR;
+  u16 EMPTY6;
+  u16 KR;
+} WDG_TypeDef;
+
+typedef volatile struct
+{
+  u8  SRL;
+  u8  EMPTY1[7];
+  u8  CTRL;
+  u8  EMPTY2[3];
+  u8  MRH;
+  u8  EMPTY3[3];
+  u8  MRL;
+  u8  EMPTY4[3];
+  u8  TRH;
+  u8  EMPTY5[3];
+  u8  TRL;
+  u8  EMPTY6[3];
+  u8  PRH;
+  u8  EMPTY7[3];
+  u8  PRL;
+} XTI_TypeDef;
+
+
+/* IRQ vectors */
+typedef volatile struct
+{
+  u32 T0TIMI_IRQHandler;
+  u32 FLASH_IRQHandler;
+  u32 RCCU_IRQHandler;
+  u32 RTC_IRQHandler;
+  u32 WDG_IRQHandler;
+  u32 XTI_IRQHandler;
+  u32 USBHP_IRQHandler;
+  u32 I2C0ITERR_IRQHandler;
+  u32 I2C1ITERR_IRQHandler;
+  u32 UART0_IRQHandler;
+  u32 UART1_IRQHandler;
+  u32 UART2_IRQHandler;
+  u32 UART3_IRQHandler;
+  u32 BSPI0_IRQHandler;
+  u32 BSPI1_IRQHandler;
+  u32 I2C0_IRQHandler;
+  u32 I2C1_IRQHandler;
+  u32 CAN_IRQHandler;
+  u32 ADC12_IRQHandler;
+  u32 T1TIMI_IRQHandler;
+  u32 T2TIMI_IRQHandler;
+  u32 T3TIMI_IRQHandler;
+  u32 EMPTY1[3];
+  u32 HDLC_IRQHandler;
+  u32 USBLP_IRQHandler;
+  u32 EMPTY2[2];
+  u32 T0TOI_IRQHandler;
+  u32 T0OC1_IRQHandler;
+  u32 T0OC2_IRQHandler;
+} IRQVectors_TypeDef;
+
+#endif
+/*===================================================================*/
+
+/* Memory mapping */
+
+#define RAM_BASE        0x20000000
+
+#define FLASHR_BASE     0x40100000
+#define FLASHPR_BASE    0x4010DFB0
+
+#define EXTMEM_BASE     0x60000000
+#define RCCU_BASE       0xA0000000
+#define PCU_BASE        0xA0000040
+#define APB1_BASE       0xC0000000
+#define APB2_BASE       0xE0000000
+#define EIC_BASE        0xFFFFF800
+
+#define I2C0_BASE       (APB1_BASE + 0x1000)
+#define I2C1_BASE       (APB1_BASE + 0x2000)
+#define UART0_BASE      (APB1_BASE + 0x4000)
+#define UART1_BASE      (APB1_BASE + 0x5000)
+#define UART2_BASE      (APB1_BASE + 0x6000)
+#define UART3_BASE      (APB1_BASE + 0x7000)
+#define CAN_BASE        (APB1_BASE + 0x9000)
+#define BSPI0_BASE      (APB1_BASE + 0xA000)
+#define BSPI1_BASE      (APB1_BASE + 0xB000)
+#define USB_BASE        (APB1_BASE + 0x8800)
+
+#define XTI_BASE        (APB2_BASE + 0x101C)
+#define GPIO0_BASE      (APB2_BASE + 0x3000)
+#define GPIO1_BASE      (APB2_BASE + 0x4000)
+#define GPIO2_BASE      (APB2_BASE + 0x5000)
+#define ADC12_BASE      (APB2_BASE + 0x7000)
+#define TIM0_BASE       (APB2_BASE + 0x9000)
+#define TIM1_BASE       (APB2_BASE + 0xA000)
+#define TIM2_BASE       (APB2_BASE + 0xB000)
+#define TIM3_BASE       (APB2_BASE + 0xC000)
+#define RTC_BASE        (APB2_BASE + 0xD000)
+#define WDG_BASE        (APB2_BASE + 0xE000)
+
+#define EMI_BASE        (EXTMEM_BASE + 0x0C000000)
+
+/*===================================================================*/
+#ifndef __ASSEMBLY__
+/* IP data access */
+
+  #define ADC12 ((ADC12_TypeDef *)ADC12_BASE)
+
+  #define APB1  ((APB_TypeDef *)APB1_BASE)
+  #define APB2  ((APB_TypeDef *)APB2_BASE)
+
+  #define BSPI0 ((BSPI_TypeDef *)BSPI0_BASE)
+  #define BSPI1 ((BSPI_TypeDef *)BSPI1_BASE)
+
+  #define CAN   ((CAN_TypeDef *)CAN_BASE)
+
+  #define EIC   ((EIC_TypeDef *)EIC_BASE)
+
+  #define EMI   ((EMI_TypeDef *)EMI_BASE)
+
+  #define FLASHR  ((FLASHR_TypeDef *)FLASHR_BASE)
+  #define FLASHPR ((FLASHPR_TypeDef *)FLASHPR_BASE)
+
+  #define GPIO0 ((GPIO_TypeDef *)GPIO0_BASE)
+  #define GPIO1 ((GPIO_TypeDef *)GPIO1_BASE)
+  #define GPIO2 ((GPIO_TypeDef *)GPIO2_BASE)
+
+  #define I2C0  ((I2C_TypeDef *)I2C0_BASE)
+  #define I2C1  ((I2C_TypeDef *)I2C1_BASE)
+
+  #define PCU   ((PCU_TypeDef *)PCU_BASE)
+
+  #define RCCU  ((RCCU_TypeDef *)RCCU_BASE)
+
+  #define RTC   ((RTC_TypeDef *)RTC_BASE)
+
+  #define TIM0  ((TIM_TypeDef *)TIM0_BASE)
+  #define TIM1  ((TIM_TypeDef *)TIM1_BASE)
+  #define TIM2  ((TIM_TypeDef *)TIM2_BASE)
+  #define TIM3  ((TIM_TypeDef *)TIM3_BASE)
+
+  #define UART0 ((UART_TypeDef *)UART0_BASE)
+  #define UART1 ((UART_TypeDef *)UART1_BASE)
+  #define UART2 ((UART_TypeDef *)UART2_BASE)
+  #define UART3 ((UART_TypeDef *)UART3_BASE)
+
+  #define USB   ((USB_TypeDef *)USB_BASE)
+
+  #define WDG   ((WDG_TypeDef *)WDG_BASE)
+
+  #define XTI   ((XTI_TypeDef *)XTI_BASE)
+
+  #define IRQVectors ((IRQVectors_TypeDef *)&T0TIMI_Addr)
+#endif
+ 
+#endif
\ No newline at end of file
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/dma.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/dma.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/dma.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/dma.h	2004-08-16 17:01:02.000000000 +0800
@@ -0,0 +1,14 @@
+/*
+ * asm/arch-armnommu/arch-STR710/dma.h:
+ * 
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+
+#define MAX_DMA_ADDRESS		0xffffffff
+#define MAX_DMA_CHANNELS        0
+//#define arch_dma_init(dma_chan)
+
+#endif /* _ASM_ARCH_DMA_H */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/hardware.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/hardware.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/hardware.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/hardware.h	2004-09-16 10:30:43.000000000 +0800
@@ -0,0 +1,114 @@
+/********************************************************/
+/*							*/
+/* STR710					*/
+/* ST MMCC 2004					*/
+/*							*/
+/********************************************************/
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "71x_map.h"
+
+/*
+ * define CPU master clock
+ */
+#define MHz		1000000
+#define fRCLK_MHz	(48 * MHz)
+#define fMCLK_MHz	(fRCLK_MHz)
+#define fPCLK1_MHz	(fRCLK_MHz/2)
+#define fPCLK2_MHz	(fRCLK_MHz/4)
+
+
+/* ****************************** */
+/* Interrupt Controller Registers */
+/* ****************************** */
+
+/* ***************** */
+/* I2C Bus Registers */
+/* ***************** */
+
+
+/* ************** */
+/* UART Macros */
+/* ************** */
+#define  UART_EVEN_PARITY  0x0000
+#define  UART_ODD_PARITY   0x0020
+
+#define  UART_0_5_StopBits  0x00
+#define  UART_1_StopBits    0x08
+#define  UART_1_5_StopBits  0x10
+#define  UART_2_StopBits    0x18
+  
+#define  UARTM_8D   0x01
+#define  UARTM_7D_P 0x03
+#define  UARTM_9D   0x04
+#define  UARTM_8D_W 0x05
+#define  UARTM_8D_P 0x07
+
+// UART IntEnable Register bit definition
+#define UART_RxHalfFull_IE                  0x0100
+#define UART_TimeOutIdle_IE              0x0080
+#define UART_TimeOutNotEmpty_IE    0x0040
+#define UART_OverrunError_IE             0x0020
+#define UART_FrameError_IE                0x0010
+#define UART_ParityError_IE                 0x0008
+#define UART_TxHalfEmpty_IE              0x0004
+#define UART_TxEmpty_IE                    0x0002
+#define UART_RxBufFull_IE                   0x0001
+
+// UART flags definition
+#define UART_TxFull          0x0200
+#define UART_RxHalfFull      0x0100
+#define UART_TimeOutIdle     0x0080
+#define UART_TimeOutNotEmpty 0x0040
+#define UART_OverrunError    0x0020
+#define UART_FrameError      0x0010
+#define UART_ParityError     0x0008
+#define UART_TxHalfEmpty     0x0004
+#define UART_TxEmpty         0x0002
+#define UART_RxBufFull       0x0001
+
+// CR regiter bit definition
+#define UART_FIFOEnableBit 10
+#define UART_SCEnableBit   9
+#define UART_RxEnableBit   8
+#define UART_RunBit        7
+#define UART_LoopBackBit   6
+#define UART_ParityOddBit  5
+#define UART_StopBits      3
+
+// Stop bits definition
+#define UART_05StopBits     0x00
+#define UART_1StopBit       (0x01<<3)
+#define UART_15StopBits     (0x02<<3)
+#define UART_2StopBits      (0x03<<3)
+
+// Modes definition
+#define UART_8BitsData       0x01
+#define UART_7BitsData       0x03
+#define UART_9BitsData       0x04
+#define UART_8BitsDataWakeUp 0x05
+#define UART_8BitsDataParity 0x07
+
+//UART output during uncompressing...
+#define DEBUG_UARTx	UART0
+#define DEBUG_BAUDRATE 115200
+
+/* **************** */
+/* Timers Registers */
+/* **************** */
+
+
+/**********************************/
+/* Ext Memory Control Register */
+/**********************************/
+
+
+/********/
+/* Misc */
+/********/
+
+#define HARD_RESET_NOW()
+
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/io.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/io.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/io.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/io.h	2004-08-16 11:26:34.000000000 +0800
@@ -0,0 +1,33 @@
+/*
+ * linux/include/asm-armnommu/arch-str710/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.
+ * --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 --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/irq.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/irq.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/irq.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/irq.h	2004-09-16 10:32:50.000000000 +0800
@@ -0,0 +1,54 @@
+/*
+ * asm/arch-STR710/irq.h:
+ * 
+ */
+
+#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 str710_mask_irq(unsigned int irq);
+extern void str710_unmask_irq(unsigned int irq);
+extern void str710_mask_ack_irq(unsigned int irq);
+extern void str710_int_init(void);
+
+#if 1
+static __inline__ unsigned int fixup_irq (unsigned int irq)
+{
+	//write 1 to clear pending int
+	EIC->IPR |= (1<<irq); 
+	return (irq);
+}
+#endif
+
+static __inline__ void clear_pending_bit(unsigned int irq)
+{
+	EIC->IPR |= (1<<irq); 
+}
+static __inline__ void irq_init_irq(void)
+{
+	unsigned long flags;
+	int irq;
+
+	save_flags_cli(flags);
+	str710_int_init();
+	restore_flags(flags);
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		if ((irq>=22 && irq<=24)||(irq==27)||(irq==28))
+			irq_desc[irq].valid	= 0;//these chanels are reserved
+		else
+			irq_desc[irq].valid	= 1;	
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= str710_mask_ack_irq;
+		irq_desc[irq].mask	= str710_mask_irq;
+		irq_desc[irq].unmask	= str710_unmask_irq;
+	}
+}
+#endif /* __ASM_ARCH_IRQ_H__ */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/irqs.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/irqs.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/irqs.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/irqs.h	2004-08-16 15:33:16.000000000 +0800
@@ -0,0 +1,38 @@
+/*
+ * asm/arch-STR710/irqs.h:
+ * 
+ */
+#ifndef __ASM_ARCH_IRQS_H__
+#define __ASM_ARCH_IRQS_H__
+#define NR_IRQS		32
+#define VALID_IRQ(i)	(i>=0 && i<NR_IRQS)
+  
+#define IRQ_T0TIMI     	0
+#define	IRQ_FLASH		1
+#define IRQ_PRCCU       2
+#define IRQ_RTC       	3
+#define IRQ_WDG         4
+#define IRQ_XTI         5
+#define IRQ_USBH		6
+#define IRQ_I2C0ITERR	7
+#define I2C1ITERR		8
+#define IRQ_UART0		9
+#define IRQ_UART1		10
+#define IRQ_UART2		11
+#define IRQ_UART3		12
+#define IRQ_SPI0		13
+#define IRQ_SPI1		14
+#define IRQ_I2C0		15
+#define IRQ_I2C1		16
+#define IRQ_CAN			17
+#define IRQ_ADC			18
+#define IRQ_T1TIMI		19
+#define IRQ_T2TIMI		20
+#define IRQ_T3TIMI		21
+#define IRQ_HDLC		25
+#define IRQ_USBLP		26
+#define IRQ_T0TOI		29
+#define IRQ_T0OC1		30
+#define IRQ_T0OC2		31
+
+#endif /* __ASM_ARCH_IRQS_H__ */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/memory.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/memory.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/memory.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/memory.h	2004-08-17 14:17:40.000000000 +0800
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm-armnommu/arch-STR710/memory.h
+ *
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_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 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)
+#endif
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/param.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/param.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/param.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/param.h	2003-05-22 09:05:24.000000000 +0800
@@ -0,0 +1,6 @@
+#ifndef __ARCH_ASM_PARAM_H__
+#define __ARCH_ASM_PARAM_H__
+
+/* nothing for now */
+
+#endif /* __ARCH_ASM_PARAM_H__ */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/processor.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/processor.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/processor.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/processor.h	2004-08-16 15:45:08.000000000 +0800
@@ -0,0 +1,15 @@
+/*
+ * uclinux/include/asm-armnommu/arch-STR710/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)
+
+#endif
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/shmparam.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/shmparam.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/shmparam.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/shmparam.h	2003-05-22 09:05:24.000000000 +0800
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-a5k/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/system.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/system.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/system.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/system.h	2004-08-16 15:55:38.000000000 +0800
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-armnommu/arch-STR710/system.h
+ *
+ *
+ */
+
+static inline void arch_idle(void)
+{
+	while (!current->need_resched && !hlt_counter);
+}
+
+extern inline void arch_reset(char mode)
+{
+	/* REVISIT --gmcnutt */
+}
+
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/time.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/time.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/time.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/time.h	2004-09-16 10:35:44.000000000 +0800
@@ -0,0 +1,44 @@
+/*
+ * linux/include/asm/arch-STR710/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/timex.h>
+
+extern struct irqaction timer_irq;
+
+extern unsigned long str710_gettimeoffset(void);
+extern void str710_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+
+void __inline__ setup_timer (void)
+{	
+	//source interrupt vector for WDG 
+	EIC->SIR[IRQ_WDG] = (IRQ_WDG << 16)|15;//the highest priority
+	
+	//We use WDG as OS timer
+	WDG->CR = 0x00;	//Free-running Timer mode
+	WDG->PR = 199;	//prescaler 199+1
+	WDG->VR = fPCLK2_MHz/(200*CLOCK_TICK_RATE);//Preset Value
+	WDG->MR = 0x1; //EC int enabled
+
+	WDG->CR = 0x2;	//Start counter
+	
+	timer_irq.handler = str710_timer_interrupt;
+	setup_arm_irq(IRQ_WDG, &timer_irq);//IRQ is enabled in this function
+	
+	/////////init GPIO LED13~15 (controlled by P2.12~14, active high)///
+	//Output_PP
+	GPIO2->PC0 |= 0x7000;
+	GPIO2->PC1 &= ~0x7000;
+	GPIO2->PC2 |= 0x7000;
+	GPIO2->PD |= 0x7000;	//all lighted
+	
+}
+
+#endif /* __ASM_ARCH_TIME_H__ */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/timex.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/timex.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/timex.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/timex.h	2004-09-16 10:32:02.000000000 +0800
@@ -0,0 +1,12 @@
+/*
+ * timex.h:
+ */
+#ifndef __ASM_ARCH_TIMEX_H__
+#define __ASM_ARCH_TIMEX_H__
+
+#include <asm/hardware.h>
+
+//100 ticks per second
+#define CLOCK_TICK_RATE	   100  
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/uncompress.c uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/uncompress.c
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/uncompress.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/uncompress.c	2004-09-14 18:23:14.000000000 +0800
@@ -0,0 +1,44 @@
+/*
+ * linux/include/asm/arch-str710/uncompress.c
+ */
+
+#include <asm/hardware.h>
+
+static int str710_decomp_setup()
+{
+	//Rx pin - IN_TRI_CMOS
+	GPIO0->PC0 &= ~(0x0001<<8);
+    GPIO0->PC1 |= (0x0001<<8);
+	GPIO0->PC2 &= ~(0x0001<<8);
+	//Tx pin - AF PushPull
+    GPIO0->PC0 |= (0x0001<<9);
+    GPIO0->PC1 |= (0x0001<<9);
+    GPIO0->PC2 |= (0x0001<<9);	
+	
+	//Disable all int
+	DEBUG_UARTx->IER = 0x00;
+	//Rx Enable,8-N-1, 0x89
+	DEBUG_UARTx->CR = (1<<UART_RxEnableBit)|UART_8BitsData|UART_1StopBit|(1<<UART_RunBit);
+	//115200 baudrate
+	DEBUG_UARTx->BRR = (u16)(fPCLK1_MHz/(16*DEBUG_BAUDRATE));
+	//Rx Fifo reset
+	DEBUG_UARTx->TRR = 0xFFFF;
+}
+
+static int str710_putc(char c)
+{
+   if (DEBUG_UARTx->CR & (0x0001<<10))// if FIFO ENABLED
+    while((DEBUG_UARTx->SR & UART_TxFull)); // while the UART_TxFIFO contain 16 characters.
+   else                  // if FIFO DISABLED
+    while (!(DEBUG_UARTx->SR & UART_TxEmpty)); // while the transmit shift register not empty
+   DEBUG_UARTx->TBR = c;
+  	
+	if(c == '\n')
+		str710_putc('\r');
+}
+
+static void str710_puts(const char *s)
+{
+	while(*s != '\0')
+		str710_putc(*s++);
+}
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/uncompress.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/uncompress.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/uncompress.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/uncompress.h	2004-08-16 17:34:20.000000000 +0800
@@ -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)			str710_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()	str710_decomp_setup()
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/vmalloc.h uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/vmalloc.h
--- uClinux-dist/linux-2.4.x/include/asm-armnommu/arch-STR710/vmalloc.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/asm-armnommu/arch-STR710/vmalloc.h	2003-05-22 09:05:24.000000000 +0800
@@ -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)
+
Only in uClinux-dist/linux-2.4.x/include/asm-armnommu: mach-types.h
Only in uClinux-dist/linux-2.4.x/include/asm-armnommu: proc
Only in uClinux-dist/linux-2.4.x/include: asm-blackfin
Only in uClinux-dist/linux-2.4.x/include: asm-cris
Only in uClinux-dist/linux-2.4.x/include: asm-e1nommu
Only in uClinux-dist/linux-2.4.x/include: asm-h8300
Only in uClinux-dist/linux-2.4.x/include: asm-i386
Only in uClinux-dist/linux-2.4.x/include: asm-ia64
Only in uClinux-dist/linux-2.4.x/include: asm-m68k
Only in uClinux-dist/linux-2.4.x/include: asm-m68knommu
Only in uClinux-dist/linux-2.4.x/include: asm-microblaze
Only in uClinux-dist/linux-2.4.x/include: asm-mips
Only in uClinux-dist/linux-2.4.x/include: asm-mips64
Only in uClinux-dist/linux-2.4.x/include: asm-niosnommu
Only in uClinux-dist/linux-2.4.x/include: asm-parisc
Only in uClinux-dist/linux-2.4.x/include: asm-ppc
Only in uClinux-dist/linux-2.4.x/include: asm-ppc64
Only in uClinux-dist/linux-2.4.x/include: asm-s390
Only in uClinux-dist/linux-2.4.x/include: asm-s390x
Only in uClinux-dist/linux-2.4.x/include: asm-sh
Only in uClinux-dist/linux-2.4.x/include: asm-sh64
Only in uClinux-dist/linux-2.4.x/include: asm-sparc
Only in uClinux-dist/linux-2.4.x/include: asm-sparc64
Only in uClinux-dist/linux-2.4.x/include: asm-sparcnommu
Only in uClinux-dist/linux-2.4.x/include: asm-v850
Only in uClinux-dist/linux-2.4.x/include: asm-x86_64
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/linux/i2c-id.h uClinux-dist-20040408/linux-2.4.x/include/linux/i2c-id.h
--- uClinux-dist/linux-2.4.x/include/linux/i2c-id.h	2004-04-08 08:17:28.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/linux/i2c-id.h	2004-09-14 17:30:08.000000000 +0800
@@ -147,6 +147,8 @@
 
 #define I2C_ALGO_EC     0x100000        /* ACPI embedded controller     */
 
+#define I2C_ALGO_STR71X 0x090000	/*str710 I2C controller*/
+
 #define I2C_ALGO_MPC8XX 0x110000	/* MPC8xx PowerPC I2C algorithm */
 
 #define I2C_ALGO_EXP	0x800000	/* experimental			*/
@@ -205,4 +207,6 @@
 /* --- ISA pseudo-adapter						*/
 #define I2C_HW_ISA 0x00
 
+/*---- STR710 I2C controleer ---*/
+#define I2C_HW_STR71X 0x00
 #endif /* I2C_ID_H */
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/include/linux/mtd/mtd.h uClinux-dist-20040408/linux-2.4.x/include/linux/mtd/mtd.h
--- uClinux-dist/linux-2.4.x/include/linux/mtd/mtd.h	2004-04-08 08:17:30.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/include/linux/mtd/mtd.h	2004-09-16 10:32:59.000000000 +0800
@@ -28,7 +28,7 @@
 
 
 #define MTD_CHAR_MAJOR 90
-#define MTD_BLOCK_MAJOR 31
+#define MTD_BLOCK_MAJOR 30
 #define MAX_MTD_DEVICES 16
 
 
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/linux-2.4.x/Makefile uClinux-dist-20040408/linux-2.4.x/Makefile
--- uClinux-dist/linux-2.4.x/Makefile	2004-04-08 08:14:46.000000000 +0800
+++ uClinux-dist-20040408/linux-2.4.x/Makefile	2004-09-08 10:26:28.000000000 +0800
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 24
-EXTRAVERSION = -uc0
+EXTRAVERSION = -uc0-str710
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Only in uClinux-dist: linux-2.6.x
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/.menuconfig.log uClinux-dist-20040408/.menuconfig.log
--- uClinux-dist/.menuconfig.log	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/.menuconfig.log	2004-09-21 12:10:40.000000000 +0800
@@ -0,0 +1 @@
+sed: can't read arch/armnommu/defconfig: No such file or directory
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/user/EEPROM/24cXX.c uClinux-dist-20040408/user/EEPROM/24cXX.c
--- uClinux-dist/user/EEPROM/24cXX.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/user/EEPROM/24cXX.c	2004-09-20 15:29:41.000000000 +0800
@@ -0,0 +1,181 @@
+/***************************************************************************
+    copyright            : (C) by 2002-2003 Stefano Barbato
+    email                : stefano@codesink.org
+
+    $Id: 24cXX.c,v 1.1 2003/11/28 03:07:48 mds 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <linux/fs.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include "24cXX.h"
+
+static int i2c_write_1b(struct eeprom *e, __u8 buf)
+{
+	int r;
+	// we must simulate a plain I2C byte write with SMBus functions
+	r = i2c_smbus_write_byte(e->fd, buf);
+	if(r < 0)
+		fprintf(stderr, "Error i2c_write_1b: %s\n", strerror(errno));
+	usleep(10);
+	return r;
+}
+
+static int i2c_write_2b(struct eeprom *e, __u8 buf[2])
+{
+	int r;
+	// we must simulate a plain I2C byte write with SMBus functions
+	r = i2c_smbus_write_byte_data(e->fd, buf[0], buf[1]);
+	if(r < 0)
+		fprintf(stderr, "Error i2c_write_2b: %s\n", strerror(errno));
+	usleep(10);
+	return r;
+}
+
+static int i2c_write_3b(struct eeprom *e, __u8 buf[3])
+{
+	int r;
+	// we must simulate a plain I2C byte write with SMBus functions
+	// the __u16 data field will be byte swapped by the SMBus protocol
+	r = i2c_smbus_write_word_data(e->fd, buf[0], buf[2] << 8 | buf[1]);
+	if(r < 0)
+		fprintf(stderr, "Error i2c_write_3b: %s\n", strerror(errno));
+	usleep(10);
+	return r;
+}
+
+
+#define CHECK_I2C_FUNC( var, label ) \
+	do { 	if(0 == (var & label)) { \
+		fprintf(stderr, "\nError: " \
+			#label " function is required. Program halted.\n\n"); \
+		exit(1); } \
+	} while(0);
+
+int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom* e)
+{
+	int funcs, fd, r;
+	e->fd = e->addr = 0;
+	e->dev = 0;
+	
+	fd = open(dev_fqn, O_RDWR);
+	if(fd <= 0)
+		return -1;
+
+	// get funcs list
+	if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0))
+		return r;
+	
+	// check for req funcs
+	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE );
+	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE );
+	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE_DATA );
+	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE_DATA );
+	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_WORD_DATA );
+	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_WORD_DATA );
+
+	// set working device
+	if( ( r = ioctl(fd, I2C_SLAVE, addr)) < 0)
+		return r;
+		
+	e->fd = fd;
+	e->addr = addr;
+	e->dev = dev_fqn;
+	e->type = type;
+	return 0;
+}
+
+int eeprom_close(struct eeprom *e)
+{
+	close(e->fd);
+	e->fd = -1;
+	e->dev = 0;
+	e->type = EEPROM_TYPE_UNKNOWN;
+	return 0;
+}
+
+#if 0
+int eeprom_24c32_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data)
+{
+	__u8 buf[3] = { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };
+	return i2c_write_3b(e, buf);
+}
+
+
+int eeprom_24c32_read_current_byte(struct eeprom* e)
+{
+	ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
+	return i2c_smbus_read_byte(e->fd);
+}
+
+int eeprom_24c32_read_byte(struct eeprom* e, __u16 mem_addr)
+{
+	int r;
+	ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
+	__u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };
+	r = i2c_write_2b(e, buf);
+	if (r < 0)
+		return r;
+	r = i2c_smbus_read_byte(e->fd);
+	return r;
+}
+#endif
+
+
+int eeprom_read_current_byte(struct eeprom* e)
+{
+	ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
+	return i2c_smbus_read_byte(e->fd);
+}
+
+int eeprom_read_byte(struct eeprom* e, __u16 mem_addr)
+{
+	int r;
+	ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
+	if(e->type == EEPROM_TYPE_8BIT_ADDR)
+	{
+		__u8 buf =  mem_addr & 0x0ff;
+		r = i2c_write_1b(e, buf);
+	} else if(e->type == EEPROM_TYPE_16BIT_ADDR) {
+		__u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };
+		r = i2c_write_2b(e, buf);
+	} else {
+		fprintf(stderr, "ERR: unknown eeprom type\n");
+		return -1;
+	}
+	if (r < 0)
+		return r;
+	r = i2c_smbus_read_byte(e->fd);
+	return r;
+}
+
+int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data)
+{
+	if(e->type == EEPROM_TYPE_8BIT_ADDR) {
+		__u8 buf[2] = { mem_addr & 0x00ff, data };
+		return i2c_write_2b(e, buf);
+	} else if(e->type == EEPROM_TYPE_16BIT_ADDR) {
+		__u8 buf[3] = 
+			{ (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };
+		return i2c_write_3b(e, buf);
+	} else {
+		fprintf(stderr, "ERR: unknown eeprom type\n");
+		return -1;
+	}
+}
+
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/user/EEPROM/24cXX.h uClinux-dist-20040408/user/EEPROM/24cXX.h
--- uClinux-dist/user/EEPROM/24cXX.h	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/user/EEPROM/24cXX.h	2004-09-20 10:48:28.000000000 +0800
@@ -0,0 +1,58 @@
+/***************************************************************************
+    copyright            : (C) by 2002-2003 Stefano Barbato
+    email                : stefano@codesink.org
+
+    $Id: 24cXX.h,v 1.1 2003/11/28 03:07:48 mds 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#ifndef _24CXX_H_
+#define _24CXX_H_
+#include "linux/i2c-dev.h"
+
+#define EEPROM_TYPE_UNKNOWN	0
+#define EEPROM_TYPE_8BIT_ADDR	1
+#define EEPROM_TYPE_16BIT_ADDR 	2
+
+struct eeprom
+{
+	char *dev; 	// device file i.e. /dev/i2c-N
+	int addr;	// i2c address
+	int fd;		// file descriptor
+	int type; 	// eeprom type
+};
+
+/*
+ * opens the eeprom device at [dev_fqn] (i.e. /dev/i2c-N) whose address is
+ * [addr] and set the eeprom_24c32 [e]
+ */
+int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom*);
+/*
+ * closees the eeprom device [e] 
+ */
+int eeprom_close(struct eeprom *e);
+/*
+ * read and returns the eeprom byte at memory address [mem_addr] 
+ * Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) 
+ */
+int eeprom_read_byte(struct eeprom* e, __u16 mem_addr);
+/*
+ * read the current byte
+ * Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) 
+ */
+int eeprom_read_current_byte(struct eeprom *e);
+/*
+ * writes [data] at memory address [mem_addr] 
+ * Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) 
+ */
+int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data);
+
+#endif
+
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/user/EEPROM/eeprog.c uClinux-dist-20040408/user/EEPROM/eeprog.c
--- uClinux-dist/user/EEPROM/eeprog.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/user/EEPROM/eeprog.c	2004-09-20 14:45:14.000000000 +0800
@@ -0,0 +1,282 @@
+/***************************************************************************
+    copyright            : (C) by 2002-2003 Stefano Barbato
+    email                : stefano@codesink.org
+
+    $Id: eeprog.c,v 1.3 2003/12/13 23:54:59 mds 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#include <stdio.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "24cXX.h"
+
+#define VERSION 	"0.7.5"
+
+#define ENV_DEV		"EEPROG_DEV"
+#define ENV_I2C_ADDR	"EEPROG_I2C_ADDR"
+
+int g_quiet;
+
+#define usage_if(a) do { do_usage_if( a , __LINE__); } while(0);
+void do_usage_if(int b, int line)
+{
+const static char *eeprog_usage = 
+"eeprog " VERSION ", a 24Cxx EEPROM reader/writer\n"
+"Copyright (c) 2003 by Stefano Barbato - All rights reserved.\n"
+"Usage: eeprog [-fqxdh] [-16|-8] [ -r addr[:count] | -w addr ]  /dev/i2c-N  i2c-address\n" 
+"\n"
+"  Address modes: \n"
+"	-8		Use 8bit address mode for 24c0x...24C16 [default]\n"
+"	-16		Use 16bit address mode for 24c32...24C256\n"
+"  Actions: \n"
+"	-r addr[:count]	Read [count] (1 if omitted) bytes from [addr]\n" 
+"			and print them to the standard output\n" 
+"	-w addr		Write input (stdin) at address [addr] of the EEPROM\n"
+"	-h		Print this help\n"
+"  Options: \n"
+"	-x		Set hex output mode\n" 
+"	-d		Dummy mode, display what *would* have been done\n" 
+"	-f		Disable warnings and don't ask confirmation\n"
+"	-q		Quiet mode\n"
+"\n"
+"The following environment variables could be set instead of the command\n"
+"line arguments:\n"
+"	EEPROG_DEV		device name(/dev/i2c-N)\n"
+"	EEPROG_I2C_ADDR		i2c-address\n"
+"\n"
+"	Examples\n"
+"	1- read 64 bytes from the EEPROM at address 0x54 on bus 0 starting\n"
+"	   at address 123 (decimal)\n"
+"		eeprog /dev/i2c-0 0x54 -r 123:64\n"
+"	2- prints the hex codes of the first 32 bytes read from bus 1 \n"
+"	   at address 0x22\n"
+"		eeprog /dev/i2c-1 0x51 -x -r 0x22:0x20\n"
+"	3- write the current timestamp at address 0x200 of the EEPROM on \n"
+"	   bus 0 at address 0x33 \n"
+"		date | eeprog /dev/i2c-0 0x33 -w 0x200\n";
+
+	if(!b)
+		return;
+	fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line);
+	exit(1);
+}
+
+
+#define die_if(a, msg) do { do_die_if( a , msg, __LINE__); } while(0);
+void do_die_if(int b, char* msg, int line)
+{
+	if(!b)
+		return;
+	fprintf(stderr, "Error at line %d: %s\n", line, msg);
+	//fprintf(stderr, "	sysmsg: %s\n", strerror(errno));
+	exit(1);
+}
+
+#define print_info(args...) do { if(!g_quiet) fprintf(stderr, args); } while(0);
+
+void parse_arg(char *arg, int* paddr, int *psize)
+{
+	char *end;
+	*paddr = strtoul(arg, &end, 0);
+	if(*end == ':')
+		*psize = strtoul(++end, 0, 0);
+}
+
+int confirm_action()
+{
+	fprintf(stderr, 
+	"\n"
+	"____________________________WARNING____________________________\n"
+	"Erroneously writing to a system EEPROM (like DIMM SPD modules)\n"
+	"can break your system.  It will NOT boot anymore so you'll not\n"
+	"be able to fix it.\n"
+	"\n"
+	"Reading from 8bit EEPROMs (like that in your DIMM) without using\n"
+	"the -8 switch can also UNEXPECTEDLY write to them, so be sure to\n"
+	"use the -8 command param when required.\n"
+	"\n"
+	"Use -f to disable this warning message\n"
+	"\n"
+	"Press ENTER to continue or hit CTRL-C to exit\n"
+	"\n"
+	);
+	getchar();
+	return 1; 
+}
+
+
+int read_from_eeprom(struct eeprom *e, int addr, int size, int hex)
+{
+
+	int ch, i;
+	// hex print out
+	die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error");
+	i = 1;
+	if(hex)
+		printf("\n %.4x|  %.2x ", addr, ch);
+	while(--size)
+	{
+		die_if((ch = eeprom_read_current_byte(e)) < 0, "read error");
+		if(hex)
+		{
+			addr++;
+			if( (i % 16) == 0 ) 
+				printf("\n %.4x|  ", addr);
+			else if( (i % 8) == 0 ) 
+				printf("  ");
+			i++;
+			printf("%.2x ", ch);
+		} else {
+			putchar(ch);
+		}
+	}
+	if(hex)
+		printf("\n\n");
+	fflush(stdout);
+	return 0;
+}
+
+int write_to_eeprom(struct eeprom *e, int addr)
+{
+	int c;
+	while((c = getchar()) != EOF)
+	{
+		print_info(".");
+		fflush(stdout);
+		die_if(eeprom_write_byte(e, addr++, c), "write error");
+	}
+	print_info("\n\n");
+	return 0;
+}
+
+int main(int argc, char** argv)
+{
+	struct eeprom e;
+	int ret, op, i2c_addr, memaddr, size, want_hex, dummy, force, sixteen;
+	char *device, *arg = 0, *i2c_addr_s;
+	struct stat st;
+	int eeprom_type = 0;
+
+	op = want_hex = dummy = force = sixteen = 0;
+	g_quiet = 0;
+
+	while((ret = getopt(argc, argv, "1:8fr:qhw:xd")) != -1)
+	{
+		switch(ret)
+		{
+		case '1':
+			usage_if(*optarg != '6' || strlen(optarg) != 1);
+			die_if(eeprom_type, "EEPROM type switch (-8 or -16) used twice");
+			eeprom_type = EEPROM_TYPE_16BIT_ADDR;	
+			break;
+		case 'x':
+			want_hex++;
+			break;
+		case 'd':
+			dummy++;
+			break;
+		case '8':
+			die_if(eeprom_type, "EEPROM type switch (-8 or -16) used twice");
+			eeprom_type = EEPROM_TYPE_8BIT_ADDR;
+			break;
+		case 'f':
+			force++;
+			break;
+		case 'q':
+			g_quiet++;
+			break;
+		case 'h':
+			usage_if(1);
+			break;
+		default:
+			die_if(op != 0, "Both read and write requested"); 
+			arg = optarg;
+			op = ret;
+		}
+	}
+	if(!eeprom_type)
+		eeprom_type = EEPROM_TYPE_8BIT_ADDR; // default
+
+	usage_if(op == 0); // no switches 
+	// set device and i2c_addr reading from cmdline or env
+	device = i2c_addr_s = 0;
+	switch(argc - optind)
+	{
+	case 0:
+		device = getenv(ENV_DEV);
+		i2c_addr_s = getenv(ENV_I2C_ADDR);
+		break;
+	case 1:
+		if(stat(argv[optind], &st) != -1)
+		{
+			device = argv[optind];
+			i2c_addr_s = getenv(ENV_I2C_ADDR);
+		} else {
+			device = getenv(ENV_DEV);
+			i2c_addr_s = argv[optind];
+		}
+		break;
+	case 2:
+		device = argv[optind++];
+		i2c_addr_s = argv[optind];
+		break;
+	default:
+		usage_if(1);
+	}
+	usage_if(!device || !i2c_addr_s);
+	i2c_addr = strtoul(i2c_addr_s, 0, 0);
+
+	print_info("eeprog %s, a 24Cxx EEPROM reader/writer\n", VERSION);
+	print_info("Copyright (c) 2003 by Stefano Barbato - All rights reserved.\n");
+	print_info("  Bus: %s, Address: 0x%x, Mode: %dbit\n", 
+			device, i2c_addr, 
+			(eeprom_type == EEPROM_TYPE_8BIT_ADDR ? 8 : 16) );
+	if(dummy)
+	{
+		fprintf(stderr, "Dummy mode selected, nothing done.\n");
+		return 0;
+	}
+	
+	die_if(eeprom_open(device, i2c_addr, eeprom_type, &e) < 0, 
+			"unable to open eeprom device file (check that the file exists and that it's readable)");
+	switch(op)
+	{
+	case 'r':
+		if(force == 0)
+			confirm_action();
+		size = 1; // default
+		parse_arg(arg, &memaddr, &size);
+		print_info("  Reading %d bytes from 0x%x\n", size, memaddr);
+		read_from_eeprom(&e, memaddr, size, want_hex);
+		break;
+	case 'w':
+		if(force == 0)
+			confirm_action();
+		parse_arg(arg, &memaddr, &size);
+		print_info("  Writing stdin starting at address 0x%x\n", 
+			memaddr);
+		write_to_eeprom(&e, memaddr);
+		break;
+	default:
+		usage_if(1);
+		exit(1);
+	}
+	eeprom_close(&e);
+
+	return 0;
+}
+
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/user/EEPROM/eeprom.c uClinux-dist-20040408/user/EEPROM/eeprom.c
--- uClinux-dist/user/EEPROM/eeprom.c	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/user/EEPROM/eeprom.c	2004-09-20 17:29:05.000000000 +0800
@@ -0,0 +1,294 @@
+/*
+This program is hereby placed into the public domain.
+Of course the program is provided without warranty of any kind.
+*/
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+#include "linux/i2c-dev.h"
+
+/*
+  this program can read 24C08
+ */
+
+#define DEFAULT_I2C_BUS      "/dev/i2c0"
+#define DEFAULT_EEPROM_ADDR  0x54         /* the 24C08 sits on i2c address 0x50 */
+#define DEFAULT_NUM_PAGES    4            /* we default to a 24C08 eeprom which has 8 pages */
+#define BYTES_PER_PAGE       256          /* one eeprom page is 256 byte */
+#define MAX_BYTES            16            /* max number of bytes to write in one chunk */
+       /* ... note: 24C02 and 24C01 only allow 8 bytes to be written in one chunk.   *
+        *  if you are going to write 24C04,8,16 you can change this to 16            */
+
+/* write len bytes (stored in buf) to eeprom at address addr, page-offset offset */
+/* if len=0 (buf may be NULL in this case) you can reposition the eeprom's read-pointer */
+/* return 0 on success, -1 on failure */
+int eeprom_write(int fd,
+		 unsigned int addr,
+		 unsigned int offset,
+		 unsigned char *buf,
+		 unsigned char len
+){
+	struct i2c_rdwr_ioctl_data msg_rdwr;
+	struct i2c_msg             i2cmsg;
+	int i;
+	char _buf[MAX_BYTES + 1];
+
+	if(len>MAX_BYTES){
+	    fprintf(stderr,"I can only write MAX_BYTES bytes at a time!\n");
+	    return -1;
+	}
+
+	if(len+offset >256){
+	    fprintf(stderr,"Sorry, len(%d)+offset(%d) > 256 (page boundary)\n",
+			len,offset);
+	    return -1;
+	}
+
+	_buf[0]=offset;    /* _buf[0] is the offset into the eeprom page! */
+	for(i=0;i<len;i++) /* copy buf[0..n] -> _buf[1..n+1] */
+	    _buf[1+i]=buf[i];
+
+	msg_rdwr.msgs = &i2cmsg;
+	msg_rdwr.nmsgs = 1;
+
+	i2cmsg.addr  = addr;
+	i2cmsg.flags = 0;
+	i2cmsg.len   = 1+len;
+	i2cmsg.buf   = _buf;
+
+	if((i=ioctl(fd,I2C_RDWR,&msg_rdwr))<0){
+	    perror("ioctl()");
+	    fprintf(stderr,"ioctl returned %d\n",i);
+	    return -1;
+	}
+
+	if(len>0)
+	    fprintf(stderr,"Wrote %d bytes to eeprom at 0x%02x, offset %08x\n",
+		    len,addr,offset);
+	else
+	    fprintf(stderr,"Positioned pointer in eeprom at 0x%02x to offset %08x\n",
+		    addr,offset);
+
+	return 0;
+}
+
+/* read len bytes stored in eeprom at address addr, offset offset in array buf */
+/* return -1 on error, 0 on success */
+int eeprom_read(int fd,
+		 unsigned int addr,
+		 unsigned int offset,
+		 unsigned char *buf,
+		 unsigned char len
+){
+	struct i2c_rdwr_ioctl_data msg_rdwr;
+	struct i2c_msg             i2cmsg;
+	int i;
+
+	if(len>MAX_BYTES){
+	    fprintf(stderr,"I can only write MAX_BYTES bytes at a time!\n");
+	    return -1;
+	}
+
+	if(eeprom_write(fd,addr,offset,NULL,0)<0)
+	    return -1;
+
+	msg_rdwr.msgs = &i2cmsg;
+	msg_rdwr.nmsgs = 1;
+
+	i2cmsg.addr  = addr;
+	i2cmsg.flags = I2C_M_RD;
+	i2cmsg.len   = len;
+	i2cmsg.buf   = buf;
+
+	if((i=ioctl(fd,I2C_RDWR,&msg_rdwr))<0){
+	    perror("ioctl()");
+	    fprintf(stderr,"ioctl returned %d\n",i);
+	    return -1;
+	}
+
+	fprintf(stderr,"Read %d bytes from eeprom at 0x%02x, offset %08x\n",
+		len,addr,offset);
+
+	return 0;
+}
+
+
+
+int main(int argc, char **argv){
+    int i,j;
+
+    /* filedescriptor and name of device */
+    int d; 
+    char *dn=DEFAULT_I2C_BUS;
+
+    /* filedescriptor and name of data file */
+    int f=-1;
+    char *fn=NULL;
+
+    unsigned int addr=DEFAULT_EEPROM_ADDR;
+    int rwmode=0;
+    int pages=DEFAULT_NUM_PAGES;
+
+    int force=0; /* suppress warning on write! */
+    
+    while((i=getopt(argc,argv,"d:a:p:wyf:h"))>=0){
+	switch(i){
+	case 'h':
+	    fprintf(stderr,"%s [-d dev] [-a adr] [-p pgs] [-w] [-y] [-f file]\n",argv[0]);
+	    fprintf(stderr,"\tdev: device, e.g. /dev/i2c0    (def)\n");
+	    fprintf(stderr,"\tadr: base address of eeprom, eg 0x54 (def)\n");
+	    fprintf(stderr,"\tpgs: number of pages to read, eg 4 (def)\n");
+	    fprintf(stderr,"\t-w : write to eeprom (default is reading!)\n");
+	    fprintf(stderr,"\t-y : suppress warning when writing (default is to warn!)\n");
+	    fprintf(stderr,"\t-f file: copy eeprom contents to/from file\n");
+	    fprintf(stderr,"\t         (default for read is test only; for write is all zeros)\n");
+	    fprintf(stderr,"Note on pages/addresses:\n");
+	    fprintf(stderr,"\teeproms with more than 256 byte appear as if they\n");
+	    fprintf(stderr,"\twere several eeproms with consecutive addresses on the bus\n");
+	    fprintf(stderr,"\tso we might as well address several seperate eeproms with\n");
+	    fprintf(stderr,"\tincreasing addresses....\n\n");
+	    exit(1);
+	    break;
+	case 'd':
+	    dn=optarg;
+	    break;
+	case 'a':
+	    if(sscanf(optarg,"0x%x",&addr)!=1){
+		fprintf(stderr,"Cannot parse '%s' as addrs., example: 0xa0\n",
+			optarg);
+		exit(1);
+	    }
+	    break;
+	case 'p':
+	    if(sscanf(optarg,"%d",&pages)!=1){
+		fprintf(stderr,"Cannot parse '%s' as number of pages, example: 8\n",
+			optarg);
+		exit(1);
+	    }
+	    break;
+	case 'w':
+	    rwmode++;
+	    break;
+	case 'f':
+	    fn=optarg;
+	    break;
+	case 'y':
+	    force++;
+	    break;
+	}
+
+    }
+   
+    fprintf(stderr,"base-address of eeproms       : 0x%02x\n",addr);
+    fprintf(stderr,"number of pages to read       : %d (0x%02x .. 0x%02x)\n",
+		    pages,addr,addr+pages-1);
+
+    if(fn){
+	if(!rwmode) /* if we are reading, *WRITE* to file */
+	    f=open(fn,O_WRONLY|O_CREAT,0666);
+	else /* if we are writing to eeprom, *READ* from file */
+	    f=open(fn,O_RDONLY);
+	if(f<0){
+	    fprintf(stderr,"Could not open data-file %s for reading or writing\n",fn);
+	    perror(fn);
+	    exit(1);
+	}
+	fprintf(stderr,"file opened for %7s       : %s\n",rwmode?"reading":"writing",fn);
+	fprintf(stderr,"            on filedescriptor : %d\n",f);
+    }
+
+    if((d=open(dn,O_RDWR))<0){
+	fprintf(stderr,"Could not open i2c at %s\n",dn);
+	perror(dn);
+	exit(1);
+    }
+
+    fprintf(stderr,"i2c-devicenode is             : %s\n",dn);
+    fprintf(stderr,"            on filedescriptor : %d\n\n",d);
+
+    /***
+     *** I'm not the one to blame of you screw your computer!
+     ***/
+    if(rwmode & ! force){
+	unsigned char warnbuf[4];
+	fprintf(stderr,"**WARNING**\n");
+	fprintf(stderr," - \tYou have chosen to WRITE to this eeprom.\n");
+	fprintf(stderr,"\tMake sure that this tiny chip is *NOT* vital to the\n");
+	fprintf(stderr,"\toperation of your computer as you can easily corrupt\n");
+	fprintf(stderr,"\tthe configuration memory of your SDRAM-memory-module,\n");
+	fprintf(stderr,"\tyour IBM ThinkPad or whatnot...! Fixing these errors can be\n");
+	fprintf(stderr,"\ta time-consuming and very costly process!\n\n");
+	fprintf(stderr,"Things to consider:\n");
+	fprintf(stderr," - \tYou can have more than one i2c-bus, check in /proc/bus/i2c\n");
+	fprintf(stderr,"\tand specify the correct one with -d\n");
+	fprintf(stderr,"\tright now you have chosen to use '%s'\n",dn);
+	fprintf(stderr," - \tA eeprom can occupy several i2c-addresses (one per page)\n");
+	fprintf(stderr,"\tso please make sure that there is no vital eeprom in your computer\n");
+	fprintf(stderr,"\tsitting at addresses between 0x%02x and 0x%02x\n",addr,addr+pages-1);
+
+	fprintf(stderr,"Enter 'yes' to continue:");
+	fflush(stderr);
+	if(!fgets(warnbuf,sizeof(warnbuf),stdin)){
+	    fprintf(stderr,"\nCould not read confirmation from stdin!\n");
+	    exit(1);
+	}
+	if(strncmp(warnbuf,"yes",3)){
+	    fprintf(stderr,"\n** ABORTING WRITE! **, you did not answer 'yes'\n");
+	    exit(1);
+	}
+    }
+
+    for(i=0;i<pages;i++){
+	unsigned char buf[BYTES_PER_PAGE];
+
+	if(rwmode){
+
+	    if(f>=0){
+		j=read(f,buf,sizeof(buf));
+		if(j<0){
+		    fprintf(stderr,"Cannot read from file '%s'\n",fn);
+		    perror(fn);
+		    exit(1);
+		}
+		if(j!=sizeof(buf)){
+		    fprintf(stderr,"File '%s' is too small, padding eeprom with zeroes\n",fn);
+		    while(j<sizeof(buf))
+			buf[j++]=0;
+		}
+	    } else {
+		for(j=0;j<sizeof(buf);j++)
+		    buf[j]=0;
+	    }
+            for(j=0;j<(BYTES_PER_PAGE/MAX_BYTES);j++)
+		if(eeprom_write(d,addr+i,j*MAX_BYTES,buf+(j*MAX_BYTES),MAX_BYTES)<0)
+		    exit(1);
+	} else {
+            for(j=0;j<(BYTES_PER_PAGE/MAX_BYTES);j++)
+		if(eeprom_read(d,addr+i,j*MAX_BYTES,buf+(j*MAX_BYTES),MAX_BYTES)<0)
+		    exit(1);
+	}
+
+
+	if(!rwmode && f>=0){
+	    j=write(f,buf,sizeof(buf));
+	    if(j!=sizeof(buf)){
+		fprintf(stderr,"Cannot write to file '%s'\n",fn);
+		perror(fn);
+		exit(1);
+	    }
+	}
+
+    }
+
+    if(f>=0)
+	close(f);
+
+    close(d);
+
+    exit(0);
+
+}
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/user/EEPROM/Makefile uClinux-dist-20040408/user/EEPROM/Makefile
--- uClinux-dist/user/EEPROM/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/user/EEPROM/Makefile	2004-09-20 16:41:51.000000000 +0800
@@ -0,0 +1,17 @@
+
+PROGS = eeprog eeprom
+OBJS = eeprog.o 24cXX.o
+
+all: $(PROGS)
+
+eeprog: eeprog.o 24cXX.o
+	$(CC) $(LDFLAGS) -o $@ $(OBJS) -lz $(LDLIBS$(LDLIBS_$@))
+	
+eeprom: eeprom.o
+	$(CC) $(LDFLAGS) -o $@ eeprom.o -lz $(LDLIBS$(LDLIBS_$@))
+	
+romfs:
+	$(ROMFSINST) -e CONFIG_USER_I2C_EEPROM /bin/eeprom
+
+clean:
+	-rm -f $(PROGS) *.elf *.gdb *.o
\ No newline at end of file
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/user/Makefile uClinux-dist-20040408/user/Makefile
--- uClinux-dist/user/Makefile	2004-04-08 08:27:54.000000000 +0800
+++ uClinux-dist-20040408/user/Makefile	2004-09-15 14:03:14.000000000 +0800
@@ -84,6 +84,7 @@
 dir_$(CONFIG_USER_E2FSPROGS_MISC_MKLOST_FOUND) += e2fsprogs
 dir_$(CONFIG_USER_E2FSPROGS_MISC_TUNE2FS)   += e2fsprogs
 dir_$(CONFIG_USER_E2FSPROGS_MISC_UUIDGEN)   += e2fsprogs
+dir_y	+= EEPROM
 dir_$(CONFIG_USER_ELVISTINY_VI)             += elvis-tiny
 dir_$(CONFIG_USER_ETHATTACH_ETHATTACH)      += ethattach
 dir_$(CONFIG_USER_EZIPUPDATE_EZIPUPDATE)    += ez-ipupdate
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/user/ntp/config.log uClinux-dist-20040408/user/ntp/config.log
--- uClinux-dist/user/ntp/config.log	2004-04-08 08:27:24.000000000 +0800
+++ uClinux-dist-20040408/user/ntp/config.log	2004-09-21 15:50:13.000000000 +0800
@@ -10,11 +10,11 @@
 ## Platform. ##
 ## --------- ##
 
-hostname = goober
+hostname = dgz.mmcc.st.com
 uname -m = i686
-uname -r = 2.6.5
+uname -r = 2.6.3-4mdk
 uname -s = Linux
-uname -v = #2 Wed Apr 7 11:03:10 EST 2004
+uname -v = #1 Tue Mar 2 07:26:13 CET 2004
 
 /usr/bin/uname -p = unknown
 /bin/uname -X     = unknown
@@ -27,15 +27,15 @@
 /usr/bin/oslevel       = unknown
 /bin/universe          = unknown
 
-PATH: /usr/local/sbin/
-PATH: /sbin
-PATH: /usr/sbin
-PATH: /usr/local/bin
+PATH: /usr/bin
 PATH: /bin
 PATH: /usr/bin
-PATH: /usr/X11R6/bin
-PATH: /home/gerg/bin
-PATH: /home/gerg/uClinux-dist/tools
+PATH: /usr/local/bin
+PATH: /usr/X11R6/bin/
+PATH: /usr/games
+PATH: /home/mmcc/bin
+PATH: /sbin
+PATH: /home/mmcc/linux-dev/uClinux-dist-20040408/tools
 
 
 ## ----------- ##
@@ -317,9 +317,9 @@
 AUTOKEY=''
 AUTOMAKE=''
 AWK=''
-CC='m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE'
+CC='arm-elf-gcc '
 CCDEPMODE=''
-CFLAGS='-Os -g -fomit-frame-pointer -m5200 -DCONFIG_COLDFIRE  -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/gerg/uClinux-dist/lib/libc/include -I/home/gerg/uClinux-dist/lib/libm -I/home/gerg/uClinux-dist/lib/libcrypt_old -I/home/gerg/uClinux-dist -fno-builtin -msep-data -I/home/gerg/uClinux-dist/linux-2.6.x/include -Wall -Wcast-qual -Wmissing-prototypes -Wpointer-arith -Wshadow -Wstrict-prototypes -pipe'
+CFLAGS='-O2 -g -fomit-frame-pointer   -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/include -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -I/home/mmcc/linux-dev/uClinux-dist-20040408 -fno-builtin -nostartfiles -I/home/mmcc/linux-dev/uClinux-dist-20040408/linux-2.4.x/include -Wall -Wcast-qual -Wmissing-prototypes -Wpointer-arith -Wshadow -Wstrict-prototypes -pipe'
 CHUTEST=''
 CLKTEST=''
 CPP=''
@@ -338,7 +338,7 @@
 INSTALL_PROGRAM=''
 INSTALL_SCRIPT=''
 INSTALL_STRIP_PROGRAM=''
-LDFLAGS='-Os -g -fomit-frame-pointer -m5200 -DCONFIG_COLDFIRE  -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/gerg/uClinux-dist/lib/libc/include -I/home/gerg/uClinux-dist/lib/libm -I/home/gerg/uClinux-dist/lib/libcrypt_old -I/home/gerg/uClinux-dist -fno-builtin -msep-data -I/home/gerg/uClinux-dist/linux-2.6.x/include -Wl,-elf2flt -Wl,-move-rodata -L/home/gerg/uClinux-dist/lib/libc/. -L/home/gerg/uClinux-dist/lib/libc/lib -L/home/gerg/uClinux-dist/lib/libm -L/home/gerg/uClinux-dist/lib/libnet -L/home/gerg/uClinux-dist/lib/libdes -L/home/gerg/uClinux-dist/lib/libaes -L/home/gerg/uClinux-dist/lib/libpcap -L/home/gerg/uClinux-dist/lib/libssl -L/home/gerg/uClinux-dist/lib/libcrypt_old -L/home/gerg/uClinux-dist/prop/libsnapgear++ -L/home/gerg/uClinux-dist/prop/libsnapgear -L/home/gerg/uClinux-dist/lib/zlib'
+LDFLAGS='-O2 -g -fomit-frame-pointer   -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/include -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -I/home/mmcc/linux-dev/uClinux-dist-20040408 -fno-builtin -nostartfiles -I/home/mmcc/linux-dev/uClinux-dist-20040408/linux-2.4.x/include -Wl,-elf2flt /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crt0.o /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crti.o /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crtn.o -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/. -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libnet -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libdes -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libaes -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libpcap -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libssl -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/zlib'
 LIBOBJS=''
 LIBPARSE=''
 LIBRSAREF=''
@@ -377,7 +377,7 @@
 RSASRCS=''
 SET_MAKE=''
 SHELL='/bin/sh'
-STRIP='m68k-elf-strip'
+STRIP='arm-elf-strip'
 TESTDCF=''
 U=''
 VERSION=''
Only in uClinux-dist/user/tinylogin: applet_source_list
Only in uClinux-dist/user/tinylogin: config.h
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/user/wget/config.log uClinux-dist-20040408/user/wget/config.log
--- uClinux-dist/user/wget/config.log	2004-04-08 08:27:33.000000000 +0800
+++ uClinux-dist-20040408/user/wget/config.log	2004-09-21 15:50:26.000000000 +0800
@@ -10,11 +10,11 @@
 ## Platform. ##
 ## --------- ##
 
-hostname = goober
+hostname = dgz.mmcc.st.com
 uname -m = i686
-uname -r = 2.6.5
+uname -r = 2.6.3-4mdk
 uname -s = Linux
-uname -v = #2 Wed Apr 7 11:03:10 EST 2004
+uname -v = #1 Tue Mar 2 07:26:13 CET 2004
 
 /usr/bin/uname -p = unknown
 /bin/uname -X     = unknown
@@ -27,15 +27,15 @@
 /usr/bin/oslevel       = unknown
 /bin/universe          = unknown
 
-PATH: /usr/local/sbin/
-PATH: /sbin
-PATH: /usr/sbin
-PATH: /usr/local/bin
+PATH: /usr/bin
 PATH: /bin
 PATH: /usr/bin
-PATH: /usr/X11R6/bin
-PATH: /home/gerg/bin
-PATH: /home/gerg/uClinux-dist/tools
+PATH: /usr/local/bin
+PATH: /usr/X11R6/bin/
+PATH: /usr/games
+PATH: /home/mmcc/bin
+PATH: /sbin
+PATH: /home/mmcc/linux-dev/uClinux-dist-20040408/tools
 
 
 ## ----------- ##
@@ -51,23 +51,24 @@
 configure:1463: checking for a BSD-compatible install
 configure:1517: result: /usr/bin/install -c
 configure:1579: checking for gcc
-configure:1605: result: m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE
+configure:1605: result: arm-elf-gcc 
 configure:1849: checking for C compiler version
-configure:1852: m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE --version </dev/null >&5
+configure:1852: arm-elf-gcc  --version </dev/null >&5
 2.95.3
 configure:1855: $? = 0
-configure:1857: m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE -v </dev/null >&5
-Reading specs from /usr/local/lib/gcc-lib/m68k-elf/2.95.3/specs
+configure:1857: arm-elf-gcc  -v </dev/null >&5
+Reading specs from /usr/local/lib/gcc-lib/arm-elf/2.95.3/specs
 gcc version 2.95.3 20010315 (release)(ColdFire patches - 20010318 from http://fiddes.net/coldfire/)(uClinux XIP and shared lib patches from http://www.snapgear.com/)
 configure:1860: $? = 0
-configure:1862: m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE -V </dev/null >&5
-m68k-elf-gcc: argument to `-V' is missing
+configure:1862: arm-elf-gcc  -V </dev/null >&5
+arm-elf-gcc: argument to `-V' is missing
 configure:1865: $? = 1
 configure:1889: checking for C compiler default output
-configure:1892: m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE -Os -g -fomit-frame-pointer -m5200 -DCONFIG_COLDFIRE  -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/gerg/uClinux-dist/lib/libc/include -I/home/gerg/uClinux-dist/lib/libm -I/home/gerg/uClinux-dist/lib/libcrypt_old -I/home/gerg/uClinux-dist -fno-builtin -msep-data -I/home/gerg/uClinux-dist/linux-2.6.x/include -O  -Os -g -fomit-frame-pointer -m5200 -DCONFIG_COLDFIRE  -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/gerg/uClinux-dist/lib/libc/include -I/home/gerg/uClinux-dist/lib/libm -I/home/gerg/uClinux-dist/lib/libcrypt_old -I/home/gerg/uClinux-dist -fno-builtin -msep-data -I/home/gerg/uClinux-dist/linux-2.6.x/include -Wl,-elf2flt -Wl,-move-rodata -L/home/gerg/uClinux-dist/lib/libc/. -L/home/gerg/uClinux-dist/lib/libc/lib -L/home/gerg/uClinux-dist/lib/libm -L/home/gerg/uClinux-dist/lib/libnet -L/home/gerg/uClinux-dist/lib/libdes -L/home/gerg/uClinux-dist/lib/libaes -L/home/gerg/uClinux-dist/lib/libpcap -L/home/gerg/uClinux-dist/lib/libssl -L/home/gerg/uClinux-dist/lib/libcrypt_old -L/home/gerg/uClinux-dist/prop/libsnapgear++ -L/home/gerg/uClinux-dist/prop/libsnapgear -L/home/gerg/uClinux-dist/lib/zlib  conftest.c  >&5
-a.out.elf2flt: In function `_start':
-a.out.elf2flt(.text+0x8): undefined reference to `__uClibc_main'
-collect2: ld returned 1 exit status
+configure:1892: arm-elf-gcc  -O2 -g -fomit-frame-pointer   -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/include -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -I/home/mmcc/linux-dev/uClinux-dist-20040408 -fno-builtin -nostartfiles -I/home/mmcc/linux-dev/uClinux-dist-20040408/linux-2.4.x/include -O  -O2 -g -fomit-frame-pointer   -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/include -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -I/home/mmcc/linux-dev/uClinux-dist-20040408 -fno-builtin -nostartfiles -I/home/mmcc/linux-dev/uClinux-dist-20040408/linux-2.4.x/include -Wl,-elf2flt /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crt0.o /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crti.o /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crtn.o -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/. -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libnet -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libdes -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libaes -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libpcap -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libssl -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/zlib  conftest.c  >&5
+arm-elf-gcc: /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crt0.o: No such file or directory
+arm-elf-gcc: /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crti.o: No such file or directory
+arm-elf-gcc: /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crtn.o: No such file or directory
+cc1: warning: -g with -fomit-frame-pointer may not give sensible debugging
 configure:1895: $? = 1
 configure: failed program was:
 | #line 1868 "configure"
@@ -100,15 +101,15 @@
 ac_cv_build=i686-pc-linux-gnu
 ac_cv_build_alias=i686-pc-linux-gnu
 ac_cv_env_CC_set=set
-ac_cv_env_CC_value='m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE'
+ac_cv_env_CC_value='arm-elf-gcc '
 ac_cv_env_CFLAGS_set=set
-ac_cv_env_CFLAGS_value='-Os -g -fomit-frame-pointer -m5200 -DCONFIG_COLDFIRE  -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/gerg/uClinux-dist/lib/libc/include -I/home/gerg/uClinux-dist/lib/libm -I/home/gerg/uClinux-dist/lib/libcrypt_old -I/home/gerg/uClinux-dist -fno-builtin -msep-data -I/home/gerg/uClinux-dist/linux-2.6.x/include -O'
+ac_cv_env_CFLAGS_value='-O2 -g -fomit-frame-pointer   -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/include -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -I/home/mmcc/linux-dev/uClinux-dist-20040408 -fno-builtin -nostartfiles -I/home/mmcc/linux-dev/uClinux-dist-20040408/linux-2.4.x/include -O'
 ac_cv_env_CPPFLAGS_set=
 ac_cv_env_CPPFLAGS_value=
 ac_cv_env_CPP_set=
 ac_cv_env_CPP_value=
 ac_cv_env_LDFLAGS_set=set
-ac_cv_env_LDFLAGS_value='-Os -g -fomit-frame-pointer -m5200 -DCONFIG_COLDFIRE  -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/gerg/uClinux-dist/lib/libc/include -I/home/gerg/uClinux-dist/lib/libm -I/home/gerg/uClinux-dist/lib/libcrypt_old -I/home/gerg/uClinux-dist -fno-builtin -msep-data -I/home/gerg/uClinux-dist/linux-2.6.x/include -Wl,-elf2flt -Wl,-move-rodata -L/home/gerg/uClinux-dist/lib/libc/. -L/home/gerg/uClinux-dist/lib/libc/lib -L/home/gerg/uClinux-dist/lib/libm -L/home/gerg/uClinux-dist/lib/libnet -L/home/gerg/uClinux-dist/lib/libdes -L/home/gerg/uClinux-dist/lib/libaes -L/home/gerg/uClinux-dist/lib/libpcap -L/home/gerg/uClinux-dist/lib/libssl -L/home/gerg/uClinux-dist/lib/libcrypt_old -L/home/gerg/uClinux-dist/prop/libsnapgear++ -L/home/gerg/uClinux-dist/prop/libsnapgear -L/home/gerg/uClinux-dist/lib/zlib '
+ac_cv_env_LDFLAGS_value='-O2 -g -fomit-frame-pointer   -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/include -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -I/home/mmcc/linux-dev/uClinux-dist-20040408 -fno-builtin -nostartfiles -I/home/mmcc/linux-dev/uClinux-dist-20040408/linux-2.4.x/include -Wl,-elf2flt /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crt0.o /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crti.o /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crtn.o -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/. -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libnet -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libdes -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libaes -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libpcap -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libssl -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/zlib '
 ac_cv_env_build_alias_set=
 ac_cv_env_build_alias_value=
 ac_cv_env_host_alias_set=
@@ -118,7 +119,7 @@
 ac_cv_host=i686-pc-linux-gnu
 ac_cv_host_alias=i686-pc-linux-gnu
 ac_cv_path_install='/usr/bin/install -c'
-ac_cv_prog_ac_ct_CC='m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE'
+ac_cv_prog_ac_ct_CC='arm-elf-gcc '
 ac_cv_prog_make_make_set=yes
 
 ## ----------------- ##
@@ -129,8 +130,8 @@
 ANSI2KNR=''
 CATALOGS=''
 CATOBJEXT=''
-CC='m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE'
-CFLAGS='-Os -g -fomit-frame-pointer -m5200 -DCONFIG_COLDFIRE  -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/gerg/uClinux-dist/lib/libc/include -I/home/gerg/uClinux-dist/lib/libm -I/home/gerg/uClinux-dist/lib/libcrypt_old -I/home/gerg/uClinux-dist -fno-builtin -msep-data -I/home/gerg/uClinux-dist/linux-2.6.x/include -O'
+CC='arm-elf-gcc '
+CFLAGS='-O2 -g -fomit-frame-pointer   -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/include -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -I/home/mmcc/linux-dev/uClinux-dist-20040408 -fno-builtin -nostartfiles -I/home/mmcc/linux-dev/uClinux-dist-20040408/linux-2.4.x/include -O'
 CPP=''
 CPPFLAGS=''
 DATADIRNAME=''
@@ -148,7 +149,7 @@
 INSTALL_SCRIPT='${INSTALL}'
 INSTOBJEXT=''
 INTLLIBS=''
-LDFLAGS='-Os -g -fomit-frame-pointer -m5200 -DCONFIG_COLDFIRE  -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/gerg/uClinux-dist/lib/libc/include -I/home/gerg/uClinux-dist/lib/libm -I/home/gerg/uClinux-dist/lib/libcrypt_old -I/home/gerg/uClinux-dist -fno-builtin -msep-data -I/home/gerg/uClinux-dist/linux-2.6.x/include -Wl,-elf2flt -Wl,-move-rodata -L/home/gerg/uClinux-dist/lib/libc/. -L/home/gerg/uClinux-dist/lib/libc/lib -L/home/gerg/uClinux-dist/lib/libm -L/home/gerg/uClinux-dist/lib/libnet -L/home/gerg/uClinux-dist/lib/libdes -L/home/gerg/uClinux-dist/lib/libaes -L/home/gerg/uClinux-dist/lib/libpcap -L/home/gerg/uClinux-dist/lib/libssl -L/home/gerg/uClinux-dist/lib/libcrypt_old -L/home/gerg/uClinux-dist/prop/libsnapgear++ -L/home/gerg/uClinux-dist/prop/libsnapgear -L/home/gerg/uClinux-dist/lib/zlib '
+LDFLAGS='-O2 -g -fomit-frame-pointer   -Dlinux -D__linux__ -Dunix -D__uClinux__ -DEMBED -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/include -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -I/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -I/home/mmcc/linux-dev/uClinux-dist-20040408 -fno-builtin -nostartfiles -I/home/mmcc/linux-dev/uClinux-dist-20040408/linux-2.4.x/include -Wl,-elf2flt /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crt0.o /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crti.o /home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib/crtn.o -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/. -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/uClibc/lib -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libm -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libnet -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libdes -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libaes -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libpcap -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libcrypt_old -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/libssl -L/home/mmcc/linux-dev/uClinux-dist-20040408/lib/zlib '
 LIBOBJS=''
 LIBS=''
 LTLIBOBJS=''
@@ -171,7 +172,7 @@
 USE_NLS=''
 VERSION='1.6'
 XGETTEXT=''
-ac_ct_CC='m68k-elf-gcc -m5200 -DCONFIG_COLDFIRE'
+ac_ct_CC='arm-elf-gcc '
 bindir='${exec_prefix}/bin'
 build='i686-pc-linux-gnu'
 build_alias=''
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/build-howto uClinux-dist-20040408/vendors/ST/STR710/build-howto
--- uClinux-dist/vendors/ST/STR710/build-howto	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/build-howto	2004-09-07 17:27:42.000000000 +0800
@@ -0,0 +1,9 @@
+Build Steps:
+
+make clean
+make menuconfig
+make dep
+make lib_only
+make user_only
+make romfs
+make image
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/config.arch uClinux-dist-20040408/vendors/ST/STR710/config.arch
--- uClinux-dist/vendors/ST/STR710/config.arch	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/config.arch	2003-11-05 16:42:30.000000000 +0800
@@ -0,0 +1,22 @@
+.EXPORT_ALL_VARIABLES:
+############################################################################
+#
+# Vendor specific settings
+#
+
+CONSOLE_BAUD_RATE = 19200
+
+############################################################################
+
+CPUFLAGS :=
+VENDOR_CFLAGS :=
+DISABLE_XIP := 1
+DISABLE_MOVE_RODATA := 1       # until we get a toolchain release
+# LOPT := -O2                  # library is alway 02
+# UOPT := -Os                  # user apps are always Os
+
+############################################################################
+
+include $(ROOTDIR)/vendors/config/armnommu/config.arch
+
+############################################################################
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/config.linux-2.4.x uClinux-dist-20040408/vendors/ST/STR710/config.linux-2.4.x
--- uClinux-dist/vendors/ST/STR710/config.linux-2.4.x	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/config.linux-2.4.x	2004-09-21 12:11:11.000000000 +0800
@@ -0,0 +1,406 @@
+#
+# 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 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_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_STR710=y
+# 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_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_NO_PGT_CACHE=y
+# CONFIG_CPU_WITH_CACHE is not set
+# CONFIG_CPU_WITH_MCR_INSTRUCTION is not set
+DRAM_BASE=0x62000000
+DRAM_SIZE=0x00400000
+FLASH_MEM_BASE=0x60000000
+FLASH_SIZE=0x00400000
+
+#
+# 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_BINFMT_ZFLAT is not set
+CONFIG_KERNEL_ELF=y
+# CONFIG_ARTHUR is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_RAM_ATTACHED_ROMFS 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=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+CONFIG_MTD_PARTITIONS=y
+# 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
+# CONFIG_INFTL 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 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
+# CONFIG_MTD_PSD4256G 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_SE4000 is not set
+# CONFIG_MTD_SNAPARM is not set
+# CONFIG_MTD_EDB7312 is not set
+CONFIG_MTD_STR710=y
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_UCLINUX 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
+# 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_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=1024
+# 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=y
+CONFIG_JFFS2_FS_DEBUG=2
+# 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
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_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_STR710=y
+CONFIG_SERIAL_STR710_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=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_STR710=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_PROC 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
+
+#
+# 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
+# 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=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_MAGIC_SYSRQ 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 --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/config.modules uClinux-dist-20040408/vendors/ST/STR710/config.modules
--- uClinux-dist/vendors/ST/STR710/config.modules	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/config.modules	2003-11-05 16:42:20.000000000 +0800
@@ -0,0 +1,44 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MODULES=y
+
+#
+# Audio Modules
+#
+# CONFIG_MODULES_AUDIO_AD1845 is not set
+
+#
+# ADSL Modules
+#
+# CONFIG_MODULES_ADSL_SPEEDTOUCH is not set
+
+#
+# Crypto Modules
+#
+# CONFIG_MODULES_CRYPTO_HIFN7901 is not set
+# CONFIG_MODULES_CRYPTO_HIFN7951 is not set
+# CONFIG_MODULES_CRYPTO_SAFENET is not set
+
+#
+# Debug Modules
+#
+# CONFIG_MODULES_MCF_FULL_MEMORY_PROTECT is not set
+
+#
+# IO Modules
+#
+# CONFIG_MODULES_SGIO is not set
+
+#
+# QTAB Modules
+#
+# CONFIG_MODULES_QTAB_FCC is not set
+# CONFIG_MODULES_QTAB_MDIGI is not set
+# CONFIG_MODULES_QTAB_SMARTREADER is not set
+
+#
+# Satellite Modules
+#
+# CONFIG_MODULES_SAT_PENTANET is not set
+# CONFIG_MODULES_SAT_PENTAVAL is not set
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/config.uClibc uClinux-dist-20040408/vendors/ST/STR710/config.uClibc
--- uClinux-dist/vendors/ST/STR710/config.uClibc	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/config.uClibc	2004-09-21 12:11:11.000000000 +0800
@@ -0,0 +1,143 @@
+#
+# Automatically generated make config: don't edit
+#
+# TARGET_alpha is not set
+TARGET_arm=y
+# TARGET_cris is not set
+# TARGET_e1 is not set
+# TARGET_h8300 is not set
+# TARGET_i386 is not set
+# TARGET_i960 is not set
+# TARGET_m68k is not set
+# TARGET_microblaze is not set
+# TARGET_mips is not set
+# TARGET_powerpc is not set
+# TARGET_sh is not set
+# TARGET_sparc is not set
+# TARGET_v850 is not set
+
+#
+# Target Architecture Features and Options
+#
+HAVE_ELF=y
+TARGET_ARCH="arm"
+CONFIG_GENERIC_ARM=y
+# CONFIG_ARM610 is not set
+# CONFIG_ARM710 is not set
+# CONFIG_ARM720T is not set
+# CONFIG_ARM920T is not set
+# CONFIG_ARM922T is not set
+# CONFIG_ARM926T is not set
+# CONFIG_ARM_SA110 is not set
+# CONFIG_ARM_SA1100 is not set
+# CONFIG_ARM_XSCALE is not set
+UCLIBC_HAS_SOFT_FLOAT=y
+ARCH_LITTLE_ENDIAN=y
+# ARCH_BIG_ENDIAN is not set
+# ARCH_HAS_NO_MMU is not set
+# UCLIBC_HAS_MMU is not set
+UCLIBC_HAS_FLOATS=y
+# HAS_FPU is not set
+DO_C99_MATH=y
+WARNINGS="-Wall"
+KERNEL_SOURCE="$(ROOTDIR)/$(LINUXDIR)/."
+UCLIBC_UCLINUX_BROKEN_MUNMAP=y
+EXCLUDE_BRK=y
+C_SYMBOL_PREFIX=""
+HAVE_DOT_CONFIG=y
+
+#
+# General Library Settings
+#
+# HAVE_NO_PIC is not set
+# DOPIC is not set
+# HAVE_NO_SHARED is not set
+# ARCH_HAS_NO_LDSO is not set
+# UCLIBC_PIE_SUPPORT is not set
+UCLIBC_CTOR_DTOR=y
+# UCLIBC_PROPOLICE is not set
+UCLIBC_PROFILING=y
+# HAS_NO_THREADS is not set
+UCLIBC_HAS_THREADS=y
+# PTHREADS_DEBUG_SUPPORT is not set
+UCLIBC_HAS_LFS=y
+MALLOC=y
+# MALLOC_SIMPLE is not set
+# MALLOC_STANDARD is not set
+# MALLOC_GLIBC_COMPAT is not set
+UCLIBC_DYNAMIC_ATEXIT=y
+# HAS_SHADOW is not set
+# UNIX98PTY_ONLY is not set
+ASSUME_DEVPTS=y
+UCLIBC_HAS_TM_EXTENSIONS=y
+UCLIBC_HAS_TZ_CACHING=y
+UCLIBC_HAS_TZ_FILE=y
+UCLIBC_HAS_TZ_FILE_READ_MANY=y
+UCLIBC_TZ_FILE_PATH="/etc/TZ"
+
+#
+# Networking Support
+#
+# UCLIBC_HAS_IPV6 is not set
+UCLIBC_HAS_RPC=y
+UCLIBC_HAS_FULL_RPC=y
+
+#
+# String and Stdio Support
+#
+UCLIBC_HAS_CTYPE_TABLES=y
+UCLIBC_HAS_CTYPE_SIGNED=y
+UCLIBC_HAS_CTYPE_UNSAFE=y
+# UCLIBC_HAS_CTYPE_CHECKED is not set
+# UCLIBC_HAS_CTYPE_ENFORCED is not set
+# UCLIBC_HAS_WCHAR is not set
+# UCLIBC_HAS_LOCALE is not set
+# UCLIBC_HAS_HEXADECIMAL_FLOATS is not set
+# UCLIBC_HAS_GLIBC_CUSTOM_PRINTF is not set
+# USE_OLD_VFPRINTF is not set
+UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9
+# UCLIBC_HAS_SCANF_GLIBC_A_FLAG is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_NONE is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_256 is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_512 is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_1024 is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_2048 is not set
+UCLIBC_HAS_STDIO_BUFSIZ_4096=y
+# UCLIBC_HAS_STDIO_BUFSIZ_8192 is not set
+UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y
+# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set
+# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set
+UCLIBC_HAS_STDIO_GETC_MACRO=y
+UCLIBC_HAS_STDIO_PUTC_MACRO=y
+UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y
+# UCLIBC_HAS_FOPEN_LARGEFILE_MODE is not set
+# UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE is not set
+# UCLIBC_HAS_GLIBC_CUSTOM_STREAMS is not set
+# UCLIBC_HAS_PRINTF_M_SPEC is not set
+UCLIBC_HAS_ERRNO_MESSAGES=y
+# UCLIBC_HAS_SYS_ERRLIST is not set
+UCLIBC_HAS_SIGNUM_MESSAGES=y
+# UCLIBC_HAS_SYS_SIGLIST is not set
+UCLIBC_HAS_GNU_GETOPT=y
+
+#
+# Big and Tall
+#
+UCLIBC_HAS_REGEX=y
+# UCLIBC_HAS_WORDEXP is not set
+# UCLIBC_HAS_FTW is not set
+UCLIBC_HAS_GLOB=y
+
+#
+# Library Installation Options
+#
+RUNTIME_PREFIX="/usr/$(TARGET_ARCH)-linux-uclibc/"
+DEVEL_PREFIX="/usr/$(TARGET_ARCH)-linux-uclibc"
+
+#
+# uClibc development/debugging options
+#
+# DODEBUG is not set
+# DOASSERTS is not set
+# UCLIBC_MALLOC_DEBUGGING is not set
+# UCLIBC_MJN3_ONLY is not set
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/config.vendor-2.4.x uClinux-dist-20040408/vendors/ST/STR710/config.vendor-2.4.x
--- uClinux-dist/vendors/ST/STR710/config.vendor-2.4.x	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/config.vendor-2.4.x	2004-09-21 12:11:11.000000000 +0800
@@ -0,0 +1,510 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+
+#
+# Core Applications
+#
+CONFIG_USER_INIT_INIT=y
+CONFIG_USER_INIT_CONSOLE_SH=y
+# CONFIG_USER_INIT_RUN_FIREWALL is not set
+CONFIG_USER_SASH_SH=y
+# CONFIG_USER_SH_SH is not set
+# CONFIG_USER_NWSH_SH is not set
+# CONFIG_USER_BASH_BASH is not set
+# CONFIG_USER_OTHER_SH is not set
+# CONFIG_USER_SASH_HISTORY is not set
+# CONFIG_USER_SASH_REBOOT is not set
+# CONFIG_USER_SASH_REBOOT_SNAPGEAR is not set
+CONFIG_USER_BUSYBOX_KILLALL=y
+# CONFIG_USER_SASH_SHUTDOWN is not set
+CONFIG_USER_INIT_EXPAND=y
+CONFIG_USER_INIT_EXPAND_NOZEROES=y
+# CONFIG_USER_VERSION_VERSION is not set
+# CONFIG_USER_LOGIN_LOGIN is not set
+# CONFIG_USER_OLD_PASSWORDS is not set
+# CONFIG_USER_ONLY_ROOT is not set
+# CONFIG_USER_AGETTY_AGETTY is not set
+# CONFIG_USER_GETTYD_GETTYD is not set
+# CONFIG_USER_LOGIN_PASSWD is not set
+# CONFIG_USER_CRON_CRON is not set
+# CONFIG_USER_HWCLOCK_HWCLOCK is not set
+# CONFIG_USER_RTC_M41T11 is not set
+# CONFIG_USER_RTC_DS1302 is not set
+# CONFIG_USER_VIXIECRON_CRON is not set
+# CONFIG_USER_VIXIECRON_CRONTAB is not set
+# CONFIG_USER_AT_AT is not set
+# CONFIG_USER_AT_ATD is not set
+# CONFIG_USER_AT_ATRUN is not set
+
+#
+# Library Configuration
+#
+# CONFIG_LIB_LIBAES_FORCE is not set
+# CONFIG_LIB_LIBDES_FORCE is not set
+# CONFIG_LIB_LIBSSL_FORCE is not set
+# CONFIG_LIB_LIBGMP_FORCE is not set
+# CONFIG_LIB_LIBG_FORCE is not set
+# CONFIG_LIB_LIBLDAP_FORCE is not set
+# CONFIG_LIB_LIBPAM_FORCE is not set
+# CONFIG_LIB_LIBPCAP_FORCE is not set
+# CONFIG_LIB_ZLIB_FORCE is not set
+# CONFIG_LIB_LIBATM_FORCE is not set
+# CONFIG_LIB_LIBPNG_FORCE is not set
+# CONFIG_LIB_LIBJPEG_FORCE is not set
+# CONFIG_LIB_NCURSES_FORCE is not set
+# CONFIG_LIB_UC_LIBC_TIMEZONE is not set
+
+#
+# Flash Tools
+#
+# CONFIG_USER_FLASHW_FLASHW is not set
+# CONFIG_USER_NETFLASH_NETFLASH is not set
+# CONFIG_USER_RECOVER_STATIC_TFTP is not set
+# CONFIG_USER_RECOVER_RECOVER is not set
+# CONFIG_USER_BOOTTOOLS_FLASHLOADER is not set
+# CONFIG_USER_BOOTTOOLS_HIMEMLOADER is not set
+CONFIG_USER_MTDUTILS=y
+CONFIG_USER_MTDUTILS_ERASE=y
+CONFIG_USER_MTDUTILS_ERASEALL=y
+# CONFIG_USER_MTDUTILS_FTL_CHECK is not set
+# CONFIG_USER_MTDUTILS_FTL_FORMAT is not set
+# CONFIG_USER_MTDUTILS_MKFSJFFS is not set
+# CONFIG_USER_MTDUTILS_MKFSJFFS2 is not set
+# CONFIG_USER_MTDUTILS_NFTLDUMP is not set
+# CONFIG_USER_MTDUTILS_NFTL_FORMAT is not set
+# CONFIG_USER_MTDUTILS_NANDDUMP is not set
+# CONFIG_USER_MTDUTILS_NANDTEST is not set
+# CONFIG_USER_MTDUTILS_NANDWRITE is not set
+# CONFIG_USER_MTDUTILS_DOC_LOADBIOS is not set
+# CONFIG_USER_MTDUTILS_DOC_LOADIPL is not set
+CONFIG_LIB_ZLIB=y
+
+#
+# Filesystem Applications
+#
+# CONFIG_USER_FLATFSD_FLATFSD is not set
+# CONFIG_USER_MOUNT_MOUNT is not set
+# CONFIG_USER_MOUNT_UMOUNT is not set
+# CONFIG_USER_FDISK_FDISK is not set
+# CONFIG_USER_FDISK_SFDISK is not set
+# CONFIG_USER_E2FSPROGS_E2FSCK_E2FSCK is not set
+# CONFIG_USER_E2FSPROGS_MISC_MKE2FS is not set
+# CONFIG_USER_E2FSPROGS_MISC_BADBLOCKS is not set
+# CONFIG_USER_E2FSPROGS_MISC_CHATTR is not set
+# CONFIG_USER_E2FSPROGS_MISC_DUMPE2FS is not set
+# CONFIG_USER_E2FSPROGS_MISC_E2LABEL is not set
+# CONFIG_USER_E2FSPROGS_MISC_FSCK is not set
+# CONFIG_USER_E2FSPROGS_MISC_LSATTR is not set
+# CONFIG_USER_E2FSPROGS_MISC_MKLOST_FOUND is not set
+# CONFIG_USER_E2FSPROGS_MISC_TUNE2FS is not set
+# CONFIG_USER_E2FSPROGS_MISC_UUIDGEN is not set
+# CONFIG_USER_REISERFSPROGS is not set
+# CONFIG_USER_REISERFSPROGS_DEBUGRESIERFS is not set
+# CONFIG_USER_REISERFSPROGS_MKREISERFS is not set
+# CONFIG_USER_REISERFSPROGS_REISERFSCK is not set
+# CONFIG_USER_REISERFSPROGS_RESIZE_REISERFS is not set
+# CONFIG_USER_REISERFSPROGS_UNPACK is not set
+# CONFIG_USER_SAMBA is not set
+# CONFIG_USER_SAMBA_SMBD is not set
+# CONFIG_USER_SAMBA_NMBD is not set
+# CONFIG_USER_SAMBA_SMBMOUNT is not set
+# CONFIG_USER_SAMBA_SMBUMOUNT is not set
+# CONFIG_USER_SMBMOUNT_SMBMOUNT is not set
+# CONFIG_USER_SMBMOUNT_SMBUMOUNT is not set
+# CONFIG_USER_CRAMFS_CRAMFSCK is not set
+# CONFIG_USER_CRAMFS_MKCRAMFS is not set
+
+#
+# Network Applications
+#
+# CONFIG_USER_ROUTE_ARP is not set
+# CONFIG_USER_FNORD_HTTPD is not set
+# CONFIG_USER_BOA_SRC_BOA is not set
+# CONFIG_USER_BPALOGIN_BPALOGIN is not set
+# CONFIG_USER_BR2684CTL_BR2684CTL is not set
+# CONFIG_USER_BRCFG_BRCFG is not set
+# CONFIG_USER_BRCTL_BRCTL is not set
+# CONFIG_USER_DHCPCD_DHCPCD is not set
+# CONFIG_USER_DHCPCD_NEW_DHCPCD is not set
+# CONFIG_USER_DHCPD_DHCPD is not set
+# CONFIG_USER_DHCP_ISC_SERVER_DHCPD is not set
+# CONFIG_USER_DHCP_ISC_CLIENT_DHCLIENT is not set
+# CONFIG_USER_DHCP_ISC_RELAY_DHCRELAY is not set
+# CONFIG_USER_DIALD_DIALD is not set
+# CONFIG_USER_DISCARD_DISCARD is not set
+# CONFIG_USER_DNSMASQ_DNSMASQ is not set
+# CONFIG_USER_ETHATTACH_ETHATTACH is not set
+# CONFIG_USER_EZIPUPDATE_EZIPUPDATE is not set
+# CONFIG_USER_FTP_FTP_FTP is not set
+# CONFIG_USER_FTPD_FTPD is not set
+# CONFIG_USER_FREESWAN is not set
+# CONFIG_USER_HTTPD_HTTPD is not set
+# CONFIG_USER_IFATTACH_IFATTACH is not set
+# CONFIG_USER_ROUTE_IFCONFIG is not set
+# CONFIG_USER_INETD_INETD is not set
+# CONFIG_USER_IPCHAINS_IPCHAINS is not set
+# CONFIG_USER_IPFWADM_IPFWADM is not set
+# CONFIG_USER_IPMASQADM_IPMASQADM is not set
+# CONFIG_USER_IPPORTFW_IPPORTFW is not set
+# CONFIG_USER_IPREDIR_IPREDIR is not set
+# CONFIG_USER_IPROUTE2 is not set
+# CONFIG_USER_IPTABLES_IPTABLES is not set
+# CONFIG_USER_KENDIN_CONFIG is not set
+# CONFIG_USER_KLAXON_KLAXON is not set
+# CONFIG_USER_L2TPD_L2TPD is not set
+# CONFIG_USER_LOATTACH_LOATTACH is not set
+# CONFIG_USER_SMTP_SMTPCLIENT is not set
+# CONFIG_USER_MAIL_MAIL_IP is not set
+# CONFIG_USER_MINI_HTTPD_MINI_HTTPD is not set
+# CONFIG_USER_MSNTP_MSNTP is not set
+# CONFIG_USER_NESSUS_NASL is not set
+# CONFIG_USER_ROUTE_NETSTAT is not set
+# CONFIG_USER_NETSTAT_NAT_NETSTAT_NAT is not set
+# CONFIG_USER_ROUTE_MIITOOL is not set
+# CONFIG_USER_NTPD_NTPD is not set
+# CONFIG_USER_NTPD_NTPDATE is not set
+# CONFIG_USER_NTPD_NTPQ is not set
+# CONFIG_USER_OPENSSL_APPS is not set
+# CONFIG_USER_PING_PING is not set
+# CONFIG_USER_PLUG_PLUG is not set
+# CONFIG_USER_PORTMAP_PORTMAP is not set
+# CONFIG_USER_PPPD_PPPD_PPPD is not set
+# CONFIG_USER_PPTPD_PPTPCTRL is not set
+# CONFIG_USER_PPTPD_PPTPD is not set
+# CONFIG_USER_PPTP_CLIENT_PPTP is not set
+# CONFIG_USER_PPTP_CLIENT_PPTP_CALLMGR is not set
+# CONFIG_USER_RDATE_RDATE is not set
+# CONFIG_USER_ROUTE_ROUTE is not set
+# CONFIG_USER_ROUTED_ROUTED is not set
+# CONFIG_USER_RP_PPPOE_PPPOE is not set
+# CONFIG_USER_RP_PPPOE_PPPOE_SERVER is not set
+# CONFIG_USER_SETHDLC_SETHDLC is not set
+# CONFIG_USER_SLATTACH_SLATTACH is not set
+# CONFIG_USER_SNMPD_SNMPD is not set
+# CONFIG_USER_STUNNEL_STUNNEL is not set
+# CONFIG_USER_SSLWRAP_SSLWRAP is not set
+# CONFIG_USER_SQUID_SQUID is not set
+# CONFIG_USER_SSH_SSH is not set
+# CONFIG_USER_SSH_SSHD is not set
+# CONFIG_USER_SSH_SSHKEYGEN is not set
+# CONFIG_USER_STP_STP is not set
+# CONFIG_USER_TCPWRAP_TCPD is not set
+# CONFIG_USER_TCPBLAST_TCPBLAST is not set
+# CONFIG_USER_TCPDUMP_TCPDUMP is not set
+# CONFIG_USER_TELNETD_TELNETD is not set
+# CONFIG_USER_TELNET_TELNET is not set
+# CONFIG_USER_TFTP_TFTP is not set
+# CONFIG_USER_TFTPD_TFTPD is not set
+# CONFIG_USER_THTTPD_THTTPD is not set
+# CONFIG_USER_TRACEROUTE_TRACEROUTE is not set
+# CONFIG_USER_UCDSNMP_SNMPD is not set
+# CONFIG_USER_VCONFIG_VCONFIG is not set
+# CONFIG_USER_VPNLED_VPNLED is not set
+# CONFIG_USER_WGET is not set
+# CONFIG_USER_ZEBRA_ZEBRA_ZEBRA is not set
+# CONFIG_USER_NET_TOOLS_ARP is not set
+# CONFIG_USER_NET_TOOLS_HOSTNAME is not set
+# CONFIG_USER_NET_TOOLS_IFCONFIG is not set
+# CONFIG_USER_NET_TOOLS_NAMEIF is not set
+# CONFIG_USER_NET_TOOLS_NETSTAT is not set
+# CONFIG_USER_NET_TOOLS_PLIPCONFIG is not set
+# CONFIG_USER_NET_TOOLS_RARP is not set
+# CONFIG_USER_NET_TOOLS_ROUTE is not set
+# CONFIG_USER_NET_TOOLS_SLATTACH is not set
+# CONFIG_USER_NET_TOOLS_MII_TOOL is not set
+# CONFIG_USER_WIRELESS_TOOLS is not set
+# CONFIG_USER_HOSTAP_HOSTAP is not set
+# CONFIG_USER_WLAN_NG is not set
+
+#
+# Miscellaneous Applications
+#
+# CONFIG_USER_LANG_A60 is not set
+# CONFIG_USER_CAL_CAL is not set
+# CONFIG_USER_CHAT_CHAT is not set
+# CONFIG_USER_CKSUM_CKSUM is not set
+# CONFIG_USER_CLOCK_CLOCK is not set
+# CONFIG_USER_CPU_CPU is not set
+# CONFIG_USER_CAL_DATE is not set
+# CONFIG_USER_DHRYSTONE_DHRYSTONE is not set
+# CONFIG_USER_DE2TSCAL_DE2TSCAL is not set
+# CONFIG_USER_FROB_LED_FROB_LED is not set
+# CONFIG_USER_GDBSERVER_GDBREPLAY is not set
+# CONFIG_USER_GDBSERVER_GDBSERVER is not set
+# CONFIG_USER_HD_HD is not set
+# CONFIG_USER_LCD_LCD is not set
+# CONFIG_USER_LEDCON_LEDCON is not set
+# CONFIG_USER_LILO_LILO is not set
+# CONFIG_USER_LISSA_LISSA is not set
+# CONFIG_USER_USBCBI_USBCBI is not set
+# CONFIG_USER_USBISO_USBISO is not set
+# CONFIG_USER_MATH_TEST is not set
+# CONFIG_USER_MAWK_AWK is not set
+# CONFIG_USER_MYSQL is not set
+# CONFIG_USER_NULL_NULL is not set
+# CONFIG_USER_PALMBOT_PALMBOT is not set
+# CONFIG_USER_PCMCIA_CS is not set
+# CONFIG_USER_PERL_PERL is not set
+# CONFIG_USER_PYTHON_PYTHON is not set
+# CONFIG_USER_READPROFILE_READPROFILE is not set
+# CONFIG_USER_ROOTLOADER_ROOTLOADER is not set
+# CONFIG_USER_SETSERIAL_SETSERIAL is not set
+# CONFIG_USER_TRIPWIRE_SIGGEN is not set
+# CONFIG_USER_STRACE_STRACE is not set
+# CONFIG_USER_STTY_STTY is not set
+# CONFIG_USER_TCSH_TCSH is not set
+# CONFIG_USER_TINYTCL_TCLSH is not set
+# CONFIG_USER_THREADDEMOS_THREADDEMOS is not set
+# CONFIG_USER_TIP_TIP is not set
+# CONFIG_USER_TRIPWIRE_TRIPWIRE is not set
+# CONFIG_USER_LRZSZ_LRZSZ is not set
+# CONFIG_USER_LIRC is not set
+# CONFIG_USER_LIRC_LIRCD is not set
+# CONFIG_USER_LIRC_IRRECORD is not set
+# CONFIG_USER_LIRC_LIRCMD is not set
+# CONFIG_USER_LIRC_IREXEC is not set
+# CONFIG_USER_LIRC_IRW is not set
+# CONFIG_USER_LIRC_MODE2 is not set
+# CONFIG_USER_LEVEE_VI is not set
+# CONFIG_USER_ELVISTINY_VI is not set
+# CONFIG_USER_MP3PLAY_MP3PLAY is not set
+# CONFIG_USER_OGGPLAY_OGG123 is not set
+# CONFIG_USER_OGGPLAY_EXAMPLE is not set
+# CONFIG_USER_MUSICBOX_MUSICBOX is not set
+# CONFIG_USER_PLAY_PLAY is not set
+# CONFIG_USER_PLAY_TONE is not set
+# CONFIG_USER_VPLAY_VPLAY is not set
+# CONFIG_USER_VPLAY_VREC is not set
+# CONFIG_USER_VPLAY_MIXER is not set
+# CONFIG_USER_PLAYRT_PLAYRT is not set
+# CONFIG_USER_W3CAM_VIDCAT is not set
+# CONFIG_USER_W3CAM_W3CAMD is not set
+# CONFIG_USER_FILEUTILS_CAT is not set
+# CONFIG_USER_FILEUTILS_CHGRP is not set
+# CONFIG_USER_FILEUTILS_CHMOD is not set
+# CONFIG_USER_FILEUTILS_CHOWN is not set
+# CONFIG_USER_FILEUTILS_CMP is not set
+# CONFIG_USER_FILEUTILS_CP is not set
+# CONFIG_USER_FILEUTILS_DD is not set
+# CONFIG_USER_FILEUTILS_GREP is not set
+# CONFIG_USER_FILEUTILS_L is not set
+# CONFIG_USER_FILEUTILS_LN is not set
+# CONFIG_USER_FILEUTILS_LS is not set
+# CONFIG_USER_FILEUTILS_MKDIR is not set
+# CONFIG_USER_FILEUTILS_MKFIFO is not set
+# CONFIG_USER_FILEUTILS_MKNOD is not set
+# CONFIG_USER_FILEUTILS_MORE is not set
+# CONFIG_USER_FILEUTILS_MV is not set
+# CONFIG_USER_FILEUTILS_RM is not set
+# CONFIG_USER_FILEUTILS_RMDIR is not set
+# CONFIG_USER_FILEUTILS_SYNC is not set
+# CONFIG_USER_FILEUTILS_TOUCH is not set
+# CONFIG_USER_SHUTILS_BASENAME is not set
+# CONFIG_USER_SHUTILS_DATE is not set
+# CONFIG_USER_SHUTILS_DIRNAME is not set
+# CONFIG_USER_SHUTILS_ECHO is not set
+# CONFIG_USER_SHUTILS_FALSE is not set
+# CONFIG_USER_SHUTILS_LOGNAME is not set
+# CONFIG_USER_SHUTILS_PRINTENV is not set
+# CONFIG_USER_SHUTILS_PWD is not set
+# CONFIG_USER_SHUTILS_TRUE is not set
+# CONFIG_USER_SHUTILS_UNAME is not set
+# CONFIG_USER_SHUTILS_WHICH is not set
+# CONFIG_USER_SHUTILS_WHOAMI is not set
+# CONFIG_USER_SHUTILS_YES is not set
+# CONFIG_USER_SYSUTILS_REBOOT is not set
+# CONFIG_USER_SYSUTILS_SHUTDOWN is not set
+# CONFIG_USER_SYSUTILS_DF is not set
+# CONFIG_USER_SYSUTILS_FREE is not set
+# CONFIG_USER_SYSUTILS_HOSTNAME is not set
+# CONFIG_USER_SYSUTILS_KILL is not set
+# CONFIG_USER_SYSUTILS_PS is not set
+# CONFIG_USER_PROCPS_FREE is not set
+# CONFIG_USER_PROCPS_KILL is not set
+# CONFIG_USER_PROCPS_PGREP is not set
+# CONFIG_USER_PROCPS_PKILL is not set
+# CONFIG_USER_PROCPS_PS is not set
+# CONFIG_USER_PROCPS_SNICE is not set
+# CONFIG_USER_PROCPS_SYSCTL is not set
+# CONFIG_USER_PROCPS_TLOAD is not set
+# CONFIG_USER_PROCPS_TOP is not set
+# CONFIG_USER_PROCPS_UPTIME is not set
+# CONFIG_USER_PROCPS_VMSTAT is not set
+# CONFIG_USER_PROCPS_W is not set
+# CONFIG_USER_PROCPS_WATCH is not set
+# CONFIG_USER_PCIUTILS_LSPCI is not set
+# CONFIG_USER_PCIUTILS_SETPCI is not set
+
+#
+# BusyBox
+#
+CONFIG_USER_BUSYBOX_BUSYBOX=y
+# CONFIG_USER_BUSYBOX_ADJTIMEX is not set
+# CONFIG_USER_BUSYBOX_AR is not set
+# CONFIG_USER_BUSYBOX_BASENAME is not set
+# CONFIG_USER_BUSYBOX_CAT is not set
+# CONFIG_USER_BUSYBOX_CHGRP is not set
+# CONFIG_USER_BUSYBOX_CHMOD is not set
+# CONFIG_USER_BUSYBOX_CHOWN is not set
+# CONFIG_USER_BUSYBOX_CHROOT is not set
+# CONFIG_USER_BUSYBOX_CLEAR is not set
+# CONFIG_USER_BUSYBOX_CMP is not set
+# CONFIG_USER_BUSYBOX_CP is not set
+# CONFIG_USER_BUSYBOX_CUT is not set
+# CONFIG_USER_BUSYBOX_DATE is not set
+# CONFIG_USER_BUSYBOX_DC is not set
+# CONFIG_USER_BUSYBOX_DD is not set
+# CONFIG_USER_BUSYBOX_DF is not set
+# CONFIG_USER_BUSYBOX_DIRNAME is not set
+# CONFIG_USER_BUSYBOX_DMESG is not set
+# CONFIG_USER_BUSYBOX_DUTMP is not set
+# CONFIG_USER_BUSYBOX_DU is not set
+# CONFIG_USER_BUSYBOX_ECHO is not set
+# CONFIG_USER_BUSYBOX_ENV is not set
+# CONFIG_USER_BUSYBOX_EXPR is not set
+# CONFIG_USER_BUSYBOX_FIND is not set
+# CONFIG_USER_BUSYBOX_FREE is not set
+# CONFIG_USER_BUSYBOX_FREERAMDISK is not set
+# CONFIG_USER_BUSYBOX_FSCK_MINIX is not set
+# CONFIG_USER_BUSYBOX_GETOPT is not set
+# CONFIG_USER_BUSYBOX_GREP is not set
+# CONFIG_USER_BUSYBOX_GUNZIP is not set
+# CONFIG_USER_BUSYBOX_GZIP is not set
+# CONFIG_USER_BUSYBOX_HALT is not set
+# CONFIG_USER_BUSYBOX_HEAD is not set
+# CONFIG_USER_BUSYBOX_HOSTNAME is not set
+# CONFIG_USER_BUSYBOX_ID is not set
+# CONFIG_USER_BUSYBOX_IFCONFIG is not set
+# CONFIG_USER_BUSYBOX_INIT is not set
+# CONFIG_USER_BUSYBOX_INSMOD is not set
+# CONFIG_USER_BUSYBOX_KILL is not set
+CONFIG_USER_BUSYBOX_KILLALL=y
+# CONFIG_USER_BUSYBOX_KLOGD is not set
+# CONFIG_USER_BUSYBOX_LENGTH is not set
+# CONFIG_USER_BUSYBOX_LN is not set
+# CONFIG_USER_BUSYBOX_LOGGER is not set
+# CONFIG_USER_BUSYBOX_LOGNAME is not set
+# CONFIG_USER_BUSYBOX_LS is not set
+# CONFIG_USER_BUSYBOX_LSMOD is not set
+# CONFIG_USER_BUSYBOX_MAKEDEVS is not set
+# CONFIG_USER_BUSYBOX_MD5SUM is not set
+# CONFIG_USER_BUSYBOX_MKDIR is not set
+# CONFIG_USER_BUSYBOX_MKFS_MINIX is not set
+# CONFIG_USER_BUSYBOX_MKNOD is not set
+# CONFIG_USER_BUSYBOX_MKTEMP is not set
+# CONFIG_USER_BUSYBOX_MODPROBE is not set
+# CONFIG_USER_BUSYBOX_MORE is not set
+# CONFIG_USER_BUSYBOX_MOUNT is not set
+# CONFIG_USER_BUSYBOX_MV is not set
+# CONFIG_USER_BUSYBOX_NC is not set
+# CONFIG_USER_BUSYBOX_NSLOOKUP is not set
+# CONFIG_USER_BUSYBOX_PIDOF is not set
+# CONFIG_USER_BUSYBOX_PING is not set
+# CONFIG_USER_BUSYBOX_PIVOT_ROOT is not set
+# CONFIG_USER_BUSYBOX_POWEROFF is not set
+# CONFIG_USER_BUSYBOX_PRINTF is not set
+# CONFIG_USER_BUSYBOX_PS is not set
+# CONFIG_USER_BUSYBOX_PWD is not set
+# CONFIG_USER_BUSYBOX_RDATE is not set
+# CONFIG_USER_BUSYBOX_READLINK is not set
+# CONFIG_USER_BUSYBOX_REBOOT is not set
+# CONFIG_USER_BUSYBOX_RENICE is not set
+# CONFIG_USER_BUSYBOX_RESET is not set
+# CONFIG_USER_BUSYBOX_RM is not set
+# CONFIG_USER_BUSYBOX_RMDIR is not set
+# CONFIG_USER_BUSYBOX_RMMOD is not set
+# CONFIG_USER_BUSYBOX_ROUTE is not set
+# CONFIG_USER_BUSYBOX_RPM2CPIO is not set
+# CONFIG_USER_BUSYBOX_SED is not set
+# CONFIG_USER_BUSYBOX_SHELL is not set
+# CONFIG_USER_BUSYBOX_SLEEP is not set
+# CONFIG_USER_BUSYBOX_SORT is not set
+# CONFIG_USER_BUSYBOX_STTY is not set
+# CONFIG_USER_BUSYBOX_SYNC is not set
+# CONFIG_USER_BUSYBOX_SYSLOGD is not set
+# CONFIG_USER_BUSYBOX_TAIL is not set
+# CONFIG_USER_BUSYBOX_TAR is not set
+# CONFIG_USER_BUSYBOX_TEE is not set
+# CONFIG_USER_BUSYBOX_TELNET is not set
+# CONFIG_USER_BUSYBOX_TEST is not set
+# CONFIG_USER_BUSYBOX_TFTP is not set
+# CONFIG_USER_BUSYBOX_TOUCH is not set
+# CONFIG_USER_BUSYBOX_TR is not set
+# CONFIG_USER_BUSYBOX_TRACEROUTE is not set
+# CONFIG_USER_BUSYBOX_TRUE_FALSE is not set
+# CONFIG_USER_BUSYBOX_TTY is not set
+# CONFIG_USER_BUSYBOX_UMOUNT is not set
+# CONFIG_USER_BUSYBOX_UNAME is not set
+# CONFIG_USER_BUSYBOX_UNIQ is not set
+# CONFIG_USER_BUSYBOX_UNIX2DOS is not set
+# CONFIG_USER_BUSYBOX_UPTIME is not set
+# CONFIG_USER_BUSYBOX_USLEEP is not set
+# CONFIG_USER_BUSYBOX_UUDECODE is not set
+# CONFIG_USER_BUSYBOX_UUENCODE is not set
+CONFIG_USER_BUSYBOX_VI=y
+CONFIG_USER_BUSYBOX_VI_COLON=y
+# CONFIG_USER_BUSYBOX_VI_YANKMARK is not set
+# CONFIG_USER_BUSYBOX_VI_SEARCH is not set
+# CONFIG_USER_BUSYBOX_VI_USE_SIGNALS is not set
+# CONFIG_USER_BUSYBOX_VI_DOT_CMD is not set
+# CONFIG_USER_BUSYBOX_VI_READONLY is not set
+# CONFIG_USER_BUSYBOX_VI_SETOPTS is not set
+# CONFIG_USER_BUSYBOX_VI_SET is not set
+# CONFIG_USER_BUSYBOX_VI_WIN_RESIZE is not set
+# CONFIG_USER_BUSYBOX_WATCHDOG is not set
+# CONFIG_USER_BUSYBOX_WC is not set
+# CONFIG_USER_BUSYBOX_WGET is not set
+# CONFIG_USER_BUSYBOX_WHICH is not set
+# CONFIG_USER_BUSYBOX_WHOAMI is not set
+# CONFIG_USER_BUSYBOX_XARGS is not set
+# CONFIG_USER_BUSYBOX_YES is not set
+# CONFIG_USER_BUSYBOX_VERBOSE_USAGE is not set
+# CONFIG_USER_BUSYBOX_AUTOWIDTH is not set
+# CONFIG_USER_BUSYBOX_NEW_MODULE_INTERFACE is not set
+# CONFIG_USER_BUSYBOX_OLD_MODULE_INTERFACE is not set
+# CONFIG_USER_BUSYBOX_INSMOD_VERSION_CHECKING is not set
+# CONFIG_USER_BUSYBOX_HUMAN_READABLE is not set
+
+#
+# Tinylogin
+#
+# CONFIG_USER_TINYLOGIN_TINYLOGIN is not set
+
+#
+# MicroWindows
+#
+# CONFIG_USER_MICROWIN is not set
+
+#
+# Games
+#
+# CONFIG_USER_GAMES_ADVENT4 is not set
+# CONFIG_USER_GAMES_DUNGEON is not set
+# CONFIG_USER_GAMES_RUBIK is not set
+
+#
+# Miscellaneous Configuration
+#
+# CONFIG_USER_RAMIMAGE_NONE is not set
+# CONFIG_USER_RAMIMAGE_RAMFS64 is not set
+CONFIG_USER_RAMIMAGE_RAMFS128=y
+# CONFIG_USER_RAMIMAGE_RAMFS256 is not set
+# CONFIG_USER_RAMIMAGE_RAMFS512 is not set
+# CONFIG_USER_RAMIMAGE_RAMFS1024 is not set
+# CONFIG_USER_RAMIMAGE_RAMFS2048 is not set
+# CONFIG_USER_RAMIMAGE_RAMFS8192 is not set
+# CONFIG_USER_CGI_GENERIC is not set
+# CONFIG_USER_CGIHTML is not set
+# CONFIG_USER_DEMO_BUTTON is not set
+# CONFIG_USER_DEMO_LATCH is not set
+# CONFIG_USER_DEMO_MORSE is not set
+# CONFIG_USER_DEMO_R2100 is not set
+
+#
+# Debug Builds
+#
+# CONFIG_LIB_DEBUG is not set
+# CONFIG_USER_DEBUG is not set
+# CONFIG_USER_TIMEPEG_TPT is not set
+# CONFIG_LIB_LIBCCMALLOC is not set
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/Makefile uClinux-dist-20040408/vendors/ST/STR710/Makefile
--- uClinux-dist/vendors/ST/STR710/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/Makefile	2004-09-20 18:19:26.000000000 +0800
@@ -0,0 +1,89 @@
+#
+#	Makefile -- Build instructions for ST/STR710
+#
+
+ROMFSIMG = $(IMAGEDIR)/romfs.img
+IMAGE    = $(IMAGEDIR)/image.bin
+ZIMAGE = $(IMAGEDIR)/zimage.bin
+
+ROMFS_DIRS = bin dev etc home lib mnt proc usr var ramdisk 
+
+DEVICES = \
+	tty,c,5,0	console,c,5,1	cua0,c,5,64	cua1,c,5,65 \
+	\
+	mtd0,c,90,0	mtd1,c,90,2	mtd2,c,90,4	mtd3,c,90,6 \
+	mtdblock0,b,30,0 mtdblock1,b,30,1 mtdblock2,b,30,2 mtdblock3,b,30,3 \
+	\
+	mem,c,1,1	kmem,c,1,2	null,c,1,3 \
+	zero,c,1,5	random,c,1,8	urandom,c,1,9  \
+	\
+	ram0,b,1,0	ram1,b,1,1 \
+	\
+	ptyp0,c,2,0	ptyp1,c,2,1	ptyp2,c,2,2	ptyp3,c,2,3 \
+	ptyp4,c,2,4	ptyp5,c,2,5	ptyp6,c,2,6	ptyp7,c,2,7 \
+	ptyp8,c,2,8	ptyp9,c,2,9	ptypa,c,2,10	ptypb,c,2,11 \
+	ptypc,c,2,12	ptypd,c,2,13	ptype,c,2,14	ptypf,c,2,15 \
+	\
+	rom0,b,31,0	rom1,b,31,1	rom2,b,31,2	rom3,b,31,3 \
+	rom4,b,31,4	rom5,b,31,5	rom6,b,31,6	rom7,b,31,7 \
+	rom8,b,31,8	rom9,b,31,9 \
+	\
+	tty0,c,4,0	tty1,c,4,1	tty2,c,4,2	tty3,c,4,3 \
+	ttyS0,c,4,64	ttyS1,c,4,65 \
+	\
+	ttyp0,c,3,0	ttyp1,c,3,1	ttyp2,c,3,2	ttyp3,c,3,3 \
+	ttyp4,c,3,4	ttyp5,c,3,5	ttyp6,c,3,6	ttyp7,c,3,7 \
+	ttyp8,c,3,8	ttyp9,c,3,9	ttypa,c,3,10	ttypb,c,3,11 \
+	ttypc,c,3,12	ttypd,c,3,13	ttype,c,3,14	ttypf,c,3,15 \
+	\
+	i2c0,c,89,0	i2c1,c,89,1
+
+
+clean:
+
+romfs:
+	[ -d $(ROMFSDIR)/$$i ] || mkdir -p $(ROMFSDIR)
+	for i in $(ROMFS_DIRS); do \
+		[ -d $(ROMFSDIR)/$$i ] || mkdir -p $(ROMFSDIR)/$$i; \
+	done
+	mkdir -p $(ROMFSDIR)/mnt/mnt1
+	mkdir -p $(ROMFSDIR)/mnt/mnt2
+	mkdir -p $(ROMFSDIR)/mnt/mnt3
+	#mkdir -p $(ROMFSDIR)/etc/init.d
+
+	for i in $(DEVICES); do \
+		touch $(ROMFSDIR)/dev/@$$i; \
+	done
+	$(ROMFSINST) -s /var/tmp /tmp
+	$(ROMFSINST) -s /bin /sbin
+	$(ROMFSINST) /etc/rc
+	#$(ROMFSINST) /etc/init.d/rcS
+	
+	$(ROMFSINST) /etc/inittab
+	$(ROMFSINST) ../../Generic/romfs/etc/services /etc/services
+	case "$(LINUXDIR)" in \
+	*2.4.*) ;; \
+	*) echo "ttyS0:linux:/bin/sh" >> $(ROMFSDIR)/etc/inittab ;; \
+	esac
+	$(ROMFSINST) /etc/motd
+#	$(ROMFSINST) /etc/boa.conf
+#	$(ROMFSINST) index.html /home/httpd/index.html
+#	$(ROMFSINST) /etc/passwd
+	echo "$(VERSIONSTR) -- " `date` > $(ROMFSDIR)/etc/version
+	cp $(ROOTDIR)/user/ramimage/ramfs2048.img \
+		$(ROOTDIR)/romfs/etc/ramfs2048.img
+	[ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)
+	genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)
+	$(CROSS_COMPILE)ld -r -o $(ROOTDIR)/$(LINUXDIR)/romfs.o -b binary $(ROMFSIMG)
+
+	
+image:
+	[ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)
+
+#	#$(MAKE) -C $(ROOTDIR) LINUXTARGET=zImage linux || exit 1
+	$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(ROOTDIR)/$(LINUXDIR) zImage|| exit 1
+ 
+# 	$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S $(ROOTDIR)/$(LINUXDIR)/linux $(IMAGE)
+	$(CROSS_COMPILE)objcopy -O binary -j .init -j .text -j .data -S $(ROOTDIR)/$(LINUXDIR)/linux $(IMAGE)
+	cp $(ROOTDIR)/$(LINUXDIR)/arch/armnommu/boot/zImage $(ZIMAGE)
+    
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/motd uClinux-dist-20040408/vendors/ST/STR710/motd
--- uClinux-dist/vendors/ST/STR710/motd	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/motd	2004-09-08 10:51:26.000000000 +0800
@@ -0,0 +1,12 @@
+Welcome to
+          ____ _  _
+         /  __| ||_|                 
+    _   _| |  | | _ ____  _   _  _  _ 
+   | | | | |  | || |  _ \| | | |\ \/ /
+   | |_| | |__| || | | | | |_| |/    \
+   |  ___\____|_||_|_| |_|\____|\_/\_/
+   | |
+   |_|
+
+http://www.uclinux.org/
+STR710  http://mcu.st.com
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/passwd uClinux-dist-20040408/vendors/ST/STR710/passwd
--- uClinux-dist/vendors/ST/STR710/passwd	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/passwd	2003-11-05 16:42:20.000000000 +0800
@@ -0,0 +1 @@
+root   ab6TRGT20sY26
diff --exclude=lib --exclude=uClibc -PBura uClinux-dist/vendors/ST/STR710/rc uClinux-dist-20040408/vendors/ST/STR710/rc
--- uClinux-dist/vendors/ST/STR710/rc	1970-01-01 08:00:00.000000000 +0800
+++ uClinux-dist-20040408/vendors/ST/STR710/rc	2004-09-20 17:36:40.000000000 +0800
@@ -0,0 +1,14 @@
+hostname STR710-EVAL
+/bin/expand /etc/ramfs.img /dev/ram0
+/bin/expand /etc/ramfs2048.img /dev/ram1
+mount -t proc proc /proc
+mount -t ext2 /dev/ram0 /var
+mount -t ext2 /dev/ram1 /ramdisk
+chmod 777 /ramdisk
+mkdir /var/config
+mkdir /var/tmp
+mkdir /var/log
+mkdir /var/run
+mkdir /var/lock
+mount -t jffs2 /dev/mtdblock2 /mnt/mnt1
+cat /etc/motd
