## Automatically generated incremental diff
## From:   linux-2.4.10-pre5
## To:     linux-2.4.10-pre6
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.4.10-pre5/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.10-pre5/Documentation/Configure.help	Mon Dec  3 23:08:03 2001
+++ linux/Documentation/Configure.help	Mon Dec  3 23:08:12 2001
@@ -17055,12 +17055,12 @@
 
 Motorola MPC8260 CPM support
 CONFIG_8260
-   The MPC8260 CPM (Communications Processor Module) is a typically
-   embedded CPU made by Motorola.  Selecting this option means that
-   you wish to build a kernel for a machine with specifically an 8260
-   for a CPU.
+  The MPC8260 CPM (Communications Processor Module) is a typical
+  embedded CPU made by Motorola. Selecting this option means that you
+  wish to build a kernel for a machine with specifically an 8260 for
+  a CPU.
 
-   If in doubt, say N.
+  If in doubt, say N.
 
 Workarounds for PPC601 bugs
 CONFIG_PPC601_SYNC_FIX
@@ -17084,6 +17084,121 @@
   Platform), and several embedded PowerPC systems containing 4xx, 6xx,
   7xx, 8xx, 74xx, and 82xx processors.  Currently, the default option
   is to build a kernel which works on the first three. 
+
+Embedded 8xx Board Type
+CONFIG_RPXLITE
+  RPX-Lite:
+    Embedded Planet RPX Lite
+
+  RPX-Classic:
+    Embedded Planet RPX Classic Low-fat.
+
+  BSE-IP: 
+    Bright Star Engineering ip-Engine.
+
+  TQM823L:
+  TQM850L:
+  TQM855L:
+  TQM860L:
+    MPC8xx based family of mini modules, half credit card size,
+    up to 64 MB of RAM, 8 MB Flash, (Fast) Ethernet, 2 x serial ports,
+    2 x CAN bus interface, ...
+      Manufacturer: TQ Components, www.tq-group.de
+      Date of Release: October (?) 1999
+      End of Life: not yet :-)
+      URL:
+      - module: http://www.denx.de/PDF/TQM8xxLHWM201.pdf
+      - starter kit: http://www.denx.de/PDF/STK8xxLHWM201.pdf
+      - images: http://www.denx.de/embedded-ppc-en.html
+
+  FPS850L:
+    FingerPrint Sensor System (based on TQM850L)
+      Manufacturer: IKENDI AG, http://www.ikendi.com/
+      Date of Release: November 1999
+      End of life: end 2000 ?
+      URL: see TQM850L
+
+  SPD823TS:
+    MPC823 based board used in the "Tele Server" product
+    Manufacturer: Speech Design, http://www.speech-design.de/
+    Date of Release: Mid 2000 (?)
+    End of life: -
+    URL: http://www.speech-design.de/
+         select "English", then "Teleteam Solutions", then "TeleServer"
+
+  IVMS8:
+    MPC860 based board used in the "Integrated Voice Mail System",
+    Small Version (8 voice channels)
+    Manufacturer: Speech Design, http://www.speech-design.de/
+    Date of Release: December 2000 (?)
+    End of life: -
+    URL: http://www.speech-design.de/
+
+  IVML24:
+    MPC860 based board used in the "Integrated Voice Mail System", 
+    Large Version (24 voice channels)
+    Manufacturer: Speech Design, http://www.speech-design.de/
+    Date of Release: March 2001  (?)
+    End of life: -
+    URL: http://www.speech-design.de/
+
+  SM850:
+    Service Module (based on TQM850L)
+    Manufacturer: Dependable Computer Systems, http://www.decomsys.com/
+    Date of Release: end 2000 (?)
+    End of life: mid 2001 (?)
+    URL: http://www.tz-mikroelektronik.de/ServiceModule/index.html
+
+  HERMES:
+    Hermes-Pro ISDN/LAN router with integrated 8 x hub
+    Manufacturer: Multidata Gesellschaft für Datentechnik und Informatik
+      http://www.multidata.de/
+    Date of Release: 2000 (?)
+    End of life: -
+    URL: http://www.multidata.de/english/products/hpro.htm
+
+  IP860:	
+    VMEBus IP (Industry Pack) carrier board with MPC860
+    Manufacturer: MicroSys GmbH, http://www.microsys.de/
+    Date of Release: ?
+    End of life: -
+    URL: http://www.microsys.de/html/ip860.html
+
+  PCU_E:
+    PCU = Peripheral Controller Unit, Extended
+    Manufacturer: Siemens AG, ICN (Information and Communication Networks)
+    	http://www.siemens.de/page/1,3771,224315-1-999_2_226207-0,00.html
+    Date of Release: April 2001
+    End of life: August 2001
+    URL: n. a.
+
+Embedded 82xx Board Type
+CONFIG_EST8260
+  EST8260: Wind River System, Inc. EST SBC8260
+
+  TQM8260:
+    MPC8260 based module, little larger than credit card,
+    up to 128 MB global + 64 MB local RAM, 32 MB Flash,
+    32 kB EEPROM, 256 kB L@ Cache, 10baseT + 100baseT Ethernet,
+    2 x serial ports, ...
+      Manufacturer: TQ Components, www.tq-group.de
+      Date of Release: June 2001
+      End of Life: not yet :-)
+      URL: http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf
+
+  PM826:
+    Modular system with MPC8260 CPU
+    Manufacturer: MicroSys GmbH, http://www.microsys.de/
+    Date of Release: mid 2001
+    End of life: -
+    URL: http://www.microsys.de/html/pm826.html
+
+  CU824:
+    VMEBus Board with PCI extension with MPC8240 CPU
+    Manufacturer: MicroSys GmbH, http://www.microsys.de/
+    Date of Release: early 2001 (?)
+    End of life: -
+    URL: http://www.microsys.de/html/cu824.html
 
 AltiVec Kernel Support
 CONFIG_ALTIVEC
diff -urN linux-2.4.10-pre5/Documentation/DocBook/procfs-guide.tmpl linux/Documentation/DocBook/procfs-guide.tmpl
--- linux-2.4.10-pre5/Documentation/DocBook/procfs-guide.tmpl	Mon Jul  2 13:56:40 2001
+++ linux/Documentation/DocBook/procfs-guide.tmpl	Mon Dec  3 23:08:12 2001
@@ -207,7 +207,7 @@
         will return <constant>NULL</constant>. <xref
         linkend="userland"> describes how to do something useful with
         regular files.
-      <para>
+      </para>
 
       <para>
         Note that it is specifically supported that you can pass a
@@ -577,7 +577,7 @@
         the <structfield>owner</structfield> field in the
         <structname>struct proc_dir_entry</structname> to
         <constant>THIS_MODULE</constant>.
-      <para>
+      </para>
 
       <programlisting>
 struct proc_dir_entry* entry;
diff -urN linux-2.4.10-pre5/Documentation/filesystems/ntfs.txt linux/Documentation/filesystems/ntfs.txt
--- linux-2.4.10-pre5/Documentation/filesystems/ntfs.txt	Mon Dec  3 23:08:03 2001
+++ linux/Documentation/filesystems/ntfs.txt	Mon Dec  3 23:08:12 2001
@@ -82,7 +82,6 @@
 				2		25%
 				3		37.5%
 				4		50%
-			NOTE: This is currently ignored! Work in progress.
 
 Known bugs and (mis-)features
 =============================
@@ -93,13 +92,61 @@
 
 - Writing of extension records is not supported properly.
 
-- $MFT extension is badly broken and really needs rewriting.
-
 Please send bug reports/comments/feed back/abuse to the Linux-NTFS development
 list at sourceforge: linux-ntfs-dev@lists.sourceforge.net
 
 ChangeLog
 =========
+
+NTFS 1.1.18:
+
+	- Enhanced & bug fixed cluster deallocation (race fixes, etc.)
+	- Complete rewrite of cluster allocation, now race free.
+	- Fixed several bugs in the attribute modification codepaths.
+	- Hopefully fixed bug where the first sectors of some people's
+	  partitions would be overwritten by the mft. And in general fixed up
+	  mft extension code a bit (still incomplete though).
+	- Introduce splice_runlist() to allow generic splicing of two run
+	  lists into one.
+	- MFT zone is now implemented. [Stage 2 of 3; only lack dynamic
+	  growing of mft zone but that is AFAIK not even done by Windows, and
+	  the overhead would be so large that it is probably not worth doing
+	  at all, so Stage 3 might never happen...]
+	- Complete rewrite of $MFT extension and ntfs inode allocation code.
+	- Made the NTFS driver initialization string show the compile options
+	  used (i.e. whether read-only or read-write, whether a module, and
+	  whether with debug support).
+	- Modify ntfs_fill_mft_header() to set all fields and to accept more
+	  arguments.
+	- Get rid of superfluous add_mft_header().
+	- Get rid of some unused code.
+	- Fixed several bugs in and generally cleaned up ntfs_readdir,
+	  ntfs_getdir_unsorted(), and ntfs_printcb. Now they spew out huge
+	  amounts of debug output if debugging is enabled. This will be
+	  removed once I know that this works for everyone.
+	- ntfs_readdir now shows hidden files. The only files that are now
+	  hidden are the first 16 inodes (i.e. the hard coded system files),
+	  which is consistent with Windows NT4. Using the show_sys_files mount
+	  option, these files are then shown, too.
+	- Fixed the displaying of the "." and ".." directories. We still cannot
+	  cope with more than 65536 files in a directory index block which is
+	  not a problem and we now cannot cope with more than 32766 directory
+	  index blocks which should not be a problem unless you have a
+	  directory with an insanely large number of files in it. The exact
+	  number depends on the length of the file names of the directory
+	  entries and on the size of the dircetory index blocks.
+	- Fixed all problems with the last file in a directory (e.g. the last
+	  file should no longer disappear and tab completion should work). If
+	  there are still disappearing files or any other problems with the
+	  last file in a directory, please report them! Thanks.
+	- Rewrote ntfs_extend_attr() to use the new cluster allocator and the
+	  freshly introduced splice_runlists() function. This simplified
+	  ntfs_extend_attr() a lot which in turn seems to have removed one or
+	  more bugs from it.
+	- Probably other things I have forgotten... (-;
+	- Removed dollar signs from the names in the system file enumeration.
+	  Apparently gcc doesn't support dollar signs on PPC architecture.
+	  (Andrzej Krzysztofowicz)
 
 NTFS 1.1.17:
 
diff -urN linux-2.4.10-pre5/Makefile linux/Makefile
--- linux-2.4.10-pre5/Makefile	Mon Dec  3 23:08:03 2001
+++ linux/Makefile	Mon Dec  3 23:08:12 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 10
-EXTRAVERSION =-pre5
+EXTRAVERSION =-pre6
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.10-pre5/arch/i386/kernel/bluesmoke.c linux/arch/i386/kernel/bluesmoke.c
--- linux-2.4.10-pre5/arch/i386/kernel/bluesmoke.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/i386/kernel/bluesmoke.c	Mon Dec  3 23:08:12 2001
@@ -38,7 +38,7 @@
 			high&=~(1<<31);
 			if(high&(1<<27))
 			{
-				rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
+				rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
 				printk("[%08x%08x]", alow, ahigh);
 			}
 			if(high&(1<<26))
diff -urN linux-2.4.10-pre5/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux-2.4.10-pre5/arch/i386/kernel/entry.S	Tue Jun 12 11:47:28 2001
+++ linux/arch/i386/kernel/entry.S	Mon Dec  3 23:08:12 2001
@@ -621,12 +621,6 @@
 	.long SYMBOL_NAME(sys_fcntl64)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */
 
-	/*
-	 * NOTE!! This doesn't have to be exact - we just have
-	 * to make sure we have _enough_ of the "sys_ni_syscall"
-	 * entries. Don't panic if you notice that this hasn't
-	 * been shrunk every time we add a new system call.
-	 */
-	.rept NR_syscalls-221
+	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
diff -urN linux-2.4.10-pre5/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- linux-2.4.10-pre5/arch/i386/kernel/setup.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/i386/kernel/setup.c	Mon Dec  3 23:08:12 2001
@@ -769,32 +769,9 @@
 	}
 }
 
-
-
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
-
-/*
- * 128MB for vmalloc and initrd
- */
-#define VMALLOC_RESERVE	(unsigned long)(128 << 20)
-#define MAXMEM		(unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)
-#define MAXMEM_PFN	PFN_DOWN(MAXMEM)
-#define MAX_NONPAE_PFN	(1 << 20)
-
-/* On x86 for 1GB low mem the bootmem_bitmap is at worst 32k
- * that is big but nothing to worry about.  This must be in the kernels
- * initial page tables so don't even try to get fancy where we allocate it.
- * This data must be aligned on a page boundary so since I don't
- * have a handlig __aligned_page_size attribute I allocate an extra
- * PAGE_SIZE -1 bytes.
- */
-static unsigned char bootmem_bitmap[((MAXMEM_PFN +7)/8) + PAGE_SIZE -1] __initdata = { 0 };
-
 void __init setup_arch(char **cmdline_p)
 {
-	unsigned long bootmap_pfn, low_mem_size;
+	unsigned long bootmap_size, low_mem_size;
 	unsigned long start_pfn, max_pfn, max_low_pfn;
 	int i;
 
@@ -828,18 +805,30 @@
 	init_mm.end_data = (unsigned long) &_edata;
 	init_mm.brk = (unsigned long) &_end;
 
-	code_resource.start = virt_to_phys(&_text);
-	code_resource.end = virt_to_phys(&_etext)-1;
-	data_resource.start = virt_to_phys(&_etext);
-	data_resource.end = virt_to_phys(&_edata)-1;
+	code_resource.start = virt_to_bus(&_text);
+	code_resource.end = virt_to_bus(&_etext)-1;
+	data_resource.start = virt_to_bus(&_etext);
+	data_resource.end = virt_to_bus(&_edata)-1;
 
 	parse_mem_cmdline(cmdline_p);
 
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
+
+/*
+ * 128MB for vmalloc and initrd
+ */
+#define VMALLOC_RESERVE	(unsigned long)(128 << 20)
+#define MAXMEM		(unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)
+#define MAXMEM_PFN	PFN_DOWN(MAXMEM)
+#define MAX_NONPAE_PFN	(1 << 20)
+
 	/*
 	 * partially used pages are not usable - thus
 	 * we are rounding upwards:
 	 */
-	start_pfn = PFN_UP(virt_to_phys(&_end));
+	start_pfn = PFN_UP(__pa(&_end));
 
 	/*
 	 * Find the highest page frame number we have available
@@ -894,8 +883,7 @@
 	/*
 	 * Initialize the boot-time allocator (with low memory only):
 	 */
-	bootmap_pfn = PFN_UP(virt_to_phys(&bootmem_bitmap));
-	init_bootmem(bootmap_pfn, max_low_pfn);
+	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
 
 	/*
 	 * Register fully available low RAM pages with the bootmem allocator.
@@ -931,32 +919,14 @@
 		size = last_pfn - curr_pfn;
 		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
 	}
-	/* 
-	 * Reserve the kernel memory.
+	/*
+	 * Reserve the bootmem bitmap itself as well. We do this in two
+	 * steps (first step was init_bootmem()) because this catches
+	 * the (very unlikely) case of us accidentally initializing the
+	 * bootmem allocator with an invalid RAM area.
 	 */
-	reserve_bootmem(HIGH_MEMORY, PFN_PHYS(start_pfn) + 
-		PAGE_SIZE-1 - (HIGH_MEMORY));
-
-	/* 
-	 * Reserve the initrd 
-	 */
-#ifdef CONFIG_BLK_DEV_INITRD
-	initrd_start = 0;
-	initrd_end = 0;
-	if (LOADER_TYPE && INITRD_START && INITRD_SIZE) {
-		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
-			reserve_bootmem(INITRD_START, INITRD_SIZE);
-			initrd_start = INITRD_START + PAGE_OFFSET;
-			initrd_end = initrd_start + INITRD_SIZE;
-		}
-		else {
-			printk(KERN_ERR "initrd extends beyond end of memory "
-			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-			    INITRD_START + INITRD_SIZE,
-			    max_low_pfn << PAGE_SHIFT);
-		}
-	}
-#endif
+	reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
+			 bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
 
 	/*
 	 * reserve physical page 0 - it's a special BIOS page on many boxes,
@@ -992,6 +962,23 @@
 	init_apic_mappings();
 #endif
 
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (LOADER_TYPE && INITRD_START) {
+		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
+			reserve_bootmem(INITRD_START, INITRD_SIZE);
+			initrd_start =
+				INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
+			initrd_end = initrd_start+INITRD_SIZE;
+		}
+		else {
+			printk(KERN_ERR "initrd extends beyond end of memory "
+			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+			    INITRD_START + INITRD_SIZE,
+			    max_low_pfn << PAGE_SHIFT);
+			initrd_start = 0;
+		}
+	}
+#endif
 
 	/*
 	 * Request address space for all standard RAM and ROM resources
diff -urN linux-2.4.10-pre5/arch/ppc/8xx_io/Config.in linux/arch/ppc/8xx_io/Config.in
--- linux-2.4.10-pre5/arch/ppc/8xx_io/Config.in	Wed May 16 09:57:20 2001
+++ linux/arch/ppc/8xx_io/Config.in	Mon Dec  3 23:08:12 2001
@@ -31,6 +31,7 @@
 comment 'Generic MPC8xx Options'
 bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK
 bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6
+bool 'I2C/SPI Microcode Patch' CONFIG_UCODE_PATCH
 
 if [ "$CONFIG_IDE" = "y" ]; then
 	bool 'MPC8xx direct IDE support on PCMCIA port' CONFIG_BLK_DEV_MPC8xx_IDE
diff -urN linux-2.4.10-pre5/arch/ppc/8xx_io/Makefile linux/arch/ppc/8xx_io/Makefile
--- linux-2.4.10-pre5/arch/ppc/8xx_io/Makefile	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/8xx_io/Makefile	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:20 cort
+# BK Id: SCCS/s.Makefile 1.6 08/30/01 09:33:48 trini
 #
 #
 # Makefile for the linux MPC8xx ppc-specific parts of comm processor
@@ -15,5 +15,6 @@
 
 obj-$(CONFIG_FEC_ENET)	+= fec.o
 obj-$(CONFIG_SCC_ENET)	+= enet.o
+obj-$(CONFIG_UCODE_PATCH) += micropatch.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.10-pre5/arch/ppc/8xx_io/micropatch.c linux/arch/ppc/8xx_io/micropatch.c
--- linux-2.4.10-pre5/arch/ppc/8xx_io/micropatch.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/8xx_io/micropatch.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,777 @@
+
+/* Microcode patches for the CPM as supplied by Motorola.
+ * This is the one for IIC/SPI.  There is a newer one that
+ * also relocates SMC2, but this would require additional changes
+ * to uart.c, so I am holding off on that for a moment.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/mpc8xx.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/8xx_immap.h>
+#include "commproc.h"
+
+/* Define this to get SMC patches as well.  You need to modify the uart
+ * driver as well......
+#define USE_SMC_PATCH 1
+ */
+
+#ifdef CONFIG_USB_MPC8xx
+#define USE_USB_SOF_PATCH
+#endif
+
+#ifdef USE_IIC_PATCH
+#define PATCH_DEFINED
+	/* IIC/SPI */
+uint patch_2000[] = {
+	0x7FFFEFD9,
+	0x3FFD0000,
+	0x7FFB49F7,
+	0x7FF90000,
+	0x5FEFADF7,
+	0x5F89ADF7,
+	0x5FEFAFF7,
+	0x5F89AFF7,
+	0x3A9CFBC8,
+	0xE7C0EDF0,
+	0x77C1E1BB,
+	0xF4DC7F1D,
+	0xABAD932F,
+	0x4E08FDCF,
+	0x6E0FAFF8,
+	0x7CCF76CF,
+	0xFD1FF9CF,
+	0xABF88DC6,
+	0xAB5679F7,
+	0xB0937383,
+	0xDFCE79F7,
+	0xB091E6BB,
+	0xE5BBE74F,
+	0xB3FA6F0F,
+	0x6FFB76CE,
+	0xEE0DF9CF,
+	0x2BFBEFEF,
+	0xCFEEF9CF,
+	0x76CEAD24,
+	0x90B2DF9A,
+	0x7FDDD0BF,
+	0x4BF847FD,
+	0x7CCF76CE,
+	0xCFEF7E1F,
+	0x7F1D7DFD,
+	0xF0B6EF71,
+	0x7FC177C1,
+	0xFBC86079,
+	0xE722FBC8,
+	0x5FFFDFFF,
+	0x5FB2FFFB,
+	0xFBC8F3C8,
+	0x94A67F01,
+	0x7F1D5F39,
+	0xAFE85F5E,
+	0xFFDFDF96,
+	0xCB9FAF7D,
+	0x5FC1AFED,
+	0x8C1C5FC1,
+	0xAFDD5FC3,
+	0xDF9A7EFD,
+	0xB0B25FB2,
+	0xFFFEABAD,
+	0x5FB2FFFE,
+	0x5FCE600B,
+	0xE6BB600B,
+	0x5FCEDFC6,
+	0x27FBEFDF,
+	0x5FC8CFDE,
+	0x3A9CE7C0,
+	0xEDF0F3C8,
+	0x7F0154CD,
+	0x7F1D2D3D,
+	0x363A7570,
+	0x7E0AF1CE,
+	0x37EF2E68,
+	0x7FEE10EC,
+	0xADF8EFDE,
+	0xCFEAE52F,
+	0x7D0FE12B,
+	0xF1CE5F65,
+	0x7E0A4DF8,
+	0xCFEA5F72,
+	0x7D0BEFEE,
+	0xCFEA5F74,
+	0xE522EFDE,
+	0x5F74CFDA,
+	0x0B627385,
+	0xDF627E0A,
+	0x30D8145B,
+	0xBFFFF3C8,
+	0x5FFFDFFF,
+	0xA7F85F5E,
+	0xBFFE7F7D,
+	0x10D31450,
+	0x5F36BFFF,
+	0xAF785F5E,
+	0xBFFDA7F8,
+	0x5F36BFFE,
+	0x77FD30C0,
+	0x4E08FDCF,
+	0xE5FF6E0F,
+	0xAFF87E1F,
+	0x7E0FFD1F,
+	0xF1CF5F1B,
+	0xABF80D5E,
+	0x5F5EFFEF,
+	0x79F730A2,
+	0xAFDD5F34,
+	0x47F85F34,
+	0xAFED7FDD,
+	0x50B24978,
+	0x47FD7F1D,
+	0x7DFD70AD,
+	0xEF717EC1,
+	0x6BA47F01,
+	0x2D267EFD,
+	0x30DE5F5E,
+	0xFFFD5F5E,
+	0xFFEF5F5E,
+	0xFFDF0CA0,
+	0xAFED0A9E,
+	0xAFDD0C3A,
+	0x5F3AAFBD,
+	0x7FBDB082,
+	0x5F8247F8
+};
+
+uint patch_2f00[] = {
+	0x3E303430,
+	0x34343737,
+	0xABF7BF9B,
+	0x994B4FBD,
+	0xBD599493,
+	0x349FFF37,
+	0xFB9B177D,
+	0xD9936956,
+	0xBBFDD697,
+	0xBDD2FD11,
+	0x31DB9BB3,
+	0x63139637,
+	0x93733693,
+	0x193137F7,
+	0x331737AF,
+	0x7BB9B999,
+	0xBB197957,
+	0x7FDFD3D5,
+	0x73B773F7,
+	0x37933B99,
+	0x1D115316,
+	0x99315315,
+	0x31694BF4,
+	0xFBDBD359,
+	0x31497353,
+	0x76956D69,
+	0x7B9D9693,
+	0x13131979,
+	0x79376935
+};
+#endif
+
+#ifdef USE_SMC_PATCH
+#define PATCH_DEFINED
+/* SMC2/IIC/SPI Patch */
+/* This is the area from 0x2000 to 0x23ff.
+*/
+uint patch_2000[] = {
+	0x3fff0000,
+	0x3ffd0000,
+	0x3ffb0000,
+	0x3ff90000,
+	0x5f13eff8,
+	0x5eb5eff8,
+	0x5f88adf7,
+	0x5fefadf7,
+	0x3a9cfbc8,
+	0x77cae1bb,
+	0xf4de7fad,
+	0xabae9330,
+	0x4e08fdcf,
+	0x6e0faff8,
+	0x7ccf76cf,
+	0xfdaff9cf,
+	0xabf88dc8,
+	0xab5879f7,
+	0xb0925d8d,
+	0xdfd079f7,
+	0xb090e6bb,
+	0xe5bbe74f,
+	0x9e046f0f,
+	0x6ffb76ce,
+	0xee0cf9cf,
+	0x2bfbefef,
+	0xcfeef9cf,
+	0x76cead23,
+	0x90b3df99,
+	0x7fddd0c1,
+	0x4bf847fd,
+	0x7ccf76ce,
+	0xcfef77ca,
+	0x7eaf7fad,
+	0x7dfdf0b7,
+	0xef7a7fca,
+	0x77cafbc8,
+	0x6079e722,
+	0xfbc85fff,
+	0xdfff5fb3,
+	0xfffbfbc8,
+	0xf3c894a5,
+	0xe7c9edf9,
+	0x7f9a7fad,
+	0x5f36afe8,
+	0x5f5bffdf,
+	0xdf95cb9e,
+	0xaf7d5fc3,
+	0xafed8c1b,
+	0x5fc3afdd,
+	0x5fc5df99,
+	0x7efdb0b3,
+	0x5fb3fffe,
+	0xabae5fb3,
+	0xfffe5fd0,
+	0x600be6bb,
+	0x600b5fd0,
+	0xdfc827fb,
+	0xefdf5fca,
+	0xcfde3a9c,
+	0xe7c9edf9,
+	0xf3c87f9e,
+	0x54ca7fed,
+	0x2d3a3637,
+	0x756f7e9a,
+	0xf1ce37ef,
+	0x2e677fee,
+	0x10ebadf8,
+	0xefdecfea,
+	0xe52f7d9f,
+	0xe12bf1ce,
+	0x5f647e9a,
+	0x4df8cfea,
+	0x5f717d9b,
+	0xefeecfea,
+	0x5f73e522,
+	0xefde5f73,
+	0xcfda0b61,
+	0x5d8fdf61,
+	0xe7c9edf9,
+	0x7e9a30d5,
+	0x1458bfff,
+	0xf3c85fff,
+	0xdfffa7f8,
+	0x5f5bbffe,
+	0x7f7d10d0,
+	0x144d5f33,
+	0xbfffaf78,
+	0x5f5bbffd,
+	0xa7f85f33,
+	0xbffe77fd,
+	0x30bd4e08,
+	0xfdcfe5ff,
+	0x6e0faff8,
+	0x7eef7e9f,
+	0xfdeff1cf,
+	0x5f17abf8,
+	0x0d5b5f5b,
+	0xffef79f7,
+	0x309eafdd,
+	0x5f3147f8,
+	0x5f31afed,
+	0x7fdd50af,
+	0x497847fd,
+	0x7f9e7fed,
+	0x7dfd70a9,
+	0xef7e7ece,
+	0x6ba07f9e,
+	0x2d227efd,
+	0x30db5f5b,
+	0xfffd5f5b,
+	0xffef5f5b,
+	0xffdf0c9c,
+	0xafed0a9a,
+	0xafdd0c37,
+	0x5f37afbd,
+	0x7fbdb081,
+	0x5f8147f8,
+	0x3a11e710,
+	0xedf0ccdd,
+	0xf3186d0a,
+	0x7f0e5f06,
+	0x7fedbb38,
+	0x3afe7468,
+	0x7fedf4fc,
+	0x8ffbb951,
+	0xb85f77fd,
+	0xb0df5ddd,
+	0xdefe7fed,
+	0x90e1e74d,
+	0x6f0dcbf7,
+	0xe7decfed,
+	0xcb74cfed,
+	0xcfeddf6d,
+	0x91714f74,
+	0x5dd2deef,
+	0x9e04e7df,
+	0xefbb6ffb,
+	0xe7ef7f0e,
+	0x9e097fed,
+	0xebdbeffa,
+	0xeb54affb,
+	0x7fea90d7,
+	0x7e0cf0c3,
+	0xbffff318,
+	0x5fffdfff,
+	0xac59efea,
+	0x7fce1ee5,
+	0xe2ff5ee1,
+	0xaffbe2ff,
+	0x5ee3affb,
+	0xf9cc7d0f,
+	0xaef8770f,
+	0x7d0fb0c6,
+	0xeffbbfff,
+	0xcfef5ede,
+	0x7d0fbfff,
+	0x5ede4cf8,
+	0x7fddd0bf,
+	0x49f847fd,
+	0x7efdf0bb,
+	0x7fedfffd,
+	0x7dfdf0b7,
+	0xef7e7e1e,
+	0x5ede7f0e,
+	0x3a11e710,
+	0xedf0ccab,
+	0xfb18ad2e,
+	0x1ea9bbb8,
+	0x74283b7e,
+	0x73c2e4bb,
+	0x2ada4fb8,
+	0xdc21e4bb,
+	0xb2a1ffbf,
+	0x5e2c43f8,
+	0xfc87e1bb,
+	0xe74ffd91,
+	0x6f0f4fe8,
+	0xc7ba32e2,
+	0xf396efeb,
+	0x600b4f78,
+	0xe5bb760b,
+	0x53acaef8,
+	0x4ef88b0e,
+	0xcfef9e09,
+	0xabf8751f,
+	0xefef5bac,
+	0x741f4fe8,
+	0x751e760d,
+	0x7fdbf081,
+	0x741cafce,
+	0xefcc7fce,
+	0x751e70ac,
+	0x741ce7bb,
+	0x3372cfed,
+	0xafdbefeb,
+	0xe5bb760b,
+	0x53f2aef8,
+	0xafe8e7eb,
+	0x4bf8771e,
+	0x7e247fed,
+	0x4fcbe2cc,
+	0x7fbc30a9,
+	0x7b0f7a0f,
+	0x34d577fd,
+	0x308b5db7,
+	0xde553e5f,
+	0xaf78741f,
+	0x741f30f0,
+	0xcfef5e2c,
+	0x741f3eac,
+	0xafb8771e,
+	0x5e677fed,
+	0x0bd3e2cc,
+	0x741ccfec,
+	0xe5ca53cd,
+	0x6fcb4f74,
+	0x5dadde4b,
+	0x2ab63d38,
+	0x4bb3de30,
+	0x751f741c,
+	0x6c42effa,
+	0xefea7fce,
+	0x6ffc30be,
+	0xefec3fca,
+	0x30b3de2e,
+	0xadf85d9e,
+	0xaf7daefd,
+	0x5d9ede2e,
+	0x5d9eafdd,
+	0x761f10ac,
+	0x1da07efd,
+	0x30adfffe,
+	0x4908fb18,
+	0x5fffdfff,
+	0xafbb709b,
+	0x4ef85e67,
+	0xadf814ad,
+	0x7a0f70ad,
+	0xcfef50ad,
+	0x7a0fde30,
+	0x5da0afed,
+	0x3c12780f,
+	0xefef780f,
+	0xefef790f,
+	0xa7f85e0f,
+	0xffef790f,
+	0xefef790f,
+	0x14adde2e,
+	0x5d9eadfd,
+	0x5e2dfffb,
+	0xe79addfd,
+	0xeff96079,
+	0x607ae79a,
+	0xddfceff9,
+	0x60795dff,
+	0x607acfef,
+	0xefefefdf,
+	0xefbfef7f,
+	0xeeffedff,
+	0xebffe7ff,
+	0xafefafdf,
+	0xafbfaf7f,
+	0xaeffadff,
+	0xabffa7ff,
+	0x6fef6fdf,
+	0x6fbf6f7f,
+	0x6eff6dff,
+	0x6bff67ff,
+	0x2fef2fdf,
+	0x2fbf2f7f,
+	0x2eff2dff,
+	0x2bff27ff,
+	0x4e08fd1f,
+	0xe5ff6e0f,
+	0xaff87eef,
+	0x7e0ffdef,
+	0xf11f6079,
+	0xabf8f542,
+	0x7e0af11c,
+	0x37cfae3a,
+	0x7fec90be,
+	0xadf8efdc,
+	0xcfeae52f,
+	0x7d0fe12b,
+	0xf11c6079,
+	0x7e0a4df8,
+	0xcfea5dc4,
+	0x7d0befec,
+	0xcfea5dc6,
+	0xe522efdc,
+	0x5dc6cfda,
+	0x4e08fd1f,
+	0x6e0faff8,
+	0x7c1f761f,
+	0xfdeff91f,
+	0x6079abf8,
+	0x761cee24,
+	0xf91f2bfb,
+	0xefefcfec,
+	0xf91f6079,
+	0x761c27fb,
+	0xefdf5da7,
+	0xcfdc7fdd,
+	0xd09c4bf8,
+	0x47fd7c1f,
+	0x761ccfcf,
+	0x7eef7fed,
+	0x7dfdf093,
+	0xef7e7f1e,
+	0x771efb18,
+	0x6079e722,
+	0xe6bbe5bb,
+	0xae0ae5bb,
+	0x600bae85,
+	0xe2bbe2bb,
+	0xe2bbe2bb,
+	0xaf02e2bb,
+	0xe2bb2ff9,
+	0x6079e2bb
+};
+
+	/* This is from 0x2f00 to 0x2fff
+	*/
+uint patch_2f00[] = {
+	0x30303030,
+	0x3e3e3434,
+	0xabbf9b99,
+	0x4b4fbdbd,
+	0x59949334,
+	0x9fff37fb,
+	0x9b177dd9,
+	0x936956bb,
+	0xfbdd697b,
+	0xdd2fd113,
+	0x1db9f7bb,
+	0x36313963,
+	0x79373369,
+	0x3193137f,
+	0x7331737a,
+	0xf7bb9b99,
+	0x9bb19795,
+	0x77fdfd3d,
+	0x573b773f,
+	0x737933f7,
+	0xb991d115,
+	0x31699315,
+	0x31531694,
+	0xbf4fbdbd,
+	0x35931497,
+	0x35376956,
+	0xbd697b9d,
+	0x96931313,
+	0x19797937,
+	0x6935af78,
+	0xb9b3baa3,
+	0xb8788683,
+	0x368f78f7,
+	0x87778733,
+	0x3ffffb3b,
+	0x8e8f78b8,
+	0x1d118e13,
+	0xf3ff3f8b,
+	0x6bd8e173,
+	0xd1366856,
+	0x68d1687b,
+	0x3daf78b8,
+	0x3a3a3f87,
+	0x8f81378f,
+	0xf876f887,
+	0x77fd8778,
+	0x737de8d6,
+	0xbbf8bfff,
+	0xd8df87f7,
+	0xfd876f7b,
+	0x8bfff8bd,
+	0x8683387d,
+	0xb873d87b,
+	0x3b8fd7f8,
+	0xf7338883,
+	0xbb8ee1f8,
+	0xef837377,
+	0x3337b836,
+	0x817d11f8,
+	0x7378b878,
+	0xd3368b7d,
+	0xed731b7d,
+	0x833731f3,
+	0xf22f3f23
+};
+
+uint patch_2e00[] = {
+	/* This is from 0x2e00 to 0x2e3c
+	*/
+	0x27eeeeee,
+	0xeeeeeeee,
+	0xeeeeeeee,
+	0xeeeeeeee,
+	0xee4bf4fb,
+	0xdbd259bb,
+	0x1979577f,
+	0xdfd2d573,
+	0xb773f737,
+	0x4b4fbdbd,
+	0x25b9b177,
+	0xd2d17376,
+	0x956bbfdd,
+	0x697bdd2f,
+	0xff9f79ff,
+	0xff9ff22f
+};
+#endif
+
+#ifdef USE_USB_SOF_PATCH
+#define PATCH_DEFINED
+uint patch_2000[] = {
+	0x7fff0000,
+	0x7ffd0000,
+	0x7ffb0000,
+	0x49f7ba5b,
+	0xba383ffb,
+	0xf9b8b46d,
+	0xe5ab4e07,
+	0xaf77bffe,
+	0x3f7bbf79,
+	0xba5bba38,
+	0xe7676076,
+	0x60750000
+};
+
+uint patch_2f00[] = {
+	0x3030304c,
+	0xcab9e441,
+	0xa1aaf220
+};
+#endif
+
+/* Load the microcode patch.  This is called early in the CPM initialization
+ * with the controller in the reset state.  We enable the processor after
+ * we load the patch.
+ */
+void
+cpm_load_patch(volatile immap_t *immr)
+{
+#ifdef PATCH_DEFINED
+	volatile uint		*dp;
+	volatile cpm8xx_t	*commproc;
+	volatile iic_t		*iip;
+	volatile spi_t		*spp;
+	int	i;
+
+	commproc = (cpm8xx_t *)&immr->im_cpm;
+
+	/* We work closely with commproc.c.  We know it only allocates
+	 * from data only space.
+	 * For this particular patch, we only use the bottom 512 bytes
+	 * and the upper 256 byte extension.  We will use the space
+	 * starting at 1K for the relocated parameters, as the general
+	 * CPM allocation won't come from that area.
+	 */
+	commproc->cp_rccr = 0;
+
+	/* Copy the patch into DPRAM.
+	*/
+	dp = (uint *)(commproc->cp_dpmem);
+	for (i=0; i<(sizeof(patch_2000)/4); i++)
+		*dp++ = patch_2000[i];
+
+	dp = (uint *)&(commproc->cp_dpmem[0x0f00]);
+	for (i=0; i<(sizeof(patch_2f00)/4); i++)
+		*dp++ = patch_2f00[i];
+
+#ifdef USE_USB_SOF_PATCH
+#if 0 /* usb patch should not relocate iic */
+	iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
+#define RPBASE 0x0030
+	iip->iic_rpbase = RPBASE;
+
+	/* Put SPI above the IIC, also 32-byte aligned.
+	*/
+	i = (RPBASE + sizeof(iic_t) + 31) & ~31;
+	spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
+	spp->spi_rpbase = i;
+#endif
+
+	/* Enable uCode fetches from DPRAM. */
+	commproc->cp_rccr = 0x0009;
+
+	printk("USB uCode patch installed\n");
+#endif /* USE_USB_SOF_PATCH */
+
+#if defined(USE_SMC_PATCH) || defined(USE_IIC_PATCH)
+
+	iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
+#define RPBASE 0x0400
+	iip->iic_rpbase = RPBASE;
+
+	/* Put SPI above the IIC, also 32-byte aligned.
+	*/
+	i = (RPBASE + sizeof(iic_t) + 31) & ~31;
+	spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
+	spp->spi_rpbase = i;
+
+#ifdef USE_SMC_PATCH
+	dp = (uint *)&(commproc->cp_dpmem[0x0e00]);
+	for (i=0; i<(sizeof(patch_2e00)/4); i++)
+		*dp++ = patch_2e00[i];
+
+	/* Enable the traps to get to it.
+	*/
+	commproc->cp_cpmcr1 = 0x8080;
+	commproc->cp_cpmcr2 = 0x808a;
+	commproc->cp_cpmcr3 = 0x8028;
+	commproc->cp_cpmcr4 = 0x802a;
+
+	/* Enable uCode fetches from DPRAM.
+	*/
+	commproc->cp_rccr = 3;
+#endif
+
+#ifdef USE_IIC_PATCH
+	/* Enable the traps to get to it.
+	*/
+	commproc->cp_cpmcr1 = 0x802a;
+	commproc->cp_cpmcr2 = 0x8028;
+	commproc->cp_cpmcr3 = 0x802e;
+	commproc->cp_cpmcr4 = 0x802c;
+
+	/* Enable uCode fetches from DPRAM.
+	*/
+	commproc->cp_rccr = 1;
+
+	printk("I2C uCode patch installed\n");
+#endif
+
+	/* Relocate the IIC and SPI parameter areas.  These have to
+	 * aligned on 32-byte boundaries.
+	 */
+	iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
+	iip->iic_rpbase = RPBASE;
+
+	/* Put SPI above the IIC, also 32-byte aligned.
+	*/
+	i = (RPBASE + sizeof(iic_t) + 31) & ~31;
+	spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
+	spp->spi_rpbase = i;
+
+#endif /* USE_SMC_PATCH || USE_IIC_PATCH */
+#endif /* PATCH_DEFINED */
+}
+
+void
+verify_patch(volatile immap_t *immr)
+{
+#ifdef PATCH_DEFINED
+	volatile uint		*dp;
+	volatile cpm8xx_t	*commproc;
+	int i;
+
+	commproc = (cpm8xx_t *)&immr->im_cpm;
+
+	printk("cp_rccr %x\n", commproc->cp_rccr);
+	commproc->cp_rccr = 0;
+
+	dp = (uint *)(commproc->cp_dpmem);
+	for (i=0; i<(sizeof(patch_2000)/4); i++)
+		if (*dp++ != patch_2000[i]) {
+			printk("patch_2000 bad at %d\n", i);
+			dp--;
+			printk("found 0x%X, wanted 0x%X\n", *dp, patch_2000[i]);
+			break;
+		}
+
+	dp = (uint *)&(commproc->cp_dpmem[0x0f00]);
+	for (i=0; i<(sizeof(patch_2f00)/4); i++)
+		if (*dp++ != patch_2f00[i]) {
+			printk("patch_2f00 bad at %d\n", i);
+			dp--;
+			printk("found 0x%X, wanted 0x%X\n", *dp, patch_2f00[i]);
+			break;
+		}
+
+	commproc->cp_rccr = 0x0009;
+#endif /* PATCH_DEFINED */
+}
+
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/apus_pci.c linux/arch/ppc/kernel/apus_pci.c
--- linux-2.4.10-pre5/arch/ppc/kernel/apus_pci.c	Sun Aug 12 12:43:26 2001
+++ linux/arch/ppc/kernel/apus_pci.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.apus_pci.c 1.4 07/06/01 09:19:28 trini
+ * BK Id: SCCS/s.apus_pci.c 1.5 09/08/01 15:47:42 paulus
  */
 /*
  * Copyright (C) Michel Dänzer <michdaen@iiic.ethz.ch>
@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 
-#include <asm/init.h>
 #include <asm/io.h>
 #include <asm/pci-bridge.h>
 #include <asm/machdep.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c
--- linux-2.4.10-pre5/arch/ppc/kernel/apus_setup.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/apus_setup.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.apus_setup.c 1.18 08/20/01 15:25:16 paulus
+ * BK Id: SCCS/s.apus_setup.c 1.20 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/apus_setup.c
@@ -76,7 +76,6 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/machdep.h>
-#include <asm/init.h>
 
 #include "local_irq.h"
 
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/btext.c linux/arch/ppc/kernel/btext.c
--- linux-2.4.10-pre5/arch/ppc/kernel/btext.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/btext.c	Mon Dec  3 23:08:12 2001
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/version.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/bootx.h>
 #include <asm/btext.h>
 #include <asm/prom.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c
--- linux-2.4.10-pre5/arch/ppc/kernel/chrp_pci.c	Sun Aug 12 12:43:26 2001
+++ linux/arch/ppc/kernel/chrp_pci.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_pci.c 1.20 08/08/01 16:35:43 paulus
+ * BK Id: SCCS/s.chrp_pci.c 1.22 09/08/01 15:47:42 paulus
  */
 /*
  * CHRP pci routines.
@@ -21,7 +21,7 @@
 #include <asm/prom.h>
 #include <asm/gg2.h>
 #include <asm/machdep.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/pci-bridge.h>
 
 #include "open_pic.h"
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
--- linux-2.4.10-pre5/arch/ppc/kernel/chrp_setup.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/chrp_setup.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_setup.c 1.34 08/29/01 10:07:29 paulus
+ * BK Id: SCCS/s.chrp_setup.c 1.36 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -51,7 +51,7 @@
 #include <asm/irq.h>
 #include <asm/hydra.h>
 #include <asm/keyboard.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/time.h>
 #include <asm/btext.h>
 
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/chrp_smp.c linux/arch/ppc/kernel/chrp_smp.c
--- linux-2.4.10-pre5/arch/ppc/kernel/chrp_smp.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/chrp_smp.c	Mon Dec  3 23:08:12 2001
@@ -31,7 +31,7 @@
 #include <asm/pgtable.h>
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
@@ -43,7 +43,7 @@
 
 extern unsigned long smp_chrp_cpu_nr;
 
-static int
+static int __init
 smp_chrp_probe(void)
 {
 	if (smp_chrp_cpu_nr > 1)
@@ -52,14 +52,14 @@
 	return smp_chrp_cpu_nr;
 }
 
-static void
+static void __init
 smp_chrp_kick_cpu(int nr)
 {
 	*(unsigned long *)KERNELBASE = nr;
 	asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
 }
 
-static void
+static void __init
 smp_chrp_setup_cpu(int cpu_nr)
 {
 	static atomic_t ready = ATOMIC_INIT(1);
@@ -101,7 +101,7 @@
 }
 
 #ifdef CONFIG_POWER4
-static void
+static void __chrp
 smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
 {
 	/* for now, only do reschedule messages
@@ -116,13 +116,13 @@
 	}
 }
 
-static int
+static int __chrp
 smp_xics_probe(void)
 {
 	return smp_chrp_cpu_nr;
 }
 
-static void
+static void __chrp
 smp_xics_setup_cpu(int cpu_nr)
 {
 	if (cpu_nr > 0)
@@ -131,7 +131,7 @@
 #endif /* CONFIG_POWER4 */
 
 /* CHRP with openpic */
-struct smp_ops_t chrp_smp_ops = {
+struct smp_ops_t chrp_smp_ops __chrpdata = {
 	smp_openpic_message_pass,
 	smp_chrp_probe,
 	smp_chrp_kick_cpu,
@@ -140,7 +140,7 @@
 
 #ifdef CONFIG_POWER4
 /* CHRP with new XICS interrupt controller */
-struct smp_ops_t xics_smp_ops = {
+struct smp_ops_t xics_smp_ops __chrpdata = {
 	smp_xics_message_pass,
 	smp_xics_probe,
 	smp_chrp_kick_cpu,
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/chrp_time.c linux/arch/ppc/kernel/chrp_time.c
--- linux-2.4.10-pre5/arch/ppc/kernel/chrp_time.c	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/kernel/chrp_time.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_time.c 1.7 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.chrp_time.c 1.10 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/i386/kernel/time.c
@@ -29,7 +29,7 @@
 #include <asm/processor.h>
 #include <asm/nvram.h>
 #include <asm/prom.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/time.h>
 
 extern spinlock_t rtc_lock;
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/feature.c linux/arch/ppc/kernel/feature.c
--- linux-2.4.10-pre5/arch/ppc/kernel/feature.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/feature.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.feature.c 1.19 08/19/01 22:23:04 paulus
+ * BK Id: SCCS/s.feature.c 1.21 09/08/01 15:47:42 paulus
  */
 /*
  *  arch/ppc/kernel/feature.c
@@ -20,7 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/errno.h>
 #include <asm/ohare.h>
 #include <asm/heathrow.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/indirect_pci.c linux/arch/ppc/kernel/indirect_pci.c
--- linux-2.4.10-pre5/arch/ppc/kernel/indirect_pci.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/indirect_pci.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.indirect_pci.c 1.7 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.indirect_pci.c 1.10 09/08/01 15:47:42 paulus
  */
 /*
  * Support for indirect PCI bridges.
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 
-#include <asm/init.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/m8xx_setup.c linux/arch/ppc/kernel/m8xx_setup.c
--- linux-2.4.10-pre5/arch/ppc/kernel/m8xx_setup.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/m8xx_setup.c	Mon Dec  3 23:08:12 2001
@@ -1,7 +1,6 @@
 /*
- * BK Id: SCCS/s.m8xx_setup.c 1.27 08/20/01 15:25:16 paulus
- */
-/*
+ * BK Id: SCCS/s.m8xx_setup.c 1.29 08/30/01 09:01:04 trini
+ *
  *  linux/arch/ppc/kernel/setup.c
  *
  *  Copyright (C) 1995  Linus Torvalds
@@ -172,8 +171,7 @@
 	machine_restart(NULL);
 }
 
-/* A place holder for time base interrupts, if they are ever enabled.
-*/
+/* A place holder for time base interrupts, if they are ever enabled. */
 void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
 {
 	printk ("timebase_interrupt()\n");
@@ -188,13 +186,11 @@
 	bd_t	*binfo = (bd_t *)__res;
 	int freq, fp, divisor;
 
-	/* Unlock the SCCR.
-	*/
+	/* Unlock the SCCR. */
 	((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = ~KAPWR_KEY;
 	((volatile immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk = KAPWR_KEY;
 
-	/* Force all 8xx processors to use divide by 16 processor clock.
-	*/
+	/* Force all 8xx processors to use divide by 16 processor clock. */
 	((volatile immap_t *)IMAP_ADDR)->im_clkrst.car_sccr |= 0x02000000;
 
 	/* Processor frequency is MHz.
@@ -224,15 +220,17 @@
 	 */
 	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY;
 	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY;
-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = ~KAPWR_KEY;
+	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    = ~KAPWR_KEY;
 	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
 	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
-	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk = KAPWR_KEY;
+	((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    = KAPWR_KEY;
 
-	/* Disable the RTC one second and alarm interrupts.
-	*/
+	/* Disable the RTC one second and alarm interrupts. */
 	((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
 						~(RTCSC_SIE | RTCSC_ALE);
+	/* Enable the RTC */
+	((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc |=
+						(RTCSC_RTF | RTCSC_RTE);
 
 	/* Enabling the decrementer also enables the timebase interrupts
 	 * (or from the other point of view, to get decrementer interrupts
@@ -260,15 +258,14 @@
 	return(0);
 }
 
-unsigned long
+static unsigned long
 m8xx_get_rtc_time(void)
 {
-	/* Get time from the RTC.
-	*/
+	/* Get time from the RTC. */
 	return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc));
 }
 
-void
+static void
 m8xx_restart(char *cmd)
 {
 	__volatile__ unsigned char dummy;
@@ -288,20 +285,21 @@
 	while(1);
 }
 
-void
+static void
 m8xx_power_off(void)
 {
    m8xx_restart(NULL);
 }
 
-void
+static void
 m8xx_halt(void)
 {
    m8xx_restart(NULL);
 }
 
 
-int m8xx_setup_residual(char *buffer)
+static int
+m8xx_setup_residual(char *buffer)
 {
         int     len = 0;
 	bd_t	*bp;
@@ -322,7 +320,7 @@
  * External interrupts can be either edge or level triggered, and
  * need to be initialized by the appropriate driver.
  */
-void __init
+static void __init
 m8xx_init_IRQ(void)
 {
 	int i;
@@ -353,12 +351,12 @@
  * IDE stuff.
  */
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-void ide_interrupt_handler (void *dev)
+static void ide_interrupt_handler (void *dev)
 {
 }
 #endif
 
-int
+static int
 m8xx_ide_default_irq(ide_ioreg_t base)
 {
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
@@ -371,13 +369,13 @@
 #endif
 }
 
-ide_ioreg_t
+static ide_ioreg_t
 m8xx_ide_default_io_base(int index)
 {
         return index;
 }
 
-int
+static int
 m8xx_ide_request_irq(unsigned int irq,
 		       void (*handler)(int, void *, struct pt_regs *),
 		       unsigned long flags, 
@@ -392,8 +390,9 @@
  *
  * See include/linux/ide.h for definition of hw_regs_t (p, base)
  */
-void m8xx_ide_init_hwif_ports(hw_regs_t *hw,
-	ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+static void
+m8xx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, 
+		ide_ioreg_t ctrl_port, int *irq)
 {
 	int i;
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
@@ -565,7 +564,8 @@
  * functions in the image just to get prom_init, all we really need right
  * now is the initialization of the physical memory region.
  */
-unsigned long __init m8xx_find_end_of_memory(void)
+static unsigned long __init
+m8xx_find_end_of_memory(void)
 {
 	bd_t	*binfo;
 	extern unsigned char __res[];
@@ -581,7 +581,8 @@
  * All of this fits into the same 4Mbyte region, so it only
  * requires one page table page.  (or at least it used to  -- paulus)
  */
-void __init m8xx_map_io(void)
+static void __init
+m8xx_map_io(void)
 {
         io_block_mapping(IMAP_ADDR, IMAP_ADDR, IMAP_SIZE, _PAGE_IO);
 #ifdef CONFIG_MBX
@@ -613,9 +614,8 @@
 
 void __init
 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	      unsigned long r6, unsigned long r7)
+		unsigned long r6, unsigned long r7)
 {
-
 	if ( r3 )
 		memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
 	
@@ -633,8 +633,7 @@
 #endif /* CONFIG_BLK_DEV_INITRD */
 	/* take care of cmd line */
 	if ( r6 )
-	{
-		
+	{	
 		*(char *)(r7+KERNELBASE) = 0;
 		strcpy(cmd_line, (char *)(r6+KERNELBASE));
 	}
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/open_pic.c linux/arch/ppc/kernel/open_pic.c
--- linux-2.4.10-pre5/arch/ppc/kernel/open_pic.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/open_pic.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.open_pic.c 1.26 08/20/01 22:33:28 paulus
+ * BK Id: SCCS/s.open_pic.c 1.28 09/08/01 15:47:42 paulus
  */
 /*
  *  arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
@@ -23,7 +23,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/prom.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 
 #include "local_irq.h"
 #include "open_pic.h"
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/pmac_backlight.c linux/arch/ppc/kernel/pmac_backlight.c
--- linux-2.4.10-pre5/arch/ppc/kernel/pmac_backlight.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/pmac_backlight.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_backlight.c 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.pmac_backlight.c 1.8 09/08/01 15:47:42 paulus
  */
 /*
  * Miscellaneous procedures for dealing with the PowerMac hardware.
@@ -14,7 +14,7 @@
 #include <linux/stddef.h>
 #include <linux/reboot.h>
 #include <linux/nvram.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/ptrace.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/pmac_nvram.c linux/arch/ppc/kernel/pmac_nvram.c
--- linux-2.4.10-pre5/arch/ppc/kernel/pmac_nvram.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/pmac_nvram.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_nvram.c 1.13 08/19/01 22:23:04 paulus
+ * BK Id: SCCS/s.pmac_nvram.c 1.15 09/08/01 15:47:42 paulus
  */
 /*
  * Miscellaneous procedures for dealing with the PowerMac hardware.
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/prom.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c
--- linux-2.4.10-pre5/arch/ppc/kernel/pmac_pci.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/pmac_pci.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_pci.c 1.25 08/19/01 22:23:04 paulus
+ * BK Id: SCCS/s.pmac_pci.c 1.27 09/08/01 15:47:42 paulus
  */
 /*
  * Support for PCI bridges found on Power Macintoshes.
@@ -22,7 +22,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c
--- linux-2.4.10-pre5/arch/ppc/kernel/pmac_pic.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/pmac_pic.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_pic.c 1.18 08/19/01 22:23:04 paulus
+ * BK Id: SCCS/s.pmac_pic.c 1.20 09/08/01 15:47:42 paulus
  */
 #include <linux/config.h>
 #include <linux/stddef.h>
@@ -8,7 +8,7 @@
 #include <linux/signal.h>
 #include <linux/pci.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/prom.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c
--- linux-2.4.10-pre5/arch/ppc/kernel/pmac_setup.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/pmac_setup.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_setup.c 1.37 08/29/01 10:07:29 paulus
+ * BK Id: SCCS/s.pmac_setup.c 1.39 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -51,7 +51,7 @@
 #include <linux/pmu.h>
 
 #include <asm/processor.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/pmac_smp.c linux/arch/ppc/kernel/pmac_smp.c
--- linux-2.4.10-pre5/arch/ppc/kernel/pmac_smp.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/pmac_smp.c	Mon Dec  3 23:08:12 2001
@@ -38,7 +38,7 @@
 #include <asm/pgtable.h>
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
@@ -140,7 +140,8 @@
  */
 static unsigned long psurge_smp_message[NR_CPUS];
 
-void psurge_smp_message_recv(struct pt_regs *regs)
+void __pmac
+psurge_smp_message_recv(struct pt_regs *regs)
 {
 	int cpu = smp_processor_id();
 	int msg;
@@ -157,13 +158,13 @@
 			smp_message_recv(msg, regs);
 }
 
-void
+void __pmac
 psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
 {
 	psurge_smp_message_recv(regs);
 }
 
-static void
+static void __pmac
 smp_psurge_message_pass(int target, int msg, unsigned long data, int wait)
 {
 	int i;
@@ -376,7 +377,7 @@
 		psurge_dual_sync_tb(cpu_nr);
 }
 
-static int
+static int __init
 smp_core99_probe(void)
 {
 	struct device_node *cpus;
@@ -397,7 +398,7 @@
 	return ncpus;
 }
 
-static void
+static void __init
 smp_core99_kick_cpu(int nr)
 {
 	unsigned long save_vector, new_vector;
@@ -472,7 +473,7 @@
 }
 
 /* PowerSurge-style Macs */
-struct smp_ops_t psurge_smp_ops = {
+struct smp_ops_t psurge_smp_ops __pmacdata = {
 	smp_psurge_message_pass,
 	smp_psurge_probe,
 	smp_psurge_kick_cpu,
@@ -480,7 +481,7 @@
 };
 
 /* Core99 Macs (dual G4s) */
-struct smp_ops_t core99_smp_ops = {
+struct smp_ops_t core99_smp_ops __pmacdata = {
 	smp_openpic_message_pass,
 	smp_core99_probe,
 	smp_core99_kick_cpu,
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/pmac_time.c linux/arch/ppc/kernel/pmac_time.c
--- linux-2.4.10-pre5/arch/ppc/kernel/pmac_time.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/pmac_time.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_time.c 1.14 08/19/01 22:23:04 paulus
+ * BK Id: SCCS/s.pmac_time.c 1.16 09/08/01 15:47:42 paulus
  */
 /*
  * Support for periodic interrupts (100 per second) and for getting
@@ -22,7 +22,7 @@
 #include <linux/cuda.h>
 #include <linux/pmu.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/system.h>
 #include <asm/io.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/prep_nvram.c linux/arch/ppc/kernel/prep_nvram.c
--- linux-2.4.10-pre5/arch/ppc/kernel/prep_nvram.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/prep_nvram.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_nvram.c 1.9 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.prep_nvram.c 1.12 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/prep_nvram.c
@@ -12,7 +12,7 @@
 #include <linux/slab.h>
 #include <linux/ioport.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/processor.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
--- linux-2.4.10-pre5/arch/ppc/kernel/prep_pci.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/prep_pci.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_pci.c 1.24 08/20/01 15:06:15 paulus
+ * BK Id: SCCS/s.prep_pci.c 1.26 09/08/01 15:47:42 paulus
  */
 /*
  * PReP pci functions.
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/ptrace.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- linux-2.4.10-pre5/arch/ppc/kernel/prep_setup.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/prep_setup.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_setup.c 1.34 08/29/01 10:07:29 paulus
+ * BK Id: SCCS/s.prep_setup.c 1.36 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -41,7 +41,7 @@
 #include <linux/pci.h>
 #include <linux/ide.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/mmu.h>
 #include <asm/processor.h>
 #include <asm/residual.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/prep_time.c linux/arch/ppc/kernel/prep_time.c
--- linux-2.4.10-pre5/arch/ppc/kernel/prep_time.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/prep_time.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_time.c 1.7 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.prep_time.c 1.10 09/08/01 15:47:42 paulus
  */
 /*
  *  linux/arch/i386/kernel/time.c
@@ -23,7 +23,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/init.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/processor.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- linux-2.4.10-pre5/arch/ppc/kernel/prom.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/prom.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prom.c 1.40 08/24/01 20:13:31 paulus
+ * BK Id: SCCS/s.prom.c 1.42 09/08/01 15:47:42 paulus
  */
 /*
  * Procedures for interfacing to the Open Firmware PROM on
@@ -20,7 +20,7 @@
 #include <linux/threads.h>
 #include <linux/spinlock.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/page.h>
 #include <asm/processor.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/residual.c linux/arch/ppc/kernel/residual.c
--- linux-2.4.10-pre5/arch/ppc/kernel/residual.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/residual.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.residual.c 1.7 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.residual.c 1.11 09/08/01 15:47:42 paulus
  */
 /*
  * Code to deal with the PReP residual data.
@@ -44,7 +44,7 @@
 #include <linux/pci.h>
 #include <linux/ide.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/mmu.h>
 #include <asm/processor.h>
 #include <asm/io.h>
@@ -55,7 +55,7 @@
 unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
 RESIDUAL *res = (RESIDUAL *)&__res;
 
-const char * PnP_BASE_TYPES[] __initdata = {
+char * PnP_BASE_TYPES[] __initdata = {
   "Reserved",
   "MassStorageDevice",
   "NetworkInterfaceController",
@@ -71,7 +71,7 @@
 
 /* Device Sub Type Codes */
 
-const unsigned char * PnP_SUB_TYPES[] __initdata = {
+unsigned char * PnP_SUB_TYPES[] __initdata = {
   "\001\000SCSIController",
   "\001\001IDEController",
   "\001\002FloppyController",
@@ -128,7 +128,7 @@
 
 /* Device Interface Type Codes */
 
-const  unsigned char * PnP_INTERFACES[] __initdata = {
+unsigned char * PnP_INTERFACES[] __initdata = {
   "\000\000\000General",
   "\001\000\000GeneralSCSI",
   "\001\001\000GeneralIDE",
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- linux-2.4.10-pre5/arch/ppc/kernel/setup.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/setup.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.setup.c 1.55 08/24/01 20:07:37 paulus
+ * BK Id: SCCS/s.setup.c 1.57 09/08/01 15:47:42 paulus
  */
 /*
  * Common prep/pmac/chrp boot and setup code.
@@ -17,7 +17,6 @@
 #include <linux/tty.h>
 #include <linux/bootmem.h>
 
-#include <asm/init.h>
 #include <asm/residual.h>
 #include <asm/io.h>
 #include <asm/prom.h>
diff -urN linux-2.4.10-pre5/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- linux-2.4.10-pre5/arch/ppc/kernel/smp.c	Mon Dec  3 23:08:03 2001
+++ linux/arch/ppc/kernel/smp.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.smp.c 1.29 08/20/01 21:35:14 paulus
+ * BK Id: SCCS/s.smp.c 1.31 09/08/01 15:47:42 paulus
  */
 /*
  * Smp support for ppc.
@@ -31,7 +31,6 @@
 #include <asm/pgtable.h>
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
-#include <asm/init.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
diff -urN linux-2.4.10-pre5/arch/sh/Makefile linux/arch/sh/Makefile
--- linux-2.4.10-pre5/arch/sh/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/sh/Makefile	Mon Dec  3 23:08:12 2001
@@ -75,6 +75,11 @@
 
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
+ifneq ($(CONFIG_SH_GENERIC)$(CONFIG_SH_STB1_HARP)$(CONFIG_SH_STB1_OVERDRIVE),)
+SUBDIRS += arch/sh/stboards
+CORE_FILES += arch/sh/stboards/stboards.o
+endif
+
 vmlinux: arch/sh/vmlinux.lds
 
 arch/sh/vmlinux.lds: arch/sh/vmlinux.lds.S FORCE
@@ -93,6 +98,7 @@
 archclean:
 	@$(MAKEBOOT) clean
 	$(MAKE) -C arch/$(ARCH)/kernel clean
+	$(MAKE) -C arch/$(ARCH)/stboards clean
 #	$(MAKE) -C arch/$(ARCH)/tools clean
 
 archmrproper:
diff -urN linux-2.4.10-pre5/arch/sh/config.in linux/arch/sh/config.in
--- linux-2.4.10-pre5/arch/sh/config.in	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/config.in	Mon Dec  3 23:08:12 2001
@@ -42,6 +42,7 @@
 	 CAT68701		CONFIG_SH_CAT68701		\
 	 BigSur			CONFIG_SH_BIGSUR		\
 	 SH2000			CONFIG_SH_SH2000		\
+	 ADX			CONFIG_SH_ADX			\
 	 BareCPU		CONFIG_SH_UNKNOWN" Generic
 
 # The SH7750 RTC module is disabled in the Dreamcast
@@ -88,24 +89,40 @@
    define_bool CONFIG_CPU_SH4 y
 fi
 bool 'Little Endian' CONFIG_CPU_LITTLE_ENDIAN
+# Platform-specific memory start and size definitions
 if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_HP600" = "y" -o \
      "$CONFIG_SH_BIGSUR" = "y" -o "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \
      "$CONFIG_SH_DREAMCAST" = "y" -o "$CONFIG_SH_SH2000" = "y" ]; then
-  define_hex CONFIG_MEMORY_START 0c000000
-else
-  if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then
-    bool 'Memory on LMI' CONFIG_ST40_LMI_MEMORY
-    if [ "$CONFIG_ST40_LMI_MEMORY" = "y" ] ; then
+   define_hex CONFIG_MEMORY_START 0c000000
+   define_hex CONFIG_MEMORY_SIZE 00400000
+   define_bool CONFIG_MEMORY_SET y
+fi
+if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then
+   bool 'Memory on LMI' CONFIG_ST40_LMI_MEMORY
+   if [ "$CONFIG_ST40_LMI_MEMORY" = "y" ] ; then
       define_hex CONFIG_MEMORY_START 08000000
-    else
-      hex 'EMI physical memory start address' CONFIG_MEMORY_START 08000000
-    fi
-  else
-    hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
-  fi
+      define_hex CONFIG_MEMORY_SIZE 00400000
+      define_bool CONFIG_MEMORY_SET y
+   fi
+fi
+if [ "$CONFIG_SH_ADX" = "y" ]; then
+   define_hex CONFIG_MEMORY_START 08000000
+   define_hex CONFIG_MEMORY_SIZE 00400000
+   define_bool CONFIG_MEMORY_SET y
+fi
+# If none of the above have set memory start/size, ask the user.
+if [ "$CONFIG_MEMORY_SET" != "y" ]; then
+   hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
+   hex 'Physical memory size' CONFIG_MEMORY_SIZE 00400000
 fi
 endmenu
 
+if [ "$CONFIG_SH_HP690" = "y" ]; then
+  define_bool CONFIG_DISCONTIGMEM y
+else
+  define_bool CONFIG_DISCONTIGMEM n
+fi
+
 mainmenu_option next_comment
 comment 'General setup'
 
@@ -120,10 +137,23 @@
 bool 'Networking support' CONFIG_NET
 
 if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o \
-     "$CONFIG_SH_UNKNOWN" = "y" -o "$CONFIG_SH_CAT68701" = "y" ]; then
+     "$CONFIG_SH_UNKNOWN" = "y" -o "$CONFIG_SH_CAT68701" = "y" -o \
+     "$CONFIG_SH_ADX" = "y" ]; then
   bool 'Compact Flash Enabler support' CONFIG_CF_ENABLER
 fi
 
+if [ "$CONFIG_CF_ENABLER" = "y" ]; then
+   choice 'Compact Flash Connection Area' \
+	"Area5 CONFIG_CF_AREA5 \
+	 Area6 CONFIG_CF_AREA6" Area6
+   if [ "$CONFIG_CF_AREA5" = "y" ]; then
+      define_hex CONFIG_CF_BASE_ADDR b4000000
+   fi
+   if [ "$CONFIG_CF_AREA6" = "y" ]; then
+      define_hex CONFIG_CF_BASE_ADDR b8000000
+   fi
+fi
+
 bool 'Hitachi HD64461 companion chip support' CONFIG_HD64461
 if [ "$CONFIG_HD64461" = "y" ]; then
    int 'HD64461 IRQ' CONFIG_HD64461_IRQ 36
@@ -136,6 +166,8 @@
    int 'HD64465 IRQ' CONFIG_HD64465_IRQ 5
 fi
 
+bool 'DMA controller (DMAC) support' CONFIG_SH_DMA
+
 bool 'PCI support' CONFIG_PCI
 if [ "$CONFIG_PCI" = "y" ]; then
    choice '  PCI access mode' \
@@ -148,6 +180,7 @@
    if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
       define_bool CONFIG_PCI_DIRECT y
    fi
+   define_bool CONFIG_SH_PCIDMA_NONCOHERENT n
 fi
 
 source drivers/pci/Config.in
@@ -224,13 +257,22 @@
    endmenu
 fi
 
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+   source drivers/cdrom/Config.in
+fi
+endmenu
+
 #
 # input before char - char/joystick depends on it. As does USB.
 #
 source drivers/input/Config.in
 
 if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then
-source drivers/maple/Config.in
+   source drivers/maple/Config.in
 fi
 
 mainmenu_option next_comment
@@ -259,7 +301,7 @@
      "$CONFIG_SH_BIGSUR" = "y" -o \
      "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \
      "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then
-  bool 'Heartbeat LED' CONFIG_HEARTBEAT
+   bool 'Heartbeat LED' CONFIG_HEARTBEAT
 fi
 
 if [ "$CONFIG_SH_DREAMCAST" = "y" -a "$CONFIG_MAPLE" != "n" ]; then
@@ -322,7 +364,6 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 bool 'Use LinuxSH standard BIOS' CONFIG_SH_STANDARD_BIOS
 if [ "$CONFIG_SH_STANDARD_BIOS" = "y" ]; then
-   bool 'GDB Stub kernel debug' CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
    bool 'Early printk support' CONFIG_SH_EARLY_PRINTK
 fi
 endmenu
diff -urN linux-2.4.10-pre5/arch/sh/kernel/Makefile linux/arch/sh/kernel/Makefile
--- linux-2.4.10-pre5/arch/sh/kernel/Makefile	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/Makefile	Mon Dec  3 23:08:12 2001
@@ -21,13 +21,14 @@
 obj-$(CONFIG_CF_ENABLER)	+= cf-enabler.o
 obj-$(CONFIG_CPU_SH4)		+= fpu.o
 obj-$(CONFIG_SH_RTC)            += rtc.o
+obj-$(CONFIG_SH_DMA)		+= dma.o
 obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
 
 ifeq ($(CONFIG_PCI),y)
 ifeq ($(CONFIG_SH_DREAMCAST),y)
-obj-y 				+= pci-dc.o
+obj-y 				+= pci-dc.o pcibios.o
 else
-obj-y                           += pci-dma.o 
+obj-y                           += pci-dma.o pcibios.o
 obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)+= pci_st40.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7751)+= pci-sh7751.o 
 obj-$(CONFIG_SH_BIGSUR)+= pci-bigsur.o
@@ -41,8 +42,10 @@
 obj-$(CONFIG_SH_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o
 machine-specific-objs		+= mach_se.o setup_se.o io_se.o led_se.o
 
-obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o pci-7751se.o
-machine-specific-objs           += mach_se.o setup_se.o io_se.o led_se.o pci-7751se.o
+obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= mach_7751se.o setup_7751se.o \
+					io_7751se.o led_7751se.o
+machine-specific-objs           += mach_7751se.o 7751setup_se.o \
+				   io_7751se.o led_7751se.o pci-7751se.o
 
 obj-$(CONFIG_SH_BIGSUR)		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
 machine-specific-objs		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
@@ -64,11 +67,14 @@
 
 obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) +=irq_intc2.o
 
+obj-$(CONFIG_SH_ADX)		+= mach_adx.o setup_adx.o io_adx.o irq_maskreg.o
+machine-specific-objs		+= mach_adx.o setup_adx.o io_adx.o irq_maskreg.o
+
 # Doesn't compile well, so don't include in machine-specific-objs
 obj-$(CONFIG_HD64465)		+= setup_hd64465.o io_hd64465.o hd64465_gpio.o
 obj-$(CONFIG_SH_DMIDA)		+= mach_dmida.o
 obj-$(CONFIG_SH_EC3104)         += setup_ec3104.o io_ec3104.o mach_ec3104.o
-obj-$(CONFIG_SH_DREAMCAST)	+= mach_dc.o setup_dc.o io_dc.o
+obj-$(CONFIG_SH_DREAMCAST)	+= mach_dc.o setup_dc.o io_dc.o rtc-aica.o
 
 ifeq ($(CONFIG_SH_GENERIC),y)
 obj-y		+= $(machine-specific-objs)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/cf-enabler.c linux/arch/sh/kernel/cf-enabler.c
--- linux-2.4.10-pre5/arch/sh/kernel/cf-enabler.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/cf-enabler.c	Mon Dec  3 23:08:12 2001
@@ -1,9 +1,10 @@
-/* $Id: cf-enabler.c,v 1.2 2000/06/08 05:50:10 gniibe Exp $
+/* $Id: cf-enabler.c,v 1.8 2001/07/18 12:32:21 gniibe Exp $
  *
  *  linux/drivers/block/cf-enabler.c
  *
  *  Copyright (C) 1999  Niibe Yutaka
  *  Copyright (C) 2000  Toshiharu Nozawa
+ *  Copyright (C) 2001  A&D Co., Ltd.
  *
  *  Enable the CF configuration.
  */
@@ -14,7 +15,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#define CF_CIS_BASE	0xb8000000
 /*
  * You can connect Compact Flash directly to the bus of SuperH.
  * This is the enabler for that.
@@ -29,15 +29,61 @@
  * 0xB8001000 : Common Memory
  * 0xBA000000 : I/O
  */
+#if defined(CONFIG_IDE) && defined(__SH4__)
+/* SH4 can't access PCMCIA interface through P2 area.
+ * we must remap it with appropreate attribute bit of the page set.
+ * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+
+#if defined(CONFIG_CF_AREA6)
+#define slot_no 0
+#else
+#define slot_no 1
+#endif
+
+/* defined in mm/ioremap.c */
+extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
+
+/* use this pointer to access to directly connected compact flash io area*/
+void *cf_io_base;
+
+static int __init allocate_cf_area(void)
+{
+	pgprot_t prot;
+	unsigned long paddrbase, psize;
+
+	/* open I/O area window */
+	paddrbase = virt_to_phys((void*)CONFIG_CF_BASE_ADDR);
+	psize = PAGE_SIZE;
+	prot = PAGE_KERNEL_PCC(slot_no, _PAGE_PCC_IO16);
+	cf_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
+	if (!cf_io_base) {
+		printk("allocate_cf_area : can't open CF I/O window!\n");
+		return -ENOMEM;
+	}
+/*	printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n",
+	    	paddrbase, psize, prot.pgprot, cf_io_base);*/
+
+	/* XXX : do we need attribute and common-memory area also? */
+
+	return 0;
+}
+#endif
 
 static int __init cf_init_default(void)
 {
-#ifdef CONFIG_IDE
-	/* Enable the card, and set the level interrupt */
-	ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
+/* You must have enabled the card, and set the level interrupt
+ * before reaching this point. Possibly in boot ROM or boot loader.
+ */
+#if defined(CONFIG_IDE) && defined(__SH4__)
+	allocate_cf_area();
 #endif
+#if defined(CONFIG_SH_UNKNOWN)
+	/* This should be done in each board's init_xxx_irq. */
 	make_imask_irq(14);
 	disable_irq(14);
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.10-pre5/arch/sh/kernel/dma.c linux/arch/sh/kernel/dma.c
--- linux-2.4.10-pre5/arch/sh/kernel/dma.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/dma.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,142 @@
+/*
+ * arch/sh/kernel/dma.c
+ *
+ * Copyright (C) 2000 Takashi YOSHII
+ *
+ * PC like DMA API for SuperH's DMAC.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/signal.h>
+#include <asm/dma.h>
+
+static struct dma_info_t *dma_info[MAX_DMA_CHANNELS];
+static struct dma_info_t *autoinit_info[SH_MAX_DMA_CHANNELS] = {0};
+static spinlock_t  dma_spin_lock;
+
+static unsigned int calc_chcr(struct dma_info_t *info)
+{
+	unsigned int chcr;
+
+	chcr = ( info->mode & DMA_MODE_WRITE )? info->mode_write : info->mode_read;
+	if( info->mode & DMA_AUTOINIT )
+		chcr |= CHCR_IE;
+	return chcr;
+}
+
+static __inline__ int ts_shift(unsigned long chcr)
+{
+	return ((int[]){3,0,1,2,5,0,0,0})[(chcr>>4)&0x000007];
+}
+
+static void dma_tei(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int chan = irq - DMTE_IRQ[0];
+	struct dma_info_t *info = autoinit_info[chan];
+
+	if( info->mode & DMA_MODE_WRITE )
+		ctrl_outl(info->mem_addr, SAR[info->chan]);
+	else
+		ctrl_outl(info->mem_addr, DAR[info->chan]);
+
+	ctrl_outl(info->count>>ts_shift(calc_chcr(info)), DMATCR[info->chan]);
+	ctrl_outl(ctrl_inl(CHCR[info->chan])&~CHCR_TE, CHCR[info->chan]);
+}
+
+static struct irqaction irq_tei = { dma_tei, SA_INTERRUPT, 0, "dma_tei", NULL, NULL};
+
+void setup_dma(unsigned int dmanr, struct dma_info_t *info)
+{
+	make_ipr_irq(DMTE_IRQ[info->chan], DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
+	setup_irq(DMTE_IRQ[info->chan], &irq_tei);
+	dma_info[dmanr] = info;
+}
+
+unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&dma_spin_lock, flags);
+	return flags;
+}
+
+void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+void enable_dma(unsigned int dmanr)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	ctrl_outl(calc_chcr(info)|CHCR_DE, CHCR[info->chan]);
+}
+
+void disable_dma(unsigned int dmanr)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	ctrl_outl(calc_chcr(info)&~CHCR_DE, CHCR[info->chan]);
+}
+
+void set_dma_mode(unsigned int dmanr, char mode)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+
+	info->mode = mode;
+	set_dma_addr(dmanr, info->mem_addr);
+	set_dma_count(dmanr, info->count);
+	autoinit_info[info->chan] = info;
+}
+
+void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	unsigned long sar, dar;
+
+	info->mem_addr = a;
+	sar = (info->mode & DMA_MODE_WRITE)? info->mem_addr: info->dev_addr;
+	dar = (info->mode & DMA_MODE_WRITE)? info->dev_addr: info->mem_addr;
+	ctrl_outl(sar, SAR[info->chan]);
+	ctrl_outl(dar, DAR[info->chan]);
+}
+
+void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	info->count = count;
+	ctrl_outl(count>>ts_shift(calc_chcr(info)), DMATCR[info->chan]);
+}
+
+int get_dma_residue(unsigned int dmanr)
+{
+	struct dma_info_t *info = dma_info[dmanr];
+	return ctrl_inl(DMATCR[info->chan])<<ts_shift(calc_chcr(info));
+}
+
+#if defined(__SH4__)
+static void dma_err(int irq, void *dev_id, struct pt_regs *regs)
+{
+	printk(KERN_WARNING "DMAE: DMAOR=%lx\n",ctrl_inl(DMAOR));
+	ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_NMIF, DMAOR);
+	ctrl_outl(ctrl_inl(DMAOR)&~DMAOR_AE, DMAOR);
+	ctrl_outl(ctrl_inl(DMAOR)|DMAOR_DME, DMAOR);
+}
+static struct irqaction irq_err = { dma_err, SA_INTERRUPT, 0, "dma_err", NULL, NULL};
+#endif
+
+int __init init_dma(void)
+{
+#if defined(__SH4__)
+	make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
+	setup_irq(DMAE_IRQ, &irq_err);
+#endif
+
+	ctrl_outl(DMAOR_DME, DMAOR);
+	return 0;
+}
+
+module_init(init_dma);
+
+/**/
diff -urN linux-2.4.10-pre5/arch/sh/kernel/entry.S linux/arch/sh/kernel/entry.S
--- linux-2.4.10-pre5/arch/sh/kernel/entry.S	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/entry.S	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.71 2000/03/22 13:29:33 gniibe Exp $
+/* $Id: entry.S,v 1.71 2001/07/27 11:47:50 gniibe Exp $
  *
  *  linux/arch/sh/entry.S
  *
@@ -220,7 +220,7 @@
 1:	.long	MMU_TEA
 2:	.long   SYMBOL_NAME(do_address_error)
 
-#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS)
 	.align	2
 	/* Unwind the stack and jmp to the debug entry */
 debug_kernel:
@@ -263,7 +263,7 @@
 
 	.align	2
 debug_trap:	
-#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS)
 	mov	#OFF_SR, r0
 	mov.l	@(r0,r15), r0		! get status register
 	shll	r0
@@ -293,8 +293,23 @@
 !
 !
 ENTRY(ret_from_fork)
-	bra	SYMBOL_NAME(ret_from_syscall)
-	 add	#4, r15	! pop down bogus r0 (see switch_to MACRO)
+	mov.l	@r15+,r0
+	! Call schedule_tail
+	mov.l	1f, r1
+	jsr @r1
+	 mov	r0, r4
+	! If we're being traced, return via syscall_ret_trace, otherwise
+	! return directly to ret_from_syscall
+	stc	k_current, r0
+	mov.l	@(tsk_ptrace,r0), r0	! Is current PTRACE_SYSCALL'd?
+	mov	#PT_TRACESYS, r1
+	tst	r1, r0
+	bt	ret_from_syscall
+	bra	syscall_ret_trace
+	 nop	 
+
+	.align	2
+1:	.long	SYMBOL_NAME(schedule_tail)
 
 /*
  * Old syscall interface:
diff -urN linux-2.4.10-pre5/arch/sh/kernel/io_7751se.c linux/arch/sh/kernel/io_7751se.c
--- linux-2.4.10-pre5/arch/sh/kernel/io_7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/io_7751se.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,304 @@
+/* 
+ * linux/arch/sh/kernel/io_7751se.c
+ *
+ * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
+ * Based largely on io_se.c.
+ *
+ * I/O routine for Hitachi 7751 SolutionEngine.
+ *
+ * Initial version only to support LAN access; some
+ * placeholder code from io_se.c left in with the
+ * expectation of later SuperIO and PCMCIA access.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/hitachi_7751se.h>
+#include <asm/addrspace.h>
+
+#include <asm/pci.h>
+#include <asm/pci-sh7751.h>
+
+#if 0
+/******************************************************************
+ * Variables from io_se.c, related to PCMCIA (not PCI); we're not
+ * compiling them in, and have removed references from functions
+ * which follow.  [Many checked for IO ports in the range bounded
+ * by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset.
+ * As start/stop are uninitialized, only port 0x0 would match?]
+ * When used, remember to adjust names to avoid clash with io_se?
+ *****************************************************************/
+/* SH pcmcia io window base, start and end.  */
+int sh_pcic_io_wbase = 0xb8400000;
+int sh_pcic_io_start;
+int sh_pcic_io_stop;
+int sh_pcic_io_type;
+int sh_pcic_io_dummy;
+/*************************************************************/
+#endif
+
+/*
+ * The 7751 Solution Engine uses the built-in PCI controller (PCIC)
+ * of the 7751 processor, and has a SuperIO accessible via the PCI.
+ * The board also includes a PCMCIA controller on its memory bus,
+ * like the other Solution Engine boards.
+ */ 
+
+#define PCIIOBR		(volatile long *)PCI_REG(SH7751_PCIIOBR)
+#define PCIMBR          (volatile long *)PCI_REG(SH7751_PCIMBR)
+#define PCI_IO_AREA	SH7751_PCI_IO_BASE
+#define PCI_MEM_AREA	SH7751_PCI_CONFIG_BASE
+
+#define PCI_IOMAP(adr)	(PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
+
+#define maybebadio(name,port) \
+  printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
+	 #name, (port), (__u32) __builtin_return_address(0))
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+static inline volatile __u16 *
+port2adr(unsigned int port)
+{
+	if (port >= 0x2000)
+		return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
+#if 0
+	else
+		return (volatile __u16 *) (PA_SUPERIO + (port << 1));
+#endif
+	maybebadio(name,port);
+	return (volatile __u16*)port;
+}
+
+#if 0
+/* The 7751 Solution Engine seems to have everything hooked */
+/* up pretty normally (nothing on high-bytes only...) so this */
+/* shouldn't be needed */
+static inline int
+shifted_port(unsigned long port)
+{
+	/* For IDE registers, value is not shifted */
+	if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
+		return 0;
+	else
+		return 1;
+}
+#endif
+
+/* In case someone configures the kernel w/o PCI support: in that */
+/* scenario, don't ever bother to check for PCI-window addresses */
+
+/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
+#if defined(CONFIG_PCI)
+#define CHECK_SH7751_PCIIO(port) \
+  ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
+#else
+#define CHECK_SH_7751_PCIIO(port) (0)
+#endif
+
+/*
+ * General outline: remap really low stuff [eventually] to SuperIO,
+ * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
+ * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
+ * should be way beyond the window, and is used  w/o translation for
+ * compatibility.
+ */
+unsigned char sh7751se_inb(unsigned long port)
+{
+	if (PXSEG(port))
+		return *(volatile unsigned char *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+		return *(volatile unsigned char *)PCI_IOMAP(port);
+	else
+		return (*port2adr(port))&0xff; 
+}
+
+unsigned char sh7751se_inb_p(unsigned long port)
+{
+	unsigned char v;
+
+        if (PXSEG(port))
+                v = *(volatile unsigned char *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+                v = *(volatile unsigned char *)PCI_IOMAP(port);
+	else
+		v = (*port2adr(port))&0xff; 
+	delay();
+	return v;
+}
+
+unsigned short sh7751se_inw(unsigned long port)
+{
+        if (PXSEG(port))
+                return *(volatile unsigned short *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+                return *(volatile unsigned short *)PCI_IOMAP(port);
+	else if (port >= 0x2000)
+		return *port2adr(port);
+	else
+		maybebadio(inw, port);
+	return 0;
+}
+
+unsigned int sh7751se_inl(unsigned long port)
+{
+        if (PXSEG(port))
+                return *(volatile unsigned long *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+                return *(volatile unsigned int *)PCI_IOMAP(port);
+	else if (port >= 0x2000)
+		return *port2adr(port);
+	else
+		maybebadio(inl, port);
+	return 0;
+}
+
+void sh7751se_outb(unsigned char value, unsigned long port)
+{
+
+        if (PXSEG(port))
+                *(volatile unsigned char *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+        	*((unsigned char*)PCI_IOMAP(port)) = value;
+	else
+		*(port2adr(port)) = value;
+}
+
+void sh7751se_outb_p(unsigned char value, unsigned long port)
+{
+        if (PXSEG(port))
+                *(volatile unsigned char *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+        	*((unsigned char*)PCI_IOMAP(port)) = value;
+	else
+		*(port2adr(port)) = value;
+	delay();
+}
+
+void sh7751se_outw(unsigned short value, unsigned long port)
+{
+        if (PXSEG(port))
+                *(volatile unsigned short *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+        	*((unsigned short *)PCI_IOMAP(port)) = value;
+	else if (port >= 0x2000)
+		*port2adr(port) = value;
+	else
+		maybebadio(outw, port);
+}
+
+void sh7751se_outl(unsigned int value, unsigned long port)
+{
+        if (PXSEG(port))
+                *(volatile unsigned long *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+        	*((unsigned long*)PCI_IOMAP(port)) = value;
+	else
+		maybebadio(outl, port);
+}
+
+void sh7751se_insb(unsigned long port, void *addr, unsigned long count)
+{
+	unsigned char *p = addr;
+	while (count--) *p++ = sh7751se_inb(port);
+}
+
+void sh7751se_insw(unsigned long port, void *addr, unsigned long count)
+{
+	unsigned short *p = addr;
+	while (count--) *p++ = sh7751se_inw(port);
+}
+
+void sh7751se_insl(unsigned long port, void *addr, unsigned long count)
+{
+	maybebadio(insl, port);
+}
+
+void sh7751se_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	unsigned char *p = (unsigned char*)addr;
+	while (count--) sh7751se_outb(*p++, port);
+}
+
+void sh7751se_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	unsigned short *p = (unsigned short*)addr;
+	while (count--) sh7751se_outw(*p++, port);
+}
+
+void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	maybebadio(outsw, port);
+}
+
+/* For read/write calls, just copy generic (pass-thru); PCIMBR is  */
+/* already set up.  For a larger memory space, these would need to */
+/* reset PCIMBR as needed on a per-call basis...                   */
+
+unsigned char sh7751se_readb(unsigned long addr)
+{
+	return *(volatile unsigned char*)addr;
+}
+
+unsigned short sh7751se_readw(unsigned long addr)
+{
+	return *(volatile unsigned short*)addr;
+}
+
+unsigned int sh7751se_readl(unsigned long addr)
+{
+	return *(volatile unsigned long*)addr;
+}
+
+void sh7751se_writeb(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char*)addr = b;
+}
+
+void sh7751se_writew(unsigned short b, unsigned long addr)
+{
+	*(volatile unsigned short*)addr = b;
+}
+
+void sh7751se_writel(unsigned int b, unsigned long addr)
+{
+        *(volatile unsigned long*)addr = b;
+}
+
+
+
+/* Map ISA bus address to the real address. Only for PCMCIA.  */
+
+/* ISA page descriptor.  */
+static __u32 sh_isa_memmap[256];
+
+static int
+sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
+{
+	int idx;
+
+	if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
+		return -1;
+
+	idx = start >> 12;
+	sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
+#if 0
+	printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
+	       start, length, offset, idx, sh_isa_memmap[idx]);
+#endif
+	return 0;
+}
+
+unsigned long
+sh7751se_isa_port2addr(unsigned long offset)
+{
+	int idx;
+
+	idx = (offset >> 12) & 0xff;
+	offset &= 0xfff;
+	return sh_isa_memmap[idx] + offset;
+}
diff -urN linux-2.4.10-pre5/arch/sh/kernel/io_adx.c linux/arch/sh/kernel/io_adx.c
--- linux-2.4.10-pre5/arch/sh/kernel/io_adx.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/io_adx.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,192 @@
+/* 
+ * linux/arch/sh/kernel/io_adx.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * I/O routine and setup routines for A&D ADX Board
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/machvec.h>
+#include <linux/module.h>
+
+#define PORT2ADDR(x) (adx_isa_port2addr(x))
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+unsigned char adx_inb(unsigned long port)
+{
+	return *(volatile unsigned char*)PORT2ADDR(port);
+}
+
+unsigned short adx_inw(unsigned long port)
+{
+	return *(volatile unsigned short*)PORT2ADDR(port);
+}
+
+unsigned int adx_inl(unsigned long port)
+{
+	return *(volatile unsigned long*)PORT2ADDR(port);
+}
+
+unsigned char adx_inb_p(unsigned long port)
+{
+	unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
+
+	delay();
+	return v;
+}
+
+unsigned short adx_inw_p(unsigned long port)
+{
+	unsigned long v = *(volatile unsigned short*)PORT2ADDR(port);
+
+	delay();
+	return v;
+}
+
+unsigned int adx_inl_p(unsigned long port)
+{
+	unsigned long v = *(volatile unsigned long*)PORT2ADDR(port);
+
+	delay();
+	return v;
+}
+
+void adx_insb(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned char *buf = buffer;
+	while(count--) *buf++ = inb(port);
+}
+
+void adx_insw(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned short *buf = buffer;
+	while(count--) *buf++ = inw(port);
+}
+
+void adx_insl(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned long *buf = buffer;
+	while(count--) *buf++ = inl(port);
+}
+
+void adx_outb(unsigned char b, unsigned long port)
+{
+	*(volatile unsigned char*)PORT2ADDR(port) = b;
+}
+
+void adx_outw(unsigned short b, unsigned long port)
+{
+	*(volatile unsigned short*)PORT2ADDR(port) = b;
+}
+
+void adx_outl(unsigned int b, unsigned long port)
+{
+	*(volatile unsigned long*)PORT2ADDR(port) = b;
+}
+
+void adx_outb_p(unsigned char b, unsigned long port)
+{
+	*(volatile unsigned char*)PORT2ADDR(port) = b;
+	delay();
+}
+
+void adx_outw_p(unsigned short b, unsigned long port)
+{
+	*(volatile unsigned short*)PORT2ADDR(port) = b;
+	delay();
+}
+
+void adx_outl_p(unsigned int b, unsigned long port)
+{
+	*(volatile unsigned long*)PORT2ADDR(port) = b;
+	delay();
+}
+
+void adx_outsb(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned char *buf = buffer;
+	while(count--) outb(*buf++, port);
+}
+
+void adx_outsw(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned short *buf = buffer;
+	while(count--) outw(*buf++, port);
+}
+
+void adx_outsl(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned long *buf = buffer;
+	while(count--) outl(*buf++, port);
+}
+
+unsigned char adx_readb(unsigned long addr)
+{
+	return *(volatile unsigned char*)addr;
+}
+
+unsigned short adx_readw(unsigned long addr)
+{
+	return *(volatile unsigned short*)addr;
+}
+
+unsigned int adx_readl(unsigned long addr)
+{
+	return *(volatile unsigned long*)addr;
+}
+
+void adx_writeb(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char*)addr = b;
+}
+
+void adx_writew(unsigned short b, unsigned long addr)
+{
+	*(volatile unsigned short*)addr = b;
+}
+
+void adx_writel(unsigned int b, unsigned long addr)
+{
+	*(volatile unsigned long*)addr = b;
+}
+
+void *adx_ioremap(unsigned long offset, unsigned long size)
+{
+	return (void *)P2SEGADDR(offset);
+}
+
+EXPORT_SYMBOL (adx_ioremap);
+
+void adx_iounmap(void *addr)
+{
+}
+
+EXPORT_SYMBOL(adx_iounmap);
+
+#include <linux/vmalloc.h>
+extern void *cf_io_base;
+
+unsigned long adx_isa_port2addr(unsigned long offset)
+{
+  /* CompactFlash (IDE) */
+	if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset == 0x3f6)) {
+		return (unsigned long)cf_io_base + offset;
+	}
+
+  /* eth0 */
+	if ((offset >= 0x300) && (offset <= 0x30f)) {
+		return 0xa5000000 + offset;	/* COMM BOARD (AREA1) */
+	}
+
+	return offset + 0xb0000000; /* IOBUS (AREA 4)*/
+}
diff -urN linux-2.4.10-pre5/arch/sh/kernel/irq.c linux/arch/sh/kernel/irq.c
--- linux-2.4.10-pre5/arch/sh/kernel/irq.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/irq.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.12 2000/03/06 14:07:50 gniibe Exp $
+/* $Id: irq.c,v 1.21 2001/07/17 02:26:53 gniibe Exp $
  *
  * linux/arch/sh/kernel/irq.c
  *
@@ -31,7 +31,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/bitops.h>
-#include <asm/smp.h>
 #include <asm/pgalloc.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -399,7 +398,7 @@
 
 		spin_lock_irq(&desc->lock);
 		if (!desc->action)
-		  desc->handler->startup(i);
+			desc->handler->startup(i);
 		spin_unlock_irq(&desc->lock);
 	}
 
@@ -452,7 +451,6 @@
 		}
 		spin_unlock_irq(&desc->lock);
 	}
-	spin_unlock_irq(&desc->lock);
 
 	return val;
 }
@@ -536,7 +534,7 @@
 
 	if (!shared) {
 		desc->depth = 0;
-		desc->status &= ~IRQ_DISABLED;
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
 		desc->handler->startup(irq);
 	}
 	spin_unlock_irqrestore(&desc->lock,flags);
diff -urN linux-2.4.10-pre5/arch/sh/kernel/irq_imask.c linux/arch/sh/kernel/irq_imask.c
--- linux-2.4.10-pre5/arch/sh/kernel/irq_imask.c	Sun Jan 28 18:56:00 2001
+++ linux/arch/sh/kernel/irq_imask.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: irq_imask.c,v 1.6 2000/03/06 14:11:32 gniibe Exp $
+/* $Id: irq_imask.c,v 1.13 2001/07/12 08:13:56 gniibe Exp $
  *
  * linux/arch/sh/kernel/irq_imask.c
  *
@@ -99,7 +99,8 @@
 
 static void end_imask_irq(unsigned int irq)
 {
-	enable_imask_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_imask_irq(irq);
 }
 
 static void shutdown_imask_irq(unsigned int irq)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/irq_intc2.c linux/arch/sh/kernel/irq_intc2.c
--- linux-2.4.10-pre5/arch/sh/kernel/irq_intc2.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/irq_intc2.c	Mon Dec  3 23:08:12 2001
@@ -92,7 +92,8 @@
 
 static void end_intc2_irq(unsigned int irq)
 {
-	enable_intc2_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_intc2_irq(irq);
 }
 
 void make_intc2_irq(unsigned int irq, unsigned int addr, 
diff -urN linux-2.4.10-pre5/arch/sh/kernel/irq_ipr.c linux/arch/sh/kernel/irq_ipr.c
--- linux-2.4.10-pre5/arch/sh/kernel/irq_ipr.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/irq_ipr.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: irq_ipr.c,v 1.6 2000/05/14 08:41:25 gniibe Exp $
+/* $Id: irq_ipr.c,v 1.20 2001/07/15 23:26:56 gniibe Exp $
  *
  * linux/arch/sh/kernel/irq_ipr.c
  *
@@ -102,7 +102,8 @@
 
 static void end_ipr_irq(unsigned int irq)
 {
-	enable_ipr_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_ipr_irq(irq);
 }
 
 void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
@@ -176,7 +177,8 @@
 
 static void end_pint_irq(unsigned int irq)
 {
-	enable_pint_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_pint_irq(irq);
 }
 
 void make_pint_irq(unsigned int irq)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/irq_maskreg.c linux/arch/sh/kernel/irq_maskreg.c
--- linux-2.4.10-pre5/arch/sh/kernel/irq_maskreg.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/irq_maskreg.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,107 @@
+/*
+ * linux/arch/sh/kernel/irq_maskreg.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp>
+ *
+ * This file may be copied or modified under the terms of the GNU
+ * General Public License.  See linux/COPYING for more information.
+ *
+ * Interrupt handling for Simple external interrupt mask register
+ *
+ * This is for the machine which have single 16 bit register
+ * for masking external IRQ individually.
+ * Each bit of the register is for masking each interrupt.  
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/machvec.h>
+
+/* address of external interrupt mask register
+ * address must be set prior to use these (maybe in init_XXX_irq())
+ * XXX : is it better to use .config than specifying it in code? */
+unsigned short *irq_mask_register = 0;
+
+/* forward declaration */
+static unsigned int startup_maskreg_irq(unsigned int irq);
+static void shutdown_maskreg_irq(unsigned int irq);
+static void enable_maskreg_irq(unsigned int irq);
+static void disable_maskreg_irq(unsigned int irq);
+static void mask_and_ack_maskreg(unsigned int);
+static void end_maskreg_irq(unsigned int irq);
+
+/* hw_interrupt_type */
+static struct hw_interrupt_type maskreg_irq_type = {
+	" Mask Register",
+	startup_maskreg_irq,
+	shutdown_maskreg_irq,
+	enable_maskreg_irq,
+	disable_maskreg_irq,
+	mask_and_ack_maskreg,
+	end_maskreg_irq
+};
+
+/* actual implementatin */
+static unsigned int startup_maskreg_irq(unsigned int irq)
+{ 
+	enable_maskreg_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static void shutdown_maskreg_irq(unsigned int irq)
+{
+	disable_maskreg_irq(irq);
+}
+
+static void disable_maskreg_irq(unsigned int irq)
+{
+	if (irq_mask_register) {
+		unsigned long flags;
+		unsigned short val, mask = 0x01 << irq;
+
+		/* Set "irq"th bit */
+		save_and_cli(flags);
+		val = ctrl_inw((unsigned long)irq_mask_register);
+		val |= mask;
+		ctrl_outw(val, (unsigned long)irq_mask_register);
+		restore_flags(flags);
+	}
+}
+
+static void enable_maskreg_irq(unsigned int irq)
+{
+	if (irq_mask_register) {
+		unsigned long flags;
+		unsigned short val, mask = ~(0x01 << irq);
+
+		/* Clear "irq"th bit */
+		save_and_cli(flags);
+		val = ctrl_inw((unsigned long)irq_mask_register);
+		val &= mask;
+		ctrl_outw(val, (unsigned long)irq_mask_register);
+		restore_flags(flags);
+	}
+}
+
+static void mask_and_ack_maskreg(unsigned int irq)
+{
+	disable_maskreg_irq(irq);
+}
+
+static void end_maskreg_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_maskreg_irq(irq);
+}
+
+void make_maskreg_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &maskreg_irq_type;
+	disable_maskreg_irq(irq);
+}
diff -urN linux-2.4.10-pre5/arch/sh/kernel/led_7751se.c linux/arch/sh/kernel/led_7751se.c
--- linux-2.4.10-pre5/arch/sh/kernel/led_7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/led_7751se.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/sh/kernel/led_se.c
+ *
+ * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * This file contains Solution Engine specific LED code.
+ */
+
+#include <linux/config.h>
+#include <asm/hitachi_7751se.h>
+
+static void mach_led(int position, int value)
+{
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
+
+	if (value) {
+		*p |= (1<<8);
+	} else {
+		*p &= ~(1<<8);
+	}
+}
+
+#ifdef CONFIG_HEARTBEAT
+
+#include <linux/sched.h>
+
+/* Cycle the LED's in the clasic Knightrider/Sun pattern */
+void heartbeat_7751se(void)
+{
+	static unsigned int cnt = 0, period = 0;
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
+	static unsigned bit = 0, up = 1;
+
+	cnt += 1;
+	if (cnt < period) {
+		return;
+	}
+
+	cnt = 0;
+
+	/* Go through the points (roughly!):
+	 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
+	 */
+	period = 110 - ( (300<<FSHIFT)/
+			 ((avenrun[0]/5) + (3<<FSHIFT)) );
+
+	if (up) {
+		if (bit == 7) {
+			bit--;
+			up=0;
+		} else {
+			bit ++;
+		}
+	} else {
+		if (bit == 0) {
+			bit++;
+			up=1;
+		} else {
+			bit--;
+		}
+	}
+	*p = 1<<(bit+8);
+
+}
+#endif /* CONFIG_HEARTBEAT */
diff -urN linux-2.4.10-pre5/arch/sh/kernel/led_se.c linux/arch/sh/kernel/led_se.c
--- linux-2.4.10-pre5/arch/sh/kernel/led_se.c	Wed Aug  9 13:59:04 2000
+++ linux/arch/sh/kernel/led_se.c	Mon Dec  3 23:08:12 2001
@@ -10,10 +10,11 @@
  */
 
 #include <linux/config.h>
+#include <asm/hitachi_se.h>
 
 static void mach_led(int position, int value)
 {
-	volatile unsigned short* p = (volatile unsigned short*)0xb0c00000;
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
 
 	if (value) {
 		*p |= (1<<8);
@@ -30,7 +31,7 @@
 void heartbeat_se(void)
 {
 	static unsigned int cnt = 0, period = 0;
-	volatile unsigned short* p = (volatile unsigned short*)0xb0c00000;
+	volatile unsigned short* p = (volatile unsigned short*)PA_LED;
 	static unsigned bit = 0, up = 1;
 
 	cnt += 1;
diff -urN linux-2.4.10-pre5/arch/sh/kernel/mach_7751se.c linux/arch/sh/kernel/mach_7751se.c
--- linux-2.4.10-pre5/arch/sh/kernel/mach_7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/mach_7751se.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/sh/kernel/mach_7751se.c
+ *
+ * Minor tweak of mach_se.c file to reference 7751se-specific items.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi 7751 SolutionEngine
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_7751se.h>
+
+void heartbeat_7751se(void);
+void setup_7751se(void);
+void init_7751se_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_7751se __initmv = {
+	mv_name:		"7751 SolutionEngine",
+
+	mv_nr_irqs:		72,
+
+	mv_inb:			sh7751se_inb,
+	mv_inw:			sh7751se_inw,
+	mv_inl:			sh7751se_inl,
+	mv_outb:		sh7751se_outb,
+	mv_outw:		sh7751se_outw,
+	mv_outl:		sh7751se_outl,
+
+	mv_inb_p:		sh7751se_inb_p,
+	mv_inw_p:		sh7751se_inw,
+	mv_inl_p:		sh7751se_inl,
+	mv_outb_p:		sh7751se_outb_p,
+	mv_outw_p:		sh7751se_outw,
+	mv_outl_p:		sh7751se_outl,
+
+	mv_insb:		sh7751se_insb,
+	mv_insw:		sh7751se_insw,
+	mv_insl:		sh7751se_insl,
+	mv_outsb:		sh7751se_outsb,
+	mv_outsw:		sh7751se_outsw,
+	mv_outsl:		sh7751se_outsl,
+
+	mv_readb:		sh7751se_readb,
+	mv_readw:		sh7751se_readw,
+	mv_readl:		sh7751se_readl,
+	mv_writeb:		sh7751se_writeb,
+	mv_writew:		sh7751se_writew,
+	mv_writel:		sh7751se_writel,
+
+	mv_ioremap:		generic_ioremap,
+	mv_iounmap:		generic_iounmap,
+
+	mv_isa_port2addr:	sh7751se_isa_port2addr,
+
+	mv_init_arch:		setup_7751se,
+	mv_init_irq:		init_7751se_IRQ,
+#ifdef CONFIG_HEARTBEAT
+	mv_heartbeat:		heartbeat_7751se,
+#endif
+
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+
+	mv_hw_7751se:		1,
+};
+ALIAS_MV(7751se)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/mach_adx.c linux/arch/sh/kernel/mach_adx.c
--- linux-2.4.10-pre5/arch/sh/kernel/mach_adx.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/mach_adx.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,73 @@
+/*
+ * linux/arch/sh/kernel/mach_adx.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * This file may be copied or modified under the terms of the GNU
+ * General Public License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the A&D ADX Board
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/io_adx.h>
+
+extern void setup_adx(void);
+extern void init_adx_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_adx __initmv = {
+	mv_name:		"A&D_ADX",
+
+	mv_nr_irqs:		48,
+
+	mv_inb:			adx_inb,
+	mv_inw:			adx_inw,
+	mv_inl:			adx_inl,
+	mv_outb:		adx_outb,
+	mv_outw:		adx_outw,
+	mv_outl:		adx_outl,
+
+	mv_inb_p:		adx_inb_p,
+	mv_inw_p:		adx_inw,
+	mv_inl_p:		adx_inl,
+	mv_outb_p:		adx_outb_p,
+	mv_outw_p:		adx_outw,
+	mv_outl_p:		adx_outl,
+
+	mv_insb:		adx_insb,
+	mv_insw:		adx_insw,
+	mv_insl:		adx_insl,
+	mv_outsb:		adx_outsb,
+	mv_outsw:		adx_outsw,
+	mv_outsl:		adx_outsl,
+
+	mv_readb:		adx_readb,
+	mv_readw:		adx_readw,
+	mv_readl:		adx_readl,
+	mv_writeb:		adx_writeb,
+	mv_writew:		adx_writew,
+	mv_writel:		adx_writel,
+
+	mv_ioremap:		adx_ioremap,
+	mv_iounmap:		adx_iounmap,
+
+	mv_isa_port2addr:	adx_isa_port2addr,
+
+	mv_init_arch:		setup_adx,
+	mv_init_irq:		init_adx_IRQ,
+
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+
+	mv_hw_adx:		1,
+};
+ALIAS_MV(adx)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/mach_dc.c linux/arch/sh/kernel/mach_dc.c
--- linux-2.4.10-pre5/arch/sh/kernel/mach_dc.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/mach_dc.c	Mon Dec  3 23:08:12 2001
@@ -1,10 +1,11 @@
 /*
- *	$Id: mach_dc.c,v 1.4 2001/05/24 05:09:16 mrbrown Exp $
+ *	$Id: mach_dc.c,v 1.5 2001/09/01 14:34:31 mrbrown Exp $
  *	SEGA Dreamcast machine vector
  */
 
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/time.h>
 
 #include <asm/machvec.h>
 #include <asm/machvec_init.h>
@@ -16,6 +17,10 @@
 void __init setup_dreamcast(void);
 void __init dreamcast_pcibios_init(void);
 
+/* Custom Dreamcast RTC routines */
+void aica_rtc_gettimeofday(struct timeval *tv);
+int aica_rtc_settimeofday(const struct timeval *tv);
+
 /*
  * The Machine Vector
  */
@@ -59,6 +64,9 @@
 	mv_init_arch:		setup_dreamcast,
 	mv_isa_port2addr:	dreamcast_isa_port2addr,
 	mv_irq_demux:		systemasic_irq_demux,
+
+	mv_rtc_gettimeofday:	aica_rtc_gettimeofday,
+	mv_rtc_settimeofday:	aica_rtc_settimeofday,
 
 	mv_hw_dreamcast:	1,
 };
diff -urN linux-2.4.10-pre5/arch/sh/kernel/mach_hp600.c linux/arch/sh/kernel/mach_hp600.c
--- linux-2.4.10-pre5/arch/sh/kernel/mach_hp600.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/mach_hp600.c	Mon Dec  3 23:08:12 2001
@@ -15,8 +15,8 @@
 #include <asm/rtc.h>
 #include <asm/machvec_init.h>
 
-#include <asm/io_hd64461.h>
-#include <asm/io_generic.h>
+#include <asm/io.h>
+#include <asm/hd64461.h>
 #include <asm/irq.h>
 
 /*
@@ -26,7 +26,7 @@
 struct sh_machine_vector mv_hp620 __initmv = {
 	mv_name:		"hp620",
 
-	mv_nr_irqs:		80, /* HD64461_IRQBASE+16, see hd64461.h */
+	mv_nr_irqs:		HD64461_IRQBASE+HD64461_IRQ_NUM,
 
 	mv_inb:			hd64461_inb,
 	mv_inw:			hd64461_inw,
@@ -71,7 +71,7 @@
 struct sh_machine_vector mv_hp680 __initmv = {
 	mv_name:		"hp680",
 
-	mv_nr_irqs:		80, /* HD64461_IRQBASE+16, see hd64461.h */
+	mv_nr_irqs:		HD64461_IRQBASE+HD64461_IRQ_NUM,
 
 	mv_inb:			hd64461_inb,
 	mv_inw:			hd64461_inw,
@@ -116,7 +116,7 @@
 struct sh_machine_vector mv_hp690 __initmv = {
 	mv_name:		"hp690",
 
-	mv_nr_irqs:		80, /* HD64461_IRQBASE+16, see hd64461.h */
+	mv_nr_irqs:		HD64461_IRQBASE+HD64461_IRQ_NUM,
 
 	mv_inb:			hd64461_inb,
 	mv_inw:			hd64461_inw,
diff -urN linux-2.4.10-pre5/arch/sh/kernel/pci-7751se.c linux/arch/sh/kernel/pci-7751se.c
--- linux-2.4.10-pre5/arch/sh/kernel/pci-7751se.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/pci-7751se.c	Mon Dec  3 23:08:12 2001
@@ -41,13 +41,13 @@
    unsigned long bcr1, wcr1, wcr2, wcr3, mcr;
    unsigned short bcr2;
 
-   //
-   // Initialize the slave bus controller on the pcic.  The values used
-   // here should not be hardcoded, but they should be taken from the bsc
-   // on the processor, to make this function as generic as possible.
-   // (i.e. Another sbc may usr different SDRAM timing settings -- in order
-   // for the pcic to work, its settings need to be exactly the same.)
-   //
+   /*
+    * Initialize the slave bus controller on the pcic.  The values used
+    * here should not be hardcoded, but they should be taken from the bsc
+    * on the processor, to make this function as generic as possible.
+    * (i.e. Another sbc may usr different SDRAM timing settings -- in order
+    * for the pcic to work, its settings need to be exactly the same.)
+    */
    bcr1 = (*(volatile unsigned long*)(SH7751_BCR1));
    bcr2 = (*(volatile unsigned short*)(SH7751_BCR2));
    wcr1 = (*(volatile unsigned long*)(SH7751_WCR1));
@@ -67,21 +67,47 @@
    mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
    PCIC_WRITE(SH7751_PCIMCR, mcr);      /* PCIC MCR */
 
+
+   /* Enable all interrupts, so we know what to fix */
    PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff);
-   PCIC_WRITE(SH7751_PCIAINTM, 0x0000980f);
-   PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7);  /* FB9000C7 */
-   PCIC_WRITE(SH7751_PCICONF2, 0x00000000);  /* PCI Class code & Revision ID */
-   PCIC_WRITE(SH7751_PCICONF4, 0xab000001);  /* PCI I/O */
-   PCIC_WRITE(SH7751_PCICONF5, 0x0c000000);  /* PCI MEM0 old val: 0xb0000000 */
-   PCIC_WRITE(SH7751_PCICONF6, 0xd0000000);  /* PCI MEM1 */
-   PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Sub system ID & Sub system vendor ID */
-   PCIC_WRITE(SH7751_PCILSR0, 0x03f00000);   /* PCI MEM0 */
-   PCIC_WRITE(SH7751_PCILSR1, 0x00000000);   /* PCI MEM1 */
-   PCIC_WRITE(SH7751_PCILAR0, 0x0c000000);   /* MEM0 */
-   PCIC_WRITE(SH7751_PCILAR1, 0x00000000);   /* MEM1 */
+   PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f);
+
+   /* Set up standard PCI config registers */
+   PCIC_WRITE(SH7751_PCICONF1, 	0xF39000C7); /* Bus Master, Mem & I/O access */
+   PCIC_WRITE(SH7751_PCICONF2, 	0x00000000); /* PCI Class code & Revision ID */
+   PCIC_WRITE(SH7751_PCICONF4, 	0xab000001); /* PCI I/O address (local regs) */
+   PCIC_WRITE(SH7751_PCICONF5, 	0x0c000000); /* PCI MEM address (local RAM)  */
+   PCIC_WRITE(SH7751_PCICONF6, 	0xd0000000); /* PCI MEM address (unused)     */
+   PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */
+   PCIC_WRITE(SH7751_PCILSR0, 0x03f00000);   /* MEM (full 64M exposed)       */
+   PCIC_WRITE(SH7751_PCILSR1, 0x00000000);   /* MEM (unused)                 */
+   PCIC_WRITE(SH7751_PCILAR0, 0x0c000000);   /* MEM (direct map from PCI)    */
+   PCIC_WRITE(SH7751_PCILAR1, 0x00000000);   /* MEM (unused)                 */
 
+   /* Now turn it on... */
    PCIC_WRITE(SH7751_PCICR, 0xa5000001);
 
+   /*
+    * Set PCIMBR and PCIIOBR here, assuming a single window
+    * (16M MEM, 256K IO) is enough.  If a larger space is
+    * needed, the readx/writex and inx/outx functions will
+    * have to do more (e.g. setting registers for each call).
+    */
+
+   /*
+    * Set the MBR so PCI address is one-to-one with window,
+    * meaning all calls go straight through... use ifdef to
+    * catch erroneous assumption.
+    */
+#if PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE
+#error One-to-one assumption for PCI memory mapping is wrong!?!?!?
+#endif   
+   PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM);
+
+   /* Set IOBR for window containing area specified in pci.h */
+   PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK));
+
+   /* All done, may as well say so... */
    printk("SH7751 PCI: Finished initialization of the PCI controller\n");
 
    return 1;
diff -urN linux-2.4.10-pre5/arch/sh/kernel/pci-dc.c linux/arch/sh/kernel/pci-dc.c
--- linux-2.4.10-pre5/arch/sh/kernel/pci-dc.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/pci-dc.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- $	$Id: pci-dc.c,v 1.2 2001/05/24 05:09:16 mrbrown Exp $
+ $	$Id: pci-dc.c,v 1.5 2001/08/24 12:38:19 dwmw2 Exp $
  *	Dreamcast PCI: Supports SEGA Broadband Adaptor only.
  */
 
@@ -104,62 +104,6 @@
 };
 
 
-void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
-{
-}
-
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-}
-
-
-void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			     struct resource *res, int resource)
-{
-}
-
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	/* No special bus mastering setup handling */
-}
-
-
-int pcibios_enable_device(struct pci_dev *dev)
-{
-
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for (idx = 0; idx < 6; idx++) {
-		r = dev->resource + idx;
-		if (!r->start && r->end) {
-			printk(KERN_ERR
-			       "PCI: Device %s not available because"
-			       " of resource collisions\n",
-			       dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (cmd != old_cmd) {
-		printk("PCI: enabling device %s (%04x -> %04x)\n",
-		       dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-
-}
-
-
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 			   dma_addr_t * dma_handle)
 {
@@ -172,7 +116,7 @@
 
 	gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
 	
-	printk("pci_alloc_consistent: %ld bytes at 0x%p\n", size, buf);
+	printk("pci_alloc_consistent: %ld bytes at 0x%lx\n", (long)size, buf);
 
 	*dma_handle = (dma_addr_t)buf;
 
@@ -184,6 +128,7 @@
 			 void *vaddr, dma_addr_t dma_handle)
 {
 	/* XXX */
+	gapspci_dma_used = 0;
 }
 
 
diff -urN linux-2.4.10-pre5/arch/sh/kernel/pci-dma.c linux/arch/sh/kernel/pci-dma.c
--- linux-2.4.10-pre5/arch/sh/kernel/pci-dma.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/pci-dma.c	Mon Dec  3 23:08:12 2001
@@ -29,7 +29,7 @@
 		*dma_handle = virt_to_bus(ret);
 	}
 	/* We must flush the cache before we pass it on to the device */
-	flush_cache_all();
+	dma_cache_wback_inv(ret, size);
 	return  P2SEGADDR(ret);
 }
 
diff -urN linux-2.4.10-pre5/arch/sh/kernel/pci-sh7751.c linux/arch/sh/kernel/pci-sh7751.c
--- linux-2.4.10-pre5/arch/sh/kernel/pci-sh7751.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/pci-sh7751.c	Mon Dec  3 23:08:12 2001
@@ -20,7 +20,6 @@
 #include <linux/errno.h>
 #include <linux/irq.h>
 
-#include <asm/segment.h>
 #include <asm/machvec.h>
 #include <asm/io.h>
 #include <asm/pci-sh7751.h>
@@ -57,10 +56,10 @@
     /* PCIPDR may only be accessed as 32 bit words, 
      * so we must do byte alignment by hand 
      */
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	word = inl(PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	switch (where & 0x3) {
 	    case 3:
 		    *value = (u8)(word >> 24);
@@ -88,10 +87,10 @@
     /* PCIPDR may only be accessed as 32 bit words, 
      * so we must do word alignment by hand 
      */
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	word = inl(PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	switch (where & 0x3) {
 	    case 3:
 		    // This should never happen...
@@ -116,10 +115,10 @@
 {
 	unsigned long flags;
 	
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	*value = inl(PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	PCIDBG(4,"pci_conf1_read_config_dword@0x%08x=0x%x\n",
 	     CONFIG_CMD(dev,where),*value);
 	return PCIBIOS_SUCCESSFUL;    
@@ -135,14 +134,14 @@
     /* Since SH7751 only does 32bit access we'll have to do a
      * read,mask,write operation
      */ 
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	word = inl(PCI_REG(SH7751_PCIPDR)) ;
 	word &= ~mask;
 	word |= value << shift;
  
 	outl(word, PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	PCIDBG(4,"pci_conf1_write_config_byte@0x%08x=0x%x\n",
 	     CONFIG_CMD(dev,where),word);
 	return PCIBIOS_SUCCESSFUL;
@@ -161,14 +160,14 @@
      */ 
 	if (shift == 24)
 	    return PCIBIOS_BAD_REGISTER_NUMBER;
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	word = inl(PCI_REG(SH7751_PCIPDR)) ;
 	word &= ~mask;
 	word |= value << shift;
  
 	outl(value, PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	PCIDBG(4,"pci_conf1_write_config_word@0x%08x=0x%x\n",
 	     CONFIG_CMD(dev,where),word);
 	return PCIBIOS_SUCCESSFUL;
@@ -178,10 +177,10 @@
 {
 	unsigned long flags;
 
-	__save_and_cli(flags);
+	save_and_cli(flags);
 	outl(CONFIG_CMD(dev,where), PCI_REG(SH7751_PCIPAR));
 	outl(value, PCI_REG(SH7751_PCIPDR));
-	__restore_flags(flags);
+	restore_flags(flags);
 	PCIDBG(4,"pci_conf1_write_config_dword@0x%08x=0x%x\n",
 	     CONFIG_CMD(dev,where),value);
 	return PCIBIOS_SUCCESSFUL;
@@ -233,7 +232,7 @@
  * BIOS32 and PCI BIOS handling.
  * 
  * The BIOS version of the pci functions is not yet implemented but it is left
- * in for completeness.  Currently an error will be genereated at compile time. 
+ * in for completeness.  Currently an error will be generated at compile time. 
  */
  
 #ifdef CONFIG_PCI_BIOS
@@ -417,54 +416,6 @@
 	return str;
 }
 
-void
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			struct resource *res, int resource)
-{
-	u32 new, check;
-	int reg;
-
-	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
-	if (resource < 6) {
-		reg = PCI_BASE_ADDRESS_0 + 4*resource;
-	} else if (resource == PCI_ROM_RESOURCE) {
-		res->flags |= PCI_ROM_ADDRESS_ENABLE;
-		new |= PCI_ROM_ADDRESS_ENABLE;
-		reg = dev->rom_base_reg;
-	} else {
-		/* Somebody might have asked allocation of a non-standard resource */
-		return;
-	}
-	
-	pci_write_config_dword(dev, reg, new);
-	pci_read_config_dword(dev, reg, &check);
-	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
-		printk(KERN_ERR "PCI: Error while updating region "
-		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
-		       new, check);
-	}
-}
-
-/*
- * We need to avoid collisions with `mirrored' VGA ports
- * and other strange ISA hardware, so we always want the
- * addresses to be allocated in the 0x000-0x0ff region
- * modulo 0x400.
- */
-void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
-{
-	if (res->flags & IORESOURCE_IO) {
-		unsigned long start = res->start;
-
-		if (start & 0x300) {
-			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
-	}
-}
-
-
 /*
  *    Allocate the bridge and device resources
  */
@@ -593,53 +544,6 @@
 	pcibios_assign_resources();
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
-{
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for(idx=0; idx<6; idx++) {
-		r = &dev->resource[idx];
-		if (!r->start && r->end) {
-			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (dev->resource[PCI_ROM_RESOURCE].start)
-		cmd |= PCI_COMMAND_MEMORY;
-	if (cmd != old_cmd) {
-		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-}
-
-/*
- *  If we set up a device for bus mastering, we need to check and set
- *  the latency timer as it may not be properly set.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
 
 /***************************************************************************************/
 /* 
@@ -665,10 +569,4 @@
 	PCIDBG(2,"Setting IRQ for slot %s to %d\n", dev->slot_name, irq);
 
 	return irq;
-}
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-	PCIDBG(3,"PCI: Update IRQ for %s on irq %d\n", dev->name, irq);
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 }
diff -urN linux-2.4.10-pre5/arch/sh/kernel/pci_st40.c linux/arch/sh/kernel/pci_st40.c
--- linux-2.4.10-pre5/arch/sh/kernel/pci_st40.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/pci_st40.c	Mon Dec  3 23:08:12 2001
@@ -458,91 +458,6 @@
 
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
-{
-
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for (idx = 0; idx < 6; idx++) {
-		r = dev->resource + idx;
-		if (!r->start && r->end) {
-			printk(KERN_ERR
-			       "PCI: Device %s not available because"
-			       " of resource collisions\n",
-			       dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (cmd != old_cmd) {
-		printk("PCI: enabling device %s (%04x -> %04x)\n",
-		       dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-
-}
-
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
-}
-
-void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
-{
-}
-
-void __init pcibios_update_resource(struct pci_dev *dev,
-				    struct resource *root,
-				    struct resource *res, int resource)
-{
-
-	unsigned long where, size;
-	u32 reg;
-
-	printk("PCI: Assigning %3s %08lx to %s\n",
-	       res->flags & IORESOURCE_IO ? "IO" : "MEM",
-	       res->start, dev->name);
-
-	where = PCI_BASE_ADDRESS_0 + resource * 4;
-	size = res->end - res->start;
-
-	pci_read_config_dword(dev, where, &reg);
-	reg = (reg & size) | (((u32) (res->start - root->start)) & ~size);
-	pci_write_config_dword(dev, where, reg);
-
-}
-
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-	printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
diff -urN linux-2.4.10-pre5/arch/sh/kernel/pcibios.c linux/arch/sh/kernel/pcibios.c
--- linux-2.4.10-pre5/arch/sh/kernel/pcibios.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/pcibios.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,126 @@
+/*
+ * $Id: pcibios.c,v 1.1 2001/08/24 12:38:19 dwmw2 Exp $
+ *
+ * arch/sh/kernel/pcibios.c
+ *
+ * This is GPL'd.
+ *
+ * Provided here are generic versions of:
+ *	pcibios_update_resource()
+ *	pcibios_align_resource()
+ *	pcibios_enable_device()
+ *	pcibios_set_master()
+ *	pcibios_update_irq()
+ *
+ * These functions are collected here to reduce duplication of common
+ * code amongst the many platform-specific PCI support code files.
+ *
+ * Platform-specific files are expected to provide:
+ *	pcibios_fixup_bus()
+ *	pcibios_init()
+ *	pcibios_setup()
+ *	pcibios_fixup_pbus_ranges()
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ */
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check and set
+ *  the latency timer as it may not be properly set.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
diff -urN linux-2.4.10-pre5/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
--- linux-2.4.10-pre5/arch/sh/kernel/process.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/process.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.33 2000/03/25 00:06:15 gniibe Exp $
+/* $Id: process.c,v 1.34 2001/07/30 12:42:11 gniibe Exp $
  *
  *  linux/arch/sh/kernel/process.c
  *
@@ -11,40 +11,13 @@
  * This file handles the architecture-dependent parts of process handling..
  */
 
-#define __KERNEL_SYSCALLS__
-#include <stdarg.h>
-
-#include <linux/config.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/stddef.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
 #include <linux/unistd.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/slab.h>
 
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
 #include <asm/io.h>
-#include <asm/processor.h>
+#include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/elf.h>
-#ifdef CONFIG_SH_STANDARD_BIOS
-#include <asm/sh_bios.h>
-#endif
 
 static int hlt_counter=0;
 
@@ -71,11 +44,17 @@
 	current->counter = -100;
 
 	while (1) {
-		while (!current->need_resched) {
-			if (hlt_counter)
-				continue;
+		if (hlt_counter) {
+			if (current->need_resched)
+				break;
+		} else {
+			__cli();
+			while (!current->need_resched) {
+				__sti();
+				asm volatile("sleep" : : : "memory");
+				__cli();
+			}
 			__sti();
-			asm volatile("sleep" : : : "memory");
 		}
 		schedule();
 		check_pgt_cache();
@@ -84,16 +63,15 @@
 
 void machine_restart(char * __unused)
 {
-#ifdef CONFIG_SH_STANDARD_BIOS
-	sh_bios_shutdown(1);
-#endif
+	/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
+	asm volatile("ldc %0, sr\n\t"
+		     "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
 }
 
 void machine_halt(void)
 {
-#ifdef CONFIG_SH_STANDARD_BIOS
-	sh_bios_shutdown(0);
-#endif
+	while (1)
+		asm volatile("sleep" : : : "memory");
 }
 
 void machine_power_off(void)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/ptrace.c linux/arch/sh/kernel/ptrace.c
--- linux-2.4.10-pre5/arch/sh/kernel/ptrace.c	Fri Jul 20 12:39:55 2001
+++ linux/arch/sh/kernel/ptrace.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: ptrace.c,v 1.6 2000/06/08 23:44:50 gniibe Exp $
+/* $Id: ptrace.c,v 1.12 2001/07/23 00:00:56 gniibe Exp $
  *
  * linux/arch/sh/kernel/ptrace.c
  *
@@ -122,24 +122,29 @@
 {
 	ctrl_outl(nextpc1, UBC_BARA);
 	ctrl_outb(asid, UBC_BASRA);
-#if defined(CONFIG_CPU_SUBTYPE_SH7709)
-	ctrl_outl(0x0fff, UBC_BAMRA);
-#else
-	ctrl_outb(BAMR_12, UBC_BAMRA);
-#endif
-	ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
+	if(UBC_TYPE_SH7729){
+		ctrl_outl(0x0fff, UBC_BAMRA);
+		ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
+	}else{
+		ctrl_outb(BAMR_12, UBC_BAMRA);
+		ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
+	}
 
 	if (nextpc2 != (unsigned long) -1) {
 		ctrl_outl(nextpc2, UBC_BARB);
 		ctrl_outb(asid, UBC_BASRB);
-#if defined(CONFIG_CPU_SUBTYPE_SH7709)
-		ctrl_outl(0x0fff, UBC_BAMRA);
-#else
-		ctrl_outb(BAMR_12, UBC_BAMRB);
-#endif
-		ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB);
-	}
-	ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR);
+		if(UBC_TYPE_SH7729){
+			ctrl_outl(0x0fff, UBC_BAMRB);
+			ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRB);
+		}else{
+			ctrl_outb(BAMR_12, UBC_BAMRB);
+			ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB);
+		}
+	}
+	if(UBC_TYPE_SH7729)
+		ctrl_outl(BRCR_PCBA | BRCR_PCBB | BRCR_PCTE, UBC_BRCR);
+	else
+		ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR);
 }
 
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/rtc-aica.c linux/arch/sh/kernel/rtc-aica.c
--- linux-2.4.10-pre5/arch/sh/kernel/rtc-aica.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/rtc-aica.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,70 @@
+/* arch/sh/kernel/rtc-aica.c
+ *
+ * Dreamcast AICA RTC routines.
+ *
+ * Copyright (c) 2001 M. R. Brown <mrbrown@0xd6.org>
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ *
+ */
+
+#include <linux/time.h>
+
+#include <asm/io.h>
+
+/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
+   seconds to get the standard Unix Epoch when getting the time, and add 20
+   years when setting the time. */
+#define TWENTY_YEARS ((20 * 365LU + 5) * 86400)
+
+/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit
+   registers.*/
+#define AICA_RTC_SECS_H		0xa0710000
+#define AICA_RTC_SECS_L		0xa0710004
+
+/**
+ * aica_rtc_gettimeofday - Get the time from the AICA RTC
+ * @tv: pointer to resulting timeval
+ *
+ * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
+ */
+void aica_rtc_gettimeofday(struct timeval *tv) {
+	unsigned long val1, val2;
+
+	do {
+		val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+
+		val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+	} while (val1 != val2);
+
+	tv->tv_sec = val1 - TWENTY_YEARS;
+
+	/* Can't get microseconds with just a seconds counter. */
+	tv->tv_usec = 0;
+}
+
+/**
+ * aica_rtc_settimeofday - Set the AICA RTC to the current time
+ * @tv: contains the timeval to set
+ *
+ * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
+ */
+int aica_rtc_settimeofday(const struct timeval *tv) {
+	unsigned long val1, val2;
+	unsigned long secs = tv->tv_sec + TWENTY_YEARS;
+
+	do {
+		ctrl_outl((secs & 0xffff0000) >> 16, AICA_RTC_SECS_H);
+		ctrl_outl((secs & 0xffff), AICA_RTC_SECS_L);
+
+		val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+
+		val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) |
+			(ctrl_inl(AICA_RTC_SECS_L) & 0xffff);
+	} while (val1 != val2);
+
+	return 0;
+}
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup.c linux/arch/sh/kernel/setup.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/setup.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.20 2000/03/05 02:44:41 gniibe Exp $
+/* $Id: setup.c,v 1.31 2001/08/23 16:36:40 dwmw2 Exp $
  *
  *  linux/arch/sh/kernel/setup.c
  *
@@ -38,7 +38,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/io_generic.h>
-#include <asm/smp.h>
 #include <asm/machvec.h>
 #ifdef CONFIG_SH_EARLY_PRINTK
 #include <asm/sh_bios.h>
@@ -48,7 +47,12 @@
  * Machine setup..
  */
 
-struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 0, 0, };
+/*
+ * Initialize loops_per_jiffy as 10000000 (1000MIPS).
+ * This value will be used at the very early stage of serial setup.
+ * The bigger value means no problem.
+ */
+struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 0, 10000000, };
 struct screen_info screen_info;
 unsigned char aux_device_present = 0xaa;
 
@@ -209,8 +213,7 @@
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 
 	memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
-	/* Default is 4Mbyte. */
-	memory_end = (unsigned long)PAGE_OFFSET+0x00400000+__MEMORY_START;
+	memory_end = memory_start + __MEMORY_SIZE;
 
 	for (;;) {
 		/*
@@ -268,7 +271,9 @@
 
 void __init setup_arch(char **cmdline_p)
 {
+#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_UNKNOWN)
 	extern struct sh_machine_vector mv_unknown;
+#endif
 	struct sh_machine_vector *mv = NULL;
 	char mv_name[MV_NAME_SIZE] = "";
 	unsigned long mv_io_base = 0;
@@ -356,6 +361,18 @@
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
 
+#ifdef CONFIG_DISCONTIGMEM
+	NODE_DATA(0)->bdata = &discontig_node_bdata[0];
+	NODE_DATA(1)->bdata = &discontig_node_bdata[1];
+
+	bootmap_size = init_bootmem_node(NODE_DATA(1), 
+					 PFN_UP(__MEMORY_START_2ND),
+					 PFN_UP(__MEMORY_START_2ND),
+					 PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
+	free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
+	reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
+#endif
+
 	/*
 	 * Find the highest page frame number we have available
 	 */
@@ -377,7 +394,7 @@
 	 * is intact) must be done via bootmem_alloc().
 	 */
 	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
-					 __MEMORY_START>>PAGE_SHIFT, 
+					 __MEMORY_START>>PAGE_SHIFT,
 					 max_low_pfn);
 
 	/*
@@ -399,7 +416,8 @@
 			last_pfn = max_low_pfn;
 
 		pages = last_pfn - curr_pfn;
-		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
+		free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
+				  PFN_PHYS(pages));
 	}
 
 	/*
@@ -409,19 +427,19 @@
 	 * case of us accidentally initializing the bootmem allocator with
 	 * an invalid RAM area.
 	 */
-	reserve_bootmem(__MEMORY_START+PAGE_SIZE, (PFN_PHYS(start_pfn) + 
-			bootmap_size + PAGE_SIZE-1) - __MEMORY_START);
+	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE,
+		(PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
 
 	/*
 	 * reserve physical page 0 - it's a special BIOS page on many boxes,
 	 * enabling clean reboots, SMP operation, laptop functions.
 	 */
-	reserve_bootmem(__MEMORY_START, PAGE_SIZE);
+	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (LOADER_TYPE && INITRD_START) {
 		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
-			reserve_bootmem(INITRD_START+__MEMORY_START, INITRD_SIZE);
+			reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
 			initrd_start =
 				INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
 			initrd_end = initrd_start + INITRD_SIZE;
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup_7751se.c linux/arch/sh/kernel/setup_7751se.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup_7751se.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/setup_7751se.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,136 @@
+/* 
+ * linux/arch/sh/kernel/setup_7751se.c
+ *
+ * Copyright (C) 2000  Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ * Modified for 7751 Solution Engine by
+ * Ian da Silva and Jeremy Siegel, 2001.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <asm/io.h>
+#include <asm/hitachi_7751se.h>
+
+/*
+ * Configure the Super I/O chip
+ */
+#if 0
+/* Leftover code from regular Solution Engine, for reference. */
+/* The SH7751 Solution Engine has a different SuperIO. */
+static void __init smsc_config(int index, int data)
+{
+	outb_p(index, INDEX_PORT);
+	outb_p(data, DATA_PORT);
+}
+
+static void __init init_smsc(void)
+{
+	outb_p(CONFIG_ENTER, CONFIG_PORT);
+	outb_p(CONFIG_ENTER, CONFIG_PORT);
+
+	/* FDC */
+	smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
+
+	/* IDE1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
+
+	/* AUXIO (GPIO): to use IDE1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
+	smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
+	smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
+
+	/* COM1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IO_BASE_HI_INDEX, 0x03);
+	smsc_config(IO_BASE_LO_INDEX, 0xf8);
+	smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
+
+	/* COM2 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IO_BASE_HI_INDEX, 0x02);
+	smsc_config(IO_BASE_LO_INDEX, 0xf8);
+	smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
+
+	/* RTC */
+	smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
+
+	/* XXX: PARPORT, KBD, and MOUSE will come here... */
+	outb_p(CONFIG_EXIT, CONFIG_PORT);
+}
+#endif
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_7751se_IRQ(void)
+{
+
+  /* Leave old Solution Engine code in for reference. */
+#if defined(CONFIG_SH_SOLUTION_ENGINE)
+	/*
+	 * Super I/O (Just mimic PC):
+	 *  1: keyboard
+	 *  3: serial 0
+	 *  4: serial 1
+	 *  5: printer
+	 *  6: floppy
+	 *  8: rtc
+	 * 12: mouse
+	 * 14: ide0
+	 */
+	make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
+	make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); 
+	make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); 
+	make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
+	make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
+	make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
+	make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
+	make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
+
+	make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
+
+	make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
+	make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
+	make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
+	make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
+
+	/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+	/* NOTE: #2 and #13 are not used on PC */
+	make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
+	make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
+
+#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
+
+	make_ipr_irq(13, BCR_ILCRD, 3, 2);
+
+	/* Add additional calls to make_ipr_irq() as drivers are added
+	 * and tested.
+	 */
+#endif
+
+}
+
+
+/*
+ * Initialize the board
+ */
+void __init setup_7751se(void)
+{
+	/* Call init_smsc() replacement to set up SuperIO. */
+	/* XXX: RTC setting comes here */
+}
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup_adx.c linux/arch/sh/kernel/setup_adx.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup_adx.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/kernel/setup_adx.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,40 @@
+/* 
+ * linux/arch/sh/kernel/setup_adx.c
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * I/O routine and setup routines for A&D ADX Board
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/machvec.h>
+#include <asm/irq.h>
+#include <linux/module.h>
+
+void setup_adx(void)
+{
+	/* nothing to do just yet */
+/*	printk("setup_adx()\n");*/
+}
+
+void init_adx_IRQ(void)
+{
+	int i;
+
+/*	printk("init_adx_IRQ()\n");*/
+	/* setup irq_mask_register */
+	irq_mask_register = (unsigned short *)0xa6000008;
+
+	/* cover all external interrupt area by maskreg_irq_type
+	 * (Actually, irq15 doesn't exist)
+	 */
+	for (i = 0; i < 16; i++) {
+		make_maskreg_irq(i);
+		disable_irq(i);
+	}
+}
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup_bigsur.c linux/arch/sh/kernel/setup_bigsur.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup_bigsur.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/setup_bigsur.c	Mon Dec  3 23:08:12 2001
@@ -181,10 +181,12 @@
 static void end_bigsur_irq(unsigned int irq)
 {
    	DPRINTK("end_bigsur_irq IRQ %d\n", irq);
-	if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)	
-		enable_bigsur_l1irq(irq);
-	else
-		enable_bigsur_l2irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+		if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)	
+			enable_bigsur_l1irq(irq);
+		else
+			enable_bigsur_l2irq(irq);
+	}
 }
 
 static unsigned int startup_bigsur_irq(unsigned int irq)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup_cqreek.c linux/arch/sh/kernel/setup_cqreek.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup_cqreek.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/setup_cqreek.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: setup_cqreek.c,v 1.6 2001/02/14 09:36:42 gniibe Exp $
+/* $Id: setup_cqreek.c,v 1.9 2001/07/30 12:43:28 gniibe Exp $
  *
  * arch/sh/kernel/setup_cqreek.c
  *
@@ -85,15 +85,16 @@
 	unsigned short stat_port = cqreek_irq_data[irq].stat_port;
 	unsigned short bit = cqreek_irq_data[irq].bit;
 
-	inw(stat_port);
 	disable_cqreek_irq(irq);
 	/* Clear IRQ (it might be edge IRQ) */
+	inw(stat_port);
 	outw_p(bit, stat_port);
 }
 
 static void end_cqreek_irq(unsigned int irq)
 {
-	enable_cqreek_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_cqreek_irq(irq);
 }
 
 static unsigned int startup_cqreek_irq(unsigned int irq)
@@ -156,16 +157,9 @@
  */
 void __init setup_cqreek(void)
 {
-	extern void disable_hlt(void);
 	int i;
 /* udelay is not available at setup time yet... */
 #define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
-
-	/*
-	 * XXX: I don't know the reason, but it becomes so fragile with
-	 * "sleep", so we need to stop sleeping.
-	 */
-	disable_hlt();
 
 	if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
 		outw_p(0, BRIDGE_IDE_INTR_LVL);
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup_dc.c linux/arch/sh/kernel/setup_dc.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup_dc.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/setup_dc.c	Mon Dec  3 23:08:12 2001
@@ -8,8 +8,8 @@
  *
  * Released under the terms of the GNU GPL v2.0.
  * 
- * This file originally bore the message:
- *	$Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp $
+ * This file originally bore the message (with enclosed-$):
+ *	Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
  *	SEGA Dreamcast support
  */
 
@@ -70,21 +70,29 @@
 /* Disable the hardware event by masking its bit in its EMR */
 static inline void disable_systemasic_irq(unsigned int irq)
 {
+	unsigned long flags;
 	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
 	__u32 mask;
+
+	save_and_cli(flags);
 	mask = inl(emr);
 	mask &= ~(1 << EVENT_BIT(irq));
 	outl(mask, emr);
+	restore_flags(flags);
 }
 
 /* Enable the hardware event by setting its bit in its EMR */
 static inline void enable_systemasic_irq(unsigned int irq)
 {
+	unsigned long flags;
 	__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
 	__u32 mask;
+
+	save_and_cli(flags);
 	mask = inl(emr);
 	mask |= (1 << EVENT_BIT(irq));
 	outl(mask, emr);
+	restore_flags(flags);
 }
 
 /* Acknowledge a hardware event by writing its bit back to its ESR */
@@ -98,7 +106,8 @@
 /* After a IRQ has been ack'd and responded to, it needs to be renabled */
 static void end_systemasic_irq(unsigned int irq)
 {
-	enable_systemasic_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_systemasic_irq(irq);
 }
 
 static unsigned int startup_systemasic_irq(unsigned int irq)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup_ec3104.c linux/arch/sh/kernel/setup_ec3104.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup_ec3104.c	Sun May 20 12:11:38 2001
+++ linux/arch/sh/kernel/setup_ec3104.c	Mon Dec  3 23:08:12 2001
@@ -167,7 +167,8 @@
 
 static void end_ec3104_irq(unsigned int irq)
 {
-	unmask_ec3104_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_ec3104_irq(irq);
 }
 
 static unsigned int startup_ec3104_irq(unsigned int irq)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup_hd64461.c linux/arch/sh/kernel/setup_hd64461.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup_hd64461.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/setup_hd64461.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- *	$Id: setup_hd64461.c,v 1.1 2000/06/10 21:45:18 yaegashi Exp $
+ *	$Id: setup_hd64461.c,v 1.9 2001/07/15 23:26:56 gniibe Exp $
  *	Copyright (C) 2000 YAEGASHI Takeshi
  *	Hitachi HD64461 companion chip support
  */
@@ -57,7 +57,8 @@
 
 static void end_hd64461_irq(unsigned int irq)
 {
-	enable_hd64461_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_hd64461_irq(irq);
 }
 
 
diff -urN linux-2.4.10-pre5/arch/sh/kernel/setup_hd64465.c linux/arch/sh/kernel/setup_hd64465.c
--- linux-2.4.10-pre5/arch/sh/kernel/setup_hd64465.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/setup_hd64465.c	Mon Dec  3 23:08:12 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: setup_hd64465.c,v 1.3 2001/02/07 17:52:53 stuart_menefy Exp $
+ * $Id: setup_hd64465.c,v 1.4 2001/07/15 23:26:56 gniibe Exp $
  *
  * Setup and IRQ handling code for the HD64465 companion chip.
  * by Greg Banks <gbanks@pocketpenguins.com>
@@ -70,7 +70,8 @@
 
 static void end_hd64465_irq(unsigned int irq)
 {
-	enable_hd64465_irq(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_hd64465_irq(irq);
 }
 
 
diff -urN linux-2.4.10-pre5/arch/sh/kernel/sh_ksyms.c linux/arch/sh/kernel/sh_ksyms.c
--- linux-2.4.10-pre5/arch/sh/kernel/sh_ksyms.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/sh_ksyms.c	Mon Dec  3 23:08:12 2001
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
+#include <linux/pci.h>
 
 #include <asm/semaphore.h>
 #include <asm/processor.h>
@@ -18,7 +19,6 @@
 #include <asm/hardirq.h>
 #include <asm/delay.h>
 #include <asm/pgalloc.h>
-#include <asm/pci.h>
 #include <linux/irq.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
diff -urN linux-2.4.10-pre5/arch/sh/kernel/sys_sh.c linux/arch/sh/kernel/sys_sh.c
--- linux-2.4.10-pre5/arch/sh/kernel/sys_sh.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/sh/kernel/sys_sh.c	Mon Dec  3 23:08:12 2001
@@ -43,6 +43,45 @@
 	return error;
 }
 
+#if defined(__SH4__)
+/*
+ * To avoid cache alias, we map the shard page with same color.
+ */
+#define COLOUR_ALIGN(addr)	(((addr)+SHMLBA-1)&~(SHMLBA-1))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct *vma;
+
+	if (flags & MAP_FIXED) {
+		/* We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+	if (!addr)
+		addr = TASK_UNMAPPED_BASE;
+
+	addr = COLOUR_ALIGN(addr);
+
+	for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vma || addr + len <= vma->vm_start)
+			return addr;
+		addr = vma->vm_end;
+		addr = COLOUR_ALIGN(addr);
+	}
+}
+#endif
+
 static inline long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 
 	 unsigned long flags, int fd, unsigned long pgoff)
diff -urN linux-2.4.10-pre5/arch/sh/kernel/time.c linux/arch/sh/kernel/time.c
--- linux-2.4.10-pre5/arch/sh/kernel/time.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/kernel/time.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.20 2000/02/28 12:42:51 gniibe Exp $
+/* $Id: time.c,v 1.30 2001/09/01 14:34:31 mrbrown Exp $
  *
  *  linux/arch/sh/kernel/time.c
  *
@@ -183,10 +183,9 @@
 static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	do_timer(regs);
-#if 0
+
 	if (!user_mode(regs))
 		sh_do_profile(regs->pc);
-#endif
 
 #ifdef CONFIG_HEARTBEAT
 	if (sh_mv.mv_heartbeat != NULL) 
@@ -360,17 +359,11 @@
 #endif
 #endif
 
-	if (MACH_DREAMCAST)
-		xtime.tv_sec = xtime.tv_usec = 0;
-	else
-		rtc_gettimeofday(&xtime);
+	rtc_gettimeofday(&xtime);
 
 	setup_irq(TIMER_IRQ, &irq0);
 
-	if (MACH_DREAMCAST)
-		timer_freq = 50*1000*1000/4;
-	else
-		timer_freq = get_timer_frequency();
+	timer_freq = get_timer_frequency();
 
 	module_clock = timer_freq * 4;
 
@@ -391,10 +384,9 @@
 	}
 #elif defined(__SH4__)
 	{
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
 		unsigned long pvr;
-		frqcr = ctrl_inw(FRQCR);
 
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
 		/* This should probably be moved into the SH3 probing code, and then use the processor
 		 * structure to determine which CPU we are running on.
 		 */
@@ -435,6 +427,8 @@
 		} else
 #endif
 		{
+			frqcr = ctrl_inw(FRQCR);
+
 			ifc  = ifc_table[(frqcr>> 6) & 0x0007];
 			bfc  = bfc_table[(frqcr>> 3) & 0x0007];
 			pfc = pfc_table[frqcr & 0x0007];
diff -urN linux-2.4.10-pre5/arch/sh/kernel/traps.c linux/arch/sh/kernel/traps.c
--- linux-2.4.10-pre5/arch/sh/kernel/traps.c	Mon Jan 29 16:19:41 2001
+++ linux/arch/sh/kernel/traps.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.5 2000/02/27 08:27:55 gniibe Exp $
+/* $Id: traps.c,v 1.14 2001/07/24 08:07:10 gniibe Exp $
  *
  *  linux/arch/sh/traps.c
  *
@@ -314,10 +314,10 @@
 
 	/* shout about the first ten userspace fixups */
 	if (user_mode(regs) && handle_unaligned_notify_count>0) {
-	    handle_unaligned_notify_count--;
+		handle_unaligned_notify_count--;
 
-	    printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-		   current->comm,current->pid,(u16*)regs->pc,instruction);
+		printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+		       current->comm,current->pid,(u16*)regs->pc,instruction);
 	}
 
 	ret = -EFAULT;
@@ -502,7 +502,7 @@
 	die_if_kernel("exception", &regs, ex);
 }
 
-#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS)
 void *gdb_vbr_vector;
 #endif
 
@@ -514,7 +514,7 @@
 	exception_handling_table[12] = (void *)do_reserved_inst;
 	exception_handling_table[13] = (void *)do_illegal_slot_inst;
 
-#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS)
     	/*
 	 * Read the old value of the VBR register to initialise
 	 * the vector through which debug and BIOS traps are
diff -urN linux-2.4.10-pre5/arch/sh/lib/Makefile linux/arch/sh/lib/Makefile
--- linux-2.4.10-pre5/arch/sh/lib/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/sh/lib/Makefile	Mon Dec  3 23:08:12 2001
@@ -4,7 +4,7 @@
 
 L_TARGET = lib.a
 obj-y  = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \
-	 checksum.o strcasecmp.o
+	 checksum.o strcasecmp.o strlen.o
 
 USE_STANDARD_AS_RULE := true
 
diff -urN linux-2.4.10-pre5/arch/sh/lib/checksum.S linux/arch/sh/lib/checksum.S
--- linux-2.4.10-pre5/arch/sh/lib/checksum.S	Sun Jan 28 18:56:00 2001
+++ linux/arch/sh/lib/checksum.S	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: checksum.S,v 1.4 2000/05/14 08:41:26 gniibe Exp $
+/* $Id: checksum.S,v 1.10 2001/07/06 13:11:32 gniibe Exp $
  *
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -54,13 +54,14 @@
 	tst	#2, r0		! Check alignment.
 	bt	2f		! Jump if alignment is ok.
 	!
-	add	#-2, r5	! Alignment uses up two bytes.
+	add	#-2, r5		! Alignment uses up two bytes.
 	cmp/pz	r5		!
 	bt/s	1f		! Jump if we had at least two bytes.
 	 clrt
 	bra	6f
 	 add	#2, r5		! r5 was < 2.  Deal with it.
 1:
+	mov	r5, r1		! Save new len for later use.
 	mov.w	@r4+, r0
 	extu.w	r0, r0
 	addc	r0, r6
@@ -90,7 +91,7 @@
 	addc	r3, r6
 	addc	r0, r6
 	addc	r2, r6
-	movt	r0	
+	movt	r0
 	dt	r5
 	bf/s	3b
 	 cmp/eq	#1, r0
@@ -185,48 +186,48 @@
 	mov.l	r5,@-r15
 	mov.l	r6,@-r15
 
-	mov	#3, r0			! Check src and dest are equally aligned
-	mov	r4, r1
-	and	r0, r1
-	and	r5, r0
-	cmp/eq	r1, r0
-	bf	3f			! Different alignments, use slow version
-	tst	#1,r0			! Check dest word aligned
-	bf	3f			! If not, do it the slow way
+	mov	#3,r0		! Check src and dest are equally aligned
+	mov	r4,r1
+	and	r0,r1
+	and	r5,r0
+	cmp/eq	r1,r0
+	bf	3f		! Different alignments, use slow version
+	tst	#1,r0		! Check dest word aligned
+	bf	3f		! If not, do it the slow way
 
 	mov	#2,r0
-	tst	r0,r5			! Check dest alignment. 
-	bt	2f			! Jump if alignment is ok.
-	add	#-2,r6			! Alignment uses up two bytes.
-	cmp/pz	r6			! Jump if we had at least two bytes.
+	tst	r0,r5		! Check dest alignment. 
+	bt	2f		! Jump if alignment is ok.
+	add	#-2,r6		! Alignment uses up two bytes.
+	cmp/pz	r6		! Jump if we had at least two bytes.
 	bt/s	1f
 	 clrt
 	bra	4f
-	 add	#2,r6			! r6 was < 2.	Deal with it.
+	 add	#2,r6		! r6 was < 2.	Deal with it.
 
-3:	! Handle different src and dest alinments.
+3:	! Handle different src and dest alignments.
 	! This is not common, so simple byte by byte copy will do.
-	mov	r6, r2
+	mov	r6,r2
 	shlr	r6
-	tst	r6, r6
+	tst	r6,r6
 	bt	4f
 	clrt
-5:	
-SRC(	mov.b	@r4+,r0 )
-DST(	mov.b	r0,@r5	)
-	add	#1, r5
-SRC(	mov.b	@r4+,r1	)
-DST(	mov.b	r1,@r5	)
-	add	#1,r5
-
-	extu.b	r0,r0
+	.align	2
+5:
+SRC(	mov.b	@r4+,r1 	)
+SRC(	mov.b	@r4+,r0		)
 	extu.b	r1,r1
+DST(	mov.b	r1,@r5		)
+DST(	mov.b	r0,@(1,r5)	)
+	extu.b	r0,r0
+	add	#2,r5
+
 #ifdef	__LITTLE_ENDIAN__
-	shll8	r1
-#else
 	shll8	r0
+#else
+	shll8	r1
 #endif
-	or	r1,r0	
+	or	r1,r0
 
 	addc	r0,r7
 	movt	r0
@@ -238,16 +239,16 @@
 
 	mov	r2, r0
 	tst	#1, r0
-	bt	7f	
+	bt	7f
 	bra	5f
 	 clrt
 
 	! src and dest equally aligned, but to a two byte boundary.
 	! Handle first two bytes as a special case
-	.align	5
+	.align	2
 1:	
-SRC(	mov.w	@r4+,r0	)
-DST(	mov.w	r0,@r5	)
+SRC(	mov.w	@r4+,r0		)
+DST(	mov.w	r0,@r5		)
 	add	#2,r5
 	extu.w	r0,r0
 	addc	r0,r7
@@ -260,42 +261,36 @@
 	tst	r6,r6
 	bt/s	2f
 	 clrt
+	.align	2
 1:	
-SRC(	mov.l	@r4+,r0	)
-SRC(	mov.l	@r4+,r1	)
+SRC(	mov.l	@r4+,r0		)
+SRC(	mov.l	@r4+,r1		)
 	addc	r0,r7
-DST(	mov.l	r0,@r5	)
-	add	#4,r5
+DST(	mov.l	r0,@r5		)
+DST(	mov.l	r1,@(4,r5)	)
 	addc	r1,r7
-DST(	mov.l	r1,@r5	)
-	add	#4,r5
 
-SRC(	mov.l	@r4+,r0	)
-SRC(	mov.l	@r4+,r1	)
+SRC(	mov.l	@r4+,r0		)
+SRC(	mov.l	@r4+,r1		)
 	addc	r0,r7
-DST(	mov.l	r0,@r5	)
-	add	#4,r5
+DST(	mov.l	r0,@(8,r5)	)
+DST(	mov.l	r1,@(12,r5)	)
 	addc	r1,r7
-DST(	mov.l	r1,@r5	)
-	add	#4,r5
 
 SRC(	mov.l	@r4+,r0 	)
-SRC(	mov.l	@r4+,r1	)
+SRC(	mov.l	@r4+,r1		)
 	addc	r0,r7
-DST(	mov.l	r0,@r5	)
-	add	#4,r5
+DST(	mov.l	r0,@(16,r5)	)
+DST(	mov.l	r1,@(20,r5)	)
 	addc	r1,r7
-DST(	mov.l	r1,@r5	)
-	add	#4,r5
 
-SRC(	mov.l	@r4+,r0	)
-SRC(	mov.l	@r4+,r1	)
+SRC(	mov.l	@r4+,r0		)
+SRC(	mov.l	@r4+,r1		)
 	addc	r0,r7
-DST(	mov.l	r0,@r5	)
-	add	#4,r5
+DST(	mov.l	r0,@(24,r5)	)
+DST(	mov.l	r1,@(28,r5)	)
 	addc	r1,r7
-DST(	mov.l	r1,@r5	)
-	add	#4,r5
+	add	#32,r5
 	movt	r0
 	dt	r6
 	bf/s	1b
diff -urN linux-2.4.10-pre5/arch/sh/lib/strlen.S linux/arch/sh/lib/strlen.S
--- linux-2.4.10-pre5/arch/sh/lib/strlen.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/lib/strlen.S	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,70 @@
+/* $Id: strlen.S,v 1.2 2001/06/29 14:07:15 gniibe Exp $
+ *
+ * "strlen" implementation of SuperH
+ *
+ * Copyright (C) 1999  Kaz Kojima
+ *
+ */
+
+/* size_t strlen (const char *s)  */
+
+#include <linux/linkage.h>
+ENTRY(strlen)
+	mov	r4,r0
+	and	#3,r0
+	tst	r0,r0
+	bt/s	1f
+	 mov	#0,r2
+
+	add	#-1,r0
+	shll2	r0
+	shll	r0
+	braf	r0
+	 nop
+
+	mov.b	@r4+,r1
+	tst	r1,r1
+	bt	8f
+	add	#1,r2
+
+	mov.b	@r4+,r1
+	tst	r1,r1
+	bt	8f
+	add	#1,r2
+
+	mov.b	@r4+,r1
+	tst	r1,r1
+	bt	8f
+	add	#1,r2	
+
+1:
+	mov	#0,r3
+2:
+	mov.l	@r4+,r1
+	cmp/str	r3,r1
+	bf/s	2b
+	 add	#4,r2
+
+	add	#-4,r2
+#ifndef __LITTLE_ENDIAN__
+	swap.b	r1,r1
+	swap.w	r1,r1
+	swap.b	r1,r1
+#endif
+	extu.b	r1,r0
+	tst	r0,r0
+	bt/s	8f
+	 shlr8	r1
+	add	#1,r2
+	extu.b	r1,r0
+	tst	r0,r0
+	bt/s	8f
+	 shlr8	r1
+	add	#1,r2
+	extu.b	r1,r0
+	tst	r0,r0
+	bt	8f
+	add	#1,r2
+8:
+	rts
+	 mov	r2,r0
diff -urN linux-2.4.10-pre5/arch/sh/mm/Makefile linux/arch/sh/mm/Makefile
--- linux-2.4.10-pre5/arch/sh/mm/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/sh/mm/Makefile	Mon Dec  3 23:08:12 2001
@@ -8,6 +8,11 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-obj-y	 := init.o fault.o extable.o cache.o # ioremap.o 
+obj-y	 := init.o fault.o extable.o clear_page.o copy_page.o
+
+obj-$(CONFIG_CPU_SH3) += cache-sh3.o
+obj-$(CONFIG_CPU_SH4) += cache-sh4.o __clear_user_page-sh4.o __copy_user_page-sh4.o ioremap.o
+
+USE_STANDARD_AS_RULE := true
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.10-pre5/arch/sh/mm/__clear_user_page-sh4.S linux/arch/sh/mm/__clear_user_page-sh4.S
--- linux-2.4.10-pre5/arch/sh/mm/__clear_user_page-sh4.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/__clear_user_page-sh4.S	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,49 @@
+/* $Id$
+ *
+ * __clear_user_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ *
+ */
+
+/*
+ * __clear_user_page
+ * @to: P1 address (with same color)
+ * @orig_to: P1 address
+ *
+ * void __clear_user_page(void *to, void *orig_to)
+ */
+
+/*
+ * r0 --- scratch 
+ * r4 --- to
+ * r5 --- orig_to
+ * r6 --- to + 4096
+ */
+#include <linux/linkage.h>
+ENTRY(__clear_user_page)
+	mov	r4,r6
+	mov.w	.L4096,r0
+	add	r0,r6
+	mov	#0,r0
+	!
+1:	ocbi	@r5
+	add	#32,r5
+	movca.l	r0,@r4
+	mov	r4,r1
+	add	#32,r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	add	#28,r4
+	cmp/eq	r6,r4
+	bf/s	1b
+	 ocbwb	@r1
+	!
+	rts
+	 nop
+.L4096:	.word	4096
diff -urN linux-2.4.10-pre5/arch/sh/mm/__copy_user_page-sh4.S linux/arch/sh/mm/__copy_user_page-sh4.S
--- linux-2.4.10-pre5/arch/sh/mm/__copy_user_page-sh4.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/__copy_user_page-sh4.S	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,69 @@
+/* $Id: __copy_user_page-sh4.S,v 1.1 2001/07/23 09:02:17 gniibe Exp $
+ *
+ * __copy_user_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ *
+ */
+
+/*
+ * __copy_user_page
+ * @to: P1 address (with same color)
+ * @from: P1 address
+ * @orig_to: P1 address
+ *
+ * void __copy_user_page(void *to, void *from, void *orig_to)
+ */
+
+/*
+ * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch 
+ * r8 --- from + 4096
+ * r9 --- orig_to
+ * r10 --- to
+ * r11 --- from
+ */
+#include <linux/linkage.h>
+ENTRY(__copy_user_page)
+	mov.l	r8,@-r15
+	mov.l	r9,@-r15
+	mov.l	r10,@-r15
+	mov.l	r11,@-r15
+	mov	r4,r10
+	mov	r5,r11
+	mov	r6,r9
+	mov	r5,r8
+	mov.w	.L4096,r0
+	add	r0,r8
+	!
+1:	ocbi	@r9
+	add	#32,r9
+	mov.l	@r11+,r0
+	mov.l	@r11+,r1
+	mov.l	@r11+,r2
+	mov.l	@r11+,r3
+	mov.l	@r11+,r4
+	mov.l	@r11+,r5
+	mov.l	@r11+,r6
+	mov.l	@r11+,r7
+	movca.l	r0,@r10
+	mov	r10,r0
+	add	#32,r10
+	mov.l	r7,@-r10
+	mov.l	r6,@-r10
+	mov.l	r5,@-r10
+	mov.l	r4,@-r10
+	mov.l	r3,@-r10
+	mov.l	r2,@-r10
+	mov.l	r1,@-r10
+	ocbwb	@r0
+	cmp/eq	r11,r8
+	bf/s	1b
+	 add	#28,r10
+	!
+	mov.l	@r15+,r11
+	mov.l	@r15+,r10
+	mov.l	@r15+,r9
+	mov.l	@r15+,r8
+	rts
+	 nop
+.L4096:	.word	4096
diff -urN linux-2.4.10-pre5/arch/sh/mm/cache-sh3.c linux/arch/sh/mm/cache-sh3.c
--- linux-2.4.10-pre5/arch/sh/mm/cache-sh3.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/cache-sh3.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,219 @@
+/* $Id: cache-sh3.c,v 1.5 2001/08/24 15:31:41 dwmw2 Exp $
+ *
+ *  linux/arch/sh/mm/cache-sh3.c
+ *
+ * Copyright (C) 1999, 2000  Niibe Yutaka
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/threads.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+
+#define CCR		0xffffffec	/* Address of Cache Control Register */
+#define CCR_CACHE_VAL	0x00000005	/* 8k-byte cache, P1-wb, enable */
+#define CCR_CACHE_INIT	0x0000000d	/* 8k-byte cache, CF, P1-wb, enable */
+#define CCR_CACHE_ENABLE	 1
+
+#define CACHE_OC_ADDRESS_ARRAY 0xf0000000
+#define CACHE_VALID	  1
+#define CACHE_UPDATED	  2
+#define CACHE_PHYSADDR_MASK 0x1ffffc00
+
+/* 7709A/7729 has 16K cache (256-entry), while 7702 has only 2K(direct)
+   7702 is not supported (yet) */
+struct _cache_system_info {
+	int way_shift;
+	int entry_mask;
+	int num_entries;
+};
+
+/* Data at BSS is cleared after setting this variable.
+   So, we Should not placed this variable at BSS section.
+   Initialize this, it is placed at data section. */
+static struct _cache_system_info cache_system_info = {0,};
+
+#define CACHE_OC_WAY_SHIFT	(cache_system_info.way_shift)
+#define CACHE_OC_ENTRY_SHIFT    4
+#define CACHE_OC_ENTRY_MASK	(cache_system_info.entry_mask)
+#define CACHE_OC_NUM_ENTRIES	(cache_system_info.num_entries)
+#define CACHE_OC_NUM_WAYS	4
+#define CACHE_OC_ASSOC_BIT    (1<<3)
+
+
+/*
+ * Write back all the cache.
+ *
+ * For SH-4, we only need to flush (write back) Operand Cache,
+ * as Instruction Cache doesn't have "updated" data.
+ *
+ * Assumes that this is called in interrupt disabled context, and P2.
+ * Shuld be INLINE function.
+ */
+static inline void cache_wback_all(void)
+{
+	unsigned long addr, data, i, j;
+
+	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
+		for (j=0; j<CACHE_OC_NUM_WAYS; j++) {
+			addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
+				(i<<CACHE_OC_ENTRY_SHIFT);
+			data = ctrl_inl(addr);
+			if ((data & (CACHE_UPDATED|CACHE_VALID))
+			    == (CACHE_UPDATED|CACHE_VALID))
+				ctrl_outl(data & ~CACHE_UPDATED, addr);
+		}
+	}
+}
+
+static void __init
+detect_cpu_and_cache_system(void)
+{
+	unsigned long addr0, addr1, data0, data1, data2, data3;
+
+	jump_to_P2();
+	/*
+	 * Check if the entry shadows or not.
+	 * When shadowed, it's 128-entry system.
+	 * Otherwise, it's 256-entry system.
+	 */
+	addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
+	addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
+
+	/* First, write back & invalidate */
+	data0  = ctrl_inl(addr0);
+	ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0);
+	data1  = ctrl_inl(addr1);
+	ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1);
+
+	/* Next, check if there's shadow or not */
+	data0 = ctrl_inl(addr0);
+	data0 ^= CACHE_VALID;
+	ctrl_outl(data0, addr0);
+	data1 = ctrl_inl(addr1);
+	data2 = data1 ^ CACHE_VALID;
+	ctrl_outl(data2, addr1);
+	data3 = ctrl_inl(addr0);
+
+	/* Lastly, invaliate them. */
+	ctrl_outl(data0&~CACHE_VALID, addr0);
+	ctrl_outl(data2&~CACHE_VALID, addr1);
+	back_to_P1();
+
+	if (data0 == data1 && data2 == data3) {	/* Shadow */
+		cache_system_info.way_shift = 11;
+		cache_system_info.entry_mask = 0x7f0;
+		cache_system_info.num_entries = 128;
+		cpu_data->type = CPU_SH7708;
+	} else {				/* 7709A or 7729  */
+		cache_system_info.way_shift = 12;
+		cache_system_info.entry_mask = 0xff0;
+		cache_system_info.num_entries = 256;
+		cpu_data->type = CPU_SH7729;
+	}
+}
+
+void __init cache_init(void)
+{
+	unsigned long ccr;
+
+	detect_cpu_and_cache_system();
+
+	jump_to_P2();
+	ccr = ctrl_inl(CCR);
+	if (ccr & CCR_CACHE_ENABLE)
+		/*
+		 * XXX: Should check RA here. 
+		 * If RA was 1, we only need to flush the half of the caches.
+		 */
+		cache_wback_all();
+
+	ctrl_outl(CCR_CACHE_INIT, CCR);
+	back_to_P1();
+}
+
+/*
+ * Write back the dirty D-caches, but not invalidate them.
+ *
+ * Is this really worth it, or should we just alias this routine
+ * to __flush_purge_region too?
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+
+void __flush_wback_region(void *start, int size)
+{
+	unsigned long v, j;
+	unsigned long begin, end;
+	unsigned long flags;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		for (j=0; j<CACHE_OC_NUM_WAYS; j++) {
+			unsigned long data, addr, p;
+
+			p = __pa(v);
+			addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
+				(v&CACHE_OC_ENTRY_MASK);
+			save_and_cli(flags);
+			data = ctrl_inl(addr);
+			
+			if ((data & CACHE_PHYSADDR_MASK) ==
+			    (p & CACHE_PHYSADDR_MASK)) {
+				data &= ~CACHE_UPDATED;
+				ctrl_outl(data, addr);
+				restore_flags(flags);
+				break;
+			}
+			restore_flags(flags);
+		}
+	}
+}
+
+/*
+ * Write back the dirty D-caches and invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+void __flush_purge_region(void *start, int size)
+{
+	unsigned long v;
+	unsigned long begin, end;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		unsigned long data, addr;
+
+		data = (v & 0xfffffc00); /* _Virtual_ address, ~U, ~V */
+		addr = CACHE_OC_ADDRESS_ARRAY | (v&CACHE_OC_ENTRY_MASK) | 
+			CACHE_OC_ASSOC_BIT;
+		ctrl_outl(data, addr);
+	}
+}
+
+/*
+ * No write back please
+ *
+ * Except I don't think there's any way to avoid the writeback. So we
+ * just alias it to __flush_purge_region(). dwmw2.
+ */
+void __flush_invalidate_region(void *start, int size)
+	__attribute__((alias("__flush_purge_region")));
diff -urN linux-2.4.10-pre5/arch/sh/mm/cache-sh4.c linux/arch/sh/mm/cache-sh4.c
--- linux-2.4.10-pre5/arch/sh/mm/cache-sh4.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/cache-sh4.c	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,439 @@
+/* $Id: cache-sh4.c,v 1.15 2001/08/10 14:13:13 gniibe Exp $
+ *
+ *  linux/arch/sh/mm/cache.c
+ *
+ * Copyright (C) 1999, 2000  Niibe Yutaka
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/threads.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+
+#define CCR		 0xff00001c	/* Address of Cache Control Register */
+#define CCR_CACHE_VAL	 0x00000105	/* 8k+16k-byte cache,P1-wb,enable */
+#define CCR_CACHE_INIT	 0x0000090d	/* ICI,ICE(8k), OCI,P1-wb,OCE(16k) */
+#define CCR_CACHE_ENABLE 0x00000101
+
+#define CACHE_IC_ADDRESS_ARRAY 0xf0000000
+#define CACHE_OC_ADDRESS_ARRAY 0xf4000000
+#define CACHE_VALID	  1
+#define CACHE_UPDATED	  2
+
+#define CACHE_OC_WAY_SHIFT       13
+#define CACHE_IC_WAY_SHIFT       13
+#define CACHE_OC_ENTRY_SHIFT      5
+#define CACHE_IC_ENTRY_SHIFT      5
+#define CACHE_OC_ENTRY_MASK		0x3fe0
+#define CACHE_OC_ENTRY_PHYS_MASK	0x0fe0
+#define CACHE_IC_ENTRY_MASK		0x1fe0
+#define CACHE_IC_NUM_ENTRIES	256
+#define CACHE_OC_NUM_ENTRIES	512
+
+static void __init
+detect_cpu_and_cache_system(void)
+{
+#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+	cpu_data->type = CPU_ST40STB1;
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
+	cpu_data->type = CPU_SH7750;
+#else
+#error Unknown SH4 CPU type
+#endif
+}
+
+void __init cache_init(void)
+{
+	unsigned long ccr;
+
+	detect_cpu_and_cache_system();
+
+	jump_to_P2();
+	ccr = ctrl_inl(CCR);
+	if (ccr & CCR_CACHE_ENABLE) {
+		/*
+		 * XXX: Should check RA here. 
+		 * If RA was 1, we only need to flush the half of the caches.
+		 */
+		unsigned long addr, data;
+
+		for (addr = CACHE_OC_ADDRESS_ARRAY;
+		     addr < (CACHE_OC_ADDRESS_ARRAY+
+			     (CACHE_OC_NUM_ENTRIES << CACHE_OC_ENTRY_SHIFT));
+		     addr += (1 << CACHE_OC_ENTRY_SHIFT)) {
+			data = ctrl_inl(addr);
+			if ((data & (CACHE_UPDATED|CACHE_VALID))
+			    == (CACHE_UPDATED|CACHE_VALID))
+				ctrl_outl(data & ~CACHE_UPDATED, addr);
+		}
+	}
+
+	ctrl_outl(CCR_CACHE_INIT, CCR);
+	back_to_P1();
+}
+
+/*
+ * SH-4 has virtually indexed and physically tagged cache.
+ */
+
+static struct semaphore p3map_sem[4];
+
+void __init p3_cache_init(void)
+{
+	/* In ioremap.c */
+	extern int remap_area_pages(unsigned long address,
+				    unsigned long phys_addr,
+				    unsigned long size, unsigned long flags);
+
+	if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE))
+		panic("p3_cachie_init failed.");
+	sema_init (&p3map_sem[0], 1);
+	sema_init (&p3map_sem[1], 1);
+	sema_init (&p3map_sem[2], 1);
+	sema_init (&p3map_sem[3], 1);
+}
+
+/*
+ * Write back the dirty D-caches, but not invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+void __flush_wback_region(void *start, int size)
+{
+	unsigned long v;
+	unsigned long begin, end;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		asm volatile("ocbwb	%0"
+			     : /* no output */
+			     : "m" (__m(v)));
+	}
+}
+
+/*
+ * Write back the dirty D-caches and invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+void __flush_purge_region(void *start, int size)
+{
+	unsigned long v;
+	unsigned long begin, end;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		asm volatile("ocbp	%0"
+			     : /* no output */
+			     : "m" (__m(v)));
+	}
+}
+
+
+/*
+ * No write back please
+ */
+void __flush_invalidate_region(void *start, int size)
+{
+	unsigned long v;
+	unsigned long begin, end;
+
+	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
+	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+		asm volatile("ocbi	%0"
+			     : /* no output */
+			     : "m" (__m(v)));
+	}
+}
+
+/*
+ * Write back the range of D-cache, and purge the I-cache.
+ *
+ * Called from kernel/module.c:sys_init_module and routine for a.out format.
+ */
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+/*
+ * Write back the D-cache and purge the I-cache for signal trampoline. 
+ */
+void flush_cache_sigtramp(unsigned long addr)
+{
+	unsigned long v, index;
+	unsigned long flags; 
+
+	v = addr & ~(L1_CACHE_BYTES-1);
+	asm volatile("ocbwb	%0"
+		     : /* no output */
+		     : "m" (__m(v)));
+
+	index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK);
+	save_and_cli(flags);
+	jump_to_P2();
+	ctrl_outl(0, index);	/* Clear out Valid-bit */
+	back_to_P1();
+	restore_flags(flags);
+}
+
+/*
+ * Writeback&Invalidate the D-cache of the page
+ */
+static void __flush_dcache_page(unsigned long phys)
+{
+	unsigned long addr, data;
+	unsigned long flags;
+
+	phys |= CACHE_VALID;
+
+	save_and_cli(flags);
+	jump_to_P2();
+
+	/* Loop all the D-cache */
+	for (addr = CACHE_OC_ADDRESS_ARRAY;
+	     addr < (CACHE_OC_ADDRESS_ARRAY
+		     +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT));
+	     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
+		data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+		if (data == phys)
+			ctrl_outl(0, addr);
+	}
+
+#if 0 /* DEBUG DEBUG */
+	/* Loop all the I-cache */
+	for (addr = CACHE_IC_ADDRESS_ARRAY;
+	     addr < (CACHE_IC_ADDRESS_ARRAY
+		     +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT));
+	     addr += (1<<CACHE_IC_ENTRY_SHIFT)) {
+		data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+		if (data == phys) {
+			printk(KERN_INFO "__flush_cache_page: I-cache entry found\n");
+			ctrl_outl(0, addr);
+		}
+	}
+#endif
+	back_to_P1();
+	restore_flags(flags);
+}
+
+/*
+ * Write back & invalidate the D-cache of the page.
+ * (To avoid "alias" issues)
+ */
+void flush_dcache_page(struct page *page)
+{
+	if (test_bit(PG_mapped, &page->flags))
+		__flush_dcache_page(PHYSADDR(page_address(page)));
+}
+
+void flush_cache_all(void)
+{
+	extern unsigned long empty_zero_page[1024];
+	unsigned long flags;
+	unsigned long addr;
+
+	save_and_cli(flags);
+
+	/* Prefetch the data to write back D-cache */
+	for (addr = (unsigned long)empty_zero_page;
+	     addr < (unsigned long)empty_zero_page + 1024*16;
+	     addr += L1_CACHE_BYTES)
+		asm volatile("pref @%0"::"r" (addr));
+
+	jump_to_P2();
+	/* Flush D-cache/I-cache */
+	ctrl_outl(CCR_CACHE_INIT, CCR);
+	back_to_P1();
+	restore_flags(flags);
+}
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+	/* Is there any good way? */
+	/* XXX: possibly call flush_cache_range for each vm area */
+	flush_cache_all();
+}
+
+/*
+ * Write back and invalidate D-caches.
+ *
+ * START, END: Virtual Address (U0 address)
+ *
+ * NOTE: We need to flush the _physical_ page entry.
+ * Flushing the cache lines for U0 only isn't enough.
+ * We need to flush for P1 too, which may contain aliases.
+ */
+void flush_cache_range(struct mm_struct *mm, unsigned long start,
+		       unsigned long end)
+{
+	/*
+	 * We could call flush_cache_page for the pages of these range,
+	 * but it's not efficient (scan the caches all the time...).
+	 *
+	 * We can't use A-bit magic, as there's the case we don't have
+	 * valid entry on TLB.
+	 */
+	flush_cache_all();
+}
+
+/*
+ * Write back and invalidate I/D-caches for the page.
+ *
+ * ADDR: Virtual Address (U0 address)
+ */
+void flush_cache_page(struct vm_area_struct *vma, unsigned long address)
+{
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	pte_t entry;
+	unsigned long phys, addr, data;
+	unsigned long flags;
+
+	dir = pgd_offset(vma->vm_mm, address);
+	pmd = pmd_offset(dir, address);
+	if (pmd_none(*pmd) || pmd_bad(*pmd))
+		return;
+	pte = pte_offset(pmd, address);
+	entry = *pte;
+	if (pte_none(entry) || !pte_present(entry))
+		return;
+
+	phys = pte_val(entry)&PTE_PHYS_MASK;
+
+	phys |= CACHE_VALID;
+	save_and_cli(flags);
+	jump_to_P2();
+
+	/* We only need to flush D-cache when we have alias */
+	if ((address^phys) & CACHE_ALIAS) {
+		/* Loop 4K of the D-cache */
+		for (addr = CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS);
+		     addr < (CACHE_OC_ADDRESS_ARRAY + (address & CACHE_ALIAS) 
+			     +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT));
+		     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
+			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+			if (data == phys)
+				ctrl_outl(0, addr);
+		}
+		/* Loop another 4K of the D-cache */
+		for (addr = CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS);
+		     addr < (CACHE_OC_ADDRESS_ARRAY + (phys & CACHE_ALIAS) 
+			     +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT));
+		     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
+			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+			if (data == phys)
+				ctrl_outl(0, addr);
+		}
+	}
+
+	if (vma->vm_flags & VM_EXEC)
+		/* Loop 4K of the I-cache */
+		for (addr = CACHE_IC_ADDRESS_ARRAY|(address&0x1000);
+		     addr < ((CACHE_IC_ADDRESS_ARRAY|(address&0x1000))
+			     +(CACHE_IC_NUM_ENTRIES/2<<CACHE_IC_ENTRY_SHIFT));
+		     addr += (1<<CACHE_IC_ENTRY_SHIFT)) {
+			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
+			if (data == phys)
+				ctrl_outl(0, addr);
+		}
+	back_to_P1();
+	restore_flags(flags);
+}
+
+/*
+ * clear_user_page
+ * @to: P1 address
+ * @address: U0 address to be mapped
+ */
+void clear_user_page(void *to, unsigned long address)
+{
+	struct page *page = virt_to_page(to);
+
+	__set_bit(PG_mapped, &page->flags);
+	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
+		clear_page(to);
+	else {
+		pgprot_t pgprot = __pgprot(_PAGE_PRESENT | 
+					   _PAGE_RW | _PAGE_CACHABLE |
+					   _PAGE_DIRTY | _PAGE_ACCESSED | 
+					   _PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
+		unsigned long phys_addr = PHYSADDR(to);
+		unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
+		pgd_t *dir = pgd_offset_k(p3_addr);
+		pmd_t *pmd = pmd_offset(dir, p3_addr);
+		pte_t *pte = pte_offset(pmd, p3_addr);
+		pte_t entry;
+		unsigned long flags;
+
+		entry = mk_pte_phys(phys_addr, pgprot);
+		down(&p3map_sem[(address & CACHE_ALIAS)>>12]);
+		set_pte(pte, entry);
+		save_and_cli(flags);
+		__flush_tlb_page(get_asid(), p3_addr);
+		restore_flags(flags);
+		update_mmu_cache(NULL, p3_addr, entry);
+		__clear_user_page((void *)p3_addr, to);
+		pte_clear(pte);
+		up(&p3map_sem[(address & CACHE_ALIAS)>>12]);
+	}
+}
+
+/*
+ * copy_user_page
+ * @to: P1 address
+ * @from: P1 address
+ * @address: U0 address to be mapped
+ */
+void copy_user_page(void *to, void *from, unsigned long address)
+{
+	struct page *page = virt_to_page(to);
+
+	__set_bit(PG_mapped, &page->flags);
+	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
+		copy_page(to, from);
+	else {
+		pgprot_t pgprot = __pgprot(_PAGE_PRESENT | 
+					   _PAGE_RW | _PAGE_CACHABLE |
+					   _PAGE_DIRTY | _PAGE_ACCESSED | 
+					   _PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
+		unsigned long phys_addr = PHYSADDR(to);
+		unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
+		pgd_t *dir = pgd_offset_k(p3_addr);
+		pmd_t *pmd = pmd_offset(dir, p3_addr);
+		pte_t *pte = pte_offset(pmd, p3_addr);
+		pte_t entry;
+		unsigned long flags;
+
+		entry = mk_pte_phys(phys_addr, pgprot);
+		down(&p3map_sem[(address & CACHE_ALIAS)>>12]);
+		set_pte(pte, entry);
+		save_and_cli(flags);
+		__flush_tlb_page(get_asid(), p3_addr);
+		restore_flags(flags);
+		update_mmu_cache(NULL, p3_addr, entry);
+		__copy_user_page((void *)p3_addr, from, to);
+		pte_clear(pte);
+		up(&p3map_sem[(address & CACHE_ALIAS)>>12]);
+	}
+}
diff -urN linux-2.4.10-pre5/arch/sh/mm/cache.c linux/arch/sh/mm/cache.c
--- linux-2.4.10-pre5/arch/sh/mm/cache.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/mm/cache.c	Wed Dec 31 16:00:00 1969
@@ -1,524 +0,0 @@
-/* $Id: cache.c,v 1.10 2000/03/07 11:58:34 gniibe Exp $
- *
- *  linux/arch/sh/mm/cache.c
- *
- * Copyright (C) 1999, 2000  Niibe Yutaka
- *
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/threads.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/cache.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#if defined(__sh3__)
-#define CCR		0xffffffec	/* Address of Cache Control Register */
-#define CCR_CACHE_VAL	0x00000005	/* 8k-byte cache, P1-wb, enable */
-#define CCR_CACHE_INIT	0x0000000d	/* 8k-byte cache, CF, P1-wb, enable */
-#define CCR_CACHE_ENABLE	 1
-
-#define CACHE_IC_ADDRESS_ARRAY 0xf0000000 /* SH-3 has unified cache system */
-#define CACHE_OC_ADDRESS_ARRAY 0xf0000000
-#define CACHE_VALID	  1
-#define CACHE_UPDATED	  2
-
-/* 7709A/7729 has 16K cache (256-entry), while 7702 has only 2K(direct)
-   7702 is not supported (yet) */
-struct _cache_system_info {
-	int way_shift;
-	int entry_mask;
-	int num_entries;
-};
-
-/* Data at BSS is cleared after setting this variable.
-   So, we Should not placed this variable at BSS section.
-   Initialize this, it is placed at data section. */
-static struct _cache_system_info cache_system_info = {0,};
-
-#define CACHE_OC_WAY_SHIFT	(cache_system_info.way_shift)
-#define CACHE_IC_WAY_SHIFT	(cache_system_info.way_shift)
-#define CACHE_OC_ENTRY_SHIFT    4
-#define CACHE_OC_ENTRY_MASK	(cache_system_info.entry_mask)
-#define CACHE_IC_ENTRY_MASK	(cache_system_info.entry_mask)
-#define CACHE_OC_NUM_ENTRIES	(cache_system_info.num_entries)
-#define CACHE_OC_NUM_WAYS	4
-#define CACHE_IC_NUM_WAYS	4
-#elif defined(__SH4__)
-#define CCR		 0xff00001c	/* Address of Cache Control Register */
-#define CCR_CACHE_VAL	 0x00000105	/* 8k+16k-byte cache,P1-wb,enable */
-#define CCR_CACHE_INIT	 0x0000090d	/* ICI,ICE(8k), OCI,P1-wb,OCE(16k) */
-#define CCR_CACHE_ENABLE 0x00000101
-
-#define CACHE_IC_ADDRESS_ARRAY 0xf0000000
-#define CACHE_OC_ADDRESS_ARRAY 0xf4000000
-#define CACHE_VALID	  1
-#define CACHE_UPDATED	  2
-
-#define CACHE_OC_WAY_SHIFT       13
-#define CACHE_IC_WAY_SHIFT       13
-#define CACHE_OC_ENTRY_SHIFT      5
-#define CACHE_IC_ENTRY_SHIFT      5
-#define CACHE_OC_ENTRY_MASK		0x3fe0
-#define CACHE_OC_ENTRY_PHYS_MASK	0x0fe0
-#define CACHE_IC_ENTRY_MASK		0x1fe0
-#define CACHE_IC_NUM_ENTRIES	256
-#define CACHE_OC_NUM_ENTRIES	512
-#define CACHE_OC_NUM_WAYS	  1
-#define CACHE_IC_NUM_WAYS	  1
-#endif
-
-
-/*
- * Write back all the cache.
- *
- * For SH-4, we only need to flush (write back) Operand Cache,
- * as Instruction Cache doesn't have "updated" data.
- *
- * Assumes that this is called in interrupt disabled context, and P2.
- * Shuld be INLINE function.
- */
-static inline void cache_wback_all(void)
-{
-	unsigned long addr, data, i, j;
-
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		for (j=0; j<CACHE_OC_NUM_WAYS; j++) {
-			addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
-				(i<<CACHE_OC_ENTRY_SHIFT);
-			data = ctrl_inl(addr);
-			if ((data & (CACHE_UPDATED|CACHE_VALID))
-			    == (CACHE_UPDATED|CACHE_VALID)) {
-				data &= ~CACHE_UPDATED;
-				ctrl_outl(data, addr);
-			}
-		}
-	}
-}
-
-static void __init
-detect_cpu_and_cache_system(void)
-{
-#if defined(__sh3__)
-	unsigned long addr0, addr1, data0, data1, data2, data3;
-
-	jump_to_P2();
-	/*
-	 * Check if the entry shadows or not.
-	 * When shadowed, it's 128-entry system.
-	 * Otherwise, it's 256-entry system.
-	 */
-	addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
-	addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
-
-	/* First, write back & invalidate */
-	data0  = ctrl_inl(addr0);
-	ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0);
-	data1  = ctrl_inl(addr1);
-	ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1);
-
-	/* Next, check if there's shadow or not */
-	data0 = ctrl_inl(addr0);
-	data0 ^= CACHE_VALID;
-	ctrl_outl(data0, addr0);
-	data1 = ctrl_inl(addr1);
-	data2 = data1 ^ CACHE_VALID;
-	ctrl_outl(data2, addr1);
-	data3 = ctrl_inl(addr0);
-
-	/* Lastly, invaliate them. */
-	ctrl_outl(data0&~CACHE_VALID, addr0);
-	ctrl_outl(data2&~CACHE_VALID, addr1);
-	back_to_P1();
-
-	if (data0 == data1 && data2 == data3) {	/* Shadow */
-		cache_system_info.way_shift = 11;
-		cache_system_info.entry_mask = 0x7f0;
-		cache_system_info.num_entries = 128;
-		cpu_data->type = CPU_SH7708;
-	} else {				/* 7709A or 7729  */
-		cache_system_info.way_shift = 12;
-		cache_system_info.entry_mask = 0xff0;
-		cache_system_info.num_entries = 256;
-		cpu_data->type = CPU_SH7729;
-	}
-#elif defined(__SH4__)
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-	cpu_data->type = CPU_ST40STB1;
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
-      defined(CONFIG_CPU_SUBTYPE_SH7751)
-	cpu_data->type = CPU_SH7750;
-#else
-#error Unknown SH4 CPU type
-#endif
-#endif
-}
-
-void __init cache_init(void)
-{
-	unsigned long ccr;
-
-	detect_cpu_and_cache_system();
-
-	ccr = ctrl_inl(CCR);
-	jump_to_P2();
-	if (ccr & CCR_CACHE_ENABLE)
-		/*
-		 * XXX: Should check RA here. 
-		 * If RA was 1, we only need to flush the half of the caches.
-		 */
-		cache_wback_all();
-
-	ctrl_outl(CCR_CACHE_INIT, CCR);
-	back_to_P1();
-}
-
-#if defined(__SH4__)
-/*
- * SH-4 has virtually indexed and physically tagged cache.
- */
-
-/*
- * Write back the dirty D-caches, but not invalidate them.
- *
- * START, END: Virtual Address
- */
-static void dcache_wback_range(unsigned long start, unsigned long end)
-{
-	unsigned long v;
-
-	start &= ~(L1_CACHE_BYTES-1);
-	for (v = start; v < end; v+=L1_CACHE_BYTES) {
-		asm volatile("ocbwb	%0"
-			     : /* no output */
-			     : "m" (__m(v)));
-	}
-}
-
-/*
- * Invalidate I-caches.
- *
- * START, END: Virtual Address
- *
- */
-static void icache_purge_range(unsigned long start, unsigned long end)
-{
-	unsigned long addr, data, v;
-
-	start &= ~(L1_CACHE_BYTES-1);
-
-	jump_to_P2();
-	/*
-	 * To handle the cache-line, we calculate the entry with virtual
-	 * address: entry = vaddr & CACHE_IC_ENTRY_MASK.
-	 *
-	 * With A-bit "on", data written to is translated by MMU and
-	 * compared the tag of cache and if it's not matched, nothing
-	 * will be occurred.  (We can avoid flushing other caches.)
-	 * 
-	 * NOTE: We can use A-bit feature here, because we have valid
-	 * entriy in TLB (at least in UTLB), as dcache_wback_range is
-	 * called before this function is called.
-	 */
-	for (v = start; v < end; v+=L1_CACHE_BYTES) {
-		addr = CACHE_IC_ADDRESS_ARRAY |	(v&CACHE_IC_ENTRY_MASK)
-			| 0x8 /* A-bit */;
-		data = (v&0xfffffc00); /* Valid=0 */
-		ctrl_outl(data, addr);
-	}
-	back_to_P1();
-}
-
-/*
- * Write back the range of D-cache, and purge the I-cache.
- *
- * Called from sh/kernel/signal.c, after accessing the memory
- * through U0 area.  START and END is the address of U0.
- */
-void flush_icache_range(unsigned long start, unsigned long end)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	dcache_wback_range(start, end);
-	icache_purge_range(start, end);
-	restore_flags(flags);
-}
-
-/*
- * Write back the D-cache and purge the I-cache for signal trampoline. 
- */
-void flush_cache_sigtramp(unsigned long addr)
-{
-	unsigned long v, index;
-
-	v = addr & ~(L1_CACHE_BYTES-1);
-	asm volatile("ocbwb	%0"
-		     : /* no output */
-		     : "m" (__m(v)));
-
-	index = CACHE_IC_ADDRESS_ARRAY| (v&CACHE_IC_ENTRY_MASK);
-	ctrl_outl(0, index);	/* Clear out Valid-bit */
-}
-
-/*
- * Invalidate the I-cache of the page (don't need to write back D-cache).
- *
- * Called from kernel/ptrace.c, mm/memory.c after flush_page_to_ram is called.
- */
-void flush_icache_page(struct vm_area_struct *vma, struct page *pg)
-{
-	unsigned long phys, addr, data, i;
-
-	/* Physical address of this page */
-	phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
-
-	jump_to_P2();
-	/* Loop all the I-cache */
-	for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) {
-		addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
-			data &= ~CACHE_VALID;
-			ctrl_outl(data, addr);
-		}
-	}
-	back_to_P1();
-}
-
-/*
- * Write back & invalidate the D-cache of the page.
- * (To avoid "alias" issues)
- */
-void flush_dcache_page(struct page *pg)
-{
-	unsigned long phys, addr, data, i;
-
-	/* Physical address of this page */
-	phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
-
-	jump_to_P2();
-	/* Loop all the D-cache */
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
-			data &= ~(CACHE_VALID|CACHE_UPDATED);
-			ctrl_outl(data, addr);
-		}
-	}
-	back_to_P1();
-}
-
-void flush_cache_all(void)
-{
-	unsigned long addr, data, i;
-	unsigned long flags;
-
-	save_and_cli(flags);
-	jump_to_P2();
-
-	/* Loop all the D-cache */
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		addr = CACHE_OC_ADDRESS_ARRAY|(i<<CACHE_OC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if (data & CACHE_VALID) {
-			data &= ~(CACHE_UPDATED|CACHE_VALID);
-			ctrl_outl(data, addr);
-		}
-	}
-
-	/* Loop all the I-cache */
-	for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) {
-		addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if (data & CACHE_VALID) {
-			data &= ~CACHE_VALID;
-			ctrl_outl(data, addr);
-		}
-	}
-
-	back_to_P1();
-	restore_flags(flags);
-}
-
-void flush_cache_mm(struct mm_struct *mm)
-{
-	/* Is there any good way? */
-	/* XXX: possibly call flush_cache_range for each vm area */
-	flush_cache_all();
-}
-
-/*
- * Write back and invalidate D-caches.
- *
- * START, END: Virtual Address (U0 address)
- *
- * NOTE: We need to flush the _physical_ page entry.
- * Flushing the cache lines for U0 only isn't enough.
- * We need to flush for P1 too, which may contain aliases.
- */
-void flush_cache_range(struct mm_struct *mm, unsigned long start,
-		       unsigned long end)
-{
-	/*
-	 * We could call flush_cache_page for the pages of these range,
-	 * but it's not efficient (scan the caches all the time...).
-	 *
-	 * We can't use A-bit magic, as there's the case we don't have
-	 * valid entry on TLB.
-	 */
-	flush_cache_all();
-}
-
-/*
- * Write back and invalidate D-caches for the page.
- *
- * ADDR: Virtual Address (U0 address)
- *
- * NOTE: We need to flush the _physical_ page entry.
- * Flushing the cache lines for U0 only isn't enough.
- * We need to flush for P1 too, which may contain aliases.
- */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
-{
-	pgd_t *dir;
-	pmd_t *pmd;
-	pte_t *pte;
-	pte_t entry;
-	unsigned long phys;
-	struct page *pg;
-
-	dir = pgd_offset(vma->vm_mm, addr);
-	pmd = pmd_offset(dir, addr);
-	if (pmd_none(*pmd))
-		return;
-	if (pmd_bad(*pmd))
-		return;
-	pte = pte_offset(pmd, addr);
-	entry = *pte;
-	if (pte_none(entry) || !pte_present(entry))
-		return;
-	phys = pte_val(entry)&PAGE_MASK;
-	pg = virt_to_page(__va(phys));
-	flush_dcache_page(pg);
-}
-
-/*
- * Write-back & invalidate the cache.
- *
- * After accessing the memory from kernel space (P1-area), we need to 
- * write back the cache line.
- *
- * We search the D-cache to see if we have the entries corresponding to
- * the page, and if found, write back them.
- */
-void __flush_page_to_ram(void *kaddr)
-{
-	unsigned long phys, addr, data, i;
-
-	/* Physical address of this page */
-	phys = PHYSADDR(kaddr);
-
-	jump_to_P2();
-	/* Loop all the D-cache */
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
-			data &= ~(CACHE_UPDATED|CACHE_VALID);
-			ctrl_outl(data, addr);
-		}
-	}
-	back_to_P1();
-}
-
-void flush_page_to_ram(struct page *pg)
-{
-	unsigned long phys;
-
-	/* Physical address of this page */
-	phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
-	__flush_page_to_ram(phys_to_virt(phys));
-}
-
-/*
- * Check entries of the I-cache & D-cache of the page.
- * (To see "alias" issues)
- */
-void check_cache_page(struct page *pg)
-{
-	unsigned long phys, addr, data, i;
-	unsigned long kaddr;
-	unsigned long cache_line_index;
-	int bingo = 0;
-
-	/* Physical address of this page */
-	phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
-	kaddr = phys + PAGE_OFFSET;
-	cache_line_index = (kaddr&CACHE_OC_ENTRY_MASK)>>CACHE_OC_ENTRY_SHIFT;
-
-	jump_to_P2();
-	/* Loop all the D-cache */
-	for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
-		addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & (CACHE_UPDATED|CACHE_VALID))
-		    == (CACHE_UPDATED|CACHE_VALID)
-		    && (data&PAGE_MASK) == phys) {
-			data &= ~(CACHE_VALID|CACHE_UPDATED);
-			ctrl_outl(data, addr);
-			if ((i^cache_line_index)&0x180)
-				bingo = 1;
-		}
-	}
-
-	cache_line_index &= 0xff;
-	/* Loop all the I-cache */
-	for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) {
-		addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT);
-		data = ctrl_inl(addr);
-		if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
-			data &= ~CACHE_VALID;
-			ctrl_outl(data, addr);
-			if (((i^cache_line_index)&0x80))
-				bingo = 2;
-		}
-	}
-	back_to_P1();
-
-	if (bingo) {
-		extern void dump_stack(void);
-
-		if (bingo ==1)
-			printk("BINGO!\n");
-		else
-			printk("Bingo!\n");
-		dump_stack();
-		printk("--------------------\n");
-	}
-}
-
-/* Page is 4K, OC size is 16K, there are four lines. */
-#define CACHE_ALIAS 0x00003000
-
-void clear_user_page(void *to, unsigned long address)
-{
-	clear_page(to);
-	if (((address ^ (unsigned long)to) & CACHE_ALIAS))
-		__flush_page_to_ram(to);
-}
-
-void copy_user_page(void *to, void *from, unsigned long address)
-{
-	copy_page(to, from);
-	if (((address ^ (unsigned long)to) & CACHE_ALIAS))
-		__flush_page_to_ram(to);
-}
-#endif
diff -urN linux-2.4.10-pre5/arch/sh/mm/clear_page.S linux/arch/sh/mm/clear_page.S
--- linux-2.4.10-pre5/arch/sh/mm/clear_page.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/clear_page.S	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,52 @@
+/* $Id: clear_page.S,v 1.1 2001/07/23 10:08:50 gniibe Exp $
+ *
+ * clear_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ *
+ */
+
+/*
+ * clear_page
+ * @to: P1 address
+ *
+ * void clear_page(void *to)
+ */
+
+/*
+ * r0 --- scratch
+ * r4 --- to
+ * r5 --- to + 4096
+ */
+#include <linux/linkage.h>
+ENTRY(clear_page)
+	mov	r4,r5
+	mov.w	.Llimit,r0
+	add	r0,r5
+	mov	#0,r0
+	!
+1:
+#if defined(__sh3__)
+	mov.l	r0,@r4
+#elif defined(__SH4__)
+	movca.l	r0,@r4
+	mov	r4,r1
+#endif
+	add	#32,r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+#if defined(__SH4__)
+	ocbwb	@r1
+#endif
+	cmp/eq	r5,r4
+	bf/s	1b
+	 add	#28,r4
+	!
+	rts
+	 nop
+.Llimit:	.word	(4096-28)
diff -urN linux-2.4.10-pre5/arch/sh/mm/copy_page.S linux/arch/sh/mm/copy_page.S
--- linux-2.4.10-pre5/arch/sh/mm/copy_page.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sh/mm/copy_page.S	Mon Dec  3 23:08:12 2001
@@ -0,0 +1,69 @@
+/* $Id: copy_page.S,v 1.2 2001/07/23 10:27:25 gniibe Exp $
+ *
+ * copy_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ *
+ */
+
+/*
+ * copy_page
+ * @to: P1 address
+ * @from: P1 address
+ *
+ * void copy_page(void *to, void *from)
+ */
+
+/*
+ * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch 
+ * r8 --- from + 4096
+ * r9 --- not used
+ * r10 --- to
+ * r11 --- from
+ */
+#include <linux/linkage.h>
+ENTRY(copy_page)
+	mov.l	r8,@-r15
+	mov.l	r10,@-r15
+	mov.l	r11,@-r15
+	mov	r4,r10
+	mov	r5,r11
+	mov	r5,r8
+	mov.w	.L4096,r0
+	add	r0,r8
+	!
+1:	mov.l	@r11+,r0
+	mov.l	@r11+,r1
+	mov.l	@r11+,r2
+	mov.l	@r11+,r3
+	mov.l	@r11+,r4
+	mov.l	@r11+,r5
+	mov.l	@r11+,r6
+	mov.l	@r11+,r7
+#if defined(__sh3__)
+	mov.l	r0,@r10
+#elif defined(__SH4__)
+	movca.l	r0,@r10
+	mov	r10,r0
+#endif
+	add	#32,r10
+	mov.l	r7,@-r10
+	mov.l	r6,@-r10
+	mov.l	r5,@-r10
+	mov.l	r4,@-r10
+	mov.l	r3,@-r10
+	mov.l	r2,@-r10
+	mov.l	r1,@-r10
+#if defined(__SH4__)
+	ocbwb	@r0
+#endif
+	cmp/eq	r11,r8
+	bf/s	1b
+	 add	#28,r10
+	!
+	mov.l	@r15+,r11
+	mov.l	@r15+,r10
+	mov.l	@r15+,r8
+	rts
+	 nop
+.L4096:	.word	4096
diff -urN linux-2.4.10-pre5/arch/sh/mm/extable.c linux/arch/sh/mm/extable.c
--- linux-2.4.10-pre5/arch/sh/mm/extable.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/mm/extable.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: extable.c,v 1.1 1999/09/18 16:57:37 gniibe Exp $
+/* $Id: extable.c,v 1.2 2001/03/31 10:43:18 gniibe Exp $
  *
  * linux/arch/sh/mm/extable.c
  *  Taken from:
diff -urN linux-2.4.10-pre5/arch/sh/mm/fault.c linux/arch/sh/mm/fault.c
--- linux-2.4.10-pre5/arch/sh/mm/fault.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/mm/fault.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.13 2000/03/07 12:05:24 gniibe Exp $
+/* $Id: fault.c,v 1.48 2001/08/09 00:27:04 gniibe Exp $
  *
  *  linux/arch/sh/mm/fault.c
  *  Copyright (C) 1999  Niibe Yutaka
@@ -28,10 +28,6 @@
 #include <asm/mmu_context.h>
 
 extern void die(const char *,struct pt_regs *,long);
-static void __flush_tlb_page(unsigned long asid, unsigned long page);
-#if defined(__SH4__)
-static void __flush_tlb_phys(unsigned long phys);
-#endif
 
 /*
  * Ugly, ugly, but the goto's result in better assembly..
@@ -242,8 +238,10 @@
 	pte_t *pte;
 	pte_t entry;
 
-	if (address >= VMALLOC_START && address < VMALLOC_END)
+	if (address >= P3SEG && address < P4SEG)
 		dir = pgd_offset_k(address);
+	else if (address >= TASK_SIZE)
+		return 1;
 	else
 		dir = pgd_offset(current->mm, address);
 
@@ -257,7 +255,7 @@
 	}
 	pte = pte_offset(pmd, address);
 	entry = *pte;
-	if (pte_none(entry) || !pte_present(entry)
+	if (pte_none(entry) || pte_not_present(entry)
 	    || (writeaccess && !pte_write(entry)))
 		return 1;
 
@@ -283,27 +281,24 @@
 	unsigned long pteval;
 	unsigned long vpn;
 #if defined(__SH4__)
+	struct page *page;
 	unsigned long ptea;
 #endif
 
-	save_and_cli(flags);
-#if defined(__SH4__)
-	if (pte_shared(pte)) {
-		struct page *pg;
+	/* Ptrace may call this routine. */
+	if (vma && current->active_mm != vma->vm_mm)
+		return;
 
-		pteval = pte_val(pte);
-		pteval &= PAGE_MASK; /* Physicall page address */
-		__flush_tlb_phys(pteval);
-		pg = virt_to_page(__va(pteval));
-		flush_dcache_page(pg);
+#if defined(__SH4__)
+	page = pte_page(pte);
+	if (VALID_PAGE(page) && !test_bit(PG_mapped, &page->flags)) {
+		unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+		__flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
+		__set_bit(PG_mapped, &page->flags);
 	}
 #endif
 
-	/* Ptrace may call this routine. */
-	if (vma && current->active_mm != vma->vm_mm) {
-		restore_flags(flags);
-		return;
-	}
+	save_and_cli(flags);
 
 	/* Set PTEH register */
 	vpn = (address & MMU_VPN_MASK) | get_asid();
@@ -327,7 +322,7 @@
 	restore_flags(flags);
 }
 
-static void __flush_tlb_page(unsigned long asid, unsigned long page)
+void __flush_tlb_page(unsigned long asid, unsigned long page)
 {
 	unsigned long addr, data;
 
@@ -349,40 +344,6 @@
 	back_to_P1();
 #endif
 }
-
-#if defined(__SH4__)
-static void __flush_tlb_phys(unsigned long phys)
-{
-	unsigned long addr, data, pte;
-
-	pte = phys | MMU_UTLB_VALID;
-	for (addr = MMU_UTLB_DATA_ARRAY;
-	     addr < MMU_UTLB_DATA_ARRAY+(MMU_UTLB_ENTRIES<<MMU_U_ENTRY_SHIFT);
-	     addr += (1<<MMU_U_ENTRY_SHIFT)) {
-		data = ctrl_inl(addr);
-		if ((data & (MMU_UTLB_VALID|PAGE_MASK)) == pte) {
-			data &= ~MMU_UTLB_VALID;
-			jump_to_P2();
-			ctrl_outl(data, addr);
-			back_to_P1();
-			break;
-		}
-	}
-	pte = phys | MMU_ITLB_VALID;
-	for (addr = MMU_ITLB_DATA_ARRAY;
-	     addr < MMU_ITLB_DATA_ARRAY+(MMU_ITLB_ENTRIES<<MMU_I_ENTRY_SHIFT);
-	     addr += (1<<MMU_I_ENTRY_SHIFT)) {
-		data = ctrl_inl(addr);
-		if ((data & (MMU_ITLB_VALID|PAGE_MASK)) == pte) {
-			data &= ~MMU_ITLB_VALID;
-			jump_to_P2();
-			ctrl_outl(data, addr);
-			back_to_P1();
-			break;
-		}
-	}
-}
-#endif
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
diff -urN linux-2.4.10-pre5/arch/sh/mm/init.c linux/arch/sh/mm/init.c
--- linux-2.4.10-pre5/arch/sh/mm/init.c	Wed Jun 27 13:55:29 2001
+++ linux/arch/sh/mm/init.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.17 2000-04-08 15:38:54+09 gniibe Exp $
+/* $Id: init.c,v 1.18 2001/08/03 11:22:06 gniibe Exp $
  *
  *  linux/arch/sh/mm/init.c
  *
@@ -40,35 +40,14 @@
  */
 unsigned long mmu_context_cache;
 
+#ifdef CONFIG_DISCONTIGMEM
+pg_data_t discontig_page_data[NR_NODES];
+bootmem_data_t discontig_node_bdata[NR_NODES];
+#endif
+
 static unsigned long totalram_pages;
 static unsigned long totalhigh_pages;
 
-extern unsigned long init_smp_mappings(unsigned long);
-
-extern unsigned long empty_zero_page[1024];
-
-int do_check_pgt_cache(int low, int high)
-{
-	int freed = 0;
-	if (pgtable_cache_size > high) {
-		do {
-			if (pgd_quicklist) {
-				free_pgd_slow(get_pgd_fast());
-				freed++;
-			}
-			if (pmd_quicklist) {
-				pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
-				freed++;
-			}
-			if (pte_quicklist) {
-				pte_free_slow(pte_alloc_one_fast(NULL, 0));
-				freed++;
-			}
-		} while (pgtable_cache_size > low);
-	}
-	return freed;
-}
-
 void show_mem(void)
 {
 	int i, total = 0, reserved = 0;
@@ -91,7 +70,6 @@
 	printk("%d reserved pages\n",reserved);
 	printk("%d pages shared\n",shared);
 	printk("%d pages swap cached\n",cached);
-	printk("%ld pages in page table cache\n",pgtable_cache_size);
 	show_buffers();
 }
 
@@ -146,12 +124,18 @@
 			zones_size[ZONE_DMA] = max_dma - start_pfn;
 			zones_size[ZONE_NORMAL] = low - max_dma;
 		}
-		free_area_init_node(0, 0, 0, zones_size, __MEMORY_START, 0);
+		free_area_init_node(0, NODE_DATA(0), 0, zones_size, __MEMORY_START, 0);
+#ifdef CONFIG_DISCONTIGMEM
+		zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT;
+		zones_size[ZONE_NORMAL] = 0;
+		free_area_init_node(1, NODE_DATA(1), 0, zones_size, __MEMORY_START_2ND, 0);
+#endif
  	}
 }
 
 void __init mem_init(void)
 {
+	extern unsigned long empty_zero_page[1024];
 	int codesize, reservedpages, datasize, initsize;
 	int tmp;
 
@@ -160,10 +144,13 @@
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
-	flush_page_to_ram(virt_to_page(empty_zero_page));
+	__flush_wback_region(empty_zero_page, PAGE_SIZE);
 
 	/* this will put all low memory onto the freelists */
-	totalram_pages += free_all_bootmem();
+	totalram_pages += free_all_bootmem_node(NODE_DATA(0));
+#ifdef CONFIG_DISCONTIGMEM
+	totalram_pages += free_all_bootmem_node(NODE_DATA(1));
+#endif
 	reservedpages = 0;
 	for (tmp = 0; tmp < num_physpages; tmp++)
 		/*
@@ -182,6 +169,8 @@
 		reservedpages << (PAGE_SHIFT-10),
 		datasize >> 10,
 		initsize >> 10);
+
+	p3_cache_init();
 }
 
 void free_initmem(void)
diff -urN linux-2.4.10-pre5/arch/sh/mm/ioremap.c linux/arch/sh/mm/ioremap.c
--- linux-2.4.10-pre5/arch/sh/mm/ioremap.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/mm/ioremap.c	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: ioremap.c,v 1.2 1999/11/25 14:00:28 gniibe Exp $
+/* $Id: ioremap.c,v 1.4 2001/06/30 09:18:39 gniibe Exp $
  *
  * arch/sh/mm/ioremap.c
  *
@@ -13,8 +13,8 @@
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+	unsigned long size, unsigned long phys_addr, unsigned long flags)
 {
 	unsigned long end;
 	pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW |
@@ -36,11 +36,11 @@
 		address += PAGE_SIZE;
 		phys_addr += PAGE_SIZE;
 		pte++;
-	} while (address && address < end);
+	} while (address && (address < end));
 }
 
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+	unsigned long size, unsigned long phys_addr, unsigned long flags)
 {
 	unsigned long end;
 
@@ -58,19 +58,19 @@
 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
-	} while (address && address < end);
+	} while (address && (address < end));
 	return 0;
 }
 
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
-			    unsigned long size, unsigned long flags)
+int remap_area_pages(unsigned long address, unsigned long phys_addr,
+		     unsigned long size, unsigned long flags)
 {
 	int error;
 	pgd_t * dir;
 	unsigned long end = address + size;
 
 	phys_addr -= address;
-	dir = pgd_offset(&init_mm, address);
+	dir = pgd_offset_k(address);
 	flush_cache_all();
 	if (address >= end)
 		BUG();
@@ -106,7 +106,7 @@
  * have to convert them into an offset in a page-aligned mapping, but the
  * caller shouldn't need to know that small detail.
  */
-void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
 {
 	void * addr;
 	struct vm_struct * area;
@@ -150,7 +150,7 @@
 	return (void *) (offset + (char *)addr);
 }
 
-void iounmap(void *addr)
+void p3_iounmap(void *addr)
 {
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
diff -urN linux-2.4.10-pre5/arch/sh/vmlinux.lds.S linux/arch/sh/vmlinux.lds.S
--- linux-2.4.10-pre5/arch/sh/vmlinux.lds.S	Mon Jul  2 14:40:58 2001
+++ linux/arch/sh/vmlinux.lds.S	Mon Dec  3 23:08:12 2001
@@ -1,4 +1,4 @@
-/* $Id: vmlinux.lds.S,v 1.4 1999/12/23 11:37:45 gniibe Exp $
+/* $Id: vmlinux.lds.in,v 1.5 2001/07/27 11:45:55 gniibe Exp $
  * ld script to make SuperH Linux kernel
  * Written by Niibe Yutaka
  */
@@ -74,7 +74,11 @@
   . = ALIGN(4096);
   .data.page_aligned : { *(.data.idt) }
 
+#ifdef CONFIG_CPU_SH3	
+  . = ALIGN(16);
+#else
   . = ALIGN(32);
+#endif	
   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
 
   . = ALIGN(4);
diff -urN linux-2.4.10-pre5/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- linux-2.4.10-pre5/drivers/acorn/block/mfmhd.c	Sun Aug 12 10:38:48 2001
+++ linux/drivers/acorn/block/mfmhd.c	Mon Dec  3 23:08:13 2001
@@ -1450,10 +1450,7 @@
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB?) read ahread */
 
-#ifndef MODULE
-	mfm_gendisk.next = gendisk_head;
-	gendisk_head = &mfm_gendisk;
-#endif
+	add_gendisk(&mfm_gendisk);
 
 	Busy = 0;
 	lastspecifieddrive = -1;
@@ -1512,6 +1509,7 @@
 		outw (0, mfm_irqenable);	/* Required to enable IRQs from MFM podule */
 	free_irq(mfm_irq, NULL);
 	unregister_blkdev(MAJOR_NR, "mfm");
+	del_gendisk(&mfm_gendisk);
 	if (ecs)
 		ecard_release(ecs);
 	if (mfm_addr)
diff -urN linux-2.4.10-pre5/drivers/acpi/Makefile linux/drivers/acpi/Makefile
--- linux-2.4.10-pre5/drivers/acpi/Makefile	Wed Jun 20 17:47:39 2001
+++ linux/drivers/acpi/Makefile	Mon Dec  3 23:08:13 2001
@@ -38,9 +38,8 @@
 obj-$(CONFIG_ACPI)	+= $(foreach dir,$(acpi-subdirs),$(dir)/$(dir).o) 
 ifdef CONFIG_ACPI_KERNEL_CONFIG
    obj-$(CONFIG_ACPI) 	+= acpiconf.o osconf.o
-else
-   obj-$(CONFIG_ACPI)	+= driver.o
 endif
+obj-$(CONFIG_ACPI)	+= driver.o
 
 ifeq ($(CONFIG_ACPI_BUSMGR),y)
 	obj-y			+= ospm/ospm.o
diff -urN linux-2.4.10-pre5/drivers/atm/firestream.c linux/drivers/atm/firestream.c
--- linux-2.4.10-pre5/drivers/atm/firestream.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/atm/firestream.c	Wed Apr 11 19:02:30 2001
@@ -295,7 +295,6 @@
 
 
 static int fs_keystream = 0;
-static int fs_maxphy = 1;
 
 #ifdef DEBUG
 /* I didn't forget to set this to zero before shipping. Hit me with a stick 
@@ -309,7 +308,6 @@
 #ifdef DEBUG 
 MODULE_PARM(fs_debug, "i");
 #endif
-MODULE_PARM(fs_maxphy, "i");
 MODULE_PARM(loopback, "i");
 MODULE_PARM(num, "i");
 MODULE_PARM(fs_keystream, "i");
@@ -868,7 +866,6 @@
 	int bfp;
 	int to;
 	unsigned short tmc0;
-	int uaddr;
 
 	func_enter ();
 
@@ -911,9 +908,6 @@
 	txtp = &atm_vcc->qos.txtp;
 	rxtp = &atm_vcc->qos.rxtp;
 
-	/* XXX Use VPI? How many bits? Which bits? */
-	uaddr = atm_vcc->dev->number - dev->start_number;
-
 	if (!test_bit(ATM_VF_PARTIAL, &atm_vcc->flags)) {
 		if (IS_FS50(dev)) {
 			/* Increment the channel numer: take a free one next time.  */
@@ -1018,7 +1012,7 @@
 		tc->TMC[2] = 0; /* Unused */
 		tc->TMC[3] = 0; /* Unused */
     
-		tc->spec = uaddr << 16;  /* UTOPIA address, UDF, HEC: Unused -> 0 */
+		tc->spec = 0;    /* UTOPIA address, UDF, HEC: Unused -> 0 */
 		tc->rtag[0] = 0; /* What should I do with routing tags??? 
 				    -- Not used -- AS -- Thanks -- REW*/
 		tc->rtag[1] = 0;
@@ -1087,7 +1081,7 @@
 			submit_command (dev, &dev->hp_txq, 
 					QE_CMD_REG_WR | QE_CMD_IMM_INQ,
 					0x80 + vcc->channo,
-					(uaddr << 28) | (vpi << 16) | vci, 0 ); /* XXX -- Use defines. */
+					(vpi << 16) | vci, 0 ); /* XXX -- Use defines. */
 		}
 		submit_command (dev, &dev->hp_txq, 
 				QE_CMD_RX_EN | QE_CMD_IMM_INQ | vcc->channo,
@@ -1778,10 +1772,8 @@
 
 	if (IS_FS50 (dev)) {
 		write_fs (dev, RAS0, RAS0_DCD_XHLT);
-		for (i=0;i<fs_maxphy;i++) {
-			dev->atm_dev[i]->ci_range.vpi_bits = 12;
-			dev->atm_dev[i]->ci_range.vci_bits = 16;
-		}
+		dev->atm_dev->ci_range.vpi_bits = 12;
+		dev->atm_dev->ci_range.vci_bits = 16;
 		dev->nchannels = FS50_NR_CHANNELS;
 	} else {
 		write_fs (dev, RAS0, RAS0_DCD_XHLT 
@@ -1789,10 +1781,8 @@
 			  | (((1 << FS155_VCI_BITS) - 1) * RAS0_VCSEL));
 		/* We can chose the split arbitarily. We might be able to 
 		   support more. Whatever. This should do for now. */
-		for (i=0;i<fs_maxphy;i++) {
-			dev->atm_dev[i]->ci_range.vpi_bits = FS155_VPI_BITS;
-			dev->atm_dev[i]->ci_range.vci_bits = FS155_VCI_BITS;
-		}
+		dev->atm_dev->ci_range.vpi_bits = FS155_VPI_BITS;
+		dev->atm_dev->ci_range.vci_bits = FS155_VCI_BITS;
     
 		/* Address bits we can't use should be compared to 0. */
 		write_fs (dev, RAC, 0);
@@ -1827,14 +1817,9 @@
 	}
 	memset (dev->tx_inuse, 0, dev->nchannels / 8);
 
-	if (IS_FS50 (dev)) {
-		/* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for FS155, FS50/multiphy needs the maxPHY set... */
-		write_fs (dev, RAS1, (fs_maxphy - 1) * RAS1_UTREG);
+	/* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */
+	/* -- RAS2 : FS50 only: Default is OK. */
 
-		/* -- RAS2 : FS50 only: Default is OK. */
-		/* Enable selecting for Utopia address for multiphy configs. */
-		write_fs (dev, RAS2, RAS2_USEL);
-	}
 	/* DMAMODE, default should be OK. -- REW */
 	write_fs (dev, DMAMR, DMAMR_TX_MODE_FULL);
 
@@ -1903,8 +1888,7 @@
 	add_timer (&dev->timer);
 #endif
 
-	for (i=0;i<fs_maxphy;i++)
-		dev->atm_dev[i]->dev_data = dev;
+	dev->atm_dev->dev_data = dev;
   
 	func_exit ();
 	return 0;
@@ -1913,9 +1897,9 @@
 static int __init firestream_init_one (struct pci_dev *pci_dev,
 				       const struct pci_device_id *ent) 
 {
+	struct atm_dev *atm_dev;
 	struct fs_dev *fs_dev;
-	int i;
-
+	
 	if (pci_enable_device(pci_dev)) 
 		goto err_out;
 
@@ -1926,17 +1910,13 @@
 		goto err_out;
 
 	memset (fs_dev, 0, sizeof (struct fs_dev));
-
-	for (i=0;i<fs_maxphy;i++) {
-		fs_dev->atm_dev[i] = atm_dev_register("fs", &ops, -1, NULL);
-		if (!fs_dev->atm_dev[i])
-			goto err_out_free_atm_dev;
-	}
-	/* XXX if another device is registering atm devices at the same time
-	   we get confusion.  */
-	fs_dev->start_number = fs_dev->atm_dev[0]->number;
-
+  
+	atm_dev = atm_dev_register("fs", &ops, -1, NULL);
+	if (!atm_dev)
+		goto err_out_free_fs_dev;
+  
 	fs_dev->pci_dev = pci_dev;
+	fs_dev->atm_dev = atm_dev;
 	fs_dev->flags = ent->driver_data;
 
 	if (fs_init(fs_dev))
@@ -1947,8 +1927,7 @@
 	return 0;
 
  err_out_free_atm_dev:
-	for (i--;i >= 0;i--)
-		atm_dev_deregister(fs_dev->atm_dev[i]);
+	atm_dev_deregister(atm_dev);
  err_out_free_fs_dev:
 	kfree(fs_dev);
  err_out:
@@ -2023,9 +2002,7 @@
 		free_irq (dev->irq, dev);
 		del_timer (&dev->timer);
 
-		for (i=0;i<fs_maxphy;i++)
-			atm_dev_deregister(dev->atm_dev[i]);
-
+		atm_dev_deregister(dev->atm_dev);
 		free_queue (dev, &dev->hp_txq);
 		free_queue (dev, &dev->lp_txq);
 		free_queue (dev, &dev->tx_relq);
diff -urN linux-2.4.10-pre5/drivers/atm/firestream.h linux/drivers/atm/firestream.h
--- linux-2.4.10-pre5/drivers/atm/firestream.h	Mon Dec  3 23:08:03 2001
+++ linux/drivers/atm/firestream.h	Mon Dec  3 23:08:13 2001
@@ -466,7 +466,6 @@
 	int n;
 };
 
-#define MAX_PHY 0x20
 
 struct fs_dev {
 	struct fs_dev *next;		/* other FS devices */
@@ -474,9 +473,8 @@
 
 	unsigned char irq;		/* IRQ */
 	struct pci_dev *pci_dev;	/* PCI stuff */
-	struct atm_dev *atm_dev[MAX_PHY];
+	struct atm_dev *atm_dev;
 	struct timer_list timer;
-	int start_number; 
 
 	unsigned long hw_base;		/* mem base address */
 	unsigned long base;             /* Mapping of base address */
diff -urN linux-2.4.10-pre5/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- linux-2.4.10-pre5/drivers/block/DAC960.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/block/DAC960.c	Mon Dec  3 23:08:13 2001
@@ -1938,13 +1938,7 @@
   /*
     Install the Generic Disk Information structure at the end of the list.
   */
-  if ((GenericDiskInfo = gendisk_head) != NULL)
-    {
-      while (GenericDiskInfo->next != NULL)
-	GenericDiskInfo = GenericDiskInfo->next;
-      GenericDiskInfo->next = &Controller->GenericDiskInfo;
-    }
-  else gendisk_head = &Controller->GenericDiskInfo;
+  add_gendisk(&Controller->GenericDiskInfo);
   /*
     Indicate the Block Device Registration completed successfully,
   */
@@ -1980,16 +1974,7 @@
   /*
     Remove the Generic Disk Information structure from the list.
   */
-  if (gendisk_head != &Controller->GenericDiskInfo)
-    {
-      GenericDiskInfo_T *GenericDiskInfo = gendisk_head;
-      while (GenericDiskInfo != NULL &&
-	     GenericDiskInfo->next != &Controller->GenericDiskInfo)
-	GenericDiskInfo = GenericDiskInfo->next;
-      if (GenericDiskInfo != NULL)
-	GenericDiskInfo->next = GenericDiskInfo->next->next;
-    }
-  else gendisk_head = Controller->GenericDiskInfo.next;
+  del_gendisk(&Controller->GenericDiskInfo);
 }
 
 
diff -urN linux-2.4.10-pre5/drivers/block/acsi.c linux/drivers/block/acsi.c
--- linux-2.4.10-pre5/drivers/block/acsi.c	Wed Aug 15 01:22:15 2001
+++ linux/drivers/block/acsi.c	Mon Dec  3 23:08:13 2001
@@ -1792,8 +1792,7 @@
 	
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	read_ahead[MAJOR_NR] = 8;		/* 8 sector (4kB) read-ahead */
-	acsi_gendisk.next = gendisk_head;
-	gendisk_head = &acsi_gendisk;
+	add_gendisk(&acsi_gendisk);
 
 #ifdef CONFIG_ATARI_SLM
 	err = slm_init();
@@ -1817,8 +1816,6 @@
 
 void cleanup_module(void)
 {
-	struct gendisk ** gdp;
-
 	del_timer( &acsi_timer );
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 	atari_stram_free( acsi_buffer );
@@ -1826,13 +1823,7 @@
 	if (devfs_unregister_blkdev( MAJOR_NR, "ad" ) != 0)
 		printk( KERN_ERR "acsi: cleanup_module failed\n");
 
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-		if (*gdp == &acsi_gendisk)
-			break;
-	if (!*gdp)
-		printk( KERN_ERR "acsi: entry in disk chain missing!\n" );
-	else
-		*gdp = (*gdp)->next;
+	del_gendisk(&acsi_gendisk);
 }
 #endif
 
diff -urN linux-2.4.10-pre5/drivers/block/blkpg.c linux/drivers/block/blkpg.c
--- linux-2.4.10-pre5/drivers/block/blkpg.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/block/blkpg.c	Mon Dec  3 23:08:13 2001
@@ -54,17 +54,6 @@
  * Note that several drives may have the same major.
  */
 
-/* a linear search, superfluous when dev is a pointer */
-static struct gendisk *get_gendisk(kdev_t dev) {
-	struct gendisk *g;
-	int m = MAJOR(dev);
-
-	for (g = gendisk_head; g; g = g->next)
-		if (g->major == m)
-			break;
-	return g;
-}
-
 /*
  * Add a partition.
  *
diff -urN linux-2.4.10-pre5/drivers/block/cciss.c linux/drivers/block/cciss.c
--- linux-2.4.10-pre5/drivers/block/cciss.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/block/cciss.c	Mon Dec  3 23:08:13 2001
@@ -1965,8 +1965,7 @@
 	hba[i]->gendisk.nr_real = hba[i]->num_luns;
 
 	/* Get on the disk list */ 
-	hba[i]->gendisk.next = gendisk_head;
-	gendisk_head = &(hba[i]->gendisk); 
+	add_gendisk(&(hba[i]->gendisk));
 
 	cciss_geninit(i);
 	for(j=0; j<NWD; j++)
@@ -1982,7 +1981,6 @@
 {
 	ctlr_info_t *tmp_ptr;
 	int i;
-	struct gendisk *g;
 
 	if (pdev->driver_data == NULL)
 	{
@@ -2007,19 +2005,8 @@
 	
 
 	/* remove it from the disk list */
-	if (gendisk_head == &(hba[i]->gendisk))
-	{
-		gendisk_head = hba[i]->gendisk.next;
-	} else
-	{
-		for(g=gendisk_head; g ; g=g->next)
-		{
-			if(g->next == &(hba[i]->gendisk))
-			{
-				g->next = hba[i]->gendisk.next;
-			}
-		}
-	}
+	del_gendisk(&(hba[i]->gendisk));
+
 	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), 
 		hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
 	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
diff -urN linux-2.4.10-pre5/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- linux-2.4.10-pre5/drivers/block/cpqarray.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/block/cpqarray.c	Mon Dec  3 23:08:13 2001
@@ -311,7 +311,6 @@
 void cleanup_module(void)
 {
 	int i;
-	struct gendisk *g;
 	char buff[4]; 
 
 	for(i=0; i<nr_ctlr; i++) {
@@ -335,16 +334,7 @@
 			hba[i]->cmd_pool_dhandle);
 		kfree(hba[i]->cmd_pool_bits);
 
-		if (gendisk_head == &ida_gendisk[i]) {
-			gendisk_head = ida_gendisk[i].next;
-		} else {
-			for(g=gendisk_head; g; g=g->next) {
-				if (g->next == &ida_gendisk[i]) {
-					g->next = ida_gendisk[i].next;
-					break;
-				}
-			}
-		}
+		del_gendisk(&ida_gendisk[i]);
 	}
 	remove_proc_entry("cpqarray", proc_root_driver);
 	kfree(ida);
@@ -550,8 +540,7 @@
 		ida_gendisk[i].nr_real = 0; 
 	
 		/* Get on the disk list */
-		ida_gendisk[i].next = gendisk_head;
-		gendisk_head = &ida_gendisk[i];
+		add_gendisk(&ida_gendisk[i]);
 
 		init_timer(&hba[i]->timer);
 		hba[i]->timer.expires = jiffies + IDA_TIMER;
diff -urN linux-2.4.10-pre5/drivers/block/genhd.c linux/drivers/block/genhd.c
--- linux-2.4.10-pre5/drivers/block/genhd.c	Thu Jul 19 17:48:15 2001
+++ linux/drivers/block/genhd.c	Mon Dec  3 23:08:13 2001
@@ -17,6 +17,75 @@
 #include <linux/blk.h>
 #include <linux/init.h>
 
+
+struct gendisk *gendisk_head;
+
+void
+add_gendisk(struct gendisk *gp)
+{
+	gp->next = gendisk_head;
+	gendisk_head = gp;
+}
+
+void
+del_gendisk(struct gendisk *gp)
+{
+	struct gendisk **gpp;
+
+	for (gpp = &gendisk_head; *gpp; gpp = &((*gpp)->next))
+		if (*gpp == gp)
+			break;
+	if (*gpp)
+		*gpp = (*gpp)->next;
+}
+
+struct gendisk *
+get_gendisk(kdev_t dev)
+{
+	struct gendisk *gp = NULL;
+	int maj = MAJOR(dev);
+
+	for (gp = gendisk_head; gp; gp = gp->next)
+		if (gp->major == maj)
+			return gp;
+	return NULL;
+}
+
+#ifdef CONFIG_PROC_FS
+int
+get_partition_list(char *page, char **start, off_t offset, int count)
+{
+	struct gendisk *gp;
+	char buf[64];
+	int len, n;
+
+	len = sprintf(page, "major minor  #blocks  name\n\n");
+	for (gp = gendisk_head; gp; gp = gp->next) {
+		for (n = 0; n < (gp->nr_real << gp->minor_shift); n++) {
+			if (gp->part[n].nr_sects == 0)
+				continue;
+
+			len += snprintf(page + len, 63,
+					"%4d  %4d %10d %s\n",
+					gp->major, n, gp->sizes[n],
+					disk_name(gp, n, buf));
+			if (len < offset)
+				offset -= len, len = 0;
+			else if (len >= offset + count)
+				goto out;
+		}
+	}
+
+out:
+	*start = page + offset;
+	len -= offset;
+	if (len < 0)
+		len = 0;
+	return len > count ? count : len;
+}
+#endif
+
+
 extern int blk_dev_init(void);
 #ifdef CONFIG_BLK_DEV_DAC960
 extern void DAC960_Initialize(void);
diff -urN linux-2.4.10-pre5/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux-2.4.10-pre5/drivers/block/ll_rw_blk.c	Fri Aug  3 22:37:09 2001
+++ linux/drivers/block/ll_rw_blk.c	Mon Dec  3 23:08:13 2001
@@ -131,7 +131,7 @@
 	return max_sectors[MAJOR(dev)][MINOR(dev)];
 }
 
-inline request_queue_t *__blk_get_queue(kdev_t dev)
+inline request_queue_t *blk_get_queue(kdev_t dev)
 {
 	struct blk_dev_struct *bdev = blk_dev + MAJOR(dev);
 
@@ -141,22 +141,6 @@
 		return &blk_dev[MAJOR(dev)].request_queue;
 }
 
-/*
- * NOTE: the device-specific queue() functions
- * have to be atomic!
- */
-request_queue_t *blk_get_queue(kdev_t dev)
-{
-	request_queue_t *ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&io_request_lock,flags);
-	ret = __blk_get_queue(dev);
-	spin_unlock_irqrestore(&io_request_lock,flags);
-
-	return ret;
-}
-
 static int __blk_cleanup_queue(struct list_head *head)
 {
 	struct request *rq;
@@ -1272,7 +1256,6 @@
 EXPORT_SYMBOL(end_that_request_last);
 EXPORT_SYMBOL(blk_init_queue);
 EXPORT_SYMBOL(blk_get_queue);
-EXPORT_SYMBOL(__blk_get_queue);
 EXPORT_SYMBOL(blk_cleanup_queue);
 EXPORT_SYMBOL(blk_queue_headactive);
 EXPORT_SYMBOL(blk_queue_make_request);
diff -urN linux-2.4.10-pre5/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
--- linux-2.4.10-pre5/drivers/block/paride/pd.c	Sat Apr 28 11:27:53 2001
+++ linux/drivers/block/paride/pd.c	Mon Dec  3 23:08:13 2001
@@ -455,8 +455,7 @@
         
 	pd_gendisk.major = major;
 	pd_gendisk.major_name = name;
-	pd_gendisk.next = gendisk_head;
-	gendisk_head = &pd_gendisk;
+	add_gendisk(&pd_gendisk);
 
 	for(i=0;i<PD_DEVS;i++) pd_blocksizes[i] = 1024;
 	blksize_size[MAJOR_NR] = pd_blocksizes;
@@ -642,12 +641,7 @@
 	int unit;
 
         devfs_unregister_blkdev(MAJOR_NR,name);
-        for(gdp=&gendisk_head;*gdp;gdp=&((*gdp)->next))
-                if (*gdp == &pd_gendisk) break;
-        if (*gdp) *gdp = (*gdp)->next;
-
-	for (unit=0;unit<PD_UNITS;unit++) 
-	   if (PD.present) pi_release(PI);
+	del_gendisk(&pd_gendisk);
 }
 
 #endif
diff -urN linux-2.4.10-pre5/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- linux-2.4.10-pre5/drivers/block/ps2esdi.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/block/ps2esdi.c	Mon Dec  3 23:08:13 2001
@@ -184,8 +184,7 @@
 	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read ahead */
 
 	/* some minor housekeeping - setup the global gendisk structure */
-	ps2esdi_gendisk.next = gendisk_head;
-	gendisk_head = &ps2esdi_gendisk;
+	add_gendisk(&ps2esdi_gendisk);
 	ps2esdi_geninit();
 	return 0;
 }				/* ps2esdi_init */
@@ -232,6 +231,7 @@
 	free_dma(dma_arb_level);
   	free_irq(PS2ESDI_IRQ, NULL)
 	devfs_unregister_blkdev(MAJOR_NR, "ed");
+	del_gendisk(&ps2esdi_gendisk);
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 }
 #endif /* MODULE */
diff -urN linux-2.4.10-pre5/drivers/block/xd.c linux/drivers/block/xd.c
--- linux-2.4.10-pre5/drivers/block/xd.c	Thu May 24 15:14:08 2001
+++ linux/drivers/block/xd.c	Mon Dec  3 23:08:13 2001
@@ -173,8 +173,7 @@
 	devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read ahead */
-	xd_gendisk.next = gendisk_head;
-	gendisk_head = &xd_gendisk;
+	add_gendisk(&xd_gendisk);
 	xd_geninit();
 
 	return 0;
@@ -1112,18 +1111,12 @@
 
 static void xd_done (void)
 {
-	struct gendisk ** gdp;
-	
 	blksize_size[MAJOR_NR] = NULL;
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 	blk_size[MAJOR_NR] = NULL;
 	hardsect_size[MAJOR_NR] = NULL;
 	read_ahead[MAJOR_NR] = 0;
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-		if (*gdp == &xd_gendisk)
-			break;
-	if (*gdp)
-		*gdp = (*gdp)->next;
+	del_gendisk(&xd_gendisk);
 	release_region(xd_iobase,4);
 }
 
diff -urN linux-2.4.10-pre5/drivers/char/sh-sci.c linux/drivers/char/sh-sci.c
--- linux-2.4.10-pre5/drivers/char/sh-sci.c	Wed Jun 27 13:55:29 2001
+++ linux/drivers/char/sh-sci.c	Mon Dec  3 23:08:13 2001
@@ -44,7 +44,7 @@
 
 #include <linux/generic_serial.h>
 
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#ifdef CONFIG_SH_STANDARD_BIOS
 #include <asm/sh_bios.h>
 #endif
 
@@ -94,6 +94,7 @@
 
 #define dprintk(x...) do { if (sci_debug) printk(x); } while(0)
 
+#ifdef CONFIG_SERIAL_CONSOLE
 static void put_char(struct sci_port *port, char c)
 {
 	unsigned long flags;
@@ -111,8 +112,9 @@
 
 	restore_flags(flags);
 }
+#endif
 
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#ifdef CONFIG_SH_STANDARD_BIOS
 
 static void handle_error(struct sci_port *port)
 {				/* Clear error flags */
@@ -161,12 +163,12 @@
  * This routine does not wait for a positive acknowledge.
  */
 
-static void put_string(struct sci_port *port,
-				  const char *buffer, int count)
+#ifdef CONFIG_SERIAL_CONSOLE
+static void put_string(struct sci_port *port, const char *buffer, int count)
 {
 	int i;
 	const unsigned char *p = buffer;
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#ifdef CONFIG_SH_STANDARD_BIOS
 	int checksum;
 
     	/* This call only does a trap the first time it is
@@ -202,7 +204,7 @@
 		put_char(port, *p++);
 	}
 }
-
+#endif
 
 
 static struct real_driver sci_real_driver = {
@@ -1159,7 +1161,7 @@
 
 	sci_init_drivers();
 
-#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+#ifdef CONFIG_SH_STANDARD_BIOS
 	sh_bios_gdb_detach();
 #endif
 	return 0;		/* Return -EIO when not detected */
diff -urN linux-2.4.10-pre5/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- linux-2.4.10-pre5/drivers/i2o/i2o_block.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/i2o/i2o_block.c	Mon Dec  3 23:08:13 2001
@@ -1975,9 +1975,8 @@
 
 	/*
 	 *	Adding i2ob_gendisk into the gendisk list.
-	 */	
-	i2ob_gendisk.next = gendisk_head;
-	gendisk_head = &i2ob_gendisk;
+	 */
+	add_gendisk(&i2ob_gendisk);
 
 	return 0;
 }
@@ -2047,20 +2046,6 @@
 	 */
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 
-	/*
-	 *	Why isnt register/unregister gendisk in the kernel ???
-	 */
-
-	if (gendisk_head == &i2ob_gendisk) {
-		gendisk_head = i2ob_gendisk.next;
-		}
-	else {
-		for (gdp = gendisk_head; gdp; gdp = gdp->next)
-			if (gdp->next == &i2ob_gendisk)
-			{
-				gdp->next = i2ob_gendisk.next;
-				break;
-			}
-	}
+	del_gendisk(&i2ob_gendisk);
 }
 #endif
diff -urN linux-2.4.10-pre5/drivers/ide/hd.c linux/drivers/ide/hd.c
--- linux-2.4.10-pre5/drivers/ide/hd.c	Sat Apr 28 11:27:53 2001
+++ linux/drivers/ide/hd.c	Mon Dec  3 23:08:13 2001
@@ -842,8 +842,7 @@
 	}
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 	read_ahead[MAJOR_NR] = 8;		/* 8 sector (4kB) read-ahead */
-	hd_gendisk.next = gendisk_head;
-	gendisk_head = &hd_gendisk;
+	add_gendisk(&hd_gendisk, MAJOR_NR);
 	init_timer(&device_timer);
 	device_timer.function = hd_times_out;
 	hd_geninit();
diff -urN linux-2.4.10-pre5/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.4.10-pre5/drivers/ide/ide-probe.c	Mon Aug 13 15:00:37 2001
+++ linux/drivers/ide/ide-probe.c	Mon Dec  3 23:08:13 2001
@@ -747,7 +747,7 @@
  */
 static void init_gendisk (ide_hwif_t *hwif)
 {
-	struct gendisk *gd, **gdp;
+	struct gendisk *gd;
 	unsigned int unit, units, minors;
 	int *bs, *max_sect, *max_ra;
 	extern devfs_handle_t ide_devfs_handle;
@@ -800,8 +800,8 @@
 	if (gd->flags)
 		memset (gd->flags, 0, sizeof *gd->flags * units);
 
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) ;
-	hwif->gd = *gdp = gd;			/* link onto tail of list */
+	hwif->gd = gd;
+	add_gendisk(gd);
 
 	for (unit = 0; unit < units; ++unit) {
 		if (hwif->drives[unit].present) {
diff -urN linux-2.4.10-pre5/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.4.10-pre5/drivers/ide/ide.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/ide/ide.c	Mon Dec  3 23:08:13 2001
@@ -2059,7 +2059,7 @@
 
 void ide_unregister (unsigned int index)
 {
-	struct gendisk *gd, **gdp;
+	struct gendisk *gd;
 	ide_drive_t *drive, *d;
 	ide_hwif_t *hwif, *g;
 	ide_hwgroup_t *hwgroup;
@@ -2179,13 +2179,9 @@
 	blk_dev[hwif->major].data = NULL;
 	blk_dev[hwif->major].queue = NULL;
 	blksize_size[hwif->major] = NULL;
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-		if (*gdp == hwif->gd)
-			break;
-	if (*gdp == NULL)
-		printk("gd not in disk chain!\n");
-	else {
-		gd = *gdp; *gdp = gd->next;
+	gd = hwif->gd;
+	if (gd) {
+		del_gendisk(gd);
 		kfree(gd->sizes);
 		kfree(gd->part);
 		if (gd->de_arr)
@@ -2193,6 +2189,7 @@
 		if (gd->flags)
 			kfree (gd->flags);
 		kfree(gd);
+		hwif->gd = NULL;
 	}
 	old_hwif		= *hwif;
 	init_hwif_data (index);	/* restore hwif data to pristine status */
diff -urN linux-2.4.10-pre5/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- linux-2.4.10-pre5/drivers/macintosh/macserial.c	Wed Jun 27 13:37:35 2001
+++ linux/drivers/macintosh/macserial.c	Mon Dec  3 23:08:13 2001
@@ -32,7 +32,7 @@
 #endif
 #include <linux/slab.h>
 
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
@@ -185,9 +185,9 @@
 		      dev_t device, const char *routine)
 {
 #ifdef SERIAL_PARANOIA_CHECK
-	static const char *badmagic =
+	static const char badmagic[] = KERN_WARNING
 		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
-	static const char *badinfo =
+	static const char badinfo[] = KERN_WARNING
 		"Warning: null mac_serial for (%d, %d) in %s\n";
 
 	if (!info) {
@@ -418,7 +418,8 @@
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 			static int flip_buf_ovf;
 			if (++flip_buf_ovf <= 1)
-				printk("FB. overflow: %d\n", flip_buf_ovf);
+				printk(KERN_WARNING "FB. overflow: %d\n",
+						    flip_buf_ovf);
 			break;
 		}
 		tty->flip.count++;
@@ -513,7 +514,7 @@
 		if ((status & CTS) == 0) {
 			if (info->tx_stopped) {
 #ifdef SERIAL_DEBUG_FLOW
-				printk("CTS up\n");
+				printk(KERN_DEBUG "CTS up\n");
 #endif
 				info->tx_stopped = 0;
 				if (!info->tx_active)
@@ -521,7 +522,7 @@
 			}
 		} else {
 #ifdef SERIAL_DEBUG_FLOW
-			printk("CTS down\n");
+			printk(KERN_DEBUG "CTS down\n");
 #endif
 			info->tx_stopped = 1;
 		}
@@ -568,7 +569,8 @@
 	int shift;
 
 	if (!(info->flags & ZILOG_INITIALIZED)) {
-		printk("rs_interrupt: irq %d, port not initialized\n", irq);
+		printk(KERN_WARNING "rs_interrupt: irq %d, port not "
+				    "initialized\n", irq);
 		disable_irq(irq);
 		return;
 	}
@@ -589,7 +591,7 @@
 	for (;;) {
 		zs_intreg = read_zsreg(info->zs_chan_a, 3) >> shift;
 #ifdef SERIAL_DEBUG_INTR
-		printk("rs_interrupt: irq %d, zs_intreg 0x%x\n",
+		printk(KERN_DEBUG "rs_interrupt: irq %d, zs_intreg 0x%x\n",
 		       irq, (int)zs_intreg);
 #endif
 
@@ -662,7 +664,7 @@
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 
 #ifdef SERIAL_DEBUG_STOP
-	printk("rs_stop %ld....\n",
+	printk(KERN_DEBUG "rs_stop %ld....\n",
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
@@ -686,7 +688,7 @@
 	unsigned long flags;
 
 #ifdef SERIAL_DEBUG_STOP
-	printk("rs_start %ld....\n", 
+	printk(KERN_DEBUG "rs_start %ld....\n", 
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
@@ -1214,13 +1216,8 @@
 		else
 			feature_set(info->dev_node, FEATURE_Serial_IO_B);
 		delay = 10;
-		if (info->is_cobalt_modem){
-			mdelay(300);
-			feature_set(info->dev_node, FEATURE_Modem_power);
-	   		mdelay(5);
-			feature_clear(info->dev_node, FEATURE_Modem_power);
-	   		mdelay(10);
-			feature_set(info->dev_node, FEATURE_Modem_power);
+		if (info->is_cobalt_modem) {
+			feature_set_modem_power(info->dev_node, 1);
 			delay = 2500;	/* wait for 2.5s before using */
 		}
 #ifdef CONFIG_PMAC_PBOOK
@@ -1228,11 +1225,13 @@
 			pmu_enable_irled(1);
 #endif /* CONFIG_PMAC_PBOOK */
 	} else {
+		/* TODO: Make that depend on a timer, don't power down
+		 * immediately
+		 */
 		PWRDBG("ttyS%02d: shutting down hardware\n", info->line);
 		if (info->is_cobalt_modem) {
 			PWRDBG("ttyS%02d: shutting down modem\n", info->line);
-			feature_clear(info->dev_node, FEATURE_Modem_power);
-			mdelay(10);
+			feature_set_modem_power(info->dev_node, 0);
 		}
 #ifdef CONFIG_PMAC_PBOOK
 		if (info->is_irda)
@@ -1648,7 +1647,7 @@
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
-	printk("throttle %ld....\n",tty->ldisc.chars_in_buffer(tty));
+	printk(KERN_DEBUG "throttle %ld....\n",tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
@@ -1701,7 +1700,8 @@
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
-	printk("unthrottle %s: %d....\n",tty->ldisc.chars_in_buffer(tty));
+	printk(KERN_DEBUG "unthrottle %s: %d....\n",
+			tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
@@ -1855,13 +1855,11 @@
 static int set_modem_info(struct mac_serial *info, unsigned int cmd,
 			  unsigned int *value)
 {
-	int error;
 	unsigned int arg, bits;
 	unsigned long flags;
 
-	error = get_user(arg, value);
-	if (error)
-		return error;
+	if (get_user(arg, value))
+		return -EFAULT;
 	bits = (arg & TIOCM_RTS? RTS: 0) + (arg & TIOCM_DTR? DTR: 0);
 	save_flags(flags); cli();
 	switch (cmd) {
@@ -2000,13 +1998,13 @@
 		 * 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);
+		printk(KERN_ERR "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);
+		printk(KERN_ERR "rs_close: bad serial port count for "
+				"ttys%d: %d\n", info->line, info->count);
 		info->count = 0;
 	}
 	if (info->count) {
@@ -2104,14 +2102,16 @@
 	 * interval should also be less than the timeout.
 	 */
 	if (info->timeout <= HZ/50) {
-		printk("macserial: invalid info->timeout=%d\n", info->timeout);
+		printk(KERN_INFO "macserial: invalid info->timeout=%d\n",
+				    info->timeout);
 		info->timeout = HZ/50+1;
 	}
 
 	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
 	char_time = char_time / 5;
 	if (char_time > HZ) {
-		printk("macserial: char_time %ld >HZ !!!\n", char_time);
+		printk(KERN_WARNING "macserial: char_time %ld >HZ !!!\n",
+				    char_time);
 		char_time = 1;
 	} else if (char_time == 0)
 		char_time = 1;
@@ -2374,7 +2374,7 @@
 
 static void show_serial_version(void)
 {
-	printk("PowerMac Z8530 serial driver version 2.0\n");
+	printk(KERN_INFO "PowerMac Z8530 serial driver version 2.0\n");
 }
 
 /*
@@ -2461,8 +2461,8 @@
 		nchan = 0;
 		chip = n;
 		if (n >= NUM_CHANNELS) {
-			printk("Sorry, can't use %s: no more channels\n",
-			       dev->full_name);
+			printk(KERN_WARNING "Sorry, can't use %s: no more "
+					    "channels\n", dev->full_name);
 			continue;
 		}
 		chan_a_index = 0;
@@ -2631,7 +2631,8 @@
 
 		/* If console serial line, then enable interrupts. */
 		if (zs_soft[channel].is_cons) {
-			printk("macserial: console line, enabling interrupt %d\n", zs_soft[channel].irq);
+			printk(KERN_INFO "macserial: console line, enabling "
+					"interrupt %d\n", zs_soft[channel].irq);
 			panic("macserial: console not supported yet !");
 			write_zsreg(zs_soft[channel].zs_channel, R1,
 				    (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB));
@@ -2669,7 +2670,7 @@
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
 		info->timeout = HZ;
-		printk("tty%02d at 0x%08x (irq = %d)", info->line, 
+		printk(KERN_INFO "tty%02d at 0x%08x (irq = %d)", info->line, 
 			info->port, info->irq);
 		printk(" is a Z8530 ESCC");
 		connector = get_property(info->dev_node, "AAPL,connector", &lenp);
diff -urN linux-2.4.10-pre5/drivers/macintosh/mediabay.c linux/drivers/macintosh/mediabay.c
--- linux-2.4.10-pre5/drivers/macintosh/mediabay.c	Sun Sep 17 09:48:05 2000
+++ linux/drivers/macintosh/mediabay.c	Mon Dec  3 23:08:13 2001
@@ -27,7 +27,7 @@
 #include <asm/io.h>
 #include <asm/feature.h>
 #include <asm/mediabay.h>
-#include <asm/init.h>
+#include <asm/sections.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 
diff -urN linux-2.4.10-pre5/drivers/macintosh/rtc.c linux/drivers/macintosh/rtc.c
--- linux-2.4.10-pre5/drivers/macintosh/rtc.c	Sun Aug 12 10:38:48 2001
+++ linux/drivers/macintosh/rtc.c	Mon Dec  3 23:08:13 2001
@@ -49,11 +49,7 @@
 {
 	unsigned long nowtime;
 
-	printk(KERN_INFO "rtc.c:set_rtc_time: %04d-%02d-%02d %02d:%02d:%02d.\n", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
-
 	nowtime = mktime(t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
-
-	printk(KERN_INFO "rtc.c:set_rtc_time: set rtc time to %ld seconds.\n", nowtime);
 
 	(ppc_md.set_rtc_time)(nowtime);
 }
diff -urN linux-2.4.10-pre5/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
--- linux-2.4.10-pre5/drivers/macintosh/via-pmu.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/macintosh/via-pmu.c	Mon Dec  3 23:08:13 2001
@@ -42,6 +42,7 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
+#include <asm/sections.h>
 #include <asm/irq.h>
 #include <asm/hardirq.h>
 #include <asm/feature.h>
@@ -1736,7 +1737,6 @@
 int __openfirmware powerbook_sleep_3400(void)
 {
 	int ret, i, x;
-	unsigned long msr;
 	unsigned int hid0;
 	unsigned long p, wait;
 	struct adb_request sleep_req;
diff -urN linux-2.4.10-pre5/drivers/md/lvm.c linux/drivers/md/lvm.c
--- linux-2.4.10-pre5/drivers/md/lvm.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/md/lvm.c	Mon Dec  3 23:08:13 2001
@@ -394,8 +394,6 @@
  */
 int lvm_init(void)
 {
-	struct gendisk *gendisk_ptr = NULL;
-
 	if (register_chrdev(LVM_CHAR_MAJOR, lvm_name, &lvm_chr_fops) < 0) {
 		printk(KERN_ERR "%s -- register_chrdev failed\n", lvm_name);
 		return -EIO;
@@ -423,19 +421,7 @@
 	lvm_init_vars();
 	lvm_geninit(&lvm_gendisk);
 
-	/* insert our gendisk at the corresponding major */
-	if (gendisk_head != NULL) {
-		gendisk_ptr = gendisk_head;
-		while (gendisk_ptr->next != NULL &&
-		       gendisk_ptr->major > lvm_gendisk.major) {
-			gendisk_ptr = gendisk_ptr->next;
-		}
-		lvm_gendisk.next = gendisk_ptr->next;
-		gendisk_ptr->next = &lvm_gendisk;
-	} else {
-		gendisk_head = &lvm_gendisk;
-		lvm_gendisk.next = NULL;
-	}
+	add_gendisk(&lvm_gendisk);
 
 #ifdef LVM_HD_NAME
 	/* reference from drivers/block/genhd.c */
@@ -469,8 +455,6 @@
  */
 static void lvm_cleanup(void)
 {
-	struct gendisk *gendisk_ptr = NULL, *gendisk_ptr_prev = NULL;
-
 	devfs_unregister (lvm_devfs_handle);
 
 	if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0) {
@@ -481,16 +465,7 @@
 	}
 
 
-	gendisk_ptr = gendisk_ptr_prev = gendisk_head;
-	while (gendisk_ptr != NULL) {
-		if (gendisk_ptr == &lvm_gendisk)
-			break;
-		gendisk_ptr_prev = gendisk_ptr;
-		gendisk_ptr = gendisk_ptr->next;
-	}
-	/* delete our gendisk from chain */
-	if (gendisk_ptr == &lvm_gendisk)
-		gendisk_ptr_prev->next = gendisk_ptr->next;
+	del_gendisk(&lvm_gendisk);
 
 	blk_size[MAJOR_NR] = NULL;
 	blksize_size[MAJOR_NR] = NULL;
diff -urN linux-2.4.10-pre5/drivers/md/md.c linux/drivers/md/md.c
--- linux-2.4.10-pre5/drivers/md/md.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/md/md.c	Mon Dec  3 23:08:13 2001
@@ -222,18 +222,6 @@
 	return mddev;
 }
 
-struct gendisk * find_gendisk (kdev_t dev)
-{
-	struct gendisk *tmp = gendisk_head;
-
-	while (tmp != NULL) {
-		if (tmp->major == MAJOR(dev))
-			return (tmp);
-		tmp = tmp->next;
-	}
-	return (NULL);
-}
-
 mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
 {
 	mdk_rdev_t * rdev;
@@ -281,7 +269,7 @@
 	/*
 	 * ok, add this new device name to the list
 	 */
-	hd = find_gendisk (dev);
+	hd = get_gendisk (dev);
 	dname->name = NULL;
 	if (hd)
 		dname->name = disk_name (hd, MINOR(dev), dname->namebuf);
@@ -569,7 +557,7 @@
 static kdev_t dev_unit(kdev_t dev)
 {
 	unsigned int mask;
-	struct gendisk *hd = find_gendisk(dev);
+	struct gendisk *hd = get_gendisk(dev);
 
 	if (!hd)
 		return 0;
@@ -3515,9 +3503,8 @@
 	
 
 	read_ahead[MAJOR_NR] = INT_MAX;
-	md_gendisk.next = gendisk_head;
 
-	gendisk_head = &md_gendisk;
+	add_gendisk(&md_gendisk);
 
 	md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
 	if (!md_recovery_thread)
@@ -3843,8 +3830,6 @@
 
 void cleanup_module (void)
 {
-	struct gendisk **gendisk_ptr;
-
 	md_unregister_thread(md_recovery_thread);
 	devfs_unregister(devfs_handle);
 
@@ -3854,15 +3839,9 @@
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("mdstat", NULL);
 #endif
-	
-	gendisk_ptr = &gendisk_head;
-	while (*gendisk_ptr) {
-		if (*gendisk_ptr == &md_gendisk) {
-			*gendisk_ptr = md_gendisk.next;
-			break;
-		}
-		gendisk_ptr = & (*gendisk_ptr)->next;
-	}
+
+	del_gendisk(&md_gendisk);
+
 	blk_dev[MAJOR_NR].queue = NULL;
 	blksize_size[MAJOR_NR] = NULL;
 	blk_size[MAJOR_NR] = NULL;
diff -urN linux-2.4.10-pre5/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
--- linux-2.4.10-pre5/drivers/mtd/ftl.c	Tue Jun 12 10:30:27 2001
+++ linux/drivers/mtd/ftl.c	Mon Dec  3 23:08:13 2001
@@ -1428,8 +1428,7 @@
     blksize_size[FTL_MAJOR] = ftl_blocksizes;
     ftl_gendisk.major = FTL_MAJOR;
     blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request);
-    ftl_gendisk.next = gendisk_head;
-    gendisk_head = &ftl_gendisk;
+    add_gendisk(&ftl_gendisk);
     
     register_mtd_user(&ftl_notifier);
     
@@ -1438,19 +1437,13 @@
 
 mod_exit_t cleanup_ftl(void)
 {
-    struct gendisk *gd, **gdp;
-
     unregister_mtd_user(&ftl_notifier);
 
     unregister_blkdev(FTL_MAJOR, "ftl");
     blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR));
     blksize_size[FTL_MAJOR] = NULL;
 
-    for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-	if (*gdp == &ftl_gendisk) {
-	    gd = *gdp; *gdp = gd->next;
-	    break;
-	}
+    del_gendisk(&ftl_gendisk);
 }
 
 module_init(init_ftl);
diff -urN linux-2.4.10-pre5/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c
--- linux-2.4.10-pre5/drivers/mtd/nftlcore.c	Tue Jun 12 10:30:27 2001
+++ linux/drivers/mtd/nftlcore.c	Mon Dec  3 23:08:13 2001
@@ -1059,8 +1059,7 @@
 		}
 		blksize_size[MAJOR_NR] = nftl_blocksizes;
 
-		nftl_gendisk.next = gendisk_head;
-		gendisk_head = &nftl_gendisk;
+		add_gendisk(&nftl_gendisk);
 	}
 	
 	register_mtd_user(&nftl_notifier);
@@ -1083,11 +1082,7 @@
 
 	/* remove ourself from generic harddisk list
 	   FIXME: why can't I found this partition on /proc/partition */
-  	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-    		if (*gdp == &nftl_gendisk) {
-      			gd = *gdp; *gdp = gd->next;
-      			break;
-		}
+	del_gendisk(&nftl_gendisk);:
 }
 
 module_init(init_nftl);
diff -urN linux-2.4.10-pre5/drivers/net/irda/irda-usb.c linux/drivers/net/irda/irda-usb.c
--- linux-2.4.10-pre5/drivers/net/irda/irda-usb.c	Sun Aug  5 13:12:40 2001
+++ linux/drivers/net/irda/irda-usb.c	Mon Dec  3 23:08:13 2001
@@ -76,7 +76,8 @@
 	{ USB_DEVICE(0x50f, 0x180), driver_info: IUC_SPEED_BUG | IUC_NO_WINDOW },
 	/* Extended Systems, Inc.,  XTNDAccess IrDA USB (ESI-9685) */
 	{ USB_DEVICE(0x8e9, 0x100), driver_info: IUC_SPEED_BUG | IUC_NO_WINDOW },
-	{ match_flags: USB_DEVICE_ID_MATCH_INT_CLASS,
+	{ match_flags: USB_DEVICE_ID_MATCH_INT_CLASS |
+	               USB_DEVICE_ID_MATCH_INT_SUBCLASS,
 	  bInterfaceClass: USB_CLASS_APP_SPEC,
 	  bInterfaceSubClass: USB_CLASS_IRDA,
 	  driver_info: IUC_DEFAULT, },
diff -urN linux-2.4.10-pre5/drivers/net/smc9194.c linux/drivers/net/smc9194.c
--- linux-2.4.10-pre5/drivers/net/smc9194.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/smc9194.c	Mon Dec  3 23:08:13 2001
@@ -88,7 +88,11 @@
  . Do you want to use 32 bit xfers?  This should work on all chips, as
  . the chipset is designed to accommodate them.
 */
+#ifdef __sh__
+#undef USE_32_BIT
+#else
 #define USE_32_BIT 1
+#endif
 
 /*
  .the SMC9194 can be at any of the following port addresses.  To change,
@@ -983,12 +987,6 @@
 		retval = -ENODEV;
 		goto err_out;
 	}
-	if (dev->irq == 2) {
-		/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
-		 * or don't know which one to set.
-		 */
-		dev->irq = 9;
-	}
 
 	/* now, print out the card info, in a short format.. */
 
@@ -1369,13 +1367,11 @@
 			packet_length & 0x3  );
 #else
 		PRINTK3((" Reading %d words and %d byte(s) \n",
-			(packet_length >> 1 ), packet_length & 1 );
-		if ( packet_length & 1 )
-			*(data++) = inb( ioaddr + DATA_1 );
-		insw(ioaddr + DATA_1 , data, (packet_length + 1 ) >> 1);
+			(packet_length >> 1 ), packet_length & 1 ));
+		insw(ioaddr + DATA_1 , data, packet_length >> 1);
 		if ( packet_length & 1 ) {
 			data += packet_length & ~1;
-			*((data++) = inb( ioaddr + DATA_1 );
+			*(data++) = inb( ioaddr + DATA_1 );
 		}
 #endif
 #if	SMC_DEBUG > 2
diff -urN linux-2.4.10-pre5/drivers/net/smc9194.h linux/drivers/net/smc9194.h
--- linux-2.4.10-pre5/drivers/net/smc9194.h	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/smc9194.h	Mon Dec  3 23:08:13 2001
@@ -169,7 +169,8 @@
 	/* 5 */ "SMC91C95",
 	NULL,
 	/* 7 */ "SMC91C100", 
-	NULL, NULL, NULL, NULL, 
+	/* 8 */ "SMC91C100FD", 
+	NULL, NULL, NULL, 
 	NULL, NULL, NULL};  
 
 /* 
diff -urN linux-2.4.10-pre5/drivers/net/wan/farsync.c linux/drivers/net/wan/farsync.c
--- linux-2.4.10-pre5/drivers/net/wan/farsync.c	Sun Aug 12 10:38:48 2001
+++ linux/drivers/net/wan/farsync.c	Mon Dec  3 23:08:13 2001
@@ -1200,7 +1200,8 @@
                 /* Sanity check the parameters. We don't support partial writes
                  * when going over the top
                  */
-                if ( wrthdr.size + wrthdr.offset > FST_MEMSIZE )
+                if ( wrthdr.size > FST_MEMSIZE || wrthdr.offset > FST_MEMSIZE
+                                || wrthdr.size + wrthdr.offset > FST_MEMSIZE )
                 {
                         return -ENXIO;
                 }
diff -urN linux-2.4.10-pre5/drivers/net/wan/sdla_chdlc.c linux/drivers/net/wan/sdla_chdlc.c
--- linux-2.4.10-pre5/drivers/net/wan/sdla_chdlc.c	Wed Aug 15 01:22:16 2001
+++ linux/drivers/net/wan/sdla_chdlc.c	Mon Dec  3 23:08:13 2001
@@ -48,6 +48,7 @@
 * Aug 07, 1998	David Fong	Initial version.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -urN linux-2.4.10-pre5/drivers/net/wan/sdla_fr.c linux/drivers/net/wan/sdla_fr.c
--- linux-2.4.10-pre5/drivers/net/wan/sdla_fr.c	Wed Aug 15 01:22:16 2001
+++ linux/drivers/net/wan/sdla_fr.c	Mon Dec  3 23:08:13 2001
@@ -138,6 +138,7 @@
 * Jan 02, 1997	Gene Kozin	Initial version.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -urN linux-2.4.10-pre5/drivers/net/wan/sdla_ft1.c linux/drivers/net/wan/sdla_ft1.c
--- linux-2.4.10-pre5/drivers/net/wan/sdla_ft1.c	Sun Aug 12 10:38:48 2001
+++ linux/drivers/net/wan/sdla_ft1.c	Mon Dec  3 23:08:13 2001
@@ -20,6 +20,7 @@
 * Aug 07, 1998	David Fong	Initial version.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -urN linux-2.4.10-pre5/drivers/net/wan/sdla_ppp.c linux/drivers/net/wan/sdla_ppp.c
--- linux-2.4.10-pre5/drivers/net/wan/sdla_ppp.c	Wed Aug 15 01:22:16 2001
+++ linux/drivers/net/wan/sdla_ppp.c	Mon Dec  3 23:08:13 2001
@@ -90,6 +90,7 @@
 * Jan 06, 1997	Gene Kozin	Initial version.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -urN linux-2.4.10-pre5/drivers/net/wan/sdla_x25.c linux/drivers/net/wan/sdla_x25.c
--- linux-2.4.10-pre5/drivers/net/wan/sdla_x25.c	Wed Aug 15 01:22:16 2001
+++ linux/drivers/net/wan/sdla_x25.c	Mon Dec  3 23:08:13 2001
@@ -81,6 +81,7 @@
  * 	Includes 
  *=====================================================*/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -urN linux-2.4.10-pre5/drivers/net/wan/wanpipe_multppp.c linux/drivers/net/wan/wanpipe_multppp.c
--- linux-2.4.10-pre5/drivers/net/wan/wanpipe_multppp.c	Wed Aug 15 01:22:16 2001
+++ linux/drivers/net/wan/wanpipe_multppp.c	Mon Dec  3 23:08:13 2001
@@ -17,6 +17,7 @@
 *  		module.
 *****************************************************************************/
 
+#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -urN linux-2.4.10-pre5/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
--- linux-2.4.10-pre5/drivers/s390/block/dasd.c	Mon Dec  3 23:08:03 2001
+++ linux/drivers/s390/block/dasd.c	Mon Dec  3 23:08:13 2001
@@ -714,10 +714,9 @@
 
 	INIT_BLK_DEV (major, do_dasd_request, dasd_get_queue, NULL);
 
-	major_info->gendisk.major = major;
-	major_info->gendisk.next = gendisk_head;
 	major_info->gendisk.sizes = blk_size[major];
-	gendisk_head = &major_info->gendisk;
+	major_info->gendisk.major = major;
+	add_gendisk (&major_info->gendisk);
 	return major;
 
         /* error handling - free the prior allocated memory */  
@@ -775,7 +774,6 @@
 {
 	int rc = 0;
 	int major;
-	struct gendisk *dd, *prev = NULL;
 	unsigned long flags;
 
 	if (major_info == NULL) {
@@ -784,20 +782,8 @@
 	major = major_info->gendisk.major;
 	INIT_BLK_DEV (major, NULL, NULL, NULL);
 
-	/* do the gendisk stuff */
-	for (dd = gendisk_head; dd; dd = dd->next) {
-		if (dd == &major_info->gendisk) {
-			if (prev)
-				prev->next = dd->next;
-			else
-				gendisk_head = dd->next;
-			break;
-		}
-		prev = dd;
-	}
-	if (dd == NULL) {
-		return -ENOENT;
-	}
+	del_gendisk (&major_info->gendisk);
+
 	kfree (major_info->dasd_device);
 	kfree (major_info->gendisk.part);
 
diff -urN linux-2.4.10-pre5/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- linux-2.4.10-pre5/drivers/scsi/sd.c	Mon Dec  3 23:08:04 2001
+++ linux/drivers/scsi/sd.c	Mon Dec  3 23:08:13 2001
@@ -578,7 +578,6 @@
 static struct gendisk *sd_gendisks = &sd_gendisk;
 
 #define SD_GENDISK(i)    sd_gendisks[(i) / SCSI_DISKS_PER_MAJOR]
-#define LAST_SD_GENDISK  sd_gendisks[N_USED_SD_MAJORS - 1]
 
 /*
  * rw_intr is the interrupt routine for the device driver.
@@ -1147,12 +1146,10 @@
 		sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4);
 		sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4);
 		sd_gendisks[i].nr_real = 0;
-		sd_gendisks[i].next = sd_gendisks + i + 1;
 		sd_gendisks[i].real_devices =
 		    (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR);
 	}
 
-	LAST_SD_GENDISK.next = NULL;
 	return 0;
 
 cleanup_gendisks_flags:
@@ -1184,19 +1181,13 @@
 
 static void sd_finish()
 {
-	struct gendisk *gendisk;
 	int i;
 
 	for (i = 0; i < N_USED_SD_MAJORS; i++) {
 		blk_dev[SD_MAJOR(i)].queue = sd_find_queue;
+		add_gendisk(&sd_gendisks[i]);
 	}
-	for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next)
-		if (gendisk == sd_gendisks)
-			break;
-	if (gendisk == NULL) {
-		LAST_SD_GENDISK.next = gendisk_head;
-		gendisk_head = sd_gendisks;
-	}
+
 	for (i = 0; i < sd_template.dev_max; ++i)
 		if (!rscsi_disks[i].capacity && rscsi_disks[i].device) {
 			sd_init_onedisk(i);
@@ -1377,10 +1368,7 @@
 
 static void __exit exit_sd(void)
 {
-	struct gendisk **prev_sdgd_link;
-	struct gendisk *sdgd;
 	int i;
-	int removed = 0;
 
 	scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
 
@@ -1394,26 +1382,9 @@
 		kfree(sd_blocksizes);
 		kfree(sd_hardsizes);
 		kfree((char *) sd);
-
-		/*
-		 * Now remove sd_gendisks from the linked list
-		 */
-		prev_sdgd_link = &gendisk_head;
-		while ((sdgd = *prev_sdgd_link) != NULL) {
-			if (sdgd >= sd_gendisks && sdgd <= &LAST_SD_GENDISK) {
-				removed++;
-				*prev_sdgd_link = sdgd->next;
-				continue;
-			}
-			prev_sdgd_link = &sdgd->next;
-		}
-
-		if (removed != N_USED_SD_MAJORS)
-			printk("%s %d sd_gendisks in disk chain",
-			       removed > N_USED_SD_MAJORS ? "total" : "just", removed);
-
 	}
 	for (i = 0; i < N_USED_SD_MAJORS; i++) {
+		del_gendisk(&sd_gendisks[i]);
 		blk_size[SD_MAJOR(i)] = NULL;
 		hardsect_size[SD_MAJOR(i)] = NULL;
 		read_ahead[SD_MAJOR(i)] = 0;
diff -urN linux-2.4.10-pre5/fs/ntfs/Makefile linux/fs/ntfs/Makefile
--- linux-2.4.10-pre5/fs/ntfs/Makefile	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/Makefile	Mon Dec  3 23:08:13 2001
@@ -5,7 +5,7 @@
 obj-y   := fs.o sysctl.o support.o util.o inode.o dir.o super.o attr.o unistr.o
 obj-m   := $(O_TARGET)
 # New version format started 3 February 2001.
-EXTRA_CFLAGS = -DNTFS_VERSION=\"1.1.17\" #-DDEBUG
+EXTRA_CFLAGS = -DNTFS_VERSION=\"1.1.18\" #-DDEBUG
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.10-pre5/fs/ntfs/attr.c linux/fs/ntfs/attr.c
--- linux-2.4.10-pre5/fs/ntfs/attr.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/attr.c	Mon Dec  3 23:08:13 2001
@@ -247,83 +247,97 @@
 		ntfs_memmove(attr->d.r.runlist + cnum + 1,
 			     attr->d.r.runlist + cnum,
 			     (attr->d.r.len - cnum) * sizeof(ntfs_runlist));
-	attr->d.r.runlist[cnum].cluster = cluster;
+	attr->d.r.runlist[cnum].lcn = cluster;
 	attr->d.r.runlist[cnum].len = len;
 	attr->d.r.len++;
 	return 0;
 }
 
-/* Extends an attribute. Another run will be added if necessary, but we try to
- * extend the last run in the run list first.
- * FIXME: what if there isn't enough contiguous space, we don't create
- * multiple runs?
+/**
+ * ntfs_extend_attr - extend allocated size of an attribute
+ * @ino:	ntfs inode containing the attribute to extend
+ * @attr:	attribute which to extend
+ * @len:	desired new length for @attr (_not_ the amount to extend by)
  *
- * *len: the desired new length of the attr (_not_ the amount to extend by)
+ * Extends an attribute. Allocate clusters on the volume which @ino belongs to.
+ * Extends the run list accordingly, preferably by extending the last run of
+ * the existing run list, first.
+ *
+ * Only modifies attr->allocated, i.e. doesn't touch attr->size, nor
+ * attr->initialized.
  */
-int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, __s64 *len, int flags)
+int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, const __s64 len)
 {
-	int error = 0;
-	ntfs_runlist *rl;
-	int rlen;
-	ntfs_cluster_t cluster;
-	int clen;
+	int rlen, rl2_len, err = 0;
+	ntfs_cluster_t cluster, clen;
+	ntfs_runlist *rl, *rl2;
 
 	if ((attr->flags & (ATTR_IS_COMPRESSED | ATTR_IS_ENCRYPTED)) ||
 			ino->record_count > 1)
 		return -EOPNOTSUPP;
+	/*
+	 * FIXME: Don't make non-resident if the attribute type is not right.
+	 * For example cannot make index attribute non-resident! (AIA)
+	 */
 	if (attr->resident) {
-		error = ntfs_make_attr_nonresident(ino, attr);
-		if (error)
-			return error;
+		err = ntfs_make_attr_nonresident(ino, attr);
+		if (err)
+			return err;
 	}
-	if (*len <= attr->allocated)
+	if (len <= attr->allocated)
 		return 0;	/* Truly stupid things do sometimes happen. */
 	rl = attr->d.r.runlist;
-	rlen = attr->d.r.len - 1;
-	if (rlen >= 0)
-		cluster = rl[rlen].cluster + rl[rlen].len;
+	rlen = attr->d.r.len;
+	if (rlen > 0)
+		cluster = rl[rlen - 1].lcn + rl[rlen - 1].len;
 	else
 		/* No preference for allocation space. */
-		cluster = 0;
-	/* Calculate the extra space we need, and round up to multiple of
-	 * cluster size to get number of new clusters needed */
-	clen = ((*len - attr->allocated) + ino->vol->cluster_size - 1) >>
-						ino->vol->cluster_size_bits;
-	if (clen == 0)
+		cluster = (ntfs_cluster_t)-1;
+	/*
+	 * Calculate the extra space we need, and round up to multiple of
+	 * cluster size to get number of new clusters needed.
+	 */
+	clen = (len - attr->allocated + ino->vol->cluster_size - 1) >>
+			ino->vol->cluster_size_bits;
+	if (!clen)
 		return 0;
-	/* FIXME: try to allocate smaller pieces */
-	error = ntfs_allocate_clusters(ino->vol, &cluster, &clen,
-				       flags | ALLOC_REQUIRE_SIZE);
-	if (error)
-		return error;
+	err = ntfs_allocate_clusters(ino->vol, &cluster, &clen, &rl2,
+			&rl2_len, DATA_ZONE);
+	if (err)
+		return err;
 	attr->allocated += (__s64)clen << ino->vol->cluster_size_bits;
-	*len = attr->allocated;
-	/* Contiguous chunk. */
-	if (rlen >= 0 && cluster == rl[rlen].cluster + rl[rlen].len) {
-		rl[rlen].len += clen;
-		return 0;
+	if (rlen > 0) {
+		err = splice_runlists(&rl, &rlen, rl2, rl2_len);
+		ntfs_vfree(rl2);
+		if (err)
+			return err;
+	} else {
+		if (rl)
+			ntfs_vfree(rl);
+		rl = rl2;
+		rlen = rl2_len;
 	}
-	/*
-	 * FIXME: if ntfs_insert_run fails we need to deallocate the cluster
-	 * to revert to state before we were called...
-	 */
-	ntfs_insert_run(attr, rlen + 1, cluster, clen);
+	attr->d.r.runlist = rl;
+	attr->d.r.len = rlen;
 	return 0;
 }
 
 int ntfs_make_attr_nonresident(ntfs_inode *ino, ntfs_attribute *attr)
 {
-	void *data = attr->d.data;
-	__s64 len = attr->size;
 	int error;
-	__s64 alen;
 	ntfs_io io;
+	void *data = attr->d.data;
+	__s64 len = attr->size;
+
 	attr->d.r.len = 0;
-	attr->d.r.runlist = 0;
+	attr->d.r.runlist = NULL;
 	attr->resident = 0;
+	/*
+	 * ->allocated is updated by ntfs_extend_attr(), while ->initialized
+	 * and ->size are updated by ntfs_readwrite_attr(). (AIA)
+	 */
 	attr->allocated = attr->initialized = 0;
-	alen = len;
-	error = ntfs_extend_attr(ino, attr, &alen, ALLOC_REQUIRE_SIZE);
+	error = ntfs_extend_attr(ino, attr, len);
 	if (error)
 		return error; /* FIXME: On error, restore old values. */
 	io.fn_put = ntfs_put;
@@ -349,21 +363,22 @@
 	return error;
 }
 
-/* Resize the attribute to a newsize. */
+/*
+ * Resize the attribute to a newsize. attr->allocated and attr->size are
+ * updated, but attr->initialized is not changed unless it becomes bigger than
+ * attr->size, in which case it is set to attr->size.
+ */
 int ntfs_resize_attr(ntfs_inode *ino, ntfs_attribute *attr, __s64 newsize)
 {
 	int error = 0;
 	__s64 oldsize = attr->size;
 	int clustersizebits = ino->vol->cluster_size_bits;
 	int i, count, newcount;
-	ntfs_runlist *rl;
-	__s64 newlen;
+	ntfs_runlist *rl, *rlt;
 
 	if (newsize == oldsize)
 		return 0;
-	/* FIXME: Modifying compressed attributes not supported yet. */
 	if (attr->flags & (ATTR_IS_COMPRESSED | ATTR_IS_ENCRYPTED))
-		/* FIXME: Extending is easy: just insert sparse runs. */
 		return -EOPNOTSUPP;
 	if (attr->resident) {
 		void *v;
@@ -396,58 +411,72 @@
 	/* Non-resident attribute. */
 	rl = attr->d.r.runlist;
 	if (newsize < oldsize) {
+		int rl_size;
 		/*
 		 * FIXME: We might be going awfully wrong for newsize = 0,
 		 * possibly even leaking memory really badly. But considering
-		 * in that case there is more breakage due to -ENOTSUP stuff
+		 * in that case there is more breakage due to -EOPNOTSUPP stuff
 		 * further down the code path, who cares for the moment... (AIA)
 		 */
 		for (i = 0, count = 0; i < attr->d.r.len; i++) {
 			if ((__s64)(count + rl[i].len) << clustersizebits >
-									newsize)
+					newsize) {
+				i++;
 				break;
+			}
 			count += (int)rl[i].len;
 		}
-		newlen = i + 1;
-		/* Free unused clusters in current run, unless sparse. */
 		newcount = count;
-		if (rl[i].cluster != (ntfs_cluster_t)-1) {
-			int rounded = newsize - ((__s64)count <<
-							clustersizebits);
+		/* Free unused clusters in current run, unless sparse. */
+		if (rl[--i].lcn != (ntfs_cluster_t)-1) {
+			ntfs_cluster_t rounded = newsize - ((__s64)count <<
+					clustersizebits);
 			rounded = (rounded + ino->vol->cluster_size - 1) >>
-								clustersizebits;
-			error = ntfs_deallocate_clusters(ino->vol, 
-						rl[i].cluster + rounded,
-						(int)rl[i].len - rounded);
+					clustersizebits;
+			error = ntfs_deallocate_cluster_run(ino->vol, 
+					rl[i].lcn + rounded,
+					rl[i].len - rounded);
 			if (error)
 				return error; /* FIXME: Incomplete operation. */
 			rl[i].len = rounded;
 			newcount = count + rounded;
 		}
 		/* Free all other runs. */
-		for (i++; i < attr->d.r.len; i++)
-			if (rl[i].cluster != (ntfs_cluster_t)-1) {
-				error = ntfs_deallocate_clusters(ino->vol,
-								rl[i].cluster,
-								(int)rl[i].len);
-				if (error)
-					return error; /* FIXME: Incomplete 
-						       * operation */
+		i++;
+		error = ntfs_deallocate_clusters(ino->vol, rl + i,
+				attr->d.r.len - i);
+		if (error)
+			return error; /* FIXME: Incomplete operation. */
+		/*
+		 * Free space for extra runs in memory if enough memory left
+		 * to do so. FIXME: Only do it if it would free memory. (AIA)
+		 */
+		rl_size = ((i + 1) * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &
+				PAGE_MASK;
+		if (rl_size < ((attr->d.r.len * sizeof(ntfs_runlist) +
+				PAGE_SIZE - 1) & PAGE_MASK)) {
+			rlt = ntfs_vmalloc(rl_size);
+			if (rlt) {
+				ntfs_memcpy(rlt, rl, i * sizeof(ntfs_runlist));
+				ntfs_vfree(rl);
+				attr->d.r.runlist = rl = rlt;
 			}
-		/* FIXME: Free space for extra runs in memory? */
-		attr->d.r.len = newlen;
+		}
+		rl[i].lcn = (ntfs_cluster_t)-1;
+		rl[i].len = (ntfs_cluster_t)0;
+		attr->d.r.len = i;
 	} else {
-		newlen = newsize;
-		error = ntfs_extend_attr(ino, attr, &newlen,
-					 ALLOC_REQUIRE_SIZE);
+		error = ntfs_extend_attr(ino, attr, newsize);
 		if (error)
 			return error; /* FIXME: Incomplete operation. */
-		newcount = newlen >> clustersizebits;
+		newcount = (newsize + ino->vol->cluster_size - 1) >>
+				clustersizebits;
 	}
 	/* Fill in new sizes. */
 	attr->allocated = (__s64)newcount << clustersizebits;
 	attr->size = newsize;
-	/* attr->initialized does not change. */
+	if (attr->initialized > newsize)
+		attr->initialized = newsize;
 	if (!newsize)
 		error = ntfs_make_attr_resident(ino, attr);
 	return error;
@@ -535,7 +564,7 @@
 	 * base mft record contains the last extent instead of the first one
 	 * and the first extent is stored, like any intermediate extents in
 	 * extension mft records. This would be difficult to allow the way the
-	 * run list is stored in memory. Thus we fix else where by causing the
+	 * runlist is stored in memory. Thus we fix elsewhere by causing the
 	 * attribute list attribute to be processed immediately when found. The
 	 * extents will then be processed starting with the first one. */
 	for (cnum = 0, vcn = 0; cnum < attr->d.r.len; cnum++)
@@ -549,7 +578,7 @@
 			ntfs_error("Problem with runlist in extended record\n");
 			return -1;
 		}
-		/* Tried to insert an already inserted run list. */
+		/* Tried to insert an already inserted runlist. */
 		return 0;
 	}
 	if (!endvcn) {
@@ -731,7 +760,7 @@
 	io.do_read = 1;
 	io.fn_put = ntfs_put;
 	io.fn_get = 0;
-	cluster = rl->cluster;
+	cluster = rl->lcn;
 	len = rl->len;
 	copied = 0;
 	while (l) {
@@ -780,7 +809,7 @@
 					rnum++;
 					rl++;
 					vcn += len;
-					cluster = cl1 = rl->cluster;
+					cluster = cl1 = rl->lcn;
 					len = rl->len;
 				}
 				got += l1;
@@ -822,7 +851,7 @@
 			rnum++;
 			rl++;
 			vcn += len;
-			cluster = rl->cluster;
+			cluster = rl->lcn;
 			len = rl->len;
 		}
 	}
diff -urN linux-2.4.10-pre5/fs/ntfs/attr.h linux/fs/ntfs/attr.h
--- linux-2.4.10-pre5/fs/ntfs/attr.h	Mon Jul 16 15:14:10 2001
+++ linux/fs/ntfs/attr.h	Mon Dec  3 23:08:13 2001
@@ -9,8 +9,7 @@
 ntfs_u8* ntfs_find_attr_in_mft_rec(ntfs_volume *vol, ntfs_u8 *m, __u32 type,
 			wchar_t *name, __u32 name_len, int ic, __u16 instance);
 
-int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, __s64 *len,
-		     int flags);
+int ntfs_extend_attr(ntfs_inode *ino, ntfs_attribute *attr, const __s64 len);
 
 int ntfs_resize_attr(ntfs_inode *ino, ntfs_attribute *attr, __s64 newsize);
 
@@ -35,5 +34,5 @@
 		  void *value, int value_len, int *pos, int *found);
 
 int ntfs_insert_run(ntfs_attribute *attr, int cnum, ntfs_cluster_t cluster,
-		     int len );
+		     int len);
 
diff -urN linux-2.4.10-pre5/fs/ntfs/dir.c linux/fs/ntfs/dir.c
--- linux-2.4.10-pre5/fs/ntfs/dir.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/dir.c	Mon Dec  3 23:08:13 2001
@@ -430,7 +430,7 @@
 
 	ra = ntfs_find_attr(ino, ino->vol->at_index_root, I30);
 	if (!ra)
-		return -E2BIG;
+		return -ENOTDIR;
 	bsize = ino->vol->mft_record_size;
 	root = ntfs_malloc(bsize);
 	if (!root)
@@ -740,7 +740,7 @@
 
 /* Find an entry in the directory. Return 0 if not found, otherwise copy the
  * entry to the result buffer. */
-int ntfs_getdir(ntfs_iterate_s* walk)
+int ntfs_getdir(ntfs_iterate_s *walk)
 {
 	int length = walk->dir->vol->mft_record_size;
 	int retval, error;
@@ -788,31 +788,31 @@
 	return ntfs_getdir(walk);
 }
 
-int ntfs_getdir_unsorted(ntfs_inode *ino, ntfs_u32 *p_high, ntfs_u32* p_low,
-			 int (*cb)(ntfs_u8*, void*), void *param)
+int ntfs_getdir_unsorted(ntfs_inode *ino, u32 *p_high, u32 *p_low,
+		int (*cb)(ntfs_u8 *, void *), void *param)
 {
 	char *buf = 0, *entry = 0;
-	ntfs_io io;
-	int length;
-	int block;
-	int start;
 	ntfs_attribute *attr;
 	ntfs_volume *vol;
-	int byte, bit;
-	int error = 0;
+	int length, block, byte, bit, error = 0;
+	u32 start, finish;
+	ntfs_io io;
 
 	if (!ino) {
-		ntfs_error("No inode passed to getdir_unsorted\n");
+		ntfs_error(__FUNCTION__ "(): No inode! Returning -EINVAL.\n");
 		return -EINVAL;
 	}
 	vol = ino->vol;
 	if (!vol) {
-		ntfs_error("Inode %d has no volume\n", ino->i_number);
+		ntfs_error(__FUNCTION__ "(): Inode %lx has no volume. "
+				"Returning -EINVAL.\n", ino->i_number);
 		return -EINVAL;
 	}
-	ntfs_debug(DEBUG_DIR3, "unsorted 1\n");
-	/* Are we still in the index root? */
+	ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 1: Entering for "
+			"inode 0x%lx, p_high = 0x%x, p_low = 0x%x.\n",
+			ino->i_number, *p_high, *p_low);
 	if (*p_high == 0) {
+		/* We are still in the index root. */
 		buf = ntfs_malloc(length = vol->mft_record_size);
 		if (!buf)
 			return -ENOMEM;
@@ -820,15 +820,16 @@
 		io.param = buf;
 		io.size = length;
 		error = ntfs_read_attr(ino, vol->at_index_root, I30, 0, &io);
-		if (error) {
-			ntfs_free(buf);
-			return error;
-		}
+		if (error)
+			goto read_err_ret;
 		ino->u.index.recordsize = NTFS_GETU32(buf + 0x8);
 		ino->u.index.clusters_per_record = NTFS_GETU32(buf + 0xC);
 		entry = buf + 0x20;
-		ntfs_debug(DEBUG_DIR3, "unsorted 2\n");
-	} else { /* we are in an index record */
+		ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 2: In index "
+				"root.\n");
+		/* Compensate for faked "." and "..". */
+		start = 2;
+	} else { /* We are in an index record. */
 		length = ino->u.index.recordsize;
 		buf = ntfs_malloc(length);
 		if (!buf)
@@ -840,43 +841,48 @@
 		block = *p_high - ino->u.index.clusters_per_record;
 		error = ntfs_read_attr(ino, vol->at_index_allocation, I30,
 				(__s64)block << vol->cluster_size_bits, &io);
-		if (!error && io.size != length)
-			error = -EIO;
-		if (error) {
-			ntfs_error("read failed\n");
-			ntfs_free(buf);
-			return error;
-		}
+		if (error || io.size != length)
+			goto read_err_ret;
 		if (!ntfs_check_index_record(ino, buf)) {
-			ntfs_error("%x is not an index record\n", block);
+			ntfs_error(__FUNCTION__ "(): Block 0x%x is not an "
+					"index record. Returning -ENOTDIR.\n",
+					block);
 			ntfs_free(buf);
 			return -ENOTDIR;
 		}
 		entry = buf + NTFS_GETU16(buf + 0x18) + 0x18;
-		ntfs_debug(DEBUG_DIR3, "unsorted 3\n");
+		ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 3: In index "
+				"allocation.\n");
+		start = 0;
 	}
 	/* Process the entries. */
-	start = *p_low;
-	while (ntfs_entry_is_used(entry)) {
-		ntfs_debug(DEBUG_DIR3, "unsorted 4\n");
-		if (start)
-			start--; /* Skip entries that were already processed. */
-		else {
-			ntfs_debug(DEBUG_DIR3, "unsorted 5\n");
-			if ((error = cb(entry, param)))
-				/* The entry could not be processed. */
-				break;
-			(*p_low)++;
+	finish = *p_low;
+	for (; ntfs_entry_is_used(entry); entry += NTFS_GETU16(entry + 8)) {
+		if (start < finish) {
+			/* Skip entries that were already processed. */
+			ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 4: "
+					"Skipping already processed entry "
+					"p_high 0x%x, p_low 0x%x.\n", *p_high,
+					start);
+			start++;
+			continue;
 		}
-		entry += NTFS_GETU16(entry + 8);
-	}
-	ntfs_debug(DEBUG_DIR3, "unsorted 6\n");
-	/* Caller did not process all entries. */
-	if (error) {
-		ntfs_free(buf);
-		ntfs_debug(DEBUG_DIR3, "unsorted 7\n");
-		return error;
+		ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 5: "
+				"Processing entry p_high 0x%x, p_low 0x%x.\n",
+				*p_high, *p_low);
+		if ((error = cb(entry, param))) {
+			/* filldir signalled us to stop. */
+			ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): "
+					"Unsorted 6: cb returned %i, "
+					"returning 0, p_high 0x%x, p_low 0x%x."
+					"\n", *p_high, *p_low);
+			ntfs_free(buf);
+			return 0;
+		}
+		++*p_low;
 	}
+	ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 7: After processing "
+			"entries, p_high 0x%x, p_low 0x%x.\n", *p_high, *p_low);
 	/* We have to locate the next record. */
 	ntfs_free(buf);
 	buf = 0;
@@ -884,9 +890,10 @@
 	attr = ntfs_find_attr(ino, vol->at_bitmap, I30);
 	if (!attr) {
 		/* Directory does not have index allocation. */
-		*p_high = 0xFFFFFFFF;
-		*p_low = 0;
-		ntfs_debug(DEBUG_DIR3, "unsorted 8\n");
+		*p_high = 0x7fff;
+		ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 8: No index "
+				"allocation. Returning 0, p_high 0x7fff, "
+				"p_low 0x0.\n");
 		return 0;
 	}
 	buf = ntfs_malloc(length = attr->size);
@@ -895,38 +902,44 @@
 	io.param = buf;
 	io.size = length;
 	error = ntfs_read_attr(ino, vol->at_bitmap, I30, 0, &io);
-	if (!error && io.size != length)
-		error = -EIO;
-	if (error) {
-		ntfs_free(buf);
-		ntfs_debug(DEBUG_DIR3, "unsorted 9\n");
-		return -EIO;
-	}
+	if (error || io.size != length)
+		goto read_err_ret;
 	attr = ntfs_find_attr(ino, vol->at_index_allocation, I30);
 	if (!attr) {
 		ntfs_free(buf);
-		ntfs_debug(DEBUG_DIR3, "unsorted 9.5\n");
+		ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 9: Find "
+				"attr failed. Returning -EIO.\n");
 		return -EIO;
 	}
-	while (1) {
-		if ((__s64)*p_high << vol->cluster_size_bits > attr->size) {
+	/* Loop while going through non-allocated index records. */
+	do {
+		if ((s64)*p_high << vol->cluster_size_bits >
+				attr->initialized) {
 			/* No more index records. */
-			*p_high = 0xFFFFFFFF;
+			*p_high = 0x7fff;
 			ntfs_free(buf);
-			ntfs_debug(DEBUG_DIR3, "unsorted 10\n");
+			ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 10: "
+					"No more index records. Returning 0, "
+					"p_high 0x7fff, p_low 0x%x.\n", *p_low);
 			return 0;
 		}
 		*p_high += ino->u.index.clusters_per_record;
 		byte = *p_high / ino->u.index.clusters_per_record - 1;
 		bit = 1 << (byte & 7);
 		byte = byte >> 3;
-		/* This record is allocated. */
-		if (buf[byte] & bit)
-			break;
-	}
-	ntfs_debug(DEBUG_DIR3, "unsorted 11\n");
+	} while (!(buf[byte] & bit));
+	ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 11: Done. "
+			"Returning 0, p_high 0x%x, p_low 0x%x.\n", *p_high,
+			*p_low);
 	ntfs_free(buf);
 	return 0;
+read_err_ret:
+	if (!error)
+		error = -EIO;
+	ntfs_error(__FUNCTION__ "(): Read failed. Returning error code %i.\n",
+			error);
+	ntfs_free(buf);
+	return error;
 }
 
 int ntfs_dir_add(ntfs_inode *dir, ntfs_inode *new, ntfs_attribute *name)
@@ -1033,7 +1046,7 @@
 				data, sizeof(data), &da);
 }
 
-int ntfs_mkdir(ntfs_inode* dir, const char* name, int namelen,
+int ntfs_mkdir(ntfs_inode *dir, const char *name, int namelen,
 	       ntfs_inode *result)
 {
 	int error;
diff -urN linux-2.4.10-pre5/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- linux-2.4.10-pre5/fs/ntfs/fs.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/fs.c	Mon Dec  3 23:08:13 2001
@@ -21,6 +21,7 @@
 #include "support.h"
 #include "macros.h"
 #include "sysctl.h"
+#include "attr.h"
 #include <linux/module.h>
 #include <asm/uaccess.h>
 #include <linux/locks.h>
@@ -100,175 +101,221 @@
 }
 
 #ifdef CONFIG_NTFS_RW
-static ssize_t ntfs_write(struct file *filp, const char* buf, size_t count,
-			  loff_t *pos)
+static ssize_t ntfs_write(struct file *filp, const char *buf, size_t count,
+		loff_t *pos)
 {
-	int ret;
+	int err;
+	struct inode *vfs_ino = filp->f_dentry->d_inode;
+	ntfs_inode *ntfs_ino = NTFS_LINO2NINO(vfs_ino);
+	ntfs_attribute *data;
 	ntfs_io io;
-	struct inode *inode = filp->f_dentry->d_inode;
-	ntfs_inode *ino = NTFS_LINO2NINO(inode);
 	struct ntfs_getuser_update_vm_s param;
 
-	if (!ino)
+	if (!ntfs_ino)
 		return -EINVAL;
-	ntfs_debug(DEBUG_LINUX, "ntfs_write %x, %x, %x ->\n",
-		   (unsigned)ino->i_number, (unsigned)*pos, (unsigned)count);
+	ntfs_debug(DEBUG_LINUX, __FUNCTION__ "(): Entering for inode 0x%lx, "
+			"*pos 0x%Lx, count 0x%x.\n", ntfs_ino->i_number, *pos,
+			count);
 	/* Allows to lock fs ro at any time. */
-	if (inode->i_sb->s_flags & MS_RDONLY)
-		return -ENOSPC;
-	if (!ntfs_find_attr(ino, ino->vol->at_data, NULL))
+	if (vfs_ino->i_sb->s_flags & MS_RDONLY)
+		return -EROFS;
+	data = ntfs_find_attr(ntfs_ino, ntfs_ino->vol->at_data, NULL);
+	if (!data)
 		return -EINVAL;
 	/* Evaluating O_APPEND is the file system's job... */
 	if (filp->f_flags & O_APPEND)
-		*pos = inode->i_size;
+		*pos = vfs_ino->i_size;
+	if (!data->resident && *pos + count > data->allocated) {
+		err = ntfs_extend_attr(ntfs_ino, data, *pos + count);
+		if (err < 0)
+			return err;
+	}
 	param.user = buf;
-	param.ino = inode;
+	param.ino = vfs_ino;
 	param.off = *pos;
 	io.fn_put = 0;
 	io.fn_get = ntfs_getuser_update_vm;
 	io.param = &param;
 	io.size = count;
-	ret = ntfs_write_attr(ino, ino->vol->at_data, NULL, *pos, &io);
-	ntfs_debug(DEBUG_LINUX, "write -> %x\n", ret);
-	if (ret < 0)
-		return -EINVAL;
-	*pos += io.size;
-	if (*pos > inode->i_size)
-		inode->i_size = *pos;
-	mark_inode_dirty(filp->f_dentry->d_inode);
-	return io.size;
+	io.do_read = 0;
+	err = ntfs_readwrite_attr(ntfs_ino, data, *pos, &io);
+	ntfs_debug(DEBUG_LINUX, __FUNCTION__ "(): Returning %i\n", -err);
+	if (!err) {
+		*pos += io.size;
+		if (*pos > vfs_ino->i_size)
+			vfs_ino->i_size = *pos;
+		mark_inode_dirty(vfs_ino);
+		return io.size;
+	}
+	return err;
 }
 #endif
 
-struct ntfs_filldir{
+struct ntfs_filldir {
 	struct inode *dir;
 	filldir_t filldir;
 	unsigned int type;
-	ntfs_u32 ph,pl;
+	u32 ph, pl;
 	void *dirent;
 	char *name;
 	int namelen;
+	int ret_code;
 };
-	
+
 static int ntfs_printcb(ntfs_u8 *entry, void *param)
 {
+	unsigned long inum = NTFS_GETU64(entry) & 0xffffffffffff;
 	struct ntfs_filldir *nf = param;
-	int flags = NTFS_GETU8(entry + 0x51);
-	int show_hidden = 0;
-	int length = NTFS_GETU8(entry + 0x50);
-	int inum = NTFS_GETU32(entry);
-	int error;
-#ifdef NTFS_NGT_NT_DOES_LOWER
-	int i, to_lower = 0;
-#endif
+	u32 flags = NTFS_GETU32(entry + 0x48);
+	char show_sys_files = 0;
+	u8 name_len = NTFS_GETU8(entry + 0x50);
+	u8 name_type = NTFS_GETU8(entry + 0x51);
+	int err;
+	unsigned file_type;
+
 	switch (nf->type) {
 	case ngt_dos:
 		/* Don't display long names. */
-		if ((flags & 2) == 0)
+		if (!(name_type & 2))
 			return 0;
 		break;
 	case ngt_nt:
 		/* Don't display short-only names. */
-		switch (flags & 3) {
-		case 2: 
+		if ((name_type & 3) == 2)
 			return 0;
-#ifdef NTFS_NGT_NT_DOES_LOWER
-		case 3: 
-			to_lower = 1;
-#endif
-		}
 		break;
 	case ngt_posix:
 		break;
 	case ngt_full:
-		show_hidden = 1;
+		show_sys_files = 1;
 		break;
+	default:
+		BUG();
 	}
-	if (!show_hidden && ((NTFS_GETU8(entry + 0x48) & 2) == 2)) {
-		ntfs_debug(DEBUG_OTHER, "Skipping hidden file\n");
-		return 0;
-	}
-	nf->name = 0;
 	if (ntfs_encodeuni(NTFS_INO2VOL(nf->dir), (ntfs_u16*)(entry + 0x52),
-			   length, &nf->name, &nf->namelen)){
-		ntfs_debug(DEBUG_OTHER, "Skipping unrepresentable file\n");
+			name_len, &nf->name, &nf->namelen)) {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Skipping "
+				"unrepresentable file.\n");
 		if (nf->name)
 			ntfs_free(nf->name);
 		return 0;
 	}
+	if (!show_sys_files && inum < 0x10UL) {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Skipping system "
+				"file (%s).\n", nf->name);
+		return 0;
+	}
 	/* Do not return ".", as this is faked. */
-	if (length == 1 && *nf->name == '.')
+	if (nf->namelen == 1 && nf->name[0] == '.') {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Skipping \".\"\n");
 		return 0;
-#ifdef NTFS_NGT_NT_DOES_LOWER
-	if (to_lower)
-		for(i = 0; i < nf->namelen; i++)
-			/* This supports ASCII only. Since only DOS-only names
-			 * get converted, and since those are restricted to
-			 * ASCII, this should be correct. */
-			if (nf->name[i] >= 'A' && nf->name[i] <= 'Z')
-				nf->name[i] += 'a' - 'A';
-#endif
+	}
 	nf->name[nf->namelen] = 0;
-	ntfs_debug(DEBUG_OTHER, "readdir got %s, len %d\n", nf->name,
-		       						nf->namelen);
-	/* filldir expects an off_t rather than an loff_t. Hope we don't have
-	 * more than 65535 index records. */
-	error = nf->filldir(nf->dirent, nf->name, nf->namelen,
-			    (nf->ph << 16) | nf->pl, inum, DT_UNKNOWN);
+	if (flags & 0x10000000) /* FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT */
+		file_type = DT_DIR;
+	else
+		file_type = DT_REG;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Calling filldir for %s with "
+			"len %i, f_pos 0x%Lx, inode %lu, %s.\n",
+			nf->name, nf->namelen, (loff_t)(nf->ph << 16) | nf->pl,
+			inum, file_type == DT_DIR ? "DT_DIR" : "DT_REG");
+	/*
+	 * Userspace side of filldir expects an off_t rather than an loff_t.
+	 * And it also doesn't like the most significant bit being set as it
+	 * then considers the value to be negative. Thus this implementation
+	 * limits the number of index records to 32766, which should be plenty.
+	 */
+	err = nf->filldir(nf->dirent, nf->name, nf->namelen,
+			(loff_t)(nf->ph << 16) | nf->pl, inum, file_type);
+	if (err)
+		nf->ret_code = err;
 	ntfs_free(nf->name);
-	return error;
+	return err;
 }
 
-/* readdir returns '..', then '.', then the directory entries in sequence.
- * As the root directory contains a entry for itself, '.' is not emulated for
- * the root directory. */
+/*
+ * readdir returns '.', then '..', then the directory entries in sequence.
+ * As the root directory contains an entry for itself, '.' is not emulated for
+ * the root directory.
+ */
 static int ntfs_readdir(struct file* filp, void *dirent, filldir_t filldir)
 {
-	struct ntfs_filldir cb;
-	int error;
 	struct inode *dir = filp->f_dentry->d_inode;
+	int err;
+	struct ntfs_filldir cb;
 
-	ntfs_debug(DEBUG_OTHER, "ntfs_readdir ino %x mode %x\n",
-		   (unsigned)dir->i_ino, (unsigned int)dir->i_mode);
-
-	ntfs_debug(DEBUG_OTHER, "readdir: Looking for file %x dircount %d\n",
-		   (unsigned)filp->f_pos, atomic_read(&dir->i_count));
-	cb.pl = filp->f_pos & 0xFFFF;
-	cb.ph = filp->f_pos >> 16;
-	/* End of directory. */
-	if (cb.ph == 0xFFFF) {
-		/* FIXME: Maybe we can return those with the previous call. */
-		switch (cb.pl) {
-		case 0: 
-			filldir(dirent, ".", 1, filp->f_pos, dir->i_ino,DT_DIR);
-			filp->f_pos = 0xFFFF0001;
-			return 0;
-			/* FIXME: Parent directory. */
-		case 1:
-			filldir(dirent, "..", 2, filp->f_pos, 0, DT_DIR);
-			filp->f_pos = 0xFFFF0002;
-			return 0;
+	cb.ret_code = 0;
+	cb.pl = filp->f_pos & 0xffff;
+	cb.ph = (filp->f_pos >> 16) & 0x7fff;
+	filp->f_pos = (loff_t)(cb.ph << 16) | cb.pl;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Entering for inode %lu, "
+			"f_pos 0x%Lx, i_mode 0x%x, i_count %lu.\n", dir->i_ino,
+			filp->f_pos, (unsigned int)dir->i_mode,
+			atomic_read(&dir->i_count));
+	if (!cb.ph) {
+		/* Start of directory. Emulate "." and "..". */
+		if (!cb.pl) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Calling "
+				    "filldir for . with len 1, f_pos 0x%Lx, "
+				    "inode %lu, DT_DIR.\n", filp->f_pos,
+				    dir->i_ino);
+			cb.ret_code = filldir(dirent, ".", 1, filp->f_pos,
+				    dir->i_ino, DT_DIR);
+			if (cb.ret_code)
+				goto done;
+			cb.pl++;
+			filp->f_pos = (loff_t)(cb.ph << 16) | cb.pl;
 		}
-		ntfs_debug(DEBUG_OTHER, "readdir: EOD\n");
-		return 0;
-	}
+		if (cb.pl == (u32)1) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Calling "
+				    "filldir for .. with len 2, f_pos 0x%Lx, "
+				    "inode %lu, DT_DIR.\n", filp->f_pos,
+				    filp->f_dentry->d_parent->d_inode->i_ino);
+			cb.ret_code = filldir(dirent, "..", 2, filp->f_pos,
+				    filp->f_dentry->d_parent->d_inode->i_ino,
+				    DT_DIR);
+			if (cb.ret_code)
+				goto done;
+			cb.pl++;
+			filp->f_pos = (loff_t)(cb.ph << 16) | cb.pl;
+		}
+	} else if (cb.ph >= 0x7fff)
+		/* End of directory. */
+		goto done;
 	cb.dir = dir;
 	cb.filldir = filldir;
 	cb.dirent = dirent;
 	cb.type = NTFS_INO2VOL(dir)->ngt;
 	do {
-		ntfs_debug(DEBUG_OTHER,"looking for next file\n");
-		error = ntfs_getdir_unsorted(NTFS_LINO2NINO(dir), &cb.ph,
-					     &cb.pl, ntfs_printcb, &cb);
-	} while (!error && cb.ph != 0xFFFFFFFF);
-	filp->f_pos = (cb.ph << 16) | cb.pl;
-	ntfs_debug(DEBUG_OTHER, "new position %x\n", (unsigned)filp->f_pos);
-        /* -EINVAL is on user buffer full. This is not considered as an error
-	 * by sys_getdents. */
-	if (error == -EINVAL) 
-		error = 0;
-	/* Otherwise (device error, inconsistent data) return the error code. */
-	return error;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Looking for next "
+				"file using ntfs_getdir_unsorted(), f_pos "
+				"0x%Lx.\n", (loff_t)(cb.ph << 16) | cb.pl);
+		err = ntfs_getdir_unsorted(NTFS_LINO2NINO(dir), &cb.ph, &cb.pl,
+				ntfs_printcb, &cb);
+	} while (!err && cb.ph < 0x7fff);
+	filp->f_pos = (loff_t)(cb.ph << 16) | cb.pl;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After ntfs_getdir_unsorted()"
+			" calls, f_pos 0x%Lx.\n", filp->f_pos);
+	if (!err) {
+#ifdef DEBUG
+		if (cb.ph != 0x7fff || cb.pl)
+			BUG();
+done:
+		if (!cb.ret_code)
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): EOD, f_pos "
+					"0x%Lx, returning 0.\n", filp->f_pos);
+		else 
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): filldir "
+					"returned %i, returning 0, f_pos "
+					"0x%Lx.\n", cb.ret_code, filp->f_pos);
+#else
+done:
+#endif
+		return 0;
+	}
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Returning %i, f_pos 0x%Lx.\n",
+			err, filp->f_pos);
+	return err;
 }
 
 /* Copied from vfat driver. */
@@ -475,8 +522,8 @@
 	ntfs_iterate_s walk;
 	int error;
 	
-	ntfs_debug(DEBUG_NAME1, "Looking up %s in %x\n", d->d_name.name,
-		   (unsigned)dir->i_ino);
+	ntfs_debug(DEBUG_NAME1, __FUNCTION__ "(): Looking up %s in directory "
+			"ino 0x%x.\n", d->d_name.name, (unsigned)dir->i_ino);
 	/* Convert to wide string. */
 	error = ntfs_decodeuni(NTFS_INO2VOL(dir), (char*)d->d_name.name,
 			       d->d_name.len, &walk.name, &walk.namelen);
@@ -499,7 +546,7 @@
 	return NULL;
 }
 
-static struct file_operations ntfs_file_operations_nommap = {
+static struct file_operations ntfs_file_operations = {
 	llseek:		generic_file_llseek,
 	read:		ntfs_read,
 #ifdef CONFIG_NTFS_RW
@@ -508,7 +555,7 @@
 	open:		generic_file_open,
 };
 
-static struct inode_operations ntfs_inode_operations_nobmap;
+static struct inode_operations ntfs_inode_operations;
 
 #ifdef CONFIG_NTFS_RW
 static int ntfs_create(struct inode* dir, struct dentry *d, int mode)
@@ -554,8 +601,8 @@
 		r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr + 8));
 	}
 	/* It's not a directory */
-	r->i_op = &ntfs_inode_operations_nobmap;
-	r->i_fop = &ntfs_file_operations_nommap,
+	r->i_op = &ntfs_inode_operations;
+	r->i_fop = &ntfs_file_operations;
 	r->i_mode = S_IFREG | S_IRUGO;
 #ifdef CONFIG_NTFS_RW
 	r->i_mode |= S_IWUGO;
@@ -622,28 +669,6 @@
 }
 #endif
 
-/* It's fscking broken. */
-/* FIXME: mmap code is disabled until ntfs_get_block() gets sorted! */
-/*
-static int ntfs_get_block(struct inode *inode, long block, struct buffer_head *bh, int create)
-{
-	BUG();
-	return -1;
-}
-
-static struct file_operations ntfs_file_operations = {
-	llseek:		generic_file_llseek,
-	read:		ntfs_read,
-	mmap:		generic_file_mmap,
-#ifdef CONFIG_NTFS_RW
-	write:		ntfs_write,
-#endif
-	open:		generic_file_open,
-};
-
-static struct inode_operations ntfs_inode_operations;
-*/
-
 static struct file_operations ntfs_dir_operations = {
 	read:		generic_read_dir,
 	readdir:	ntfs_readdir,
@@ -657,39 +682,6 @@
 #endif
 };
 
-/*
-static int ntfs_writepage(struct page *page)
-{
-	return block_write_full_page(page,ntfs_get_block);
-}
-
-static int ntfs_readpage(struct file *file, struct page *page)
-{
-	return block_read_full_page(page,ntfs_get_block);
-}
-
-static int ntfs_prepare_write(struct file *file, struct page *page,
-			      unsigned from, unsigned to)
-{
-	return cont_prepare_write(page, from, to, ntfs_get_block,
-				  &page->mapping->host->u.ntfs_i.mmu_private);
-}
-
-static int _ntfs_bmap(struct address_space *mapping, long block)
-{
-	return generic_block_bmap(mapping, block, ntfs_get_block);
-}
-
-struct address_space_operations ntfs_aops = {
-	readpage: ntfs_readpage,
-	writepage: ntfs_writepage,
-	sync_page: block_sync_page,
-	prepare_write: ntfs_prepare_write,
-	commit_write: generic_commit_write,
-	bmap: _ntfs_bmap
-};
-*/
-
 /* ntfs_read_inode() is called by the Virtual File System (the kernel layer 
  * that deals with filesystems) when iget is called requesting an inode not
  * already present in the inode table. Typically filesystems have separate
@@ -697,7 +689,6 @@
 static void ntfs_read_inode(struct inode* inode)
 {
 	ntfs_volume *vol;
-	int can_mmap = 0;
 	ntfs_inode *ino;
 	ntfs_attribute *data;
 	ntfs_attribute *si;
@@ -707,7 +698,7 @@
 	ntfs_debug(DEBUG_OTHER, "ntfs_read_inode 0x%lx\n", inode->i_ino);
 	switch (inode->i_ino) {
 		/* Those are loaded special files. */
-	case FILE_$Mft:
+	case FILE_Mft:
 		if (!vol->mft_ino || ((vol->ino_flags & 1) == 0))
 			goto sys_file_error;
 		ntfs_memcpy(&inode->u.ntfs_i, vol->mft_ino, sizeof(ntfs_inode));
@@ -718,7 +709,7 @@
 		ino = vol->mft_ino;
 		ntfs_debug(DEBUG_OTHER, "Opening $MFT!\n");
 		break;
-	case FILE_$MftMirr:
+	case FILE_MftMirr:
 		if (!vol->mftmirr || ((vol->ino_flags & 2) == 0))
 			goto sys_file_error;
 		ntfs_memcpy(&inode->u.ntfs_i, vol->mftmirr, sizeof(ntfs_inode));
@@ -729,7 +720,7 @@
 		ino = vol->mftmirr;
 		ntfs_debug(DEBUG_OTHER, "Opening $MFTMirr!\n");
 		break;
-	case FILE_$BitMap:
+	case FILE_BitMap:
 		if (!vol->bitmap || ((vol->ino_flags & 4) == 0))
 			goto sys_file_error;
 		ntfs_memcpy(&inode->u.ntfs_i, vol->bitmap, sizeof(ntfs_inode));
@@ -740,9 +731,9 @@
 		ino = vol->bitmap;
 		ntfs_debug(DEBUG_OTHER, "Opening $Bitmap!\n");
 		break;
-	case FILE_$LogFile ... FILE_$AttrDef:
+	case FILE_LogFile ... FILE_AttrDef:
 	/* No need to log root directory accesses. */
-	case FILE_$Boot ... FILE_$UpCase:
+	case FILE_Boot ... FILE_UpCase:
 		ntfs_debug(DEBUG_OTHER, "Opening system file %i!\n",
 				inode->i_ino);
 	default:
@@ -761,17 +752,10 @@
 	inode->i_nlink = 1;
 	/* Use the size of the data attribute as file size */
 	data = ntfs_find_attr(ino, vol->at_data, NULL);
-	if (!data) {
+	if (!data)
 		inode->i_size = 0;
-		can_mmap = 0;
-	} else {
+	else
 		inode->i_size = data->size;
-		/* FIXME: once ntfs_get_block is implemented, uncomment the
-		 * next line and remove the "can_mmap = 0;". (AIA) */
-		/* can_mmap = !data->resident && !(data->flags &
-		 * 		(ATTR_IS_COMPRESSED | ATTR_IS_ENCRYPTED)); */
-		can_mmap = 0;
-	}
 	/* Get the file modification times from the standard information. */
 	si = ntfs_find_attr(ino, vol->at_standard_information, NULL);
 	if (si) {
@@ -789,20 +773,8 @@
 		inode->i_fop = &ntfs_dir_operations;
 		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
 	} else {
-		/* As long as ntfs_get_block() is just a call to BUG() do not
-	 	 * define any [bm]map ops or we get the BUG() whenever someone
-		 * runs mc or mpg123 on an ntfs partition!
-		 * FIXME: Uncomment the below code when ntfs_get_block is
-		 * implemented. */
-		/* if (can_mmap) {
-			inode->i_op = &ntfs_inode_operations;
-			inode->i_fop = &ntfs_file_operations;
-			inode->i_mapping->a_ops = &ntfs_aops;
-			inode->u.ntfs_i.mmu_private = inode->i_size;
-		} else */ {
-			inode->i_op = &ntfs_inode_operations_nobmap;
-			inode->i_fop = &ntfs_file_operations_nommap;
-		}
+		inode->i_op = &ntfs_inode_operations;
+		inode->i_fop = &ntfs_file_operations;
 		inode->i_mode = S_IFREG | S_IRUGO;
 	}
 #ifdef CONFIG_NTFS_RW
@@ -839,7 +811,7 @@
 		ntfs_error("_ntfs_clear_inode: vol = NTFS_INO2VOL(inode) is "
 				"NULL.\n");
 	switch (inode->i_ino) {
-	case FILE_$Mft:
+	case FILE_Mft:
 		if (vol->mft_ino && ((vol->ino_flags & 1) == 0)) {
 			ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
 			ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));
@@ -848,7 +820,7 @@
 			goto unl_out;
 		}
 		break;
-	case FILE_$MftMirr:
+	case FILE_MftMirr:
 		if (vol->mftmirr && ((vol->ino_flags & 2) == 0)) {
 			ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
 			ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));
@@ -857,7 +829,7 @@
 			goto unl_out;
 		}
 		break;
-	case FILE_$BitMap:
+	case FILE_BitMap:
 		if (vol->bitmap && ((vol->ino_flags & 4) == 0)) {
 			ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));
 			ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));
@@ -909,9 +881,11 @@
 	if (size < 0LL)
 		size = 0;
 	sf->f_bfree = sf->f_bavail = size;
-	ntfs_debug(DEBUG_OTHER, "ntfs_statfs: calling mft = iget(sb, FILE_$Mft)\n");
-	mft = iget(sb, FILE_$Mft);
-	ntfs_debug(DEBUG_OTHER, "ntfs_statfs: iget(sb, FILE_$Mft) returned 0x%x\n", mft);
+	ntfs_debug(DEBUG_OTHER, "ntfs_statfs: calling mft = iget(sb, "
+			"FILE_Mft)\n");
+	mft = iget(sb, FILE_Mft);
+	ntfs_debug(DEBUG_OTHER, "ntfs_statfs: iget(sb, FILE_Mft) returned "
+			"0x%x\n", mft);
 	if (!mft)
 		return -EIO;
 	sf->f_files = mft->i_size >> vol->mft_record_size_bits;
@@ -1021,8 +995,8 @@
  *
  * NOTE : A context switch can happen in kernel code only if the code blocks
  * (= calls schedule() in kernel/sched.c). */
-struct super_block * ntfs_read_super(struct super_block *sb, void *options,
-				     int silent)
+struct super_block *ntfs_read_super(struct super_block *sb, void *options,
+		int silent)
 {
 	ntfs_volume *vol;
 	struct buffer_head *bh;
@@ -1053,7 +1027,7 @@
 		bforget(bh);
 		goto ntfs_read_super_unl;
 	}
-	ntfs_debug(DEBUG_OTHER, "$Mft at cluster 0x%Lx\n", vol->mft_lcn);
+	ntfs_debug(DEBUG_OTHER, "$Mft at cluster 0x%lx\n", vol->mft_lcn);
 	bforget(bh);
 	NTFS_SB(vol) = sb;
 	if (vol->cluster_size > PAGE_SIZE) {
@@ -1107,7 +1081,7 @@
 	}
 	ntfs_debug(DEBUG_OTHER, "Getting RootDir\n");
 	/* Get the root directory. */
-	if (!(sb->s_root = d_alloc_root(iget(sb, FILE_$root)))) {
+	if (!(sb->s_root = d_alloc_root(iget(sb, FILE_root)))) {
 		ntfs_error("Could not get root dir inode\n");
 		goto ntfs_read_super_mft;
 	}
@@ -1131,7 +1105,19 @@
 #if defined(DEBUG) && !defined(MODULE)
 	console_verbose();
 #endif
-	printk(KERN_NOTICE "NTFS version " NTFS_VERSION "\n");
+	printk(KERN_NOTICE "NTFS driver v" NTFS_VERSION " [Flags: R/"
+#ifdef CONFIG_NTFS_RW
+			"W"
+#else
+			"O"
+#endif
+#ifdef DEBUG
+			" DEBUG"
+#endif
+#ifdef MODULE
+			" MODULE"
+#endif
+			"]\n");
 	SYSCTL(1);
 	ntfs_debug(DEBUG_OTHER, "registering %s\n", ntfs_fs_type.name);
 	/* Add this filesystem to the kernel table of filesystems. */
@@ -1151,7 +1137,7 @@
  * I am just maintaining and rewriting it.
  */
 MODULE_AUTHOR("Anton Altaparmakov <aia21@cus.cam.ac.uk>");
-MODULE_DESCRIPTION("NTFS driver");
+MODULE_DESCRIPTION("Linux NTFS driver");
 #ifdef DEBUG
 MODULE_PARM(ntdebug, "i");
 MODULE_PARM_DESC(ntdebug, "Debug level");
diff -urN linux-2.4.10-pre5/fs/ntfs/inode.c linux/fs/ntfs/inode.c
--- linux-2.4.10-pre5/fs/ntfs/inode.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/inode.c	Mon Dec  3 23:08:13 2001
@@ -8,7 +8,6 @@
  * Copyright (C) 1999 Steve Dodd
  * Copyright (C) 2000-2001 Anton Altaparmakov (AIA)
  */
-
 #include "ntfstypes.h"
 #include "ntfsendian.h"
 #include "struct.h"
@@ -34,31 +33,36 @@
 	ntfs_mft_record *records;
 } ntfs_disk_inode;
 
-void ntfs_fill_mft_header(ntfs_u8 *mft, int record_size, int blocksize,
-			  int sequence_number)
+static void ntfs_fill_mft_header(ntfs_u8 *mft, int rec_size, int seq_no,
+		int links, int flags)
 {
-	int fixup_count = record_size / blocksize + 1;
-	int attr_offset = (0x2a + (2 * fixup_count) + 7) & ~7;
-	int fixup_offset = 0x2a;
-
-	NTFS_PUTU32(mft + 0x00, 0x454c4946);	     /* FILE */
-	NTFS_PUTU16(mft + 0x04, 0x2a);		     /* Offset to fixup. */
-	NTFS_PUTU16(mft + 0x06, fixup_count);	     /* Number of fixups. */
-	NTFS_PUTU16(mft + 0x10, sequence_number);    /* Sequence number. */
-	NTFS_PUTU16(mft + 0x12, 1);                  /* Hard link count. */
-	NTFS_PUTU16(mft + 0x14, attr_offset);	     /* Offset to attributes. */
-	NTFS_PUTU16(mft + 0x16, 1);                  /* Flags: 1 = In use,
-							       2 = Directory. */
-	NTFS_PUTU32(mft + 0x18, attr_offset + 0x08); /* Bytes in use. */
-	NTFS_PUTU32(mft + 0x1c, record_size);	     /* Total allocated size. */
-	NTFS_PUTU16(mft + fixup_offset, 1);	     /* Fixup word. */
-	NTFS_PUTU32(mft + attr_offset, 0xffffffff);  /* End marker. */
+	int fixup_ofs = 0x2a;
+	int fixup_cnt = rec_size / NTFS_SECTOR_SIZE + 1;
+	int attr_ofs = (fixup_ofs + 2 * fixup_cnt + 7) & ~7;
+
+	NTFS_PUTU32(mft + 0x00, 0x454c4946);	/* FILE */
+	NTFS_PUTU16(mft + 0x04, fixup_ofs);	/* Offset to fixup. */
+	NTFS_PUTU16(mft + 0x06, fixup_cnt);	/* Number of fixups. */
+	NTFS_PUTU64(mft + 0x08, 0);		/* Logical sequence number. */
+	NTFS_PUTU16(mft + 0x10, seq_no);	/* Sequence number. */
+	NTFS_PUTU16(mft + 0x12, links);		/* Hard link count. */
+	NTFS_PUTU16(mft + 0x14, attr_ofs);	/* Offset to attributes. */
+	NTFS_PUTU16(mft + 0x16, flags);		/* Flags: 1 = In use,
+							  2 = Directory. */
+	NTFS_PUTU32(mft + 0x18, attr_ofs + 8);	/* Bytes in use. */
+	NTFS_PUTU32(mft + 0x1c, rec_size);	/* Total allocated size. */
+	NTFS_PUTU64(mft + 0x20, 0);		/* Base mft record. */
+	NTFS_PUTU16(mft + 0x28, 0);		/* Next attr instance. */
+	NTFS_PUTU16(mft + fixup_ofs, 1);	/* Fixup word. */
+	NTFS_PUTU32(mft + attr_ofs, (__u32)-1);	/* End of attributes marker. */
 }
 
-/* Search in an inode an attribute by type and name. 
+/*
+ * Search in an inode an attribute by type and name. 
  * FIXME: Check that when attributes are inserted all attribute list
  * attributes are expanded otherwise need to modify this function to deal
- * with attribute lists. (AIA) */
+ * with attribute lists. (AIA)
+ */
 ntfs_attribute *ntfs_find_attr(ntfs_inode *ino, int type, char *name)
 {
 	int i;
@@ -83,102 +87,6 @@
 	return 0;
 }
 
-/* FIXME: Need better strategy to extend the MFT. */
-static int ntfs_extend_mft(ntfs_volume *vol)
-{
-	/* Try to allocate at least 0.1% of the remaining disk space for
-	 * inodes. If the disk is almost full, make sure at least one inode is
-	 * requested. */
-	int rcount, error, mft_rec_size;
-	__s64 size;
-	ntfs_attribute *mdata, *bmp;
-	ntfs_u8 *buf;
-	ntfs_io io;
-
-	mdata = ntfs_find_attr(vol->mft_ino, vol->at_data, 0);
-	if (!mdata)
-		return -EINVAL;
-	mft_rec_size = vol->mft_record_size;
-	/* First check whether there is uninitialized space. */
-	if (mdata->allocated < mdata->size + mft_rec_size) {
-		size = (__s64)ntfs_get_free_cluster_count(vol->bitmap) <<
-				vol->cluster_size_bits >> 10;
-		/* On error, size will be negative. We can ignore this as we
-		 * will fall back to the minimal size allocation below. (AIA) */
-		if (size < mdata->size + mft_rec_size)
-			size = mdata->size + mft_rec_size;
-		size += mft_rec_size - 1;
-		size &= ~(__s64)(mft_rec_size - 1);
-		error = ntfs_extend_attr(vol->mft_ino, mdata, &size,
-				ALLOC_REQUIRE_SIZE);
-		/* Try again, now we have the largest available fragment. */
-		if (error == -ENOSPC) {
-			/* Round down to multiple of mft record size. */
-			size &= ~(__s64)(mft_rec_size - 1);
-			if (!size)
-				return -ENOSPC;
-			error = ntfs_extend_attr(vol->mft_ino, mdata, &size,
-					ALLOC_REQUIRE_SIZE);
-		}
-		if (error)
-			return error;
-	}
-	/* Even though we might have allocated more than needed, we initialize
-	 * only one record. */
-	mdata->size += mft_rec_size;
-	/* Now extend the bitmap if necessary. */
-	rcount = mdata->size >> vol->mft_record_size_bits;
-	bmp = ntfs_find_attr(vol->mft_ino, vol->at_bitmap, 0);
-	if (!bmp)
-		return -EINVAL;
-	if (bmp->size * 8 < rcount) { /* Less bits than MFT records. */
-		ntfs_u8 buf[1];
-		/* Extend bitmap by one byte. */
-		error = ntfs_resize_attr(vol->mft_ino, bmp, bmp->size + 1);
-		if (error)
-			return error;
-		/* Write the single byte. */
-		buf[0] = 0;
-		io.fn_put = ntfs_put;
-		io.fn_get = ntfs_get;
-		io.param = buf;
-		io.size = 1;
-		error = ntfs_write_attr(vol->mft_ino, vol->at_bitmap, 0,
-				bmp->size - 1, &io);
-		if (error)
-			return error;
-		if (io.size != 1)
-			return -EIO;
-	}
-	/* Now fill in the MFT header for the new block. */
-	buf = ntfs_calloc(mft_rec_size);
-	if (!buf)
-		return -ENOMEM;
-	ntfs_fill_mft_header(buf, mft_rec_size, vol->sector_size, 0);
-	error = ntfs_insert_fixups(buf, mft_rec_size);
-	if (error) {
-		printk(KERN_ALERT "NTFS: ntfs_extend_mft() caught corrupt "
-				"mtf record ntfs record header. Refusing to "
-				"write corrupt data to disk. Unmount and run "
-				"chkdsk immediately!\n");
-		return -EIO;
-	}
-	io.param = buf;
-	io.size = mft_rec_size;
-	io.fn_put = ntfs_put;
-	io.fn_get = ntfs_get;
-	error = ntfs_write_attr(vol->mft_ino, vol->at_data, 0,
-			(__s64)(rcount - 1) << vol->mft_record_size_bits, &io);
-	if (error)
-		return error;
-	if (io.size != mft_rec_size)
-		return -EIO;
-	error = ntfs_update_inode(vol->mft_ino);
-	if (error)
-		return error;
-	return 0;
-}
-
 /*
  * Insert all attributes from the record mftno of the MFT in the inode ino.
  * If mftno is a base mft record we abort as soon as we find the attribute
@@ -374,23 +282,23 @@
 	char *buf;
 	ntfs_volume *vol = ino->vol;
 	
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 1\n", ino->i_number);
+	ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 1\n", ino->i_number);
 	if (ntfs_insert_mft_attributes(ino, ino->attr, ino->i_number))
 		return;
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 2\n", ino->i_number);
+	ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 2\n", ino->i_number);
 	alist = ntfs_find_attr(ino, vol->at_attribute_list, 0);
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 3\n", ino->i_number);
+	ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 3\n", ino->i_number);
 	if (!alist)
 		return;
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 4\n", ino->i_number);
+	ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 4\n", ino->i_number);
 	datasize = alist->size;
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x: alist->size = 0x%x\n",
+	ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: alist->size = 0x%x\n",
 			ino->i_number, alist->size);
 	if (alist->resident) {
 		parse_attributes(ino, alist->d.data, &datasize);
 		return;
 	}
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 5\n", ino->i_number);
+	ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 5\n", ino->i_number);
 	buf = ntfs_malloc(1024);
 	if (!buf)    /* FIXME: Should be passing error code to caller. (AIA) */
 		return;
@@ -404,25 +312,26 @@
 		len = 1024 - delta;
 		if (len > datasize)
 			len = datasize;
-		ntfs_debug(DEBUG_FILE2, "load_attributes %x: len = %i\n",
+		ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: len = %i\n",
 						ino->i_number, len);
-		ntfs_debug(DEBUG_FILE2, "load_attributes %x: delta = %i\n",
+		ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: delta = %i\n",
 						ino->i_number, delta);
 		io.size = len;
 		if (ntfs_read_attr(ino, vol->at_attribute_list, 0, offset,
 				   &io))
 			ntfs_error("error in load_attributes\n");
 		delta += len;
-		ntfs_debug(DEBUG_FILE2, "load_attributes %x: after += len, "
+		ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: after += len, "
 				"delta = %i\n", ino->i_number, delta);
 		parse_attributes(ino, buf, &delta);
-		ntfs_debug(DEBUG_FILE2, "load_attributes %x: after parse_attr, "
-				"delta = %i\n", ino->i_number, delta);
+		ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x: after "
+				"parse_attr, delta = %i\n", ino->i_number,
+				delta);
 		if (delta)
 			/* Move remaining bytes to buffer start. */
 			ntfs_memmove(buf, buf + len - delta, delta);
 	}
-	ntfs_debug(DEBUG_FILE2, "load_attributes %x 6\n", ino->i_number);
+	ntfs_debug(DEBUG_FILE2, "load_attributes 0x%x 6\n", ino->i_number);
 	ntfs_free(buf);
 }
 	
@@ -431,7 +340,7 @@
 	char *buf;
 	int error;
 
-	ntfs_debug(DEBUG_FILE1, "Initializing inode %x\n", inum);
+	ntfs_debug(DEBUG_FILE1, "Initializing inode 0x%x\n", inum);
 	ino->i_number = inum;
 	ino->vol = vol;
 	ino->attr = buf = ntfs_malloc(vol->mft_record_size);
@@ -439,17 +348,17 @@
 		return -ENOMEM;
 	error = ntfs_read_mft_record(vol, inum, ino->attr);
 	if (error) {
-		ntfs_debug(DEBUG_OTHER, "Init inode: %x failed\n", inum);
+		ntfs_debug(DEBUG_OTHER, "Init inode: 0x%x failed\n", inum);
 		return error;
 	}
-	ntfs_debug(DEBUG_FILE2, "Init inode: got mft %x\n", inum);
+	ntfs_debug(DEBUG_FILE2, "Init inode: got mft 0x%x\n", inum);
 	ino->sequence_number = NTFS_GETU16(buf + 0x10);
 	ino->attr_count = 0;
 	ino->record_count = 0;
 	ino->records = 0;
 	ino->attrs = 0;
 	ntfs_load_attributes(ino);
-	ntfs_debug(DEBUG_FILE2, "Init inode: done %x\n", inum);
+	ntfs_debug(DEBUG_FILE2, "Init inode: done 0x%x\n", inum);
 	return 0;
 }
 
@@ -588,7 +497,7 @@
 		 * and 6 are probably necessary, and would also require making
 		 * length 64-bit throughout. */
 	default:
-		ntfs_error("Can't decode run type field %x\n", type);
+		ntfs_error("Can't decode run type field 0x%x\n", type);
 		return -1;
 	}
 //	ntfs_debug(DEBUG_FILE3, "ntfs_decompress_run: length = 0x%x\n",*length);
@@ -629,7 +538,7 @@
 		break;
 #endif
 	default:
-		ntfs_error("Can't decode run type field %x\n", type);
+		ntfs_error("Can't decode run type field 0x%x\n", type);
 		return -1;
 	}
 //	ntfs_debug(DEBUG_FILE3, "ntfs_decompress_run: cluster = 0x%x\n",
@@ -638,6 +547,8 @@
 	return 0;
 }
 
+static void dump_runlist(const ntfs_runlist *rl, const int rlen);
+
 /*
  * FIXME: ntfs_readwrite_attr() has the effect of writing @dest to @offset of
  * the attribute value of the attribute @attr in the in memory inode @ino.
@@ -652,17 +563,17 @@
  * vol into buf. Returns the number of bytes read in the ntfs_io struct.
  * Returns 0 on success, errno on failure */
 int ntfs_readwrite_attr(ntfs_inode *ino, ntfs_attribute *attr, __s64 offset,
-			ntfs_io *dest)
+		ntfs_io *dest)
 {
-	int rnum;
+	int rnum, s_vcn, error, clustersizebits;
 	ntfs_cluster_t cluster, s_cluster, vcn, len;
 	__s64 l, chunk, copied;
-	int s_vcn;
-	int error, clustersizebits;
 
-	ntfs_debug(DEBUG_FILE3, "ntfs_readwrite_attr 0: inode = 0x%x, attr->"
-		"type = 0x%x, offset = 0x%Lx, dest->size = 0x%x\n",
-		ino->i_number, attr->type, offset, dest->size);
+	ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): %s 0x%x bytes at offset "
+			"0x%Lx %s inode 0x%x, attr type 0x%x.\n",
+			dest->do_read ? "Read" : "Write", dest->size, offset,
+			dest->do_read ? "from" : "to", ino->i_number,
+			attr->type);
 	l = dest->size;
 	if (l == 0)
 		return 0;
@@ -677,19 +588,22 @@
 		if (offset + l >= attr->size)
 			l = dest->size = attr->size - offset;
 	} else {
-		/* Fixed by CSA: If writing beyond end, extend attribute. */
-		/* If write extends beyond _allocated_ size, extend attrib. */
+		/*
+		 * If write extends beyond _allocated_ size, extend attribute,
+		 * updating attr->allocated and attr->size in the process. (AIA)
+		 */
 		if (offset + l > attr->allocated) {
 			error = ntfs_resize_attr(ino, attr, offset + l);
 			if (error)
 				return error;
-		}
-		/* The amount of initialised data has increased: update. */
-		/* FIXME: Shouldn't we zero-out the section between the old
-		 * 	  initialised length and the write start? */
+		} else if (offset + l > attr->size)
+			/* If amount of data has increased: update. */
+			attr->size = offset + l;
+		/* If amount of initialised data has increased: update. */
 		if (offset + l > attr->initialized) {
+			/* FIXME: Zero-out the section between the old
+			 * initialised length and the write start. (AIA) */
 			attr->initialized = offset + l;
-			attr->size = offset + l;
 		}
 	}
 	if (attr->resident) {
@@ -720,22 +634,22 @@
 	vcn = 0;
 	clustersizebits = ino->vol->cluster_size_bits;
 	s_vcn = offset >> clustersizebits;
-	for (rnum = 0; rnum < attr->d.r.len && 
-		       vcn + attr->d.r.runlist[rnum].len <= s_vcn; rnum++) {
+	for (rnum = 0; rnum < attr->d.r.len &&
+			vcn + attr->d.r.runlist[rnum].len <= s_vcn; rnum++)
 		vcn += attr->d.r.runlist[rnum].len;
-	}
 	if (rnum == attr->d.r.len) {
-		ntfs_debug(DEBUG_FILE3, "ntfs_readwrite_attr: EOPNOTSUPP: "
-			"inode = 0x%x, rnum = %i, offset = 0x%Lx, vcn = , 0x%x"
-			"s_vcn = 0x%x\n", ino->i_number, rnum, offset, vcn,
+		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): EOPNOTSUPP: "
+			"inode = 0x%x, rnum = %i, offset = 0x%Lx, vcn = 0x%x, "
+			"s_vcn = 0x%x.\n", ino->i_number, rnum, offset, vcn,
 			s_vcn);
-		/*FIXME: Should extend run list. */
+		dump_runlist(attr->d.r.runlist, attr->d.r.len);
+		/*FIXME: Should extend runlist. */
 		return -EOPNOTSUPP;
 	}
 	copied = 0;
 	while (l) {
 		s_vcn = offset >> clustersizebits;
-		cluster = attr->d.r.runlist[rnum].cluster;
+		cluster = attr->d.r.runlist[rnum].lcn;
 		len = attr->d.r.runlist[rnum].len;
 		s_cluster = cluster + s_vcn - vcn;
 		chunk = ((__s64)(vcn + len) << clustersizebits) - offset;
@@ -745,7 +659,7 @@
 		error = ntfs_getput_clusters(ino->vol, s_cluster, offset -
 				((__s64)s_vcn << clustersizebits), dest);
 		if (error) {
-			ntfs_error("Read/write error\n");
+			ntfs_error("Read/write error.\n");
 			dest->size = copied;
 			return error;
 		}
@@ -755,7 +669,7 @@
 		if (l && offset >= ((__s64)(vcn + len) << clustersizebits)) {
 			rnum++;
 			vcn += len;
-			cluster = attr->d.r.runlist[rnum].cluster;
+			cluster = attr->d.r.runlist[rnum].lcn;
 			len = attr->d.r.runlist[rnum].len;
 		}
 	}
@@ -771,7 +685,7 @@
 	buf->do_read = 1;
 	attr = ntfs_find_attr(ino, type, name);
 	if (!attr) {
-		ntfs_debug(DEBUG_FILE3, "ntfs_read_attr: attr 0x%x not found "
+		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): attr 0x%x not found "
 				"in inode 0x%x\n", type, ino->i_number);
 		return -EINVAL;
 	}
@@ -785,8 +699,11 @@
 	
 	buf->do_read = 0;
 	attr = ntfs_find_attr(ino, type, name);
-	if (!attr)
+	if (!attr) {
+		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): attr 0x%x not found "
+				"in inode 0x%x\n", type, ino->i_number);
 		return -EINVAL;
+	}
 	return ntfs_readwrite_attr(ino, attr, offset, buf);
 }
 
@@ -803,9 +720,11 @@
 	if (data->size <= (__s64)vcn << ino->vol->cluster_size_bits)
 		return -1;
 	/*
-	 * For Linux, block number 0 represents a hole. Hopefully, nobody will
-	 * attempt to bmap $Boot. FIXME: Hopes are not good enough! We need to
-	 * fix this properly before reenabling mmap-ed stuff. (AIA)
+	 * For Linux, block number 0 represents a hole. - No problem as we do
+	 * not support bmap in any form whatsoever. The FIBMAP sys call is
+	 * deprecated anyway and NTFS is not a block based file system so
+	 * allowing bmapping is complete and utter garbage IMO. Use mmap once
+	 * we implement it... (AIA)
 	 */
 	if (data->initialized <= (__s64)vcn << ino->vol->cluster_size_bits)
 		return 0;
@@ -813,7 +732,7 @@
 				vcn >= data->d.r.runlist[rnum].len; rnum++)
 		vcn -= data->d.r.runlist[rnum].len;
 	/* We need to cope with sparse runs. (AIA) */
-	return data->d.r.runlist[rnum].cluster + vcn;
+	return data->d.r.runlist[rnum].lcn + vcn;
 }
 
 static int allocate_store(ntfs_volume *vol, ntfs_disk_inode *store, int count)
@@ -856,13 +775,13 @@
 }
 
 /**
- * layout_runs - compress run list into mapping pairs array
- * @attr:	attribute containing the run list to compress
+ * layout_runs - compress runlist into mapping pairs array
+ * @attr:	attribute containing the runlist to compress
  * @rec:	destination buffer to hold the mapping pairs array
  * @offs:	current position in @rec (in/out variable)
  * @size:	size of the buffer @rec
  *
- * layout_runs walks the run list in @attr, compresses it and writes it out the
+ * layout_runs walks the runlist in @attr, compresses it and writes it out the
  * resulting mapping pairs array into @rec (up to a maximum of @size bytes are
  * written). On entry @offs is the offset in @rec at which to begin writing the
  * mapping pairs array. On exit, it contains the offset in @rec of the first
@@ -878,16 +797,17 @@
 	offset = *offs;
 	for (i = 0; i < attr->d.r.len; i++) {
 		/*
-		 * We cheat with this check on the basis that cluster will never
-		 * be less than -1 and the cluster delta will fit in signed
+		 * We cheat with this check on the basis that lcn will never
+		 * be less than -1 and the lcn delta will fit in signed
 		 * 32-bits (ntfs_cluster_t). (AIA)
 		 */
-		if (rl[i].cluster < (ntfs_cluster_t)-1) {
+		if (rl[i].lcn < (ntfs_cluster_t)-1) {
 			ntfs_error("layout_runs() encountered an out of bounds "
-					"cluster delta!\n");
+					"cluster delta, lcn = %i.\n",
+					rl[i].lcn);
 			return -ERANGE;
 		}
-		rclus = rl[i].cluster - cluster;
+		rclus = rl[i].lcn - cluster;
 		len = rl[i].len;
 		rec[offset] = 0;
  		if (offset + 9 > size)
@@ -919,7 +839,7 @@
 		} /* else ... FIXME: When len becomes 64-bit we need to extend
 		   * 		     the else if () statements. (AIA) */
 		*(rec + offset) |= coffs++;
-		if (rl[i].cluster == (ntfs_cluster_t)-1) /* Compressed run. */
+		if (rl[i].lcn == (ntfs_cluster_t)-1) /* Compressed run. */
 			/* Nothing */;
 		else if (rclus >= -0x80 && rclus <= 0x7f) {
 			*(rec + offset) |= 0x10;
@@ -962,8 +882,8 @@
 			coffs += 8;
 		} */
 		offset += coffs;
-		if (rl[i].cluster)
-			cluster = rl[i].cluster;
+		if (rl[i].lcn)
+			cluster = rl[i].lcn;
 	}
 	if (offset >= size)
 		return -E2BIG;
@@ -992,12 +912,13 @@
  * @size:	size of the destination buffer
  * @psize:	size of converted on disk attribute record (out variable)
  *
- * layout_attr takes the attribute @attr and converts it into the appropriate
+ * layout_attr() takes the attribute @attr and converts it into the appropriate
  * on disk structure, writing it into @buf (up to @size bytes are written).
- * On return, @psize contains the actual size of the on disk attribute written
- * into @buf.
+ *
+ * On success we return 0 and set @*psize to the actual byte size of the on-
+ * disk attribute that was written into @buf.
  */
-static int layout_attr(ntfs_attribute* attr, char *buf, int size, int *psize)
+static int layout_attr(ntfs_attribute *attr, char *buf, int size, int *psize)
 {
 	int nameoff, hdrsize, asize;
 	
@@ -1015,7 +936,7 @@
 	} else {
 		int error;
 
- 		if (attr->flags & ATTR_IS_COMPRESSED)
+		if (attr->flags & ATTR_IS_COMPRESSED)
  			nameoff = 0x48;
  		else
  			nameoff = 0x40;
@@ -1057,7 +978,7 @@
 }
 
 /**
- * layout_inode - convert an in memory inode into on disk mft record(s)
+ * layout_inode - convert an in-memory inode into on disk mft record(s)
  * @ino:	in memory inode to convert
  * @store:	on disk inode, contain buffers for the on disk mft record(s)
  *
@@ -1066,8 +987,10 @@
  *
  * Return 0 on success,
  * the required mft record count (>0) if the inode does not fit,
- * -ENOMEM if memory allocation problem or
+ * -ENOMEM if memory allocation problem, or
  * -EOPNOTSUP if beyond our capabilities.
+ *
+ * TODO: We at the moment do not support extension mft records. (AIA)
  */
 int layout_inode(ntfs_inode *ino, ntfs_disk_inode *store)
 {
@@ -1097,16 +1020,16 @@
 	 	store->records[count].recno = recno;
  		rec = store->records[count].record;
 	 	count++;
- 		/* Copy header. */
-	 	offset = NTFS_GETU16(ino->attr + 0x14);
+ 		/* Copy mft record header. */
+	 	offset = NTFS_GETU16(ino->attr + 0x14); /* attrs_offset */
 		ntfs_memcpy(rec, ino->attr, offset);
 	 	/* Copy attributes. */
  		while (i < ino->attr_count) {
  			attr = ino->attrs + i;
 	 		error = layout_attr(attr, rec + offset,
-						size - offset - 8, &psize);
+					size - offset - 8, &psize);
 	 		if (error == -E2BIG && offset != NTFS_GETU16(ino->attr
-						+ 0x14))
+					+ 0x14))
  				break;
  			if (error)
  				return error;
@@ -1139,9 +1062,12 @@
 	ntfs_bzero(&store, sizeof(store));
 	error = layout_inode(ino, &store);
 	if (error == -E2BIG) {
-		error = ntfs_split_indexroot(ino);
-		if (!error)
-			error = layout_inode(ino, &store);
+		i = ntfs_split_indexroot(ino);
+		if (i != -ENOTDIR) {
+			if (!i)
+				i = layout_inode(ino, &store);
+			error = i;
+		}
 	}
 	if (error == -E2BIG) {
 		error = ntfs_attr_allnonresident(ino);
@@ -1154,7 +1080,7 @@
 	}
 	if (error) {
 		if (error == -E2BIG)
-			ntfs_error("cannot handle saving inode %x\n",
+			ntfs_error("Cannot handle saving inode 0x%x.\n",
 				   ino->i_number);
 		deallocate_store(&store);
 		return error;
@@ -1176,7 +1102,6 @@
 		}
 		io.param = store.records[i].record;
 		io.size = ino->vol->mft_record_size;
-		/* FIXME: Is this the right way? */
 		error = ntfs_write_attr(ino->vol->mft_ino, ino->vol->at_data,
 				0, (__s64)store.records[i].recno <<
 				ino->vol->mft_record_size_bits, &io);
@@ -1274,7 +1199,7 @@
  * NOTE: Neither of the ntfs_*_bit functions are atomic! But we don't need
  * them atomic at present as we never operate on shared/cached bitmaps.
  */
-static __inline__ int ntfs_get_bit(unsigned char *byte, const int bit)
+static __inline__ int ntfs_test_bit(unsigned char *byte, const int bit)
 {
 	return byte[bit >> 3] & (1 << (bit & 7)) ? 1 : 0;
 }
@@ -1289,129 +1214,813 @@
 	byte[bit >> 3] &= ~(1 << (bit & 7));
 }
 
-__inline__ int ntfs_test_and_set_bit(unsigned char *byte, const int bit)
+static __inline__ int ntfs_test_and_clear_bit(unsigned char *byte,
+		const int bit)
 {
 	unsigned char *ptr = byte + (bit >> 3);
 	int b = 1 << (bit & 7);
 	int oldbit = *ptr & b ? 1 : 0;
-	*ptr |= b;
+	*ptr &= ~b;
 	return oldbit;
 }
 
-static __inline__ int ntfs_test_and_clear_bit(unsigned char *byte,
-					      const int bit)
+static void dump_runlist(const ntfs_runlist *rl, const int rlen)
 {
-	unsigned char *ptr = byte + (bit >> 3);
-	int b = 1 << (bit & 7);
-	int oldbit = *ptr & b ? 1 : 0;
-	*ptr &= ~b;
-	return oldbit;
+#ifdef DEBUG
+	int i;
+	ntfs_cluster_t ct;
+
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): rlen = %i.\n", rlen);
+	ntfs_debug(DEBUG_OTHER, "VCN        LCN        Run length\n");
+	for (i = 0, ct = 0; i < rlen; ct += rl[i++].len) {
+		if (rl[i].lcn == (ntfs_cluster_t)-1)
+			ntfs_debug(DEBUG_OTHER, "0x%-8x LCN_HOLE   0x%-8x "
+					"(%s)\n", ct, rl[i].len, rl[i].len ?
+					"sparse run" : "run list end");
+		else
+			ntfs_debug(DEBUG_OTHER, "0x%-8x 0x%-8x 0x%-8x%s\n", ct,
+					rl[i].lcn, rl[i].len, rl[i].len &&
+					i + 1 < rlen ? "" : " (run list end)");
+		if (!rl[i].len)
+			break;
+	}
+#endif
+}
+
+/**
+ * splice_runlists - splice two run lists into one
+ * @rl1:	pointer to address of first run list
+ * @r1len:	number of elementfs in first run list
+ * @rl2:	pointer to second run list
+ * @r2len:	number of elements in second run list
+ *
+ * Append the run list @rl2 to the run list *@rl1 and return the result in
+ * *@rl1 and *@r1len.
+ *
+ * Return 0 on success or -errno on error, in which case *@rl1 and *@r1len are
+ * left untouched.
+ *
+ * The only possible error code at the moment is -ENOMEM and only happens if
+ * there is insufficient memory to allocate the new run list (only happens
+ * when size of (rl1 + rl2) > allocated size of rl1).
+ */
+int splice_runlists(ntfs_runlist **rl1, int *r1len, const ntfs_runlist *rl2,
+		int r2len)
+{
+	ntfs_runlist *rl;
+	int rlen, rl_size, rl2_pos;
+
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Entering with *r1len = %i, "
+			"r2len = %i.\n", *r1len, r2len);
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Dumping 1st runlist.\n");
+	if (*rl1)
+		dump_runlist(*rl1, *r1len);
+	else
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Not present.\n");
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Dumping 2nd runlist.\n");
+	dump_runlist(rl2, r2len);
+	rlen = *r1len + r2len + 1;
+	rl_size = (rlen * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &
+			PAGE_MASK;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): rlen = %i, rl_size = %i.\n",
+			rlen, rl_size);
+	/* Do we have enough space? */
+	if (rl_size <= ((*r1len * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &
+			PAGE_MASK)) {
+		/* Have enough space already. */
+		rl = *rl1;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Have enough space "
+				"already.\n");
+	} else {
+		/* Need more space. Reallocate. */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Need more space.\n");
+		rl = ntfs_vmalloc(rlen << sizeof(ntfs_runlist));
+		if (!rl)
+			return -ENOMEM;
+		/* Copy over rl1. */
+		ntfs_memcpy(rl, *rl1, *r1len * sizeof(ntfs_runlist));
+		ntfs_vfree(*rl1);
+		*rl1 = rl;
+	}
+	/* Reuse rl_size as the current position index into rl. */
+	rl_size = *r1len - 1;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): rl_size = %i.\n");
+	/* Coalesce neighbouring elements, if present. */
+	rl2_pos = 0;
+	if (rl[rl_size].lcn + rl[rl_size].len == rl2[rl2_pos].lcn) {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Coalescing adjacent "
+				"runs.\n");
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "
+				"rl[rl_size].len = %i.\n", rl[rl_size].len);
+		rl[rl_size].len += rl2[rl2_pos].len;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After: "
+				"rl[rl_size].len = %i.\n", rl[rl_size].len);
+		rl2_pos++;
+		r2len--;
+		rlen--;
+	}
+	rl_size++;
+	/* Copy over rl2. */
+	ntfs_memcpy(rl + rl_size, rl2 + rl2_pos, r2len * sizeof(ntfs_runlist));
+	rlen--;
+	rl[rlen].lcn = (ntfs_cluster_t)-1;
+	rl[rlen].len = (ntfs_cluster_t)0;
+	*r1len = rlen;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Dumping result runlist.\n");
+	dump_runlist(*rl1, *r1len);
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Returning with *r1len = "
+			"%i.\n", rlen);
+	return 0;
 }
 
 /**
- * ntfs_new_inode - allocate an mft record
+ * ntfs_alloc_mft_record - allocate an mft record
  * @vol:	volume to allocate an mft record on
  * @result:	the mft record number allocated
  *
- * Allocate a new mft record on disk by finding the first free mft record
- * and allocating it in the mft bitmap.
- * Return 0 on success or -ERRNO on error.
+ * Allocate a new mft record on disk. Return 0 on success or -ERRNO on error.
+ * On success, *@result contains the allocated mft record number. On error,
+ * *@result is -1UL.
  *
- * TODO(AIA): Implement mft bitmap caching.
+ * Note, this function doesn't actually set the mft record to be in use. This
+ * is done by the caller, which at the moment is only ntfs_alloc_inode().
+ *
+ * To find a free mft record, we scan the mft bitmap for a zero bit. To
+ * optimize this we start scanning at the place where we last stopped and we
+ * perform wrap around when we reach the end. Note, we do not try to allocate
+ * mft records below number 24 because numbers 0 to 15 are the defined system
+ * files anyway and 16 to 24 are special in that they are used for storing
+ * extension mft records for $MFT's $DATA attribute. This is required to avoid
+ * the possibility of creating a run list with a circular dependence which once
+ * written to disk can never be read in again. Windows will only use records
+ * 16 to 24 for normal files if the volume is completely out of space. We never
+ * use them which means that when the volume is really out of space we cannot
+ * create any more files while Windows can still create up to 8 small files. We
+ * can start doing this at some later time, doesn't matter much for now.
+ *
+ * When scanning the mft bitmap, we only search up to the last allocated mft
+ * record. If there are no free records left in the range 24 to number of
+ * allocated mft records, then we extend the mft data in order to create free
+ * mft records. We extend the allocated size of $MFT/$DATA by 16 records at a
+ * time or one cluster, if cluster size is above 16kiB. If there isn't
+ * sufficient space to do this, we try to extend by a single mft record or one
+ * cluster, if cluster size is above mft record size, but we only do this if
+ * there is enough free space, which we know from the values returned by the
+ * failed cluster allocation function when we tried to do the first allocation.
+ *
+ * No matter how many mft records we allocate, we initialize only the first
+ * allocated mft record (incrementing mft data size and initialized size) and
+ * return its number to the caller in @*result, unless there are less than 24
+ * mft records, in which case we allocate and initialize mft records until we
+ * reach record 24 which we consider as the first free mft record for use by
+ * normal files.
+ *
+ * If during any stage we overflow the initialized data in the mft bitmap, we
+ * extend the initialized size (and data size) by 8 bytes, allocating another
+ * cluster if required. The bitmap data size has to be at least equal to the
+ * number of mft records in the mft, but it can be bigger, in which case the
+ * superflous bits are padded with zeroes.
+ *
+ * Thus, when we return successfully (return value 0), we will have:
+ *	- initialized / extended the mft bitmap if necessary,
+ *	- initialized / extended the mft data if necessary,
+ *	- set the bit corresponding to the mft record being allocated in the
+ *	  mft bitmap, and we will
+ *	- return the mft record number in @*result.
+ *
+ * On error (return value below zero), nothing will have changed. If we had
+ * changed anything before the error occured, we will have reverted back to
+ * the starting state before returning to the caller. Thus, except for bugs,
+ * we should always leave the volume in a consitents state when returning from
+ * this function. NOTE: Small exception to this is that we set the bit in the
+ * mft bitmap but we do not mark the mft record in use, which is inconsistent.
+ * However, the caller will immediately add the wanted attributes to the mft
+ * record, set it in use and write it out to disk, so there should be no
+ * problem.
+ *
+ * Note, this function cannot make use of most of the normal functions, like
+ * for example for attribute resizing, etc, because when the run list overflows
+ * the base mft record and an attribute list is used, it is very important
+ * that the extension mft records used to store the $DATA attribute of $MFT
+ * can be reached without having to read the information contained inside
+ * them, as this would make it impossible to find them in the first place
+ * after the volume is dismounted. $MFT/$BITMAP probably doesn't need to
+ * follow this rule because the bitmap is not essential for finding the mft
+ * records, but on the other hand, handling the bitmap in this special way
+ * would make life easier because otherwise there might be circular invocations
+ * of functions when reading the bitmap but if we are careful, we should be
+ * able to avoid all problems.
+ *
+ * FIXME: Don't forget $MftMirr, though this probably belongs in
+ *	  ntfs_update_inode() (or even deeper). (AIA)
+ *
+ * FIXME: Want finer grained locking. (AIA)
  */
-static int ntfs_new_inode(ntfs_volume *vol, unsigned long *result)
+static int ntfs_alloc_mft_record(ntfs_volume *vol, unsigned long *result)
 {
-	int byte, bit, error, size, length;
-	unsigned char value;
-	ntfs_u8 *buffer;
+	unsigned long nr_mft_records, buf_size, buf_pos, pass_start, pass_end;
+	unsigned long last_read_pos, mft_rec_size, bit, l;
+	ntfs_attribute *data, *bmp;
+	__u8 *buf, *byte, pass, b, have_allocated_mftbmp = 0;
+	int rlen, rl_size = 0, r2len, rl2_size, old_data_rlen, err = 0;
+	ntfs_runlist *rl, *rl2;
+	ntfs_cluster_t lcn = 0, old_data_len;
 	ntfs_io io;
-	ntfs_attribute *data;
+	__s64 ll, old_data_allocated, old_data_initialized, old_data_size;
 
-	*result = 0;
-	/* Determine the number of mft records in the mft. */
-	data = ntfs_find_attr(vol->mft_ino, vol->at_data, 0);
-	if (!data)
-		return -EINVAL;
-	length = data->size >> vol->mft_record_size_bits;
-	/* Allocate sufficient space for the mft bitmap attribute value,
-	   inferring it from the number of mft records. */
-	buffer = ntfs_malloc((length + 7) >> 3);
-	if (!buffer)
+	*result = -1UL;
+	/* Allocate a buffer and setup the io structure. */
+	buf = (__u8*)__get_free_page(GFP_NOFS);
+	if (!buf)
 		return -ENOMEM;
+	lock_kernel();
+	/* Get the $DATA and $BITMAP attributes of $MFT. */
+	data = ntfs_find_attr(vol->mft_ino, vol->at_data, 0);
+	bmp = ntfs_find_attr(vol->mft_ino, vol->at_bitmap, 0);
+	if (!data || !bmp) {
+		err = -EINVAL;
+		goto err_ret;
+	}
+	/* Determine the number of allocated mft records in the mft. */
+	pass_end = nr_mft_records = data->allocated >>
+			vol->mft_record_size_bits;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): nr_mft_records = %lu.\n",
+			nr_mft_records);
+	/* Make sure we don't overflow the bitmap. */
+	l = bmp->initialized << 3;
+	if (l < nr_mft_records)
+		// FIXME: It might be a good idea to extend the bitmap instead.
+		pass_end = l;
+	pass = 1;
+	buf_pos = vol->mft_data_pos;
+	if (buf_pos >= pass_end) {
+		buf_pos = 24UL;
+		pass = 2;
+	}
+	pass_start = buf_pos;
+	rl = bmp->d.r.runlist;
+	rlen = bmp->d.r.len - 1;
+	lcn = rl[rlen].lcn + rl[rlen].len;
 	io.fn_put = ntfs_put;
 	io.fn_get = ntfs_get;
-try_again:
-	io.param = buffer;
-	io.size = (length + 7) >> 3;
-	error = ntfs_read_attr(vol->mft_ino, vol->at_bitmap, 0, 0, &io);
-	if (error)
-		goto err_out;
-	size = io.size;
-	/* Start at byte 0, as the bits for all 16 system files are already
-	   set in the bitmap. */
-	for (bit = byte = 0; (byte << 3) < length; byte++) {
-		value = buffer[byte];
-		if (value == 0xFF)
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Starting bitmap search.\n");
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): pass = %i, pass_start = %lu, "
+			"pass_end = %lu.\n", pass, pass_start, pass_end);
+	byte = NULL; // FIXME: For debugging only.
+	/* Loop until a free mft record is found. */
+	io.size = (nr_mft_records >> 3) & ~PAGE_MASK;
+	for (;; io.size = PAGE_SIZE) {
+		io.param = buf;
+		io.do_read = 1;
+		last_read_pos = buf_pos >> 3;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "
+				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+				"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+				bmp->size, bmp->initialized);
+		err = ntfs_readwrite_attr(vol->mft_ino, bmp, last_read_pos,
+				&io);
+		if (err)
+			goto err_ret;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Read %lu bytes.\n",
+				(unsigned long)io.size);
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After: "
+				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+				"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+				bmp->size, bmp->initialized);
+		if (!io.size)
+			goto pass_done;
+		buf_size = io.size << 3;
+		bit = buf_pos & 7UL;
+		buf_pos &= ~7UL;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before loop: "
+				"buf_size = %lu, buf_pos = %lu, bit = %lu, "
+				"*byte = 0x%x, b = %u.\n",
+				buf_size, buf_pos, bit, byte ? *byte : -1, b);
+		for (; bit < buf_size && bit + buf_pos < pass_end;
+				bit &= ~7UL, bit += 8UL) {
+			byte = buf + (bit >> 3);
+			if (*byte == 0xff)
+				continue;
+			b = ffz((unsigned long)*byte);
+			if (b < (__u8)8 && b >= (bit & 7UL)) {
+				bit = b + (bit & ~7UL) + buf_pos;
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Found free rec in for loop. "
+						"bit = %lu\n", bit);
+				goto found_free_rec;
+			}
+		}
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After loop: "
+				"buf_size = %lu, buf_pos = %lu, bit = %lu, "
+				"*byte = 0x%x, b = %u.\n",
+				buf_size, buf_pos, bit, byte ? *byte : -1, b);
+		buf_pos += buf_size;
+		if (buf_pos < pass_end)
 			continue;
-		bit = ffz(value);
-		if (bit < 8)
-			break;
-	}
-	if ((byte << 3) + bit >= length) {
-		/* No free space left. Need to extend the mft. */
-		error = -ENOSPC;
-		goto err_out;
-	}
-	/* Get the byte containing our bit again, now taking the BKL. */
-	io.param = buffer;
+pass_done:	/* Finished with the current pass. */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At pass_done.\n");
+		if (pass == 1) {
+			/*
+			 * Now do pass 2, scanning the first part of the zone
+			 * we omitted in pass 1.
+			 */
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Done pass "
+					"1.\n");
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Pass = 2.\n");
+			pass = 2;
+			pass_end = pass_start;
+			buf_pos = pass_start = 24UL;
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): pass = %i, "
+					"pass_start = %lu, pass_end = %lu.\n",
+					pass, pass_start, pass_end);
+			continue;
+		} /* pass == 2 */
+		/* No free records left. */
+		if (bmp->initialized << 3 > nr_mft_records &&
+				bmp->initialized > 3) {
+			/*
+			 * The mft bitmap is already bigger but the space is
+			 * not covered by mft records, this implies that the
+			 * next records are all free, so we already have found
+			 * a free record.
+			 */
+			bit = nr_mft_records;
+			if (bit < 24UL)
+				bit = 24UL;
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Found free "
+					"record bit (#1) = 0x%lx.\n", bit);
+			goto found_free_rec;
+		}
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Done pass 2.\n");
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "
+				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+				"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+				bmp->size, bmp->initialized);
+		/* Need to extend the mft bitmap. */
+		if (bmp->initialized + 8LL > bmp->allocated) {
+			ntfs_io io2;
+
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Initialized "
+					"> allocated.\n");
+			/* Need to extend bitmap by one more cluster. */
+			rl = bmp->d.r.runlist;
+			rlen = bmp->d.r.len - 1;
+			lcn = rl[rlen].lcn + rl[rlen].len;
+			io2.fn_put = ntfs_put;
+			io2.fn_get = ntfs_get;
+			io2.param = &b;
+			io2.size = 1;
+			io2.do_read = 1;
+			err = ntfs_readwrite_attr(vol->bitmap, data, lcn >> 3,
+					&io2);
+			if (err)
+				goto err_ret;
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Read %lu "
+					"bytes.\n", (unsigned long)io2.size);
+			if (io2.size == 1 && b != 0xff) {
+				__u8 tb = 1 << (lcn & (ntfs_cluster_t)7);
+				if (!(b & tb)) {
+					/* Next cluster is free. Allocate it. */
+					b |= tb;
+					io2.param = &b;
+					io2.do_read = 0;
+					err = ntfs_readwrite_attr(vol->bitmap,
+							data, lcn >> 3, &io2);
+					if (err || io.size != 1) {
+						if (!err)
+							err = -EIO;
+						goto err_ret;
+					}
+append_mftbmp_simple:			rl[rlen].len++;
+					have_allocated_mftbmp |= 1;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Appending one "
+							"cluster to mftbmp.\n");
+				}
+			}
+			if (!have_allocated_mftbmp) {
+				/* Allocate a cluster from the DATA_ZONE. */
+				ntfs_cluster_t lcn2 = lcn;
+				ntfs_cluster_t count = 1;
+				err = ntfs_allocate_clusters(vol, &lcn2,
+						&count, &rl2, &r2len,
+						DATA_ZONE);
+				if (err)
+					goto err_ret;
+				if (count != 1 || lcn2 <= 0) {
+					if (count > 0) {
+rl2_dealloc_err_out:				if (ntfs_deallocate_clusters(
+							vol, rl2, r2len))
+							ntfs_error(__FUNCTION__
+							"(): Cluster "
+							"deallocation in error "
+							"code path failed! You "
+							"should run chkdsk.\n");
+					}
+					ntfs_vfree(rl2);
+					if (!err)
+						err = -EINVAL;
+					goto err_ret;
+				}
+				if (lcn2 == lcn) {
+					ntfs_vfree(rl2);
+					goto append_mftbmp_simple;
+				}
+				/* We need to append a new run. */
+				rl_size = (rlen * sizeof(ntfs_runlist) +
+						PAGE_SIZE - 1) & PAGE_MASK;
+				/* Reallocate memory if necessary. */
+				if ((rlen + 2) * sizeof(ntfs_runlist) >=
+						rl_size) {
+					ntfs_runlist *rlt;
+
+					rl_size += PAGE_SIZE;
+					rlt = ntfs_vmalloc(rl_size);
+					if (!rlt) {
+						err = -ENOMEM;
+						goto rl2_dealloc_err_out;
+					}
+					ntfs_memcpy(rlt, rl, rl_size -
+							PAGE_SIZE);
+					ntfs_vfree(rl);
+					bmp->d.r.runlist = rl = rlt;
+				}
+				ntfs_vfree(rl2);
+				rl[rlen].lcn = lcn = lcn2;
+				rl[rlen].len = count;
+				bmp->d.r.len = ++rlen;
+				have_allocated_mftbmp |= 2;
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Adding run to mftbmp. "
+						"LCN = %i, len = %i\n", lcn,
+						count);
+			}
+			/*
+			 * We now have extended the mft bitmap allocated size
+			 * by one cluster. Reflect this in the attribute.
+			 */
+			bmp->allocated += (__s64)vol->cluster_size;
+		}
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After: "
+				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+				"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+				bmp->size, bmp->initialized);
+		/* We now have sufficient allocated space. */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Now have sufficient "
+				"allocated space in mftbmp.\n");
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "
+				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+				"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+				bmp->size, bmp->initialized);
+		buf_pos = bmp->initialized;
+		bmp->initialized += 8LL;
+		if (bmp->initialized > bmp->size)
+			bmp->size = bmp->initialized;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After: "
+				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+				"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+				bmp->size, bmp->initialized);
+		have_allocated_mftbmp |= 4;
+		/* Update the mft bitmap attribute value. */
+		memset(buf, 0, 8);
+		io.param = buf;
+		io.size = 8;
+		io.do_read = 0;
+		err = ntfs_readwrite_attr(vol->mft_ino, bmp, buf_pos, &io);
+		if (err || io.size != 8) {
+			if (!err)
+				err = -EIO;
+			goto shrink_mftbmp_err_ret;
+		}
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Wrote extended "
+				"mftbmp bytes %lu.\n", (unsigned long)io.size);
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After write: "
+				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+				"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+				bmp->size, bmp->initialized);
+		bit = buf_pos << 3;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Found free record "
+				"bit (#2) = 0x%lx.\n", bit);
+		goto found_free_rec;
+	}
+found_free_rec:
+	/* bit is the found free mft record. Allocate it in the mft bitmap. */
+	vol->mft_data_pos = bit;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At found_free_rec.\n");
+	io.param = buf;
 	io.size = 1;
-	lock_kernel();
-	error = ntfs_read_attr(vol->mft_ino, vol->at_bitmap, 0, byte, &io);
-	if (error || (io.size != 1 && (error = -EIO, 1)))
-		goto err_unl_out;
-	if (ntfs_test_and_set_bit(buffer, bit)) {
-		unlock_kernel();
-		/* Give other process(es) a chance to finish. */
-		schedule();
-		goto try_again;
+	io.do_read = 1;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before update: "
+			"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+			"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+			bmp->size, bmp->initialized);
+	err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
+	if (err || io.size != 1) {
+		if (!err)
+			err = -EIO;
+		goto shrink_mftbmp_err_ret;
 	}
-	io.param = buffer;
- 	error = ntfs_write_attr(vol->mft_ino, vol->at_bitmap, 0, byte, &io);
-	if (error || (io.size != 1 && (error = -EIO, 1)))
-		goto err_unl_out;
-	/* Change mft on disk, required when mft bitmap is resident. */
-	error = ntfs_update_inode(vol->mft_ino);
-	if (!error)
-		*result = (byte << 3) + bit;
-err_unl_out:
-	unlock_kernel();
-err_out:
-	ntfs_free(buffer);
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Read %lu bytes.\n",
+			(unsigned long)io.size);
 #ifdef DEBUG
-	if (error)
-		printk(KERN_INFO "ntfs_new_inode() failed to allocate an "
-				 "mft record. Error = %i\n", error);
-	else
-		printk(KERN_INFO "ntfs_new_inode() allocated mft record number "
-				 "0x%lx\n", *result);
+	/* Check our bit is really zero! */
+	if (*buf & (1 << (bit & 7)))
+		BUG();
 #endif
-	return error;
+	*buf |= 1 << (bit & 7);
+	io.param = buf;
+	io.do_read = 0;
+	err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
+	if (err || io.size != 1) {
+		if (!err)
+			err = -EIO;
+		goto shrink_mftbmp_err_ret;
+	}
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Wrote %lu bytes.\n",
+			(unsigned long)io.size);
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After update: "
+			"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "
+			"bmp->initialized = 0x%Lx.\n", bmp->allocated,
+			bmp->size, bmp->initialized);
+	/* The mft bitmap is now uptodate. Deal with mft data attribute now. */
+	ll = (__s64)(bit + 1) << vol->mft_record_size_bits;
+	if (ll <= data->initialized) {
+		/* The allocated record is already initialized. We are done! */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated mft record "
+				"already initialized!\n");
+		goto done_ret;
+	}
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated mft record needs "
+			"to be initialized.\n");
+	/* The mft record is outside the initialized data. */
+	mft_rec_size = (unsigned long)vol->mft_record_size;
+	/* Preserve old values for undo purposes. */
+	old_data_allocated = data->allocated;
+	old_data_rlen = data->d.r.len - 1;
+	old_data_len = data->d.r.runlist[old_data_rlen].len;
 	/*
-	 * FIXME: Don't forget $MftMirr, though this probably belongs
-	 * in ntfs_update_inode() (or even deeper). (AIA)
+	 * If necessary, extend the mft until it covers the allocated record.
+	 * The loop is only actually used when a freshly formatted volume is
+	 * first written to. But it optimizes away nicely in the common case.
 	 */
-}
-
-static int add_mft_header(ntfs_inode *ino)
-{
-	unsigned char *mft;
-	ntfs_volume *vol = ino->vol;
+	while (ll > data->allocated) {
+		ntfs_cluster_t lcn2, nr_lcn2, nr, min_nr;
 
-	mft = ino->attr;
-	ntfs_bzero(mft, vol->mft_record_size);
-	ntfs_fill_mft_header(mft, vol->mft_record_size, vol->sector_size,
-			     ino->sequence_number);
-	return 0;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Extending mft "
+				"data allocation, data->allocated = 0x%Lx, "
+				"data->size = 0x%Lx, data->initialized = "
+				"0x%Lx.\n", data->allocated, data->size,
+				data->initialized);
+		/* Minimum allocation is one mft record worth of clusters. */
+		if (mft_rec_size <= vol->cluster_size)
+			min_nr = (ntfs_cluster_t)1;
+		else
+			min_nr = mft_rec_size >> vol->cluster_size_bits;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): min_nr = %i.\n",
+				min_nr);
+		/* Allocate 16 mft records worth of clusters. */
+		nr = mft_rec_size << 4 >> vol->cluster_size_bits;
+		if (!nr)
+			nr = (ntfs_cluster_t)1;
+		/* Determine the preferred allocation location. */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): nr = %i.\n", nr);
+		rl2 = data->d.r.runlist;
+		r2len = data->d.r.len;
+		lcn2 = rl2[r2len - 1].lcn + rl2[r2len - 1].len;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): rl2[r2len - 1].lcn "
+				"= %i, .len = %i.\n", rl2[r2len - 1].lcn,
+				rl2[r2len - 1].len);
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): lcn2 = %i, r2len = "
+				"%i.\n", lcn2, r2len);
+retry_mft_data_allocation:
+		nr_lcn2 = nr;
+		err = ntfs_allocate_clusters(vol, &lcn2, &nr_lcn2, &rl2,
+				&r2len, MFT_ZONE);
+#ifdef DEBUG
+		if (!err && nr_lcn2 < min_nr)
+			/* Allocated less than minimum needed. Weird! */
+			BUG();
+#endif
+		if (err) {
+			/*
+			 * If there isn't enough space to do the wanted
+			 * allocation, but there is enough space to do a
+			 * minimal allocation, then try that, unless the wanted
+			 * allocation was already the minimal allocation.
+			 */
+			if (err == -ENOSPC && nr > min_nr &&
+					nr_lcn2 >= min_nr) {
+				nr = min_nr;
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Retrying mft data "
+						"allocation, nr = min_nr = %i"
+						".\n", nr);
+				goto retry_mft_data_allocation;
+			}
+			goto undo_mftbmp_alloc_err_ret;
+		}
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated %i "
+				"clusters starting at LCN %i.\n", nr_lcn2,
+				lcn2);
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated "
+				"runlist:\n");
+		dump_runlist(rl2, r2len);
+		/* Append rl2 to the mft data attribute's run list. */
+		err = splice_runlists(&data->d.r.runlist, (int*)&data->d.r.len,
+				rl2, r2len);
+		if (err) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+					"splice_runlists failed with error "
+					"code %i.\n", -err);
+			goto undo_partial_data_alloc_err_ret;
+		}
+		/* Reflect the allocated clusters in the mft allocated data. */
+		data->allocated += nr_lcn2 << vol->cluster_size_bits;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After extending mft "
+				"data allocation, data->allocated = 0x%Lx, "
+				"data->size = 0x%Lx, data->initialized = "
+				"0x%Lx.\n", data->allocated, data->size,
+				data->initialized);
+	}
+	/* Prepare a formatted (empty) mft record. */
+	memset(buf, 0, mft_rec_size);
+	ntfs_fill_mft_header(buf, mft_rec_size, 0, 0, 0);
+	err = ntfs_insert_fixups(buf, mft_rec_size);
+	if (err)
+		goto undo_data_alloc_err_ret;
+	/*
+	 * Extend mft data initialized size to reach the allocated mft record
+	 * and write the formatted mft record buffer to each mft record being
+	 * initialized. Note, that ntfs_readwrite_attr extends both
+	 * data->initialized and data->size, so no need for us to touch them.
+	 */
+	old_data_initialized = data->initialized;
+	old_data_size = data->size;
+	while (ll > data->initialized) {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Initializing mft "
+				"record 0x%Lx.\n",
+				data->initialized >> vol->mft_record_size_bits);
+		io.param = buf;
+		io.size = mft_rec_size;
+		io.do_read = 0;
+		err = ntfs_readwrite_attr(vol->mft_ino, data,
+				data->initialized, &io);
+		if (err || io.size != mft_rec_size) {
+			if (!err)
+				err = -EIO;
+			goto undo_data_init_err_ret;
+		}
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Wrote %i bytes to "
+				"mft data.\n", io.size);
+	}
+	/* Update the VFS inode size as well. */
+	VFS_I(vol->mft_ino)->i_size = data->size;
+#ifdef DEBUG
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After mft record "
+			"initialization: data->allocated = 0x%Lx, data->size "
+			"= 0x%Lx, data->initialized = 0x%Lx.\n",
+			data->allocated, data->size, data->initialized);
+	/* Sanity checks. */
+	if (data->size > data->allocated || data->size < data->initialized ||
+			data->initialized > data->allocated)
+		BUG();
+#endif
+done_ret:
+	/* Return the number of the allocated mft record. */
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At done_ret. *result = bit = "
+			"0x%lx.\n", bit);
+	*result = bit;
+	vol->mft_data_pos = bit + 1;
+err_ret:
+	unlock_kernel();
+	free_page((unsigned long)buf);
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Syncing inode $MFT.\n");
+	if (ntfs_update_inode(vol->mft_ino))
+		ntfs_error(__FUNCTION__ "(): Failed to sync inode $MFT. "
+				"Continuing anyway.\n");
+	if (!err) {
+		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): Done. Allocated mft "
+				"record number *result = 0x%lx.\n", *result);
+		return 0;
+	}
+	if (err != -ENOSPC)
+		ntfs_error(__FUNCTION__ "(): Failed to allocate an mft "
+				"record. Returning error code %i.\n", -err);
+	else
+		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): Failed to allocate "
+				"an mft record due to lack of free space.\n");
+	return err;
+undo_data_init_err_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At "
+			"undo_data_init_err_ret.\n");
+	data->initialized = old_data_initialized;
+	data->size = old_data_size;
+undo_data_alloc_err_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At undo_data_alloc_err_ret."
+			"\n");
+	data->allocated = old_data_allocated;
+undo_partial_data_alloc_err_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At "
+			"undo_partial_data_alloc_err_ret.\n");
+	/* Deallocate the clusters. */
+	if (ntfs_deallocate_clusters(vol, rl2, r2len))
+		ntfs_error(__FUNCTION__ "(): Error deallocating clusters in "
+				"error code path. You should run chkdsk.\n");
+	ntfs_vfree(rl2);
+	/* Revert the run list back to what it was before. */
+	r2len = data->d.r.len;
+	rl2 = data->d.r.runlist;
+	rl2[old_data_rlen++].len = old_data_len;
+	rl2[old_data_rlen].lcn = (ntfs_cluster_t)-1;
+	rl2[old_data_rlen].len = (ntfs_cluster_t)0;
+	data->d.r.len = old_data_rlen;
+	rl2_size = ((old_data_rlen + 1) * sizeof(ntfs_runlist) + PAGE_SIZE -
+			1) & PAGE_MASK;
+	/* Reallocate memory freeing any extra memory allocated. */
+	if (rl2_size < ((r2len * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &
+			PAGE_MASK)) {
+		rl2 = ntfs_vmalloc(rl2_size);
+		if (rl2) {
+			ntfs_memcpy(rl2, data->d.r.runlist, rl2_size);
+			ntfs_vfree(data->d.r.runlist);
+			data->d.r.runlist = rl2;
+		} else
+			ntfs_error(__FUNCTION__ "(): Error reallocating "
+					"memory in error code path. This "
+					"should be harmless.\n");
+	}	
+undo_mftbmp_alloc_err_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At "
+			"undo_mftbmp_alloc_err_ret.\n");
+	/* Deallocate the allocated bit in the mft bitmap. */
+	io.param = buf;
+	io.size = 1;
+	io.do_read = 1;
+	err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
+	if (!err && io.size == 1) {
+		*buf &= ~(1 << (bit & 7));
+		io.param = buf;
+		io.do_read = 0;
+		err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);
+	}
+	if (err || io.size != 1) {
+		if (!err)
+			err = -EIO;
+		ntfs_error(__FUNCTION__ "(): Error deallocating mft record in "
+				"error code path. You should run chkdsk.\n");
+	}
+shrink_mftbmp_err_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At shrink_mftbmp_err_ret.\n");
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): have_allocated_mftbmp = "
+			"%i.\n", have_allocated_mftbmp);
+	if (!have_allocated_mftbmp)
+		goto err_ret;
+	/* Shrink the mftbmp back to previous size. */
+	if (bmp->size == bmp->initialized)
+		bmp->size -= 8LL;
+	bmp->initialized -= 8LL;
+	have_allocated_mftbmp &= ~4;
+	/* If no allocation occured then we are done. */
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): have_allocated_mftbmp = "
+			"%i.\n", have_allocated_mftbmp);
+	if (!have_allocated_mftbmp)
+		goto err_ret;
+	/* Deallocate the allocated cluster. */
+	bmp->allocated -= (__s64)vol->cluster_size;
+	if (ntfs_deallocate_cluster_run(vol, lcn, (ntfs_cluster_t)1))
+		ntfs_error(__FUNCTION__ "(): Error deallocating cluster in "
+				"error code path. You should run chkdsk.\n");
+	switch (have_allocated_mftbmp & 3) {
+	case 1:
+		/* Delete the last lcn from the last run of mftbmp. */
+		rl[rlen - 1].len--;
+		break;
+	case 2:
+		/* Delete the last run of mftbmp. */
+		bmp->d.r.len = --rlen;
+		/* Reallocate memory if necessary. */
+		if ((rlen + 1) * sizeof(ntfs_runlist) <= rl_size - PAGE_SIZE) {
+			ntfs_runlist *rlt;
+
+			rl_size -= PAGE_SIZE;
+			rlt = ntfs_vmalloc(rl_size);
+			if (rlt) {
+				ntfs_memcpy(rlt, rl, rl_size);
+				ntfs_vfree(rl);
+				bmp->d.r.runlist = rl = rlt;
+			} else
+				ntfs_error(__FUNCTION__ "(): Error "
+						"reallocating memory in error "
+						"code path. This should be "
+						"harmless.\n");
+		}
+		bmp->d.r.runlist[bmp->d.r.len].lcn = (ntfs_cluster_t)-1;
+		bmp->d.r.runlist[bmp->d.r.len].len = (ntfs_cluster_t)0;
+		break;
+	default:
+		BUG();
+	}
+	goto err_ret;
 }
 
 /* We need 0x48 bytes in total. */
@@ -1420,7 +2029,6 @@
 	ntfs_time64_t now;
 	char data[0x30];
 	char *position = data;
-	int error;
 	ntfs_attribute *si;
 
 	now = ntfs_now();
@@ -1430,14 +2038,12 @@
 	NTFS_PUTU64(position + 0x18, now);		/* Last access */
 	NTFS_PUTU64(position + 0x20, 0);		/* MSDOS file perms */
 	NTFS_PUTU64(position + 0x28, 0);		/* unknown */
-	error = ntfs_create_attr(ino, ino->vol->at_standard_information, 0,
-				 data, sizeof(data), &si);
-	return error;
+	return ntfs_create_attr(ino, ino->vol->at_standard_information, 0,
+			data, sizeof(data), &si);
 }
 
-static int add_filename(ntfs_inode* ino, ntfs_inode* dir, 
-			const unsigned char *filename, int length, 
-			ntfs_u32 flags)
+static int add_filename(ntfs_inode *ino, ntfs_inode *dir, 
+		const unsigned char *filename, int length, ntfs_u32 flags)
 {
 	unsigned char *position;
 	unsigned int size;
@@ -1511,7 +2117,7 @@
 	io.size = size;
 	error = ntfs_read_attr(dir, ino->vol->at_security_descriptor, 0, 0,&io);
 	if (!error && io.size != size)
-		ntfs_error("wrong size in add_security");
+		ntfs_error("wrong size in add_security\n");
 	if (error) {
 		ntfs_free(buf);
 		return error;
@@ -1525,84 +2131,85 @@
 
 static int add_data(ntfs_inode* ino, unsigned char *data, int length)
 {
-	int error;
 	ntfs_attribute *da;
 	
-	error = ntfs_create_attr(ino, ino->vol->at_data, 0, data, length, &da);
-	return error;
+	return ntfs_create_attr(ino, ino->vol->at_data, 0, data, length, &da);
 }
 
-/* We _could_ use 'dir' to help optimise inode allocation. */
+/*
+ * We _could_ use 'dir' to help optimise inode allocation.
+ *
+ * FIXME: Need to undo what we do in ntfs_alloc_mft_record if we get an error
+ * further on in ntfs_alloc_inode. Either fold the two functions to allow
+ * proper undo or just deallocate the record from the mft bitmap. (AIA)
+ */
 int ntfs_alloc_inode(ntfs_inode *dir, ntfs_inode *result, const char *filename,
-		     int namelen, ntfs_u32 flags)
+		int namelen, ntfs_u32 flags)
 {
-	int error;
 	ntfs_volume *vol = dir->vol;
+	int err;
 	ntfs_u8 buffer[2];
 	ntfs_io io;
 
-	error = ntfs_new_inode(vol, &(result->i_number));
-	if (error == -ENOSPC) {
-		error = ntfs_extend_mft(vol);
-		if (error)
-			return error;
-		error = ntfs_new_inode(vol, &(result->i_number));
-	}
-	if (error) {
-		if (error == -ENOSPC)
-			ntfs_error("ntfs_get_empty_inode: no free inodes\n");
-		return error;
+	err = ntfs_alloc_mft_record(vol, &(result->i_number));
+	if (err) {
+		if (err == -ENOSPC)
+			ntfs_error(__FUNCTION__ "(): No free inodes.\n");
+		return err;
 	}
 	/* Get the sequence number. */
 	io.fn_put = ntfs_put;
 	io.fn_get = ntfs_get;
 	io.param = buffer;
 	io.size = 2;
-	error = ntfs_read_attr(vol->mft_ino, vol->at_data, 0, 
+	err = ntfs_read_attr(vol->mft_ino, vol->at_data, 0, 
 			((__s64)result->i_number << vol->mft_record_size_bits)
 			+ 0x10, &io);
-	if (error)
-		return error;
+	// FIXME: We are leaving the MFT in inconsistent state! (AIA)
+	if (err)
+		return err;
 	/* Increment the sequence number skipping zero. */
 	result->sequence_number = (NTFS_GETU16(buffer) + 1) & 0xffff;
 	if (!result->sequence_number)
 		result->sequence_number++;
 	result->vol = vol;
-	result->attr = ntfs_malloc(vol->mft_record_size);
-	if (!result->attr)
-		return -ENOMEM;
 	result->attr_count = 0;
 	result->attrs = 0;
 	result->record_count = 1;
-	result->records = ntfs_malloc(8 * sizeof(int));
-	if (!result->records) {
-		ntfs_free(result->attr);
-		result->attr = 0;
-		return -ENOMEM;
-	}
+	result->records = ntfs_calloc(8 * sizeof(int));
+	if (!result->records)
+		goto mem_err_out;
 	result->records[0] = result->i_number;
-	error = add_mft_header(result);
-	if (error)
-		return error;
-	error = add_standard_information(result);
-	if (error)
-		return error;
-	error = add_filename(result, dir, filename, namelen, flags);
-	if (error)
-		return error;
-	error = add_security(result, dir);
-	if (error)
-		return error;
-	return 0;
+	result->attr = ntfs_calloc(vol->mft_record_size);
+	if (!result->attr) {
+		ntfs_free(result->records);
+		result->records = NULL;
+		goto mem_err_out;
+	}
+	ntfs_fill_mft_header(result->attr, vol->mft_record_size,
+			result->sequence_number, 1, 1);
+	err = add_standard_information(result);
+	if (!err)
+		err = add_filename(result, dir, filename, namelen, flags);
+	if (!err)
+		err = add_security(result, dir);
+	// FIXME: We are leaving the MFT in inconsistent state on error! (AIA)
+	return err;
+mem_err_out:
+	// FIXME: We are leaving the MFT in inconsistent state! (AIA)
+	result->record_count = 0;
+	result->attr = NULL;
+	return -ENOMEM;
 }
 
 int ntfs_alloc_file(ntfs_inode *dir, ntfs_inode *result, char *filename,
-		    int namelen)
+		int namelen)
 {
-	int error = ntfs_alloc_inode(dir, result, filename, namelen, 0);
-	if (error)
-		return error;
-	error = add_data(result, 0, 0);
-	return error;
+	int err;
+
+	err = ntfs_alloc_inode(dir, result, filename, namelen, 0);
+	if (!err)
+		err = add_data(result, 0, 0);
+	return err;
 }
 
diff -urN linux-2.4.10-pre5/fs/ntfs/inode.h linux/fs/ntfs/inode.h
--- linux-2.4.10-pre5/fs/ntfs/inode.h	Mon Jul 16 15:14:10 2001
+++ linux/fs/ntfs/inode.h	Mon Dec  3 23:08:13 2001
@@ -40,9 +40,19 @@
 
 void ntfs_decompress(unsigned char *dest, unsigned char *src, ntfs_size_t l);
 
-void ntfs_fill_mft_header(ntfs_u8 *mft, int recordsize, int blocksize,
-		int sequence_number);
+int splice_runlists(ntfs_runlist **rl1, int *r1len, const ntfs_runlist *rl2,
+		int r2len);
 
-extern __inline__ int ntfs_test_and_set_bit(unsigned char *byte,
-		const int bit);
+/*
+ * NOTE: Neither of the ntfs_*_bit functions are atomic! But we don't need
+ * them atomic at present as we never operate on shared/cached bitmaps.
+ */
+static __inline__ int ntfs_test_and_set_bit(unsigned char *byte, const int bit)
+{
+	unsigned char *ptr = byte + (bit >> 3);
+	int b = 1 << (bit & 7);
+	int oldbit = *ptr & b ? 1 : 0;
+	*ptr |= b;
+	return oldbit;
+}
 
diff -urN linux-2.4.10-pre5/fs/ntfs/macros.h linux/fs/ntfs/macros.h
--- linux-2.4.10-pre5/fs/ntfs/macros.h	Wed Aug 15 01:22:17 2001
+++ linux/fs/ntfs/macros.h	Mon Dec  3 23:08:13 2001
@@ -1,15 +1,31 @@
-/*  macros.h
+/*
+ * macros.h
  *
- *  Copyright (C) 1995 Martin von Löwis
- *  Copyright (C) 1996 Régis Duchesne
+ * Copyright (C) 1995 Martin von Löwis
+ * Copyright (C) 1996 Régis Duchesne
+ * Copyright (c) 2001 Anton Altaparmakov
  */
+#include <linux/ntfs_fs_i.h>
+#include <linux/fs.h>
+#include <asm/page.h>
 
 #define NTFS_FD(vol)		((vol)->u.fd)
 
 #define NTFS_SB(vol)		((struct super_block*)(vol)->sb)
 #define NTFS_SB2VOL(sb)         (&(sb)->u.ntfs_sb)
 #define NTFS_INO2VOL(ino)	(&((ino)->i_sb->u.ntfs_sb))
-#define NTFS_LINO2NINO(ino)     (&((ino)->u.ntfs_i))
+#define NTFS_LINO2NINO(ino)     ((struct ntfs_inode_info*)(&((ino)->u.ntfs_i)))
+static inline struct inode *VFS_I(struct ntfs_inode_info *ntfs_ino)
+{
+	struct inode *i = (struct inode*)((char*)ntfs_ino -
+			((char*)&(((struct inode*)NULL)->u.ntfs_i) -
+			(char*)NULL));
+#ifdef DEBUG
+	if ((char*)NTFS_LINO2NINO(i) != (char*)ntfs_ino)
+		BUG();
+#endif
+	return i;
+}
 
 #define IS_MAGIC(a,b)		(*(int*)(a) == *(int*)(b))
 #define IS_MFT_RECORD(a)	IS_MAGIC((a),"FILE")
diff -urN linux-2.4.10-pre5/fs/ntfs/struct.h linux/fs/ntfs/struct.h
--- linux-2.4.10-pre5/fs/ntfs/struct.h	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/struct.h	Mon Dec  3 23:08:13 2001
@@ -10,20 +10,20 @@
 struct ntfs_inode;
 
 /* Which files should be returned from a director listing. */
-#define ngt_dos   1	/* only short names, no hidden files */
+#define ngt_dos   1	/* only short names, no system files */
 #define ngt_nt    2	/* only long names, all-uppercase becomes 
-			 * all-lowercase, no hidden files */
-#define ngt_posix 3	/* all names except hidden files */
+			 * all-lowercase, no system files */
+#define ngt_posix 3	/* all names except system files */
 #define ngt_full  4	/* all entries */
 
 typedef struct ntfs_sb_info ntfs_volume;
 
 typedef struct {
-	ntfs_cluster_t cluster;
+	ntfs_cluster_t lcn;
 	ntfs_cluster_t len;
 } ntfs_runlist;
 
-typedef struct ntfs_attribute{
+typedef struct ntfs_attribute {
 	int type;
 	ntfs_u16 *name;
 	int namelen;
diff -urN linux-2.4.10-pre5/fs/ntfs/super.c linux/fs/ntfs/super.c
--- linux-2.4.10-pre5/fs/ntfs/super.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/super.c	Mon Dec  3 23:08:13 2001
@@ -30,7 +30,7 @@
  *   NTFS_SECTOR_SIZE and not as the hardware sector size (this is concordant
  *   with what the Windows NTFS driver does).
  *
- * This function perform these 2 checks, and _fails_ if:
+ * This function performs these 2 checks, and _fails_ if:
  * . the input size is invalid
  * . the fixup header is invalid
  * . the size does not match the number of sectors
@@ -75,6 +75,7 @@
 {
 	int sectors_per_cluster_bits;
 	__s64 ll;
+	ntfs_cluster_t mft_zone_size, tc;
 
 	/* System defined default values, in case we don't load $AttrDef. */
 	vol->at_standard_information = 0x10;
@@ -157,31 +158,69 @@
 	vol->nr_clusters = (ntfs_cluster_t)ll;
 	ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->nr_clusters = 0x%x\n",
 			vol->nr_clusters);
-	/*
-	 * Determine MFT zone size. FIXME: Need to take into consideration
-	 * where the mft zone starts (at vol->mft_lcn) as vol->mft_zone_end
-	 * needs to be relative to that.
-	 */
-	vol->mft_zone_end = vol->nr_clusters;
+	vol->mft_lcn = (ntfs_cluster_t)NTFS_GETS64(boot + 0x30);
+	vol->mft_mirr_lcn = (ntfs_cluster_t)NTFS_GETS64(boot + 0x38);
+	/* Determine MFT zone size. */
+	mft_zone_size = vol->nr_clusters;
 	switch (vol->mft_zone_multiplier) {  /* % of volume size in clusters */
 	case 4:
-		vol->mft_zone_end = vol->mft_zone_end >> 1;	/* 50%   */
+		mft_zone_size >>= 1;			/* 50%   */
 		break;
 	case 3:
-		vol->mft_zone_end = vol->mft_zone_end * 3 >> 3;	/* 37.5% */
+		mft_zone_size = mft_zone_size * 3 >> 3;	/* 37.5% */
 		break;
 	case 2:
-		vol->mft_zone_end = vol->mft_zone_end >> 2;	/* 25%   */
+		mft_zone_size >>= 2;			/* 25%   */
 		break;
 	/* case 1: */
 	default:
-		vol->mft_zone_end = vol->mft_zone_end >> 3;	/* 12.5% */
+		mft_zone_size >>= 3;			/* 12.5% */
 		break;
 	}
+	/* Setup mft zone. */
+	vol->mft_zone_start = vol->mft_zone_pos = vol->mft_lcn;
+	ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->mft_zone_pos = %x\n",
+			vol->mft_zone_pos);
+	/*
+	 * Calculate the mft_lcn for an unmodified NTFS volume (see mkntfs
+	 * source) and if the actual mft_lcn is in the expected place or even
+	 * further to the front of the volume, extend the mft_zone to cover the
+	 * beginning of the volume as well. This is in order to protect the
+	 * area reserved for the mft bitmap as well within the mft_zone itself.
+	 * On non-standard volumes we don't protect it as well as the overhead
+	 * would be higher than the speed increase we would get by doing it.
+	 */
+	tc = (8192 + 2 * vol->cluster_size - 1) / vol->cluster_size;
+	if (tc * vol->cluster_size < 16 * 1024)
+		tc = (16 * 1024 + vol->cluster_size - 1) / vol->cluster_size;
+	if (vol->mft_zone_start <= tc)
+		vol->mft_zone_start = (ntfs_cluster_t)0;
+	ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->mft_zone_start = %x\n",
+			vol->mft_zone_start);
+	/*
+	 * Need to cap the mft zone on non-standard volumes so that it does
+	 * not point outside the boundaries of the volume, we do this by
+	 * halving the zone size until we are inside the volume.
+	 */
+	vol->mft_zone_end = vol->mft_lcn + mft_zone_size;
+	while (vol->mft_zone_end >= vol->nr_clusters) {
+		mft_zone_size >>= 1;
+		vol->mft_zone_end = vol->mft_lcn + mft_zone_size;
+	}
 	ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->mft_zone_end = %x\n",
 			vol->mft_zone_end);
-	vol->mft_lcn = (ntfs_cluster_t)NTFS_GETS64(boot + 0x30);
-	vol->mft_mirr_lcn = (ntfs_cluster_t)NTFS_GETS64(boot + 0x38);
+	/*
+	 * Set the current position within each data zone to the start of the
+	 * respective zone.
+	 */
+	vol->data1_zone_pos = vol->mft_zone_end;
+	ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->data1_zone_pos = %x\n",
+			vol->data1_zone_pos);
+	vol->data2_zone_pos = (ntfs_cluster_t)0;
+	ntfs_debug(DEBUG_FILE3, "ntfs_init_volume: vol->data2_zone_pos = %x\n",
+			vol->data2_zone_pos);
+	/* Set the mft data allocation position to mft record 24. */
+	vol->mft_data_pos = 24UL;
 	/* This will be initialized later. */
 	vol->upcase = 0;
 	vol->upcase_length = 0;
@@ -343,28 +382,28 @@
 	error = -ENOMEM;
 	ntfs_debug(DEBUG_BSD, "Going to load MFT\n");
 	if (!vol->mft_ino || (error = ntfs_init_inode(vol->mft_ino, vol,
-			FILE_$Mft))) {
+			FILE_Mft))) {
 		ntfs_error("Problem loading MFT\n");
 		return error;
 	}
 	ntfs_debug(DEBUG_BSD, "Going to load MIRR\n");
-	if ((error = ntfs_init_inode(vol->mftmirr, vol, FILE_$MftMirr))) {
+	if ((error = ntfs_init_inode(vol->mftmirr, vol, FILE_MftMirr))) {
 		ntfs_error("Problem %d loading MFTMirr\n", error);
 		return error;
 	}
 	ntfs_debug(DEBUG_BSD, "Going to load BITMAP\n");
-	if ((error = ntfs_init_inode(vol->bitmap, vol, FILE_$BitMap))) {
+	if ((error = ntfs_init_inode(vol->bitmap, vol, FILE_BitMap))) {
 		ntfs_error("Problem loading Bitmap\n");
 		return error;
 	}
 	ntfs_debug(DEBUG_BSD, "Going to load UPCASE\n");
-	error = ntfs_init_inode(&upcase, vol, FILE_$UpCase);
+	error = ntfs_init_inode(&upcase, vol, FILE_UpCase);
 	if (error)
 		return error;
 	ntfs_init_upcase(&upcase);
 	ntfs_clear_inode(&upcase);
 	ntfs_debug(DEBUG_BSD, "Going to load ATTRDEF\n");
-	error = ntfs_init_inode(&attrdef, vol, FILE_$AttrDef);
+	error = ntfs_init_inode(&attrdef, vol, FILE_AttrDef);
 	if (error)
 		return error;
 	error = ntfs_init_attrdef(&attrdef);
@@ -375,7 +414,7 @@
 	/* Check for NTFS version and if Win2k version (ie. 3.0+) do not allow
 	 * write access since the driver write support is broken. */
 	ntfs_debug(DEBUG_BSD, "Going to load VOLUME\n");
-	error = ntfs_init_inode(&volume, vol, FILE_$Volume);
+	error = ntfs_init_inode(&volume, vol, FILE_Volume);
 	if (error)
 		return error;
 	if ((error = ntfs_get_version(&volume)) >= 0x0300 &&
@@ -387,8 +426,8 @@
 	ntfs_clear_inode(&volume);
 	if (error < 0)
 		return error;
-	ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8,
-								error & 0xff);
+	ntfs_debug(DEBUG_BSD, "NTFS volume is v%d.%d\n", error >> 8,
+			error & 0xff);
 	return 0;
 }
 
@@ -525,234 +564,850 @@
 	return 0;
 }
 
-/* Search the bitmap bits of l bytes for *cnt zero bits. Return the bit number
- * in *loc, which is initially set to the number of the first bit. Return the
- * largest block found in *cnt. Return 0 on success, -ENOSPC if all bits are
- * used. */
-static int search_bits(unsigned char* bits, ntfs_cluster_t *loc, int *cnt,int l)
-{
-	unsigned char c = 0;
-	int bc = 0;
-	int bstart = 0, bstop = 0, found = 0;
-	int start, stop = 0, in = 0;
-	/* Special case searching for a single block. */
-	if (*cnt == 1) {
-		while (l && *bits == 0xFF) {
-			bits++;
-			*loc += 8;
-			l--;
-		}
-		if (!l)
-			return -ENOSPC;
-		for (c = *bits; c & 1; c >>= 1)
-			(*loc)++;
-		return 0;
+/**
+ * ntfs_allocate_clusters - allocate logical clusters on an ntfs volume
+ * @vol:	volume on which to allocate clusters
+ * @location:	preferred location for first allocated cluster
+ * @count:	number of clusters to allocate
+ * @rl:		address of pointer in which to return the allocated run list
+ * @rl_len:	the number of elements returned in @*rl
+ *
+ * Allocate @*count clusters (LCNs), preferably beginning at @*location in the
+ * bitmap of the volume @vol. If @*location is -1, it does not matter where the
+ * clusters are. @rl is the address of a ntfs_runlist pointer which this
+ * function will allocate and fill with the runlist of the allocated clusters.
+ * It is the callers responsibility to ntfs_vfree() @*rl after she is finished
+ * with it. If the function was not successful, @*rl will be set to NULL.
+ * @*rl_len will contain the number of ntfs_runlist elements in @*rl or 0 if
+ * @*rl is NULL.
+ *
+ * Return 0 on success, or -errno on error. On success, @*location and @*count
+ * say what was really allocated. On -ENOSPC, @*location and @*count say what
+ * could have been allocated. If nothing could be allocated or a different
+ * error occured, @*location = -1 and @*count = 0.
+ *
+ * There are two data zones. First is the area between the end of the mft zone
+ * and the end of the volume, and second is the area between the start of the
+ * volume and the start of the mft zone. On unmodified/standard volumes, the
+ * second mft zone doesn't exist due to the mft zone being expanded to cover
+ * the start of volume in order to reserve space for the mft bitmap attribute.
+ *
+ * This is not the prettiest function but the complexity stems from the need of
+ * implementing the mft vs data zoned approach and from the fact that we have
+ * access to the lcn bitmap in portions of PAGE_SIZE bytes at a time, so we
+ * need to cope with crossing over boundaries of two pages. Further, the fact
+ * that the allocator allows for caller supplied hints as to the location of
+ * where allocation should begin and the fact that the allocator keeps track of
+ * where in the data zones the next natural allocation should occur, contribute
+ * to the complexity of the function. But it should all be worthwhile, because
+ * this allocator should: 1) be a full implementation of the MFT zone approach
+ * used by Windows, 2) cause reduction in fragmentation as much as possible,
+ * and 3) be speedy in allocations (the code is not optimized for speed, but
+ * the algorithm is, so further speed improvements are probably possible).
+ *
+ * FIXME: Really need finer-grained locking but this will do for the moment. I
+ * just want to kill all races and have a working allocator. When that is done,
+ * we can beautify... (AIA)
+ * 
+ * FIXME: We should be monitoring cluster allocation and increment the MFT zone
+ * size dynamically but this is something for the future. We will just cause
+ * heavier fragmentation by not doing it and I am not even sure Windows would
+ * grow the MFT zone dynamically, so might even be correct not doing this. The
+ * overhead in doing dynamic MFT zone expansion would be very large and unlikely
+ * worth the effort. (AIA)
+ *
+ * TODO: I have added in double the required zone position pointer wrap around
+ * logic which can be optimized to having only one of the two logic sets.
+ * However, having the double logic will work fine, but if we have only one of
+ * the sets and we get it wrong somewhere, then we get into trouble, so
+ * removing the duplicate logic requires _very_ careful consideration of _all_
+ * possible code paths. So at least for now, I am leaving the double logic -
+ * better safe than sorry... (AIA)
+ */
+int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location,
+		ntfs_cluster_t *count, ntfs_runlist **rl, int *rl_len,
+		const NTFS_CLUSTER_ALLOCATION_ZONES zone)
+{
+	ntfs_runlist *rl2 = NULL, *rlt;
+	ntfs_attribute *data;
+	ntfs_cluster_t buf_pos, zone_start, zone_end, mft_zone_size;
+	ntfs_cluster_t lcn, last_read_pos, prev_lcn = (ntfs_cluster_t)0;
+	ntfs_cluster_t initial_location, prev_run_len = (ntfs_cluster_t)0;
+	ntfs_cluster_t clusters = (ntfs_cluster_t)0;
+	unsigned char *buf, *byte, bit, search_zone, done_zones;
+	unsigned char pass, need_writeback;
+	int rlpos = 0, rlsize, buf_size, err = 0;
+	ntfs_io io;
+
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Entering with *location = "
+			"0x%x, *count = 0x%x, zone = %s_ZONE.\n", *location,
+			*count, zone == DATA_ZONE ? "DATA" : "MFT");
+	buf = (char*)__get_free_page(GFP_NOFS);
+	if (!buf) {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Returning "
+				"-ENOMEM.\n");
+		return -ENOMEM;
+	}
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
+	lock_kernel();
+	/* Get the $DATA attribute of $Bitmap. */
+	data = ntfs_find_attr(vol->bitmap, vol->at_data, 0);
+	if (!data) {
+		err = -EINVAL;
+		goto err_ret;
 	}
-	start = *loc;
-	while (l || bc) {
-		if (bc == 0) {
-			c = *bits;
-			if (l) {
-				l--;
-				bits++;
+	/*
+	 * If no specific location was requested, use the current data zone
+	 * position, otherwise use the requested location but make sure it lies
+	 * outside the mft zone. Also set done_zones to 0 (no zones done) and
+	 * pass depending on whether we are starting inside a zone (1) or
+	 * at the beginning of a zone (2). If requesting from the MFT_ZONE, then
+	 * we either start at the current position within the mft zone or at the
+	 * specified position and if the latter is out of bounds then we start
+	 * at the beginning of the MFT_ZONE.
+	 */
+	done_zones = 0;
+	pass = 1;
+	/*
+	 * zone_start and zone_end are the current search range. search_zone
+	 * is 1 for mft zone, 2 for data zone 1 (end of mft zone till end of
+	 * volume) and 4 for data zone 2 (start of volume till start of mft
+	 * zone).
+	 */
+	zone_start = *location;
+	if (zone_start < 0) {
+		if (zone == DATA_ZONE)
+			zone_start = vol->data1_zone_pos;
+		else
+			zone_start = vol->mft_zone_pos;
+		if (!zone_start)
+			/*
+			 * Zone starts at beginning of volume which means a
+			 * single pass is sufficient.
+			 */
+			pass = 2;
+	} else if (zone_start >= vol->mft_zone_start && zone_start <
+			vol->mft_zone_end && zone == DATA_ZONE) {
+		zone_start = vol->mft_zone_end;
+		pass = 2;
+	} else if ((zone_start < vol->mft_zone_start || zone_start >=
+			vol->mft_zone_end) && zone == MFT_ZONE) {
+		zone_start = vol->mft_lcn;
+		if (!vol->mft_zone_end)
+			zone_start = (ntfs_cluster_t)0;
+		pass = 2;
+	}
+	if (zone == DATA_ZONE) {
+		/* Skip searching the mft zone. */
+		done_zones |= 1;
+		if (zone_start >= vol->mft_zone_end) {
+			zone_end = vol->nr_clusters;
+			search_zone = 2;
+		} else {
+			zone_end = vol->mft_zone_start;
+			search_zone = 4;
+		}
+	} else /* if (zone == MFT_ZONE) */ {
+		zone_end = vol->mft_zone_end;
+		search_zone = 1;
+	}
+	/*
+	 * buf_pos is the current bit position inside the bitmap. We use
+	 * initial_location to determine whether or not to do a zone switch.
+	 */
+	buf_pos = initial_location = zone_start;
+	/* Loop until all clusters are allocated, i.e. clusters == 0. */
+	clusters = *count;
+	rlpos = rlsize = 0;
+	if (*count <= 0) {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): *count <= 0, "
+				"returning -EINVAL.\n");
+		err = -EINVAL;
+		goto err_ret;
+	}
+	while (1) {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Start of outer while "
+				"loop: done_zones = 0x%x, search_zone = %i, "
+				"pass = %i, zone_start = 0x%x, zone_end = "
+				"0x%x, initial_location = 0x%x, buf_pos = "
+				"0x%x, rlpos = %i, rlsize = %i.\n",
+				done_zones, search_zone, pass, zone_start,
+				zone_end, initial_location, buf_pos, rlpos,
+				rlsize);
+		/* Loop until we run out of free clusters. */
+		io.param = buf;
+		io.size = PAGE_SIZE;
+		io.do_read = 1;
+		last_read_pos = buf_pos >> 3;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): last_read_pos = "
+				"0x%x.\n", last_read_pos);
+		err = ntfs_readwrite_attr(vol->bitmap, data, last_read_pos,
+				&io);
+		if (err) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+					"ntfs_read_attr failed with error "
+					"code %i, going to err_ret.\n", -err);
+			goto err_ret;
+		}
+		if (!io.size) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): !io.size, "
+					"going to zone_pass_done.\n");
+			goto zone_pass_done;
+		}
+		buf_size = io.size << 3;
+		lcn = buf_pos & 7;
+		buf_pos &= ~7;
+		need_writeback = 0;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before inner while "
+				"loop: buf_size = 0x%x, lcn = 0x%x, buf_pos = "
+				"0x%x, need_writeback = %i.\n", buf_size, lcn,
+				buf_pos, need_writeback);
+		while (lcn < buf_size && lcn + buf_pos < zone_end) {
+			byte = buf + (lcn >> 3);
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): In inner "
+					"while loop: buf_size = 0x%x, lcn = "
+					"0x%x, buf_pos = 0x%x, need_writeback "
+					"= %i, byte ofs = 0x%x, *byte = "
+					"0x%x.\n", buf_size, lcn, buf_pos,
+					need_writeback, lcn >> 3, *byte);
+			/* Skip full bytes. */
+			if (*byte == 0xff) {
+				lcn += 8;
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"continuing while loop 1.\n");
+				continue;
+			}
+			bit = 1 << (lcn & 7);
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): bit = %i.\n",
+					bit);
+			/* If the bit is already set, go onto the next one. */
+			if (*byte & bit) {
+				lcn++;
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"continuing while loop 2.\n");
+				continue;
+			}
+			/* Allocate the bitmap bit. */
+			*byte |= bit;
+			/* We need to write this bitmap buffer back to disk! */
+			need_writeback = 1;
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): *byte = "
+					"0x%x, need_writeback = %i.\n", *byte,
+					need_writeback);
+			/* Reallocate memory if necessary. */
+			if ((rlpos + 2) * sizeof(ntfs_runlist) >= rlsize) {
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Reallocating space.\n");
+				/* Setup first free bit return value. */
+				if (!rl2) {
+					*location = lcn + buf_pos;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): *location = "
+							"0x%x.\n", *location);
+				}
+				rlsize += PAGE_SIZE;
+				rlt = ntfs_vmalloc(rlsize);
+				if (!rlt) {
+					err = -ENOMEM;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Failed to "
+							"allocate memory, "
+							"returning -ENOMEM, "
+							"going to "
+							"wb_err_ret.\n");
+					goto wb_err_ret;
+				}
+				if (rl2) {
+					ntfs_memcpy(rlt, rl2, rlsize -
+							PAGE_SIZE);
+					ntfs_vfree(rl2);
+				}
+				rl2 = rlt;
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Reallocated memory, rlsize = "
+						"0x%x.\n", rlsize);
 			}
-			bc = 8;
+			/*
+			 * Coalesce with previous run if adjacent LCNs.
+			 * Otherwise, append a new run.
+			 */
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Adding run "
+					"(lcn 0x%x, len 0x%x), prev_lcn = "
+					"0x%x, lcn = 0x%x, buf_pos = 0x%x, "
+					"prev_run_len = 0x%x, rlpos = %i.\n",
+					lcn + buf_pos, 1, prev_lcn, lcn,
+					buf_pos, prev_run_len, rlpos);
+			if (prev_lcn == lcn + buf_pos - prev_run_len && rlpos) {
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Coalescing to run (lcn 0x%x, "
+						"len 0x%x).\n",
+						rl2[rlpos - 1].lcn,
+						rl2[rlpos - 1].len);
+				rl2[rlpos - 1].len = ++prev_run_len;
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Run now (lcn 0x%x, len 0x%x), "
+						"prev_run_len = 0x%x.\n",
+						rl2[rlpos - 1].lcn,
+						rl2[rlpos - 1].len,
+						prev_run_len);
+			} else {
+				if (rlpos)
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Adding new run, "
+							"(previous run lcn "
+							"0x%x, len 0x%x).\n",
+							rl2[rlpos - 1].lcn,
+							rl2[rlpos - 1].len);
+				else
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Adding new run, "
+							"is first run.\n");
+				rl2[rlpos].lcn = prev_lcn = lcn + buf_pos;
+				rl2[rlpos].len = prev_run_len =
+						(ntfs_cluster_t)1;
+				
+				rlpos++;
+			}
+			/* Done? */
+			if (!--clusters) {
+				ntfs_cluster_t tc;
+				/*
+				 * Update the current zone position. Positions
+				 * of already scanned zones have been updated
+				 * during the respective zone switches.
+				 */
+				tc = lcn + buf_pos + 1;
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Done. Updating current zone "
+						"position, tc = 0x%x, "
+						"search_zone = %i.\n", tc,
+						search_zone);
+				switch (search_zone) {
+				case 1:
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Before checks, "
+							"vol->mft_zone_pos = "
+							"0x%x.\n",
+							vol->mft_zone_pos);
+					if (tc >= vol->mft_zone_end) {
+						vol->mft_zone_pos =
+								vol->mft_lcn;
+						if (!vol->mft_zone_end)
+							vol->mft_zone_pos =
+							     (ntfs_cluster_t)0;
+					} else if ((initial_location >=
+							vol->mft_zone_pos ||
+							tc > vol->mft_zone_pos)
+							&& tc >= vol->mft_lcn)
+						vol->mft_zone_pos = tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): After checks, "
+							"vol->mft_zone_pos = "
+							"0x%x.\n",
+							vol->mft_zone_pos);
+					break;
+				case 2:
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Before checks, "
+							"vol->data1_zone_pos = "
+							"0x%x.\n",
+							vol->data1_zone_pos);
+					if (tc >= vol->nr_clusters)
+						vol->data1_zone_pos =
+							     vol->mft_zone_end;
+					else if ((initial_location >=
+						    vol->data1_zone_pos ||
+						    tc > vol->data1_zone_pos)
+						    && tc >= vol->mft_zone_end)
+						vol->data1_zone_pos = tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): After checks, "
+							"vol->data1_zone_pos = "
+							"0x%x.\n",
+							vol->data1_zone_pos);
+					break;
+				case 4:
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Before checks, "
+							"vol->data2_zone_pos = "
+							"0x%x.\n",
+							vol->data2_zone_pos);
+					if (tc >= vol->mft_zone_start)
+						vol->data2_zone_pos =
+							(ntfs_cluster_t)0;
+					else if (initial_location >=
+						      vol->data2_zone_pos ||
+						      tc > vol->data2_zone_pos)
+						vol->data2_zone_pos = tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): After checks, "
+							"vol->data2_zone_pos = "
+							"0x%x.\n",
+							vol->data2_zone_pos);
+					break;
+				default:
+					BUG();
+				}
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Going to done_ret.\n");
+				goto done_ret;
+			}
+			lcn++;
+		}
+		buf_pos += buf_size;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After inner while "
+				"loop: buf_size = 0x%x, lcn = 0x%x, buf_pos = "
+				"0x%x, need_writeback = %i.\n", buf_size, lcn,
+				buf_pos, need_writeback);
+		if (need_writeback) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Writing "
+					"back.\n");
+			need_writeback = 0;
+			io.param = buf;
+			io.do_read = 0;
+			err = ntfs_readwrite_attr(vol->bitmap, data,
+					last_read_pos, &io);
+			if (err) {
+				ntfs_error(__FUNCTION__ "(): Bitmap writeback "
+						"failed in read next buffer "
+						"code path with error code "
+						"%i.\n", -err);
+				goto err_ret;
+			}
+		}
+		if (buf_pos < zone_end) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Continuing "
+					"outer while loop, buf_pos = 0x%x, "
+					"zone_end = 0x%x.\n", buf_pos,
+					zone_end);
+			continue;
 		}
-		if (in) {
-			if ((c & 1) == 0)
-				stop++;
-			else { /* End of sequence of zeroes. */
-				in = 0;
-				if (!found || bstop-bstart < stop-start) {
-					bstop = stop; bstart = start;
-					found = 1;
-					if (bstop - bstart > *cnt)
-						break;
+zone_pass_done:	/* Finished with the current zone pass. */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At zone_pass_done, "
+				"pass = %i.\n", pass);
+		if (pass == 1) {
+			/*
+			 * Now do pass 2, scanning the first part of the zone
+			 * we omitted in pass 1.
+			 */
+			pass = 2;
+			zone_end = zone_start;
+			switch (search_zone) {
+			case 1: /* mft_zone */
+				zone_start = vol->mft_zone_start;
+				break;
+			case 2: /* data1_zone */
+				zone_start = vol->mft_zone_end;
+				break;
+			case 4: /* data2_zone */
+				zone_start = (ntfs_cluster_t)0;
+				break;
+			default:
+				BUG();
+			}
+			/* Sanity check. */
+			if (zone_end < zone_start)
+				zone_end = zone_start;
+			buf_pos = zone_start;
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Continuing "
+					"outer while loop, pass = 2, "
+					"zone_start = 0x%x, zone_end = 0x%x, "
+					"buf_pos = 0x%x.\n");
+			continue;
+		} /* pass == 2 */
+done_zones_check:
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At done_zones_check, "
+				"search_zone = %i, done_zones before = 0x%x, "
+				"done_zones after = 0x%x.\n",
+				search_zone, done_zones, done_zones |
+				search_zone);
+		done_zones |= search_zone;
+		if (done_zones < 7) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Switching "
+					"zone.\n");
+			/* Now switch to the next zone we haven't done yet. */
+			pass = 1;
+			switch (search_zone) {
+			case 1:
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Switching from mft zone to "
+						"data1 zone.\n");
+				/* Update mft zone position. */
+				if (rlpos) {
+					ntfs_cluster_t tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Before checks, "
+							"vol->mft_zone_pos = "
+							"0x%x.\n",
+							vol->mft_zone_pos);
+					tc = rl2[rlpos - 1].lcn +
+							rl2[rlpos - 1].len;
+					if (tc >= vol->mft_zone_end) {
+						vol->mft_zone_pos =
+								vol->mft_lcn;
+						if (!vol->mft_zone_end)
+							vol->mft_zone_pos =
+							     (ntfs_cluster_t)0;
+					} else if ((initial_location >=
+							vol->mft_zone_pos ||
+							tc > vol->mft_zone_pos)
+							&& tc >= vol->mft_lcn)
+						vol->mft_zone_pos = tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): After checks, "
+							"vol->mft_zone_pos = "
+							"0x%x.\n",
+							vol->mft_zone_pos);
+				}
+				/* Switch from mft zone to data1 zone. */
+switch_to_data1_zone:		search_zone = 2;
+				zone_start = initial_location =
+						vol->data1_zone_pos;
+				zone_end = vol->nr_clusters;
+				if (zone_start == vol->mft_zone_end)
+					pass = 2;
+				if (zone_start >= zone_end) {
+					vol->data1_zone_pos = zone_start =
+							vol->mft_zone_end;
+					pass = 2;
+				}
+				break;
+			case 2:
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Switching from data1 zone to "
+						"data2 zone.\n");
+				/* Update data1 zone position. */
+				if (rlpos) {
+					ntfs_cluster_t tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Before checks, "
+							"vol->data1_zone_pos = "
+							"0x%x.\n",
+							vol->data1_zone_pos);
+					tc = rl2[rlpos - 1].lcn +
+							rl2[rlpos - 1].len;
+					if (tc >= vol->nr_clusters)
+						vol->data1_zone_pos =
+							     vol->mft_zone_end;
+					else if ((initial_location >=
+						    vol->data1_zone_pos ||
+						    tc > vol->data1_zone_pos)
+						    && tc >= vol->mft_zone_end)
+						vol->data1_zone_pos = tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): After checks, "
+							"vol->data1_zone_pos = "
+							"0x%x.\n",
+							vol->data1_zone_pos);
 				}
-				start = stop + 1;
+				/* Switch from data1 zone to data2 zone. */
+				search_zone = 4;
+				zone_start = initial_location =
+						vol->data2_zone_pos;
+				zone_end = vol->mft_zone_start;
+				if (!zone_start)
+					pass = 2;
+				if (zone_start >= zone_end) {
+					vol->data2_zone_pos = zone_start =
+							initial_location =
+							(ntfs_cluster_t)0;
+					pass = 2;
+				}
+				break;
+			case 4:
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Switching from data2 zone to "
+						"data1 zone.\n");
+				/* Update data2 zone position. */
+				if (rlpos) {
+					ntfs_cluster_t tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): Before checks, "
+							"vol->data2_zone_pos = "
+							"0x%x.\n",
+							vol->data2_zone_pos);
+					tc = rl2[rlpos - 1].lcn +
+							rl2[rlpos - 1].len;
+					if (tc >= vol->mft_zone_start)
+						vol->data2_zone_pos =
+							     (ntfs_cluster_t)0;
+					else if (initial_location >=
+						      vol->data2_zone_pos ||
+						      tc > vol->data2_zone_pos)
+						vol->data2_zone_pos = tc;
+					ntfs_debug(DEBUG_OTHER, __FUNCTION__
+							"(): After checks, "
+							"vol->data2_zone_pos = "
+							"0x%x.\n",
+							vol->data2_zone_pos);
+				}
+				/* Switch from data2 zone to data1 zone. */
+				goto switch_to_data1_zone; /* See above. */
+			default:
+				BUG();
 			}
-		} else {
-			if (c & 1)
-				start++;
-			else { /* Start of sequence. */
-				in = 1;
-				stop = start + 1;
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After zone "
+					"switch, search_zone = %i, pass = %i, "
+					"initial_location = 0x%x, zone_start "
+					"= 0x%x, zone_end = 0x%x.\n",
+					search_zone, pass, initial_location,
+					zone_start, zone_end);
+			buf_pos = zone_start;
+			if (zone_start == zone_end) {
+				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "
+						"Empty zone, going to "
+						"done_zones_check.\n");
+				/* Empty zone. Don't bother searching it. */
+				goto done_zones_check;
 			}
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Continuing "
+					"outer while loop.\n");
+			continue;
+		} /* done_zones == 7 */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): All zones are "
+				"finished.\n");
+		/*
+		 * All zones are finished! If DATA_ZONE, shrink mft zone. If
+		 * MFT_ZONE, we have really run out of space.
+		 */
+		mft_zone_size = vol->mft_zone_end - vol->mft_zone_start;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): vol->mft_zone_start "
+				"= 0x%x, vol->mft_zone_end = 0x%x, "
+				"mft_zone_size = 0x%x.\n", vol->mft_zone_start,
+				vol->mft_zone_end, mft_zone_size);
+		if (zone == MFT_ZONE || mft_zone_size <= (ntfs_cluster_t)0) {
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): No free "
+					"clusters left, returning -ENOSPC, "
+					"going to fail_ret.\n");
+			/* Really no more space left on device. */
+			err = -ENOSPC;
+			goto fail_ret;
+		} /* zone == DATA_ZONE && mft_zone_size > 0 */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Shrinking mft "
+				"zone.\n");
+		zone_end = vol->mft_zone_end;
+		mft_zone_size >>= 1;
+		if (mft_zone_size > (ntfs_cluster_t)0)
+			vol->mft_zone_end = vol->mft_zone_start + mft_zone_size;
+		else /* mft zone and data2 zone no longer exist. */
+			vol->data2_zone_pos = vol->mft_zone_start =
+					vol->mft_zone_end = (ntfs_cluster_t)0;
+		if (vol->mft_zone_pos >= vol->mft_zone_end) {
+			vol->mft_zone_pos = vol->mft_lcn;
+			if (!vol->mft_zone_end)
+				vol->mft_zone_pos = (ntfs_cluster_t)0;
+		}
+		buf_pos = zone_start = initial_location =
+				vol->data1_zone_pos = vol->mft_zone_end;
+		search_zone = 2;
+		pass = 2;
+		done_zones &= ~2;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After shrinking mft "
+				"zone, mft_zone_size = 0x%x, "
+				"vol->mft_zone_start = 0x%x, vol->mft_zone_end "
+				"= 0x%x, vol->mft_zone_pos = 0x%x, search_zone "
+				"= 2, pass = 2, dones_zones = 0x%x, zone_start "
+				"= 0x%x, zone_end = 0x%x, vol->data1_zone_pos "
+				"= 0x%x, continuing outer while loop.\n",
+				mft_zone_size, vol->mft_zone_start,
+				vol->mft_zone_end, vol->mft_zone_pos,
+				search_zone, pass, done_zones, zone_start,
+				zone_end, vol->data1_zone_pos);
+	}
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After outer while loop.\n");
+done_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At done_ret.\n");
+	rl2[rlpos].lcn = (ntfs_cluster_t)-1;
+	rl2[rlpos].len = (ntfs_cluster_t)0;
+	*rl = rl2;
+	*rl_len = rlpos;
+	if (need_writeback) {
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Writing back.\n");
+		need_writeback = 0;
+		io.param = buf;
+		io.do_read = 0;
+		err = ntfs_readwrite_attr(vol->bitmap, data, last_read_pos,
+				&io);
+		if (err) {
+			ntfs_error(__FUNCTION__ "(): Bitmap writeback failed "
+					"in done code path with error code "
+					"%i.\n", -err);
+			goto err_ret;
 		}
-		bc--;
-		c >>= 1;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Wrote 0x%Lx bytes.\n",
+				io.size);
 	}
-	if (in && (!found || bstop - bstart < stop - start)) {
-		bstop = stop;
-		bstart = start;
-		found = 1;
-	}
-	if (!found)
-		return -ENOSPC;
-	*loc = bstart;
-	if (*cnt > bstop - bstart)
-		*cnt = bstop - bstart;
-	return 0;
+done_fail_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At done_fail_ret (follows "
+			"done_ret).\n");
+	unlock_kernel();
+	free_page((unsigned long)buf);
+	if (err)
+		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): Failed to allocate "
+				"clusters. Returning with error code %i.\n",
+				-err);
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Syncing $Bitmap inode.\n");
+	if (ntfs_update_inode(vol->bitmap))
+		ntfs_error(__FUNCTION__ "(): Failed to sync inode $Bitmap. "
+				"Continuing anyway.\n");
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Returning with code %i.\n",
+			err);
+	return err;
+fail_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At fail_ret.\n");
+	if (rl2) {
+		if (err == -ENOSPC) {
+			/* Return first free lcn and count of free clusters. */
+			*location = rl2[0].lcn;
+			*count -= clusters;
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): err = "
+					"-ENOSPC, *location = 0x%x, *count = "
+					"0x%x.\n", *location, *count);
+		}
+		/* Deallocate all allocated clusters. */
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Deallocating "
+				"allocated clusters.\n");
+		ntfs_deallocate_clusters(vol, rl2, rlpos);
+		/* Free the runlist. */
+		ntfs_vfree(rl2);
+	} else {
+		if (err == -ENOSPC) {
+			/* Nothing free at all. */
+			*location = vol->data1_zone_pos; /* Irrelevant... */
+			*count = 0;
+			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): No space "
+					"left at all, err = -ENOSPC, *location "
+					"= 0x%x, *count = 0.\n", *location);
+		}
+	}
+	*rl = NULL;
+	*rl_len = 0;
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): *rl = NULL, *rl_len = 0, "
+			"going to done_fail_ret.\n");
+	goto done_fail_ret;
+wb_err_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At wb_err_ret.\n");
+	if (need_writeback) {
+		int __err;
+		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Writing back.\n");
+		io.param = buf;
+		io.do_read = 0;
+		__err = ntfs_readwrite_attr(vol->bitmap, data, last_read_pos,
+				&io);
+		if (__err)
+			ntfs_error(__FUNCTION__ "(): Bitmap writeback failed "
+					"in error code path with error code "
+					"%i.\n", -__err);
+		need_writeback = 0;
+	}
+err_ret:
+	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At err_ret, *location = -1, "
+			"*count = 0, going to fail_ret.\n");
+	*location = -1;
+	*count = 0;
+	goto fail_ret;
 }
 
-int ntfs_set_bitrange(ntfs_inode* bitmap, ntfs_cluster_t loc, int cnt, int bit)
+/*
+ * IMPORTANT: Caller has to hold big kernel lock or the race monster will come
+ * to get you! (-;
+ * TODO: Need our own lock for bitmap accesses but BKL is more secure for now,
+ * considering we might not have covered all places with a lock yet. In that
+ * case the BKL offers a one way exclusion which is better than no exclusion
+ * at all... (AIA)
+ */
+static int ntfs_clear_bitrange(ntfs_inode *bitmap,
+		const ntfs_cluster_t start_bit, const ntfs_cluster_t count)
 {
-	int bsize, locit, error;
-	unsigned char *bits, *it;
+	ntfs_cluster_t buf_size, bit, nr_bits = count;
+	unsigned char *buf, *byte;
+	int err;
 	ntfs_io io;
 
 	io.fn_put = ntfs_put;
 	io.fn_get = ntfs_get;
-	bsize = (cnt + (loc & 7) + 7) >> 3; /* Round up to multiple of 8. */
-	bits = ntfs_malloc(bsize);
-	if (!bits)
-		return -ENOMEM;
-	io.param = bits;
-	io.size = bsize;
-	error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, loc >> 3, &io);
-	if (error || io.size != bsize) {
-		ntfs_free(bits);
-		return error ? error : -EIO;
-	}
-	/* Now set the bits. */
-	it = bits;
-	locit = loc;
-	while (locit % 8 && cnt) { /* Process first byte. */
-		if (bit)
-			*it |= 1 << (locit % 8);
-		else
-			*it &= ~(1 << (locit % 8));
-		cnt--;
-		locit++;
-		if (locit % 8 == 0)
-			it++;
-	}
-	while (cnt > 8) { /* Process full bytes. */
-		*it = bit ? 0xFF : 0;
-		cnt -= 8;
-		locit += 8;
-		it++;
-	}
-	while (cnt) { /* Process last byte. */
-		if (bit)
-			*it |= 1 << (locit % 8);
-		else
-			*it &= ~(1 << (locit % 8));
-		cnt--;
-		locit++;
-	}
-	/* Reset to start. */
-	io.param = bits;
-	io.size = bsize;
-	error = ntfs_write_attr(bitmap, bitmap->vol->at_data, 0, loc >> 3, &io);
-	ntfs_free(bits);
-	if (error)
-		return error;
-	if (io.size != bsize)
-		return -EIO;
-	return 0;
-}
-	
-/* Allocate count clusters around location. If location is -1, it does not
- * matter where the clusters are. Result is 0 if success, in which case
- * location and count says what they really got. */
-int ntfs_search_bits(ntfs_inode* bitmap, ntfs_cluster_t *location, int *count,
-		     int flags)
-{
-	unsigned char *bits;
-	ntfs_io io;
-	int error = 0, found = 0;
-	int cnt, bloc = -1, bcnt = 0;
-	int start;
-	ntfs_cluster_t loc;
-
-	bits = ntfs_malloc(2048);
-	if (!bits)
+	/* Calculate the required buffer size in bytes. */
+	buf_size = (ntfs_cluster_t)((start_bit & 7) + nr_bits + 7) >> 3;
+	if (buf_size <= (ntfs_cluster_t)(64 * 1024))
+		buf = ntfs_malloc(buf_size);
+	else
+		buf = ntfs_vmalloc(buf_size);
+	if (!buf)
 		return -ENOMEM;
-	io.fn_put = ntfs_put;
-	io.fn_get = ntfs_get;
-	io.param = bits;
-
-	/* first search within +/- 8192 clusters */
-	start = *location >> 3;
-	start = start > 1024 ? start - 1024 : 0;
-	io.size = 2048;
-	error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, start, &io);
-	if (error)
-		goto fail;
-	loc = start * 8;
-	cnt = *count;
-	error = search_bits(bits, &loc, &cnt, io.size);
-	if (error)
-		goto fail;
-	if (*count == cnt){
-		bloc = loc;
-		bcnt = cnt;
-		goto success;
-	}
-	/* Now search from the beginning. */
-	for (start = 0; 1; start += 2048) {
-		io.param = bits;
-		io.size = 2048;
-		error = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, start,
-									&io);
-		if (error)
-			goto fail;
-		if (io.size == 0) {
-			if(found)
-				goto success;
-			else {
-				error = -ENOSPC;
-				goto fail;
-			}
-		}
-		loc = start * 8;
-		cnt = *count;
-		error = search_bits(bits, &loc, &cnt, io.size);
-		if (error)
-			goto fail;
-		if (*count == cnt)
-			goto success;
-		if (bcnt < cnt) {
-			bcnt = cnt;
-			bloc = loc;
-			found = 1;
-		}
-	}
- success:
-	ntfs_free(bits);
-	/* check flags */
-	if ((flags & ALLOC_REQUIRE_LOCATION) && *location != bloc)
-		error = -ENOSPC;
-	else if ((flags & ALLOC_REQUIRE_SIZE) && *count != bcnt)
-		error = -ENOSPC;
+	/* Read the bitmap from the data attribute. */
+	io.param = byte = buf;
+	io.size = buf_size;
+	err = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, start_bit >> 3,
+			&io);
+	if (err || io.size != buf_size)
+		goto err_out;
+	/* Now clear the bits in the read bitmap. */
+	bit = start_bit & 7;
+	while (bit && nr_bits) { /* Process first partial byte, if present. */
+		*byte &= ~(1 << bit++);
+		nr_bits--;
+		bit &= 7;
+		if (!bit)
+			byte++;
+	}
+	while (nr_bits >= 8) { /* Process full bytes. */
+		*byte = 0;
+		nr_bits -= 8;
+		byte++;
+	}
+	bit = 0;
+	while (nr_bits) { /* Process last partial byte, if present. */
+		*byte &= ~(1 << bit);
+		nr_bits--;
+		bit++;
+	}
+	/* Write the modified bitmap back to disk. */
+	io.param = buf;
+	io.size = buf_size;
+	err = ntfs_write_attr(bitmap, bitmap->vol->at_data, 0, start_bit >> 3,
+			&io);
+err_out:
+	if (buf_size <= (ntfs_cluster_t)(64 * 1024))
+		ntfs_free(buf);
 	else
-		ntfs_set_bitrange(bitmap, bloc, bcnt, 1);
-	/* If allocation failed due to the flags, tell the caller what he could
-	 * have gotten */
-	*location = bloc;
-	*count = bcnt;
-	return 0;
- fail:
-	*location = -1;
-	*count = 0;
-	ntfs_free(bits);
-	return error;
+		ntfs_vfree(buf);
+	if (!err && io.size != buf_size)
+		err = -EIO;
+	return err;
 }
 
-int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location,
-			   int *count, int flags)
+/*
+ * See comments for lack of zone adjustments below in the description of the
+ * function ntfs_deallocate_clusters().
+ */
+int ntfs_deallocate_cluster_run(const ntfs_volume *vol,
+		const ntfs_cluster_t lcn, const ntfs_cluster_t len)
 {
-	int error;
-	error = ntfs_search_bits(vol->bitmap, location, count, flags);
-	return error;
+	int err;
+
+	lock_kernel();
+	err = ntfs_clear_bitrange(vol->bitmap, lcn, len);
+	unlock_kernel();
+	return err;
 }
 
-int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location,
-			     int count)
+/*
+ * This is inefficient, but logically trivial, so will do for now. Note, we
+ * do not touch the mft nor the data zones here because we want to minimize
+ * recycling of clusters to enhance the chances of data being undeleteable.
+ * Also we don't want the overhead. Instead we do one additional sweep of the
+ * current data zone during cluster allocation to check for freed clusters.
+ */
+int ntfs_deallocate_clusters(const ntfs_volume *vol, const ntfs_runlist *rl,
+		const int rl_len)
 {
-	int error;
-	error = ntfs_set_bitrange(vol->bitmap, location, count, 0);
-	return error;
+	int i, err;
+
+	lock_kernel();
+	for (i = err = 0; i < rl_len && !err; i++)
+		err = ntfs_clear_bitrange(vol->bitmap, rl[i].lcn, rl[i].len);
+	unlock_kernel();
+	return err;
 }
 
diff -urN linux-2.4.10-pre5/fs/ntfs/super.h linux/fs/ntfs/super.h
--- linux-2.4.10-pre5/fs/ntfs/super.h	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/super.h	Mon Dec  3 23:08:13 2001
@@ -6,9 +6,6 @@
  * Copyright (c) 2001 Anton Altaparmakov
  */
 
-#define ALLOC_REQUIRE_LOCATION 1
-#define ALLOC_REQUIRE_SIZE     2
-
 int ntfs_get_free_cluster_count(ntfs_inode *bitmap);
 
 int ntfs_get_volumesize(ntfs_volume *vol, __s64 *vol_size);
@@ -24,8 +21,12 @@
 int ntfs_fixup_record(char *record, char *magic, int size);
 
 int ntfs_allocate_clusters(ntfs_volume *vol, ntfs_cluster_t *location,
-		int *count, int flags);
+		ntfs_cluster_t *count, ntfs_runlist **rl, int *rl_len,
+		const NTFS_CLUSTER_ALLOCATION_ZONES zone);
+
+int ntfs_deallocate_cluster_run(const ntfs_volume *vol,
+		const ntfs_cluster_t lcn, const ntfs_cluster_t len);
 
-int ntfs_deallocate_clusters(ntfs_volume *vol, ntfs_cluster_t location,
-		int count);
+int ntfs_deallocate_clusters(const ntfs_volume *vol, const ntfs_runlist *rl,
+		const int rl_len);
 
diff -urN linux-2.4.10-pre5/fs/ntfs/support.c linux/fs/ntfs/support.c
--- linux-2.4.10-pre5/fs/ntfs/support.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/ntfs/support.c	Mon Dec  3 23:08:13 2001
@@ -33,8 +33,8 @@
 	/* Filter it with the debugging level required */
 	if (ntdebug & mask) {
 		va_start(ap,fmt);
-		strcpy(print_buf, KERN_DEBUG);
-		vsprintf(print_buf + 3, fmt, ap);
+		strcpy(print_buf, KERN_DEBUG "NTFS: ");
+		vsprintf(print_buf + 9, fmt, ap);
 		printk(print_buf);
 		va_end(ap);
 	}
@@ -62,9 +62,6 @@
 }
 #endif
 #else /* End of DEBUG functions. Normal ones below... */
-void ntfs_debug(int mask, const char *fmt, ...)
-{
-}
 
 #ifndef ntfs_malloc
 void *ntfs_malloc(int size)
@@ -117,7 +114,7 @@
 	ntfs_io io;
 
 	ntfs_debug(DEBUG_OTHER, "read_mft_record 0x%x\n", mftno);
-	if (mftno == FILE_$Mft)
+	if (mftno == FILE_Mft)
 	{
 		ntfs_memcpy(buf, vol->mft, vol->mft_record_size);
 		return 0;
diff -urN linux-2.4.10-pre5/fs/ntfs/support.h linux/fs/ntfs/support.h
--- linux-2.4.10-pre5/fs/ntfs/support.h	Mon Jul 16 15:14:10 2001
+++ linux/fs/ntfs/support.h	Mon Dec  3 23:08:13 2001
@@ -19,7 +19,11 @@
 #define DEBUG_NAME1  1024
 #define DEBUG_NAME2  2048
 
+#ifdef DEBUG
 void ntfs_debug(int mask, const char *fmt, ...);
+#else
+#define ntfs_debug(mask, fmt, ...)	do {} while (0)
+#endif
 
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff -urN linux-2.4.10-pre5/fs/ntfs/util.h linux/fs/ntfs/util.h
--- linux-2.4.10-pre5/fs/ntfs/util.h	Mon Aug 13 16:40:19 2001
+++ linux/fs/ntfs/util.h	Mon Dec  3 23:08:13 2001
@@ -7,18 +7,18 @@
 
 /* The first 16 inodes correspond to NTFS special files. */
 typedef enum {
-	FILE_$Mft	= 0,
-	FILE_$MftMirr	= 1,
-	FILE_$LogFile	= 2,
-	FILE_$Volume	= 3,
-	FILE_$AttrDef	= 4,
-	FILE_$root	= 5,
-	FILE_$BitMap	= 6,
-	FILE_$Boot	= 7,
-	FILE_$BadClus	= 8,
-	FILE_$Secure	= 9,
-	FILE_$UpCase	= 10,
-	FILE_$Extend	= 11,
+	FILE_Mft	= 0,
+	FILE_MftMirr	= 1,
+	FILE_LogFile	= 2,
+	FILE_Volume	= 3,
+	FILE_AttrDef	= 4,
+	FILE_root	= 5,
+	FILE_BitMap	= 6,
+	FILE_Boot	= 7,
+	FILE_BadClus	= 8,
+	FILE_Secure	= 9,
+	FILE_UpCase	= 10,
+	FILE_Extend	= 11,
 	FILE_Reserved12	= 12,
 	FILE_Reserved13	= 13,
 	FILE_Reserved14	= 14,
diff -urN linux-2.4.10-pre5/fs/partitions/check.c linux/fs/partitions/check.c
--- linux-2.4.10-pre5/fs/partitions/check.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/partitions/check.c	Mon Dec  3 23:08:13 2001
@@ -36,7 +36,6 @@
 
 extern int *blk_size[];
 
-struct gendisk *gendisk_head;
 int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
 
 static int (*check_part[])(struct gendisk *hd, kdev_t dev, unsigned long first_sect, int first_minor) = {
@@ -249,39 +248,6 @@
 
 	return ret;
 }
-
-#ifdef CONFIG_PROC_FS
-int get_partition_list(char *page, char **start, off_t offset, int count)
-{
-	struct gendisk *dsk;
-	int len;
-
-	len = sprintf(page, "major minor  #blocks  name\n\n");
-	for (dsk = gendisk_head; dsk; dsk = dsk->next) {
-		int n;
-
-		for (n = 0; n < (dsk->nr_real << dsk->minor_shift); n++)
-			if (dsk->part[n].nr_sects) {
-				char buf[64];
-
-				len += sprintf(page + len,
-					       "%4d  %4d %10d %s\n",
-					       dsk->major, n, dsk->sizes[n],
-					       disk_name(dsk, n, buf));
-				if (len < offset)
-					offset -= len, len = 0;
-				else if (len >= offset + count)
-					goto leave_loops;
-			}
-	}
-leave_loops:
-	*start = page + offset;
-	len -= offset;
-	if (len < 0)
-		len = 0;
-	return len > count ? count : len;
-}
-#endif
 
 static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
 {
diff -urN linux-2.4.10-pre5/fs/reiserfs/bitmap.c linux/fs/reiserfs/bitmap.c
--- linux-2.4.10-pre5/fs/reiserfs/bitmap.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/reiserfs/bitmap.c	Mon Dec  3 23:08:13 2001
@@ -1,7 +1,6 @@
 /*
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
-#ifdef __KERNEL__
 
 #include <linux/config.h>
 #include <linux/sched.h>
@@ -9,13 +8,6 @@
 #include <linux/locks.h>
 #include <asm/bitops.h>
 #include <linux/list.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
-
 
 #ifdef CONFIG_REISERFS_CHECK
 
diff -urN linux-2.4.10-pre5/fs/reiserfs/buffer2.c linux/fs/reiserfs/buffer2.c
--- linux-2.4.10-pre5/fs/reiserfs/buffer2.c	Mon Jan 15 15:31:19 2001
+++ linux/fs/reiserfs/buffer2.c	Mon Dec  3 23:08:13 2001
@@ -10,20 +10,12 @@
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
-#ifdef __KERNEL__
 
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/locks.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
-
 
 /*
  *  wait_buffer_until_released
diff -urN linux-2.4.10-pre5/fs/reiserfs/dir.c linux/fs/reiserfs/dir.c
--- linux-2.4.10-pre5/fs/reiserfs/dir.c	Wed Jul 18 07:46:02 2001
+++ linux/fs/reiserfs/dir.c	Mon Dec  3 23:08:13 2001
@@ -2,8 +2,6 @@
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <linux/string.h>
 #include <linux/errno.h>
@@ -12,12 +10,6 @@
 #include <linux/stat.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
 
 extern struct key  MIN_KEY;
 
diff -urN linux-2.4.10-pre5/fs/reiserfs/do_balan.c linux/fs/reiserfs/do_balan.c
--- linux-2.4.10-pre5/fs/reiserfs/do_balan.c	Wed Jul 18 07:46:02 2001
+++ linux/fs/reiserfs/do_balan.c	Mon Dec  3 23:08:13 2001
@@ -16,20 +16,11 @@
  **
  **/
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <asm/uaccess.h>
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
 
-#else
-
-#include "nokernel.h"
-
-#endif
-
-
 #ifdef CONFIG_REISERFS_CHECK
 
 struct tree_balance * cur_tb = NULL; /* detects whether more than one
@@ -662,11 +653,7 @@
 		{
 		    struct item_head * pasted;
 
-#ifdef REISERFS_FSCK
-		    if ( ! item_pos  && is_left_mergeable (tb->tb_sb, tb->tb_path) == 1 )
-#else
 			if ( ! item_pos  && op_is_left_mergeable (B_N_PKEY (tbS0, 0), tbS0->b_size) )
-#endif
 			{ /* if we paste into first item of S[0] and it is left mergable */
 			    /* then increment pos_in_item by the size of the last item in L[0] */
 			    pasted = B_N_PITEM_HEAD(tb->L[0],n-1);
@@ -1606,10 +1593,6 @@
     tb->FEB[i] = 0;
     tb->used[i] = first_b;
 
-#ifdef REISERFS_FSCK
-    mark_block_formatted (first_b->b_blocknr);
-#endif
-
     return(first_b);
 }
 
@@ -1656,20 +1639,6 @@
     */
 
     store_thrown (tb, bh);
-#if 0
-#ifdef REISERFS_FSCK
-    {
-	struct buffer_head * to_be_forgotten;
-	
-	to_be_forgotten = find_buffer (bh->b_dev, bh->b_blocknr, bh->b_size);
-	if (to_be_forgotten) {
-	    to_be_forgotten->b_count ++;
-	    bforget (to_be_forgotten);
-	}
-	unmark_block_formatted (bh->b_blocknr);
-    }
-#endif
-#endif
 }
 
 /* Replace n_dest'th key in buffer dest by n_src'th key of buffer src.*/
@@ -1915,13 +1884,6 @@
     if (check_before_balancing (tb))
 	reiserfs_panic (tb->tb_sb, "PAP-12340: do_balance: locked buffers in TB");
 
-#ifndef __KERNEL__
-    if ( atomic_read(&(PATH_PLAST_BUFFER(tb->tb_path)->b_count)) > 1 || (tb->L[0] && atomic_read(&(tb->L[0]->b_count)) > 1) ||
-	 (tb->R[0] && atomic_read(&(tb->R[0]->b_count)) > 1) ) {
-	print_cur_tb ("first three parameters are invalid");
-	reiserfs_panic (tb->tb_sb, "PAP-12345: do_balance: counter too big");
-    }
-#endif /* !__KERNEL__ */
     cur_tb = tb;
     
 #endif /* CONFIG_REISERFS_CHECK */
@@ -2003,26 +1965,6 @@
     atomic_inc (&(fs_generation (tb->tb_sb)));
     do_balance_starts (tb);
     
-#ifdef REISERFS_FSCK
-    if (flag == M_INTERNAL) {
-	insert_ptr[0] = (struct buffer_head *)body;
-	/* we must prepare insert_key */
-
-	if (PATH_H_B_ITEM_ORDER (tb->tb_path, 0)/*LAST_POSITION (tb->tb_path)*//*item_pos*/ == -1) {
-		/* get delimiting key from buffer in tree */
-		copy_key (&insert_key[0].ih_key, B_N_PKEY (PATH_PLAST_BUFFER (tb->tb_path), 0));
-		/*insert_ptr[0]->b_item_order = 0;*/
-	} else {
-	    /* get delimiting key from new buffer */
-	    copy_key (&insert_key[0].ih_key, B_N_PKEY((struct buffer_head *)body,0));
-	    /*insert_ptr[0]->b_item_order = item_pos;*/
-	}
-      
-	/* and insert_ptr instead of balance_leaf */
-	child_pos = PATH_H_B_ITEM_ORDER (tb->tb_path, 0)/*item_pos*/;
-    } else
-#endif
-
 	/* balance leaf returns 0 except if combining L R and S into
 	   one node.  see balance_internal() for explanation of this
 	   line of code.*/
diff -urN linux-2.4.10-pre5/fs/reiserfs/file.c linux/fs/reiserfs/file.c
--- linux-2.4.10-pre5/fs/reiserfs/file.c	Thu Apr 26 10:44:10 2001
+++ linux/fs/reiserfs/file.c	Mon Dec  3 23:08:14 2001
@@ -3,17 +3,9 @@
  */
 
 
-#ifdef __KERNEL__
-
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
 
 /*
 ** We pack the tails of files on file close, not at the time they are written.
diff -urN linux-2.4.10-pre5/fs/reiserfs/fix_node.c linux/fs/reiserfs/fix_node.c
--- linux-2.4.10-pre5/fs/reiserfs/fix_node.c	Wed Jul 18 07:46:02 2001
+++ linux/fs/reiserfs/fix_node.c	Mon Dec  3 23:08:14 2001
@@ -35,21 +35,12 @@
  **/
 
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/locks.h>
 #include <linux/reiserfs_fs.h>
 
-#else
-
-#include "nokernel.h"
-
-#endif
-
-
 
 /* To make any changes in the tree we find a node, that contains item
    to be changed/deleted or position in the node we insert a new item
@@ -122,11 +113,7 @@
     ih = B_N_PITEM_HEAD (Sh, 0);
 
     /* define the mergeability for 0-th item (if it is not being deleted) */
-#ifdef REISERFS_FSCK
-    if (is_left_mergeable (tb->tb_sb, tb->tb_path) == 1 && (vn->vn_mode != M_DELETE || vn->vn_affected_item_num))
-#else
     if (op_is_left_mergeable (&(ih->ih_key), Sh->b_size) && (vn->vn_mode != M_DELETE || vn->vn_affected_item_num))
-#endif
 	    vn->vn_vi[0].vi_type |= VI_TYPE_LEFT_MERGEABLE;
 
     /* go through all items those remain in the virtual node (except for the new (inserted) one) */
@@ -207,13 +194,8 @@
 	struct key * key;
 
 	key = B_N_PDELIM_KEY (tb->CFR[0], tb->rkey[0]);
-#ifdef REISERFS_FSCK
-	if (is_right_mergeable (tb->tb_sb, tb->tb_path) == 1 && (vn->vn_mode != M_DELETE ||
-								 vn->vn_affected_item_num != B_NR_ITEMS (Sh) - 1))
-#else
 	if (op_is_left_mergeable (key, Sh->b_size) && (vn->vn_mode != M_DELETE ||
 						       vn->vn_affected_item_num != B_NR_ITEMS (Sh) - 1))
-#endif
 		vn->vn_vi[vn->vn_nr_item-1].vi_type |= VI_TYPE_RIGHT_MERGEABLE;
 
 #ifdef CONFIG_REISERFS_CHECK
@@ -717,8 +699,6 @@
     ih = B_N_PITEM_HEAD (S0, 0);
     if (tb->CFR[0] && !comp_short_le_keys (&(ih->ih_key), B_N_PDELIM_KEY (tb->CFR[0], tb->rkey[0])))
 	if (is_direntry_le_ih (ih)) {
-#ifndef REISERFS_FSCK
-		
 	    /* Directory must be in correct state here: that is
 	       somewhere at the left side should exist first directory
 	       item. But the item being deleted can not be that first
@@ -735,30 +715,6 @@
 		reiserfs_panic (tb->tb_sb, "vs-8130: are_leaves_removable: "
 				"first directory item can not be removed until directory is not empty");
 #endif
-	
-	
-#else	/* REISERFS_FSCK */
-
-	    /* we can delete any directory item in fsck (if it is unreachable) */
-	    if (ih->ih_key.k_offset != DOT_OFFSET) {
-		/* must get left neighbor here to make sure, that left
-		   neighbor is of the same directory */
-		struct buffer_head * left;
-		
-		left = get_left_neighbor (tb->tb_sb, tb->tb_path);
-		if (left) {
-		    struct item_head * last;
-		    
-		    if (B_NR_ITEMS (left) == 0)
-			reiserfs_panic (tb->tb_sb, "vs-8135: are_leaves_removable: "
-					"empty node in the tree");
-		    last = B_N_PITEM_HEAD (left, B_NR_ITEMS (left) - 1);
-		    if (!comp_short_keys (&last->ih_key, &ih->ih_key))
-			ih_size = IH_SIZE;
-		    brelse (left);
-		}
-	    }
-#endif
       }
     
   }
@@ -860,11 +816,6 @@
   struct super_block *	p_s_sb = p_s_tb->tb_sb;
 
 
-#ifdef REISERFS_FSCK
-   if (n_h == 0 && p_s_tb->insert_size[n_h] == 0x7fff)
-     return CARRY_ON;
-#endif
-
   /* number_of_freeblk is the number of empty blocks which have been
      acquired for use by the balancing algorithm minus the number of
      empty blocks used in the previous levels of the analysis,
@@ -1311,13 +1262,8 @@
     if (
 	lfree + rfree + sfree < MAX_CHILD_SIZE(Sh) + levbytes
 	/* shifting may merge items which might save space */
-#ifdef REISERFS_FSCK
-	- (( ! h && is_left_mergeable (tb->tb_sb, tb->tb_path) == 1 ) ? IH_SIZE : 0)
-	- (( ! h && r_ih && is_right_mergeable (tb->tb_sb, tb->tb_path) == 1 ) ? IH_SIZE : 0)
-#else
 	- (( ! h && op_is_left_mergeable (&(ih->ih_key), Sh->b_size) ) ? IH_SIZE : 0)
 	- (( ! h && r_key && op_is_left_mergeable (r_key, Sh->b_size) ) ? IH_SIZE : 0)
-#endif
 	+ (( h ) ? KEY_SIZE : 0))
     {
 	/* node can not be removed */
@@ -1387,15 +1333,6 @@
     /* Sh is the node whose balance is currently being checked */
     struct buffer_head * Sh;
   
-#ifdef REISERFS_FSCK
-    /* special mode for insert pointer to the most low internal node */
-    if (h == 0 && vn->vn_mode == M_INTERNAL) {
-	/* blk_num == 2 is to get pointer inserted to the next level */
-	set_parameters (tb, h, 0, 0, 2, NULL, -1, -1);
-	return 0;
-    }
-#endif
-
     Sh = PATH_H_PBUFFER (tb->tb_path, h);
     levbytes = tb->insert_size[h];
   
@@ -2514,16 +2451,6 @@
             return REPEAT_SEARCH;
     }
 
-#ifndef __KERNEL__
-    if ( atomic_read (&(p_s_tbS0->b_count)) > 1 || 
-	 (p_s_tb->L[0] && atomic_read (&(p_s_tb->L[0]->b_count)) > 1) ||
-	 (p_s_tb->R[0] && atomic_read (&(p_s_tb->R[0]->b_count)) > 1) ) {
-	printk ("mode=%c, insert_size=%d\n", n_op_mode, p_s_tb->insert_size[0]);
-	print_cur_tb ("first three parameters are invalid");
-	reiserfs_panic (p_s_tb->tb_sb, "PAP-8310: fix_nodes: all buffers must be hold once in one thread processing");
-    }
-#endif
-
 #ifdef CONFIG_REISERFS_CHECK
     if ( cur_tb ) {
 	print_cur_tb ("fix_nodes");
@@ -2546,19 +2473,10 @@
 
     /* Check parameters. */
     switch (n_op_mode) {
-#ifdef REISERFS_FSCK
-    case M_INTERNAL:
-	break;
-    case M_INSERT:
-	if ( n_item_num < 0 || n_item_num > B_NR_ITEMS(p_s_tbS0) )
-	    reiserfs_panic(p_s_tb->tb_sb,"PAP-8325: fix_nodes: Incorrect item number %d (in S0 - %d) in case of insert",
-			   n_item_num, B_NR_ITEMS(p_s_tbS0));
-#else
     case M_INSERT:
 	if ( n_item_num <= 0 || n_item_num > B_NR_ITEMS(p_s_tbS0) )
 	    reiserfs_panic(p_s_tb->tb_sb,"PAP-8330: fix_nodes: Incorrect item number %d (in S0 - %d) in case of insert",
 			   n_item_num, B_NR_ITEMS(p_s_tbS0));
-#endif
 	break;
     case M_PASTE:
     case M_DELETE:
@@ -2754,151 +2672,10 @@
 	    brelse (tb->used[i]);
 	}
     }
-
-#if 0 /* shouldn't this be in CONFIG_REISERFS_CHECK??? */
-    /* make sure, that all we have released got really freed */
-    for (i = 0; i < sizeof (tb->thrown) / sizeof (tb->thrown[0]); i ++)
-	if (tb->thrown[i]) {
-	    if (atomic_read (&(tb->thrown[i]->b_count))) {
-		/* the log will have the count at one and the buffers marked */
-		if (atomic_read(&(tb->thrown[i]->b_count)) > 1 || 
-		    !(buffer_journaled(tb->thrown[i]) || 
-		      buffer_journal_dirty(tb->thrown[i]))) {
-		    foo_print (tb->thrown[i], tb->tb_sb);
-		    printk ("unfix_nodes: Waiting...(block %lu, count %d)\n", 
-			    tb->thrown[i]->b_blocknr, 
-			    atomic_read (&(tb->thrown[i]->b_count)));
-		    wait_buffer_until_released (tb->thrown[i]);
-		    printk ("unfix_nodes: Done (block %lu, count %d)\n", 
-			    tb->thrown[i]->b_blocknr, 
-			    atomic_read (&(tb->thrown[i]->b_count)));
-		}
-	    }
-	}
-#endif /* 0 */
     if (tb->vn_buf) 
 	reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
 
 } 
-
-
-
-#ifndef REISERFS_FSCK
-
-// is_left_mergeable is now one of the item methods
-
-#else
-
-// this works only in fsck
-
-int are_items_mergeable (struct item_head * left, struct item_head * right, int bsize)
-{
-  if (comp_keys (&left->ih_key, &right->ih_key) != -1) {
-    reiserfs_panic (0, "vs-16070: are_items_mergeable: left %k, right %k", &(left->ih_key), &(right->ih_key));
-  }
-
-  if (comp_short_keys (&left->ih_key, &right->ih_key))
-    return 0;
-
-  if (I_IS_DIRECTORY_ITEM (left)) {
-    return 1;
-  }
-
-  if ((I_IS_DIRECT_ITEM (left) && I_IS_DIRECT_ITEM (right)) || 
-      (I_IS_INDIRECT_ITEM (left) && I_IS_INDIRECT_ITEM (right)))
-    return (left->ih_key.k_offset + I_BYTES_NUMBER (left, bsize) == right->ih_key.k_offset) ? 1 : 0;
-
-  return 0;
-}
-
-/* get left neighbor of the leaf node */
-static struct buffer_head * get_left_neighbor (struct super_block * s, struct path * path)
-{
-  struct key key;
-  INITIALIZE_PATH (path_to_left_neighbor);
-  struct buffer_head * bh;
-
-  copy_key (&key, B_N_PKEY (PATH_PLAST_BUFFER (path), 0));
-  decrement_key (&key);
-
-/*  init_path (&path_to_left_neighbor);*/
-  search_by_key (s, &key, &path_to_left_neighbor, DISK_LEAF_NODE_LEVEL, READ_BLOCKS);
-  // FIXME: fsck is to handle I/O failures somehow as well
-  if (PATH_LAST_POSITION (&path_to_left_neighbor) == 0) {
-    pathrelse (&path_to_left_neighbor);
-    return 0;
-  }
-  bh = PATH_PLAST_BUFFER (&path_to_left_neighbor);
-  bh->b_count ++;
-  pathrelse (&path_to_left_neighbor);
-  return bh;
-}
-
-extern struct key  MIN_KEY;
-static struct buffer_head * get_right_neighbor (struct super_block * s, struct path * path)
-{
-  struct key key;
-  struct key * rkey;
-  INITIALIZE_PATH (path_to_right_neighbor);
-  struct buffer_head * bh;
-
-  rkey = get_rkey (path, s);
-  if (comp_keys (rkey, &MIN_KEY) == 0)
-    reiserfs_panic (s, "vs-16080: get_right_neighbor: get_rkey returned min key (path has changed)");
-  copy_key (&key, rkey);
-
-  
-  /*init_path (&path_to_right_neighbor);*/
-  search_by_key (s, &key, &path_to_right_neighbor, DISK_LEAF_NODE_LEVEL, READ_BLOCKS);
-  if (PATH_PLAST_BUFFER (&path_to_right_neighbor) == PATH_PLAST_BUFFER (path)) {
-    pathrelse (&path_to_right_neighbor);
-    return 0;
-  }
-  bh = PATH_PLAST_BUFFER (&path_to_right_neighbor);
-  bh->b_count ++;
-  pathrelse (&path_to_right_neighbor);
-  return bh;
-}
-
-
-int is_left_mergeable (struct super_block * s, struct path * path)
-{
-  struct item_head * right;
-  struct buffer_head * bh;
-  int retval;
-  
-  right = B_N_PITEM_HEAD (PATH_PLAST_BUFFER (path), 0);
-
-  bh = get_left_neighbor (s, path);
-  if (bh == 0) {
-    return 0;
-  }
-  retval = are_items_mergeable (B_N_PITEM_HEAD (bh, B_NR_ITEMS (bh) - 1), right, bh->b_size);
-  brelse (bh);
-  return retval;
-}
-
-
-int is_right_mergeable (struct super_block * s, struct path * path)
-{
-  struct item_head * left;
-  struct buffer_head * bh;
-  int retval;
-  
-  left = B_N_PITEM_HEAD (PATH_PLAST_BUFFER (path), B_NR_ITEMS (PATH_PLAST_BUFFER (path)) - 1);
-
-  bh = get_right_neighbor (s, path);
-  if (bh == 0) {
-    return 0;
-  }
-  retval = are_items_mergeable (left, B_N_PITEM_HEAD (bh, 0), bh->b_size);
-  brelse (bh);
-  return retval;
-}
-
-#endif /* REISERFS_FSCK */
-
-
 
 
 
diff -urN linux-2.4.10-pre5/fs/reiserfs/hashes.c linux/fs/reiserfs/hashes.c
--- linux-2.4.10-pre5/fs/reiserfs/hashes.c	Mon Jan 15 12:42:32 2001
+++ linux/fs/reiserfs/hashes.c	Mon Dec  3 23:08:14 2001
@@ -26,10 +26,6 @@
 #define FULLROUNDS 10		/* 32 is overkill, 16 is strong crypto */
 #define PARTROUNDS 6		/* 6 gets complete mixing */
 
-#ifndef __KERNEL__
-typedef __u32 u32;
-#endif
-
 /* a, b, c, d - data; h0, h1 - accumulated hash */
 #define TEACORE(rounds)							\
 	do {								\
diff -urN linux-2.4.10-pre5/fs/reiserfs/ibalance.c linux/fs/reiserfs/ibalance.c
--- linux-2.4.10-pre5/fs/reiserfs/ibalance.c	Mon Jan 15 15:31:19 2001
+++ linux/fs/reiserfs/ibalance.c	Mon Dec  3 23:08:14 2001
@@ -2,21 +2,12 @@
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
 
-#else
-
-#include "nokernel.h"
-
-#endif
-
-
 /* this is one and only function that is used outside (do_balance.c) */
 int	balance_internal (
 			  struct tree_balance * ,
@@ -1103,25 +1094,11 @@
 
     n = B_NR_ITEMS (tbSh); /*number of items in S[h] */
 
-#ifdef REISERFS_FSCK
-    if ( -1 <= child_pos && child_pos <= n && insert_num > 0 ) {
-#else
 	if ( 0 <= child_pos && child_pos <= n && insert_num > 0 ) {
-#endif
 	    bi.tb = tb;
 	    bi.bi_bh = tbSh;
 	    bi.bi_parent = PATH_H_PPARENT (tb->tb_path, h);
 	    bi.bi_position = PATH_H_POSITION (tb->tb_path, h + 1);
-#ifdef REISERFS_FSCK
-	    if (child_pos == -1) {
-		/* this is a little different from original do_balance: 
-		   here we insert the minimal keys in the tree, that has never happened when file system works */
-		if (tb->CFL[h-1] || insert_num != 1 || h != 1)
-		    die ("balance_internal: invalid child_pos");
-/*      insert_child (tb->S[h], tb->S[h-1], child_pos, insert_num, B_N_ITEM_HEAD(tb->S[0],0), insert_ptr);*/
-		internal_insert_childs (&bi, child_pos, insert_num, B_N_PITEM_HEAD (PATH_PLAST_BUFFER (tb->tb_path), 0), insert_ptr);
-	    } else
-#endif
 		internal_insert_childs (
 		    &bi,/*tbSh,*/
 		    /*		( tb->S[h-1]->b_parent == tb->S[h] ) ? tb->S[h-1]->b_next :  tb->S[h]->b_child->b_next,*/
diff -urN linux-2.4.10-pre5/fs/reiserfs/inode.c linux/fs/reiserfs/inode.c
--- linux-2.4.10-pre5/fs/reiserfs/inode.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/reiserfs/inode.c	Mon Dec  3 23:08:14 2001
@@ -1,7 +1,6 @@
 /*
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
-#ifdef __KERNEL__
 
 #include <linux/config.h>
 #include <linux/sched.h>
@@ -9,12 +8,6 @@
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
 
 /* args for the create parameter of reiserfs_get_block */
 #define GET_BLOCK_NO_CREATE 0 /* don't create new blocks or convert tails */
diff -urN linux-2.4.10-pre5/fs/reiserfs/ioctl.c linux/fs/reiserfs/ioctl.c
--- linux-2.4.10-pre5/fs/reiserfs/ioctl.c	Wed Mar 21 20:28:56 2001
+++ linux/fs/reiserfs/ioctl.c	Mon Dec  3 23:08:14 2001
@@ -2,20 +2,12 @@
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
 
-#ifdef __KERNEL__
-
 #include <linux/fs.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
 #include <linux/smp_lock.h>
 #include <linux/locks.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
 
 /*
 ** reiserfs_ioctl - handler for ioctl for inode
diff -urN linux-2.4.10-pre5/fs/reiserfs/item_ops.c linux/fs/reiserfs/item_ops.c
--- linux-2.4.10-pre5/fs/reiserfs/item_ops.c	Mon Jan 15 12:42:32 2001
+++ linux/fs/reiserfs/item_ops.c	Mon Dec  3 23:08:14 2001
@@ -2,18 +2,9 @@
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
 
-#ifdef __KERNEL__
-
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
 
-#else
-
-#include "nokernel.h"
-
-#endif
-
-
 // this contains item handlers for old item types: sd, direct,
 // indirect, directory
 
@@ -46,14 +37,7 @@
 {
     static char timebuf[256];
 
-#ifndef __KERNEL__
-//    struct tm *loctime;
-//    loctime = localtime (&t);
-    sprintf (timebuf, "%s", asctime (localtime (&t)));
-    timebuf[strlen (timebuf) - 1] = 0;
-#else
     sprintf (timebuf, "%ld", t);
-#endif
     return timebuf;
 }
 
diff -urN linux-2.4.10-pre5/fs/reiserfs/journal.c linux/fs/reiserfs/journal.c
--- linux-2.4.10-pre5/fs/reiserfs/journal.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/reiserfs/journal.c	Mon Dec  3 23:08:14 2001
@@ -41,8 +41,6 @@
 **                      log blocks to hit disk if it doesn't want to.
 */
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -61,13 +59,6 @@
 #include <linux/string.h>
 #include <linux/smp_lock.h>
 
-#else
-
-#include "nokernel.h"
-
-#endif
-
-
 /* the number of mounted filesystems.  This is used to decide when to
 ** start and kill the commit thread
 */
@@ -2333,7 +2324,6 @@
   return do_journal_end(th, p_s_sb, nblocks, COMMIT_NOW | WAIT) ;
 }
 
-#ifdef __KERNEL__
 int show_reiserfs_locks(void) {
 
   dump_journal_writers() ;
@@ -2353,7 +2343,6 @@
 #endif
   return 0 ;
 }
-#endif
 
 /*
 ** used to get memory back from async commits that are floating around
diff -urN linux-2.4.10-pre5/fs/reiserfs/lbalance.c linux/fs/reiserfs/lbalance.c
--- linux-2.4.10-pre5/fs/reiserfs/lbalance.c	Mon Jan 15 15:31:19 2001
+++ linux/fs/reiserfs/lbalance.c	Mon Dec  3 23:08:14 2001
@@ -2,20 +2,12 @@
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
 
-#else
-
-#include "nokernel.h"
-
-#endif
-
 /* these are used in do_balance.c */
 
 /* leaf_move_items
@@ -66,13 +58,8 @@
 
     /* if there are no items in dest or the first/last item in dest is not item of the same directory */
     if ( (item_num_in_dest == - 1) ||
-#ifdef REISERFS_FSCK
-	 (last_first == FIRST_TO_LAST && are_items_mergeable (B_N_PITEM_HEAD (dest, item_num_in_dest), ih, dest->b_size) == 0) ||
-	 (last_first == LAST_TO_FIRST && are_items_mergeable (ih, B_N_PITEM_HEAD (dest, item_num_in_dest), dest->b_size) == 0)) {
-#else
 	(last_first == FIRST_TO_LAST && le_key_k_offset (ih_version (ih), &(ih->ih_key)) == DOT_OFFSET) ||
 	    (last_first == LAST_TO_FIRST && comp_short_le_keys/*COMP_SHORT_KEYS*/ (&ih->ih_key, B_N_PKEY (dest, item_num_in_dest)))) {
-#endif
 	/* create new item in dest */
 	struct item_head new_ih;
 
@@ -135,11 +122,7 @@
        that we copy, so we return */
     ih = B_N_PITEM_HEAD (src, 0);
     dih = B_N_PITEM_HEAD (dest, dest_nr_item - 1);
-#ifdef REISERFS_FSCK
-    if (!dest_nr_item || (are_items_mergeable (dih, ih, src->b_size) == 0))
-#else
     if (!dest_nr_item || (!op_is_left_mergeable (&(ih->ih_key), src->b_size)))
-#endif
       /* there is nothing to merge */
       return 0;
       
@@ -202,11 +185,7 @@
   ih = B_N_PITEM_HEAD (src, src_nr_item - 1);
   dih = B_N_PITEM_HEAD (dest, 0);
 
-#ifdef REISERFS_FSCK
-  if (!dest_nr_item || are_items_mergeable (ih, dih, src->b_size) == 0)
-#else
   if (!dest_nr_item || !op_is_left_mergeable (&(dih->ih_key), src->b_size))
-#endif
     return 0;
   
   if ( is_direntry_le_ih (ih)) {
diff -urN linux-2.4.10-pre5/fs/reiserfs/namei.c linux/fs/reiserfs/namei.c
--- linux-2.4.10-pre5/fs/reiserfs/namei.c	Wed Jul 18 07:46:02 2001
+++ linux/fs/reiserfs/namei.c	Mon Dec  3 23:08:14 2001
@@ -11,19 +11,11 @@
  * NO WARRANTY
  */
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
 
 				/* there should be an overview right
                                    here, as there should be in every
diff -urN linux-2.4.10-pre5/fs/reiserfs/objectid.c linux/fs/reiserfs/objectid.c
--- linux-2.4.10-pre5/fs/reiserfs/objectid.c	Fri Apr 27 14:18:08 2001
+++ linux/fs/reiserfs/objectid.c	Mon Dec  3 23:08:14 2001
@@ -1,19 +1,12 @@
 /*
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
-#ifdef __KERNEL__
 
 #include <linux/config.h>
 #include <linux/string.h>
 #include <linux/locks.h>
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
 
 
 // find where objectid map starts
diff -urN linux-2.4.10-pre5/fs/reiserfs/prints.c linux/fs/reiserfs/prints.c
--- linux-2.4.10-pre5/fs/reiserfs/prints.c	Wed May 16 10:31:27 2001
+++ linux/fs/reiserfs/prints.c	Mon Dec  3 23:08:14 2001
@@ -1,7 +1,6 @@
 /*
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
-#ifdef __KERNEL__
 
 #include <linux/config.h>
 #include <linux/sched.h>
@@ -9,13 +8,6 @@
 #include <linux/reiserfs_fs.h>
 #include <linux/string.h>
 
-#else
-
-#include "nokernel.h"
-#include <limits.h>
-
-#endif
-
 #include <stdarg.h>
 
 static char error_buf[1024];
@@ -324,17 +316,13 @@
 
 void reiserfs_panic (struct super_block * sb, const char * fmt, ...)
 {
-#ifdef __KERNEL__
   show_reiserfs_locks() ;
-#endif
   do_reiserfs_warning;
   printk ("%s", error_buf);
   BUG ();
   // console_print (error_buf);
   // for (;;);
 
-#ifdef __KERNEL__
-
   /* comment before release */
   //for (;;);
 
@@ -354,9 +342,6 @@
 
   panic ("REISERFS: panic (device %s): %s\n",
 	 sb ? kdevname(sb->s_dev) : "sb == 0", error_buf);
-#else
-  exit (0);
-#endif
 }
 
 
@@ -676,142 +661,6 @@
 {
     printk ("%s\n%s", mes, print_tb_buf);
 }
-
-
-#ifndef __KERNEL__
-
-void print_bmap_block (int i, char * data, int size, int silent)
-{
-    int j, k;
-    int bits = size * 8;
-    int zeros = 0, ones = 0;
-  
-
-    if (test_bit (0, data)) {
-	/* first block addressed by this bitmap block is used */
-	ones ++;
-	if (!silent)
-	    printf ("Busy (%d-", i * bits);
-	for (j = 1; j < bits; j ++) {
-	    while (test_bit (j, data)) {
-		ones ++;
-		if (j == bits - 1) {
-		    if (!silent)
-			printf ("%d)\n", j + i * bits);
-		    goto end;
-		}
-		j++;
-	    }
-	    if (!silent)
-		printf ("%d) Free(%d-", j - 1 + i * bits, j + i * bits);
-
-	    while (!test_bit (j, data)) {
-		zeros ++;
-		if (j == bits - 1) {
-		    if (!silent)
-			printf ("%d)\n", j + i * bits);
-		    goto end;
-		}
-		j++;
-	    }
-	    if (!silent)
-		printf ("%d) Busy(%d-", j - 1 + i * bits, j + i * bits);
-
-	    j --;
-	end:
-	}
-    } else {
-	/* first block addressed by this bitmap is free */
-	zeros ++;
-	if (!silent)
-	    printf ("Free (%d-", i * bits);
-	for (j = 1; j < bits; j ++) {
-	    k = 0;
-	    while (!test_bit (j, data)) {
-		k ++;
-		if (j == bits - 1) {
-		    if (!silent)
-			printf ("%d)\n", j + i * bits);
-		    zeros += k;
-		    goto end2;
-		}
-		j++;
-	    }
-	    zeros += k;
-	    if (!silent)
-		printf ("%d) Busy(%d-", j - 1 + i * bits, j + i * bits);
-	    
-	    k = 0;
-	    while (test_bit (j, data)) {
-		ones ++;
-		if (j == bits - 1) {
-		    if (!silent)
-			printf ("%d)\n", j + i * bits);
-		    ones += k;
-		    goto end2;
-		}
-		j++;
-	    }
-	    ones += k;
-	    if (!silent)
-		printf ("%d) Busy(%d-", j - 1 + i * bits, j + i * bits);
-	
-	    j --;
-	end2:
-	}
-    }
-
-    printf ("used %d, free %d\n", ones, zeros);
-}
-
-
-/* if silent == 1, do not print details */
-void print_bmap (struct super_block * s, int silent)
-{
-    int bmapnr = SB_BMAP_NR (s);
-    int i;
-
-    printf ("Bitmap blocks are:\n");
-    for (i = 0; i < bmapnr; i ++) {
-	printf ("#%d: block %lu: ", i, SB_AP_BITMAP(s)[i]->b_blocknr);
-	print_bmap_block (i, SB_AP_BITMAP(s)[i]->b_data, s->s_blocksize, silent);
-    }
-
-}
-
-
-
-
-void print_objectid_map (struct super_block * s)
-{
-  int i;
-  struct reiserfs_super_block * rs;
-  unsigned long * omap;
-
-  rs = SB_DISK_SUPER_BLOCK (s);
-  omap = (unsigned long *)(rs + 1);
-  printk ("Map of objectids\n");
-      
-  for (i = 0; i < rs->s_oid_cursize; i ++) {
-    if (i % 2 == 0)
-      printk ("busy(%lu-%lu) ", omap[i], omap[i+1] - 1); 
-    else
-      printk ("free(%lu-%lu) ", 
-	      omap[i], ((i+1) == rs->s_oid_cursize) ? -1 : omap[i+1] - 1);
-    }
-  printk ("\n");
-  
-  printk ("Object id array has size %d (max %d):", rs->s_oid_cursize, 
-	  rs->s_oid_maxsize);
-  
-  for (i = 0; i < rs->s_oid_cursize; i ++)
-    printk ("%lu ", omap[i]); 
-  printk ("\n");
-
-}
-
-#endif	/* #ifndef __KERNEL__ */
-
 
 static void check_leaf_block_head (struct buffer_head * bh)
 {
diff -urN linux-2.4.10-pre5/fs/reiserfs/resize.c linux/fs/reiserfs/resize.c
--- linux-2.4.10-pre5/fs/reiserfs/resize.c	Mon Jan 15 12:42:32 2001
+++ linux/fs/reiserfs/resize.c	Mon Dec  3 23:08:14 2001
@@ -8,8 +8,6 @@
  * The kernel part of the (on-line) reiserfs resizer.
  */
 
-#ifdef __KERNEL__
-
 #include <linux/kernel.h>
 #include <linux/vmalloc.h>
 #include <linux/locks.h>
@@ -17,12 +15,6 @@
 #include <linux/errno.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/reiserfs_fs_sb.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
 
 int reiserfs_resize (struct super_block * s, unsigned long block_count_new)
 {
diff -urN linux-2.4.10-pre5/fs/reiserfs/stree.c linux/fs/reiserfs/stree.c
--- linux-2.4.10-pre5/fs/reiserfs/stree.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/reiserfs/stree.c	Mon Dec  3 23:08:14 2001
@@ -52,7 +52,6 @@
  * reiserfs_paste_into_item
  * reiserfs_insert_item
  */
-#ifdef __KERNEL__
 
 #include <linux/config.h>
 #include <linux/sched.h>
@@ -62,14 +61,6 @@
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
 
-#else
-
-#include "nokernel.h"
-
-#endif
-
-
-
 /* Does the buffer contain a disk block which is in the tree. */
 inline int B_IS_IN_TREE (struct buffer_head * p_s_bh)
 {
@@ -1212,10 +1203,6 @@
 		    /* Block is locked or held more than by one holder and by
                        journal. */
 
-#ifndef __KERNEL__
-		    reiserfs_panic(p_s_sb, "PAP-5270: prepare_for_delete_or_cut: b_count != 1");
-#endif
-
 #ifdef CONFIG_REISERFS_CHECK
 		    if (n_repeat_counter && (n_repeat_counter % 100000) == 0) {
 		      printk("prepare_for_delete, waiting on buffer %lu, b_count %d, %s%cJDIRTY %cJDIRTY_WAIT\n", 
@@ -1280,11 +1267,9 @@
 		}
 #endif
 
-#ifdef __KERNEL__
 		run_task_queue(&tq_disk);
 		current->policy |= SCHED_YIELD;
 		schedule();
-#endif
 	    }
 	    /* This loop can be optimized. */
 	} while ( (*p_n_removed < n_unfm_number || need_research) &&
diff -urN linux-2.4.10-pre5/fs/reiserfs/super.c linux/fs/reiserfs/super.c
--- linux-2.4.10-pre5/fs/reiserfs/super.c	Mon Dec  3 23:08:04 2001
+++ linux/fs/reiserfs/super.c	Mon Dec  3 23:08:14 2001
@@ -11,8 +11,6 @@
  * NO WARRANTY
  */
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -22,14 +20,6 @@
 #include <linux/locks.h>
 #include <linux/init.h>
 
-#else
-
-#include "nokernel.h"
-#include <stdlib.h> // for simple_strtoul
-
-#endif
-
-
 #define REISERFS_OLD_BLOCKSIZE 4096
 #define REISERFS_SUPER_MAGIC_STRING_OFFSET_NJ 20
 
@@ -806,8 +796,6 @@
   return 0;
 }
 
-#ifdef __KERNEL__
-
 static DECLARE_FSTYPE_DEV(reiserfs_fs_type,"reiserfs",reiserfs_read_super);
 
 //
@@ -830,8 +818,6 @@
 
 module_init(init_reiserfs_fs) ;
 module_exit(exit_reiserfs_fs) ;
-
-#endif
 
 
 
diff -urN linux-2.4.10-pre5/fs/reiserfs/tail_conversion.c linux/fs/reiserfs/tail_conversion.c
--- linux-2.4.10-pre5/fs/reiserfs/tail_conversion.c	Thu Apr 26 10:44:10 2001
+++ linux/fs/reiserfs/tail_conversion.c	Mon Dec  3 23:08:14 2001
@@ -2,20 +2,11 @@
  * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright details
  */
 
-#ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/pagemap.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/locks.h>
-
-#else
-
-#include "nokernel.h"
-
-#endif
-
 
 /* access to tail : when one is going to read tail it must make sure, that is not running.
  direct2indirect and indirect2direct can not run concurrently */
diff -urN linux-2.4.10-pre5/include/asm-alpha/softirq.h linux/include/asm-alpha/softirq.h
--- linux-2.4.10-pre5/include/asm-alpha/softirq.h	Mon Jul  9 16:04:24 2001
+++ linux/include/asm-alpha/softirq.h	Mon Dec  3 23:08:14 2001
@@ -32,6 +32,4 @@
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
-#define __cpu_raise_softirq(cpu, nr) set_bit(nr, &softirq_pending(cpu))
-
 #endif /* _ALPHA_SOFTIRQ_H */
diff -urN linux-2.4.10-pre5/include/asm-arm/softirq.h linux/include/asm-arm/softirq.h
--- linux-2.4.10-pre5/include/asm-arm/softirq.h	Sun Aug 12 11:14:00 2001
+++ linux/include/asm-arm/softirq.h	Mon Dec  3 23:08:14 2001
@@ -21,6 +21,4 @@
 		__asm__("bl%? __do_softirq": : : "lr");/* out of line */\
 } while (0)
 
-#define __cpu_raise_softirq(cpu, nr) __set_bit(nr, &softirq_pending(cpu))
-
 #endif	/* __ASM_SOFTIRQ_H */
diff -urN linux-2.4.10-pre5/include/asm-cris/softirq.h linux/include/asm-cris/softirq.h
--- linux-2.4.10-pre5/include/asm-cris/softirq.h	Thu Jul 26 15:10:07 2001
+++ linux/include/asm-cris/softirq.h	Mon Dec  3 23:08:14 2001
@@ -27,6 +27,4 @@
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
-#define __cpu_raise_softirq(cpu,nr) set_bit((nr), &softirq_pending(cpu))
-
 #endif	/* __ASM_SOFTIRQ_H */
diff -urN linux-2.4.10-pre5/include/asm-i386/page.h linux/include/asm-i386/page.h
--- linux-2.4.10-pre5/include/asm-i386/page.h	Wed Aug 15 14:21:11 2001
+++ linux/include/asm-i386/page.h	Mon Dec  3 23:08:14 2001
@@ -87,7 +87,6 @@
  * see^H^H^Hhear bugs in early bootup as well!
  */
 #define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
 	__asm__ __volatile__(".byte 0x0f,0x0b"); \
 } while (0)
 
diff -urN linux-2.4.10-pre5/include/asm-i386/softirq.h linux/include/asm-i386/softirq.h
--- linux-2.4.10-pre5/include/asm-i386/softirq.h	Wed Aug 15 14:21:11 2001
+++ linux/include/asm-i386/softirq.h	Mon Dec  3 23:08:14 2001
@@ -45,6 +45,4 @@
 		/* no registers clobbered */ );				\
 } while (0)
 
-#define __cpu_raise_softirq(cpu, nr) __set_bit(nr, &softirq_pending(cpu))
-
 #endif	/* __ASM_SOFTIRQ_H */
diff -urN linux-2.4.10-pre5/include/asm-ia64/softirq.h linux/include/asm-ia64/softirq.h
--- linux-2.4.10-pre5/include/asm-ia64/softirq.h	Tue Jul 31 10:30:09 2001
+++ linux/include/asm-ia64/softirq.h	Mon Dec  3 23:08:14 2001
@@ -18,8 +18,6 @@
 } while (0)
 
 
-#define __cpu_raise_softirq(cpu,nr)	set_bit((nr), &softirq_pending(cpu))
-
 #define in_softirq()		(local_bh_count() != 0)
 
 #endif /* _ASM_IA64_SOFTIRQ_H */
diff -urN linux-2.4.10-pre5/include/asm-ppc/init.h linux/include/asm-ppc/init.h
--- linux-2.4.10-pre5/include/asm-ppc/init.h	Sun Aug 12 12:43:26 2001
+++ linux/include/asm-ppc/init.h	Wed Dec 31 16:00:00 1969
@@ -1,36 +0,0 @@
-/*
- * BK Id: SCCS/s.init.h 1.8 07/06/01 09:19:30 trini
- */
-#ifdef __KERNEL__
-#ifndef _PPC_INIT_H
-#define _PPC_INIT_H
-
-#include <linux/init.h>
-
-#define __pmac __attribute__ ((__section__ (".text.pmac")))
-#define __pmacdata __attribute__ ((__section__ (".data.pmac")))
-#define __pmacfunc(__argpmac) \
-	__argpmac __pmac; \
-	__argpmac
-	
-#define __prep __attribute__ ((__section__ (".text.prep")))
-#define __prepdata __attribute__ ((__section__ (".data.prep")))
-#define __prepfunc(__argprep) \
-	__argprep __prep; \
-	__argprep
-
-#define __chrp __attribute__ ((__section__ (".text.chrp")))
-#define __chrpdata __attribute__ ((__section__ (".data.chrp")))
-#define __chrpfunc(__argchrp) \
-	__argchrp __chrp; \
-	__argchrp
-
-/* this is actually just common chrp/pmac code, not OF code -- Cort */
-#define __openfirmware __attribute__ ((__section__ (".text.openfirmware")))
-#define __openfirmwaredata __attribute__ ((__section__ (".data.openfirmware")))
-#define __openfirmwarefunc(__argopenfirmware) \
-	__argopenfirmware __openfirmware; \
-	__argopenfirmware
-	
-#endif /* _PPC_INIT_H */
-#endif /* __KERNEL__ */
diff -urN linux-2.4.10-pre5/include/asm-ppc/ppcboot.h linux/include/asm-ppc/ppcboot.h
--- linux-2.4.10-pre5/include/asm-ppc/ppcboot.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/ppcboot.h	Mon Dec  3 23:08:14 2001
@@ -0,0 +1,93 @@
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _PPCBOOT_H_
+#define _PPCBOOT_H_	1
+
+/*
+ * Board information passed to kernel from PPCBoot
+ *
+ * include/asm-ppc/ppcboot.h
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+typedef void (interrupt_handler_t)(void *);
+
+typedef struct monitor_functions {
+	int	(*getc)(void);
+	int	(*tstc)(void);
+	void	(*putc)(const char c);
+	void	(*puts)(const char *s);
+	void	(*printf)(const char *fmt, ...);
+	void	(*install_hdlr)(int, interrupt_handler_t *, void *);
+	void	(*free_hdlr)(int);
+	void	*(*malloc)(size_t);
+	void	(*free)(void *);
+} mon_fnc_t;
+
+typedef struct bd_info {
+	unsigned long	bi_memstart;	/* start of  DRAM memory		*/
+	unsigned long	bi_memsize;	/* size	 of  DRAM memory in bytes	*/
+	unsigned long	bi_flashstart;	/* start of FLASH memory		*/
+	unsigned long	bi_flashsize;	/* size	 of FLASH memory		*/
+	unsigned long	bi_flashoffset; /* reserved area for startup monitor	*/
+	unsigned long	bi_sramstart;	/* start of  SRAM memory		*/
+	unsigned long	bi_sramsize;	/* size	 of  SRAM memory		*/
+#if defined(CONFIG_8xx) || defined(CONFIG_8260)
+	unsigned long	bi_immr_base;	/* base of IMMR register		*/
+#endif
+	unsigned long	bi_bootflags;	/* boot / reboot flag (for LynxOS)	*/
+	unsigned long	bi_ip_addr;	/* IP Address				*/
+	unsigned char	bi_enetaddr[6]; /* Ethernet adress			*/
+	unsigned short	bi_ethspeed;	/* Ethernet speed in Mbps		*/
+	unsigned long	bi_intfreq;	/* Internal Freq, in MHz		*/
+	unsigned long	bi_busfreq;	/* Bus Freq, in MHz			*/
+#if defined(CONFIG_8260)
+	unsigned long	bi_cpmfreq;	/* CPM_CLK Freq, in MHz			*/
+	unsigned long	bi_brgfreq;	/* BRG_CLK Freq, in MHz			*/
+	unsigned long	bi_sccfreq;	/* SCC_CLK Freq, in MHz			*/
+	unsigned long	bi_vco;		/* VCO Out from PLL, in MHz		*/
+#endif
+	unsigned long	bi_baudrate;	/* Console Baudrate			*/
+#if defined(CONFIG_PPC405)
+	unsigned char	bi_s_version[4];  /* Version of this structure		*/
+	unsigned char	bi_r_version[32]; /* Version of the ROM (IBM)		*/
+	unsigned int	bi_procfreq;	/* CPU (Internal) Freq, in Hz		*/
+	unsigned int	bi_plb_busfreq;	/* PLB Bus speed, in Hz */
+	unsigned int	bi_pci_busfreq;	/* PCI Bus speed, in Hz */
+	unsigned char	bi_pci_enetaddr[6];	/* PCI Ethernet MAC address     */
+#endif
+#if defined(CONFIG_HYMOD)
+	hymod_conf_t	bi_hymod_conf;	/* hymod configuration information	*/
+#endif
+#if defined(CONFIG_EVB64260)
+	/* the board has three onboard ethernet ports */
+	unsigned char   bi_enet1addr[6];
+	unsigned char   bi_enet2addr[6];
+#endif
+	mon_fnc_t	*bi_mon_fnc;	/* Pointer to monitor functions		*/
+} bd_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif	/* _PPCBOOT_H_ */
diff -urN linux-2.4.10-pre5/include/asm-ppc/sections.h linux/include/asm-ppc/sections.h
--- linux-2.4.10-pre5/include/asm-ppc/sections.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/sections.h	Mon Dec  3 23:08:14 2001
@@ -0,0 +1,34 @@
+/*
+ * BK Id: SCCS/s.sections.h 1.11 09/08/01 15:47:43 paulus
+ */
+#ifdef __KERNEL__
+#ifndef _PPC_SECTIONS_H
+#define _PPC_SECTIONS_H
+
+#define __pmac __attribute__ ((__section__ (".text.pmac")))
+#define __pmacdata __attribute__ ((__section__ (".data.pmac")))
+#define __pmacfunc(__argpmac) \
+	__argpmac __pmac; \
+	__argpmac
+	
+#define __prep __attribute__ ((__section__ (".text.prep")))
+#define __prepdata __attribute__ ((__section__ (".data.prep")))
+#define __prepfunc(__argprep) \
+	__argprep __prep; \
+	__argprep
+
+#define __chrp __attribute__ ((__section__ (".text.chrp")))
+#define __chrpdata __attribute__ ((__section__ (".data.chrp")))
+#define __chrpfunc(__argchrp) \
+	__argchrp __chrp; \
+	__argchrp
+
+/* this is actually just common chrp/pmac code, not OF code -- Cort */
+#define __openfirmware __attribute__ ((__section__ (".text.openfirmware")))
+#define __openfirmwaredata __attribute__ ((__section__ (".data.openfirmware")))
+#define __openfirmwarefunc(__argopenfirmware) \
+	__argopenfirmware __openfirmware; \
+	__argopenfirmware
+	
+#endif /* _PPC_SECTIONS_H */
+#endif /* __KERNEL__ */
diff -urN linux-2.4.10-pre5/include/asm-ppc/softirq.h linux/include/asm-ppc/softirq.h
--- linux-2.4.10-pre5/include/asm-ppc/softirq.h	Wed Jul 18 07:14:01 2001
+++ linux/include/asm-ppc/softirq.h	Mon Dec  3 23:08:14 2001
@@ -28,8 +28,6 @@
 	}						\
 } while (0)
 
-#define __cpu_raise_softirq(cpu, nr) set_bit((nr), &softirq_pending(cpu));
-
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif	/* __ASM_SOFTIRQ_H */
diff -urN linux-2.4.10-pre5/include/asm-ppc/tqm8xx.h linux/include/asm-ppc/tqm8xx.h
--- linux-2.4.10-pre5/include/asm-ppc/tqm8xx.h	Mon Dec  3 23:08:04 2001
+++ linux/include/asm-ppc/tqm8xx.h	Mon Dec  3 23:08:14 2001
@@ -1,72 +1,54 @@
 /*
- * BK Id: SCCS/s.tqm8xx.h 1.7 08/17/01 15:23:17 paulus
+ * BK Id: SCCS/s.tqm8xx.h 1.8 08/30/01 09:01:04 trini
  */
 /*
- * A collection of structures, addresses, and values associated with
- * the TQ Systems TQM8xx(L) modules.  This was originally created for the
- * MBX860, and probably needs revisions for other boards (like the 821).
- * When this file gets out of control, we can split it up into more
- * meaningful pieces.
- *
- * Based on mbx.h, Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
- *
- * Copyright (c) 1999,2000 Wolfgang Denk (wd@denx.de)
+ * TQM8xx(L) board specific definitions
+ * 
+ * Copyright (c) 1999,2000,2001 Wolfgang Denk (wd@denx.de)
  */
-#ifndef __MACH_TQM8xx_DEFS
-#define __MACH_TQM8xx_DEFS
 
-#include <linux/config.h>
+#ifndef __MACH_TQM8xx_H
+#define __MACH_TQM8xx_H
 
-#ifndef __ASSEMBLY__
+#include <linux/config.h>
+ 
+#include <asm/ppcboot.h>
 
-typedef	void (interrupt_handler_t)(void *);
+#define	TQM_IMMR_BASE	0xFFF00000	/* phys. addr of IMMR */
+#define	TQM_IMAP_SIZE	(64 * 1024)	/* size of mapped area */
 
-typedef struct serial_io {
-	int	(*getc)(void);
-	int	(*tstc)(void);
-	void	(*putc)(const char c);
-	void	(*printf)(const char *fmt, ...);
-} serial_io_t;
+#define	IMAP_ADDR	TQM_IMMR_BASE	/* physical base address of IMMR area */
+#define IMAP_SIZE	TQM_IMAP_SIZE	/* mapped size of IMMR area */
 
-typedef struct intr_util {
-	void	(*install_hdlr)(int, interrupt_handler_t *, void *);
-	void	(*free_hdlr)(int);
-} intr_util_t;
+/*-----------------------------------------------------------------------
+ * PCMCIA stuff
+ *-----------------------------------------------------------------------
+ *
+ */
+#define PCMCIA_MEM_SIZE		( 64 << 20 )
 
+#define	MAX_HWIFS	1	/* overwrite default in include/asm-ppc/ide.h */
 
-/* A Board Information structure that is given to a program when
- * ppcboot starts it up.
+/*
+ * Definitions for IDE0 Interface
  */
-typedef struct bd_info {
-	 unsigned long	bi_memstart;	/* start of  DRAM memory		*/
-	 unsigned long	bi_memsize;	/* size	 of  DRAM memory in bytes	*/
-	 unsigned long	bi_flashstart;	/* start of FLASH memory		*/
-	 unsigned long	bi_flashsize;	/* size	 of FLASH memory		*/
-	 unsigned long	bi_flashoffset; /* reserved area for startup monitor	*/
-	 unsigned long	bi_sramstart;	/* start of  SRAM memory		*/
-	 unsigned long	bi_sramsize;	/* size	 of  SRAM memory		*/
-	 unsigned long	bi_immr_base;	/* base of IMMR register		*/
-	 unsigned long	bi_bootflags;	/* boot / reboot flag (for LynxOS)	*/
-	 unsigned long	bi_ip_addr;	/* IP Address				*/
-	 unsigned char	bi_enetaddr[6]; /* Ethernet adress			*/
-	 unsigned char	bi_reserved[2]; /* -- just for alignment --		*/
-	 unsigned long	bi_intfreq;	/* Internal Freq, in MHz		*/
-	 unsigned long	bi_busfreq;	/* Bus Freq, in MHz			*/
-	 unsigned long	bi_baudrate;	/* Console Baudrate			*/
-	 serial_io_t	bi_serial_io;	/* Addr of monitor fnc for Console I/O	*/
-	 intr_util_t	bi_interrupt;	/* Addr of monitor fnc for Interrupts	*/
-} bd_t;
-
-#endif /* __ASSEMBLY__ */
+#define IDE0_BASE_OFFSET		0
+#define IDE0_DATA_REG_OFFSET		(PCMCIA_MEM_SIZE + 0x320)
+#define IDE0_ERROR_REG_OFFSET		(2 * PCMCIA_MEM_SIZE + 0x320 + 1)
+#define IDE0_NSECTOR_REG_OFFSET		(2 * PCMCIA_MEM_SIZE + 0x320 + 2)
+#define IDE0_SECTOR_REG_OFFSET		(2 * PCMCIA_MEM_SIZE + 0x320 + 3)
+#define IDE0_LCYL_REG_OFFSET		(2 * PCMCIA_MEM_SIZE + 0x320 + 4)
+#define IDE0_HCYL_REG_OFFSET		(2 * PCMCIA_MEM_SIZE + 0x320 + 5)
+#define IDE0_SELECT_REG_OFFSET		(2 * PCMCIA_MEM_SIZE + 0x320 + 6)
+#define IDE0_STATUS_REG_OFFSET		(2 * PCMCIA_MEM_SIZE + 0x320 + 7)
+#define IDE0_CONTROL_REG_OFFSET		0x0106
+#define IDE0_IRQ_REG_OFFSET		0x000A	/* not used */
 
-#define	TQM_IMMR_BASE	0xFFF00000	/* phys. addr of IMMR			*/
-#define	TQM_IMAP_SIZE	(64 * 1024)	/* size of mapped area			*/
+#define	IDE0_INTERRUPT			13
 
-#define	IMAP_ADDR	TQM_IMMR_BASE	/* physical base address of IMMR area	*/
-#define IMAP_SIZE	TQM_IMAP_SIZE	/* mapped size of IMMR area		*/
 
 /* We don't use the 8259.
 */
 #define NR_8259_INTS	0
 
-#endif	/* __MACH_TQM8xx_DEFS */
+#endif	/* __MACH_TQM8xx_H */
diff -urN linux-2.4.10-pre5/include/asm-s390/softirq.h linux/include/asm-s390/softirq.h
--- linux-2.4.10-pre5/include/asm-s390/softirq.h	Sun Aug 12 11:13:59 2001
+++ linux/include/asm-s390/softirq.h	Mon Dec  3 23:08:14 2001
@@ -36,8 +36,6 @@
 			do_softirq();					\
 } while (0)
 
-#define __cpu_raise_softirq(cpu, nr) (softirq_pending(cpu) |= (1<<nr))
-
 #endif	/* __ASM_SOFTIRQ_H */
 
 
diff -urN linux-2.4.10-pre5/include/asm-s390x/softirq.h linux/include/asm-s390x/softirq.h
--- linux-2.4.10-pre5/include/asm-s390x/softirq.h	Sun Aug 12 11:13:59 2001
+++ linux/include/asm-s390x/softirq.h	Mon Dec  3 23:08:14 2001
@@ -36,8 +36,6 @@
 			do_softirq();					\
 } while (0)
 
-#define __cpu_raise_softirq(cpu, nr) (softirq_pending(cpu) |= (1<<nr))
-
 #endif	/* __ASM_SOFTIRQ_H */
 
 
diff -urN linux-2.4.10-pre5/include/asm-sh/atomic.h linux/include/asm-sh/atomic.h
--- linux-2.4.10-pre5/include/asm-sh/atomic.h	Tue Oct  3 09:24:40 2000
+++ linux/include/asm-sh/atomic.h	Mon Dec  3 23:08:14 2001
@@ -93,4 +93,10 @@
 	restore_flags(flags);
 }
 
+/* Atomic operations are already serializing on SH */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
 #endif /* __ASM_SH_ATOMIC_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/cache.h linux/include/asm-sh/cache.h
--- linux-2.4.10-pre5/include/asm-sh/cache.h	Sat May 20 12:05:30 2000
+++ linux/include/asm-sh/cache.h	Mon Dec  3 23:08:14 2001
@@ -1,4 +1,4 @@
-/* $Id: cache.h,v 1.3 1999/12/11 12:31:51 gniibe Exp $
+/* $Id: cache.h,v 1.3 2000/07/04 06:24:49 gniibe Exp $
  *
  * include/asm-sh/cache.h
  *
diff -urN linux-2.4.10-pre5/include/asm-sh/checksum.h linux/include/asm-sh/checksum.h
--- linux-2.4.10-pre5/include/asm-sh/checksum.h	Mon Oct  2 11:57:34 2000
+++ linux/include/asm-sh/checksum.h	Mon Dec  3 23:08:14 2001
@@ -43,14 +43,14 @@
  *	If you use these functions directly please don't forget the 
  *	verify_area().
  */
-extern __inline__
+static __inline__
 unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
 					int len, int sum)
 {
 	return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
 }
 
-extern __inline__
+static __inline__
 unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
 						int len, int sum, int *err_ptr)
 {
diff -urN linux-2.4.10-pre5/include/asm-sh/dma.h linux/include/asm-sh/dma.h
--- linux-2.4.10-pre5/include/asm-sh/dma.h	Thu Aug 10 13:03:25 2000
+++ linux/include/asm-sh/dma.h	Mon Dec  3 23:08:14 2001
@@ -5,6 +5,7 @@
 #include <asm/io.h>		/* need byte IO */
 
 #define MAX_DMA_CHANNELS 8
+#define SH_MAX_DMA_CHANNELS 4
 
 /* The maximum address that we can perform a DMA transfer to on this platform */
 /* Don't define MAX_DMA_ADDRESS; it's useless on the SuperH and any
@@ -13,8 +14,78 @@
 /* XXX: This is not applicable to SuperH, just needed for alloc_bootmem */
 #define MAX_DMA_ADDRESS      (PAGE_OFFSET+0x10000000)
 
-extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);	/* release it again */
+#if defined(__sh3__)
+#define SAR ((unsigned long[]){0xa4000020,0xa4000030,0xa4000040,0xa4000050})
+#define DAR ((unsigned long[]){0xa4000024,0xa4000034,0xa4000044,0xa4000054})
+#define DMATCR ((unsigned long[]){0xa4000028,0xa4000038,0xa4000048,0xa4000058})
+#define CHCR ((unsigned long[]){0xa400002c,0xa400003c,0xa400004c,0xa400005c})
+#define DMAOR 0xa4000060UL
+#elif defined(__SH4__)
+#define SAR ((unsigned long[]){0xbfa00000,0xbfa00010,0xbfa00020,0xbfa00030})
+#define DAR ((unsigned long[]){0xbfa00004,0xbfa00014,0xbfa00024,0xbfa00034})
+#define DMATCR ((unsigned long[]){0xbfa00008,0xbfa00018,0xbfa00028,0xbfa00038})
+#define CHCR ((unsigned long[]){0xbfa0000c,0xbfa0001c,0xbfa0002c,0xbfa0003c})
+#define DMAOR 0xbfa00040UL
+#endif
+
+#define DMTE_IRQ ((int[]){DMTE0_IRQ,DMTE1_IRQ,DMTE2_IRQ,DMTE3_IRQ})
+
+#define DMA_MODE_READ	0x00	/* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE	0x01	/* memory to I/O, no autoinit, increment, single mode */
+#define DMA_AUTOINIT	0x10
+
+#define REQ_L	0x00000000
+#define REQ_E	0x00080000
+#define RACK_H	0x00000000
+#define RACK_L	0x00040000
+#define ACK_R	0x00000000
+#define ACK_W	0x00020000
+#define ACK_H	0x00000000
+#define ACK_L	0x00010000
+#define DM_INC	0x00004000
+#define DM_DEC	0x00008000
+#define SM_INC	0x00001000
+#define SM_DEC	0x00002000
+#define RS_DUAL	0x00000000
+#define RS_IN	0x00000200
+#define RS_OUT	0x00000300
+#define TM_BURST 0x0000080
+#define TS_8	0x00000010
+#define TS_16	0x00000020
+#define TS_32	0x00000030
+#define TS_64	0x00000000
+#define TS_BLK	0x00000040
+#define CHCR_DE 0x00000001
+#define CHCR_TE 0x00000002
+#define CHCR_IE 0x00000004
+
+#define DMAOR_COD	0x00000008
+#define DMAOR_AE	0x00000004
+#define DMAOR_NMIF	0x00000002
+#define DMAOR_DME	0x00000001
+
+struct dma_info_t {
+	unsigned int chan;
+	unsigned int mode_read;
+	unsigned int mode_write;
+	unsigned long dev_addr;
+	unsigned int mode;
+	unsigned long mem_addr;
+	unsigned int count;
+};
+
+static __inline__ void clear_dma_ff(unsigned int dmanr){}
+
+/* These are in arch/sh/kernel/dma.c: */
+extern unsigned long claim_dma_lock(void);
+extern void release_dma_lock(unsigned long flags);
+extern void setup_dma(unsigned int dmanr, struct dma_info_t *info);
+extern void enable_dma(unsigned int dmanr);
+extern void disable_dma(unsigned int dmanr);
+extern void set_dma_mode(unsigned int dmanr, char mode);
+extern void set_dma_addr(unsigned int dmanr, unsigned int a);
+extern void set_dma_count(unsigned int dmanr, unsigned int count);
+extern int get_dma_residue(unsigned int dmanr);
 
 #ifdef CONFIG_PCI
 extern int isa_dma_bridge_buggy;
diff -urN linux-2.4.10-pre5/include/asm-sh/elf.h linux/include/asm-sh/elf.h
--- linux-2.4.10-pre5/include/asm-sh/elf.h	Tue Jul 11 15:43:45 2000
+++ linux/include/asm-sh/elf.h	Mon Dec  3 23:08:14 2001
@@ -7,7 +7,6 @@
 
 #include <asm/ptrace.h>
 #include <asm/user.h>
-#include <asm/byteorder.h>
 
 typedef unsigned long elf_greg_t;
 
diff -urN linux-2.4.10-pre5/include/asm-sh/hardirq.h linux/include/asm-sh/hardirq.h
--- linux-2.4.10-pre5/include/asm-sh/hardirq.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/hardirq.h	Mon Dec  3 23:08:14 2001
@@ -10,6 +10,7 @@
 	unsigned int __local_irq_count;
 	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
diff -urN linux-2.4.10-pre5/include/asm-sh/hd64461.h linux/include/asm-sh/hd64461.h
--- linux-2.4.10-pre5/include/asm-sh/hd64461.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/hd64461.h	Mon Dec  3 23:08:14 2001
@@ -1,7 +1,7 @@
 #ifndef __ASM_SH_HD64461
 #define __ASM_SH_HD64461
 /*
- *	$Id: hd64461.h,v 1.1 2000/06/10 21:45:48 yaegashi Exp $
+ *	$Id: hd64461.h,v 1.7 2001/07/07 11:43:58 yaegashi Exp $
  *	Copyright (C) 2000 YAEGASHI Takeshi
  *	Hitachi HD64461 companion chip support
  */
@@ -70,5 +70,6 @@
 #endif
 
 #define HD64461_IRQBASE		OFFCHIP_IRQ_BASE
+#define HD64461_IRQ_NUM 	16
 
 #endif
diff -urN linux-2.4.10-pre5/include/asm-sh/hitachi_7751se.h linux/include/asm-sh/hitachi_7751se.h
--- linux-2.4.10-pre5/include/asm-sh/hitachi_7751se.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/hitachi_7751se.h	Mon Dec  3 23:08:14 2001
@@ -0,0 +1,68 @@
+#ifndef __ASM_SH_HITACHI_7751SE_H
+#define __ASM_SH_HITACHI_7751SE_H
+
+/*
+ * linux/include/asm-sh/hitachi_7751se.h
+ *
+ * Copyright (C) 2000  Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine support
+
+ * Modified for 7751 Solution Engine by
+ * Ian da Silva and Jeremy Siegel, 2001.
+ */
+
+/* Box specific addresses.  */
+
+#define PA_ROM		0x00000000	/* EPROM */
+#define PA_ROM_SIZE	0x00400000	/* EPROM size 4M byte */
+#define PA_FROM		0x01000000	/* EPROM */
+#define PA_FROM_SIZE	0x00400000	/* EPROM size 4M byte */
+#define PA_EXT1		0x04000000
+#define PA_EXT1_SIZE	0x04000000
+#define PA_EXT2		0x08000000
+#define PA_EXT2_SIZE	0x04000000
+#define PA_SDRAM	0x0c000000
+#define PA_SDRAM_SIZE	0x04000000
+
+#define PA_EXT4		0x12000000
+#define PA_EXT4_SIZE	0x02000000
+#define PA_EXT5		0x14000000
+#define PA_EXT5_SIZE	0x04000000
+#define PA_PCIC		0x18000000	/* MR-SHPC-01 PCMCIA */
+
+#define PA_DIPSW0	0xb9000000	/* Dip switch 5,6 */
+#define PA_DIPSW1	0xb9000002	/* Dip switch 7,8 */
+#define PA_LED		0xba000000	/* LED */
+#define	PA_BCR		0xbb000000	/* FPGA on the MS7751SE01 */
+
+#define PA_MRSHPC	0xb83fffe0	/* MR-SHPC-01 PCMCIA controler */
+#define PA_MRSHPC_MW1	0xb8400000	/* MR-SHPC-01 memory window base */
+#define PA_MRSHPC_MW2	0xb8500000	/* MR-SHPC-01 attribute window base */
+#define PA_MRSHPC_IO	0xb8600000	/* MR-SHPC-01 I/O window base */
+#define MRSHPC_MODE     (PA_MRSHPC + 4)
+#define MRSHPC_OPTION   (PA_MRSHPC + 6)
+#define MRSHPC_CSR      (PA_MRSHPC + 8)
+#define MRSHPC_ISR      (PA_MRSHPC + 10)
+#define MRSHPC_ICR      (PA_MRSHPC + 12)
+#define MRSHPC_CPWCR    (PA_MRSHPC + 14)
+#define MRSHPC_MW0CR1   (PA_MRSHPC + 16)
+#define MRSHPC_MW1CR1   (PA_MRSHPC + 18)
+#define MRSHPC_IOWCR1   (PA_MRSHPC + 20)
+#define MRSHPC_MW0CR2   (PA_MRSHPC + 22)
+#define MRSHPC_MW1CR2   (PA_MRSHPC + 24)
+#define MRSHPC_IOWCR2   (PA_MRSHPC + 26)
+#define MRSHPC_CDCR     (PA_MRSHPC + 28)
+#define MRSHPC_PCIC_INFO (PA_MRSHPC + 30)
+
+#define BCR_ILCRA	(PA_BCR + 0)
+#define BCR_ILCRB	(PA_BCR + 2)
+#define BCR_ILCRC	(PA_BCR + 4)
+#define BCR_ILCRD	(PA_BCR + 6)
+#define BCR_ILCRE	(PA_BCR + 8)
+#define BCR_ILCRF	(PA_BCR + 10)
+#define BCR_ILCRG	(PA_BCR + 12)
+
+#define IRQ_79C973	13
+
+#endif  /* __ASM_SH_HITACHI_7751SE_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/ide.h linux/include/asm-sh/ide.h
--- linux-2.4.10-pre5/include/asm-sh/ide.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/ide.h	Mon Dec  3 23:08:14 2001
@@ -27,8 +27,8 @@
 static __inline__ int ide_default_irq_hp600(ide_ioreg_t base)
 {
 	switch (base) {
-		case 0x01f0: return 77;
-		case 0x0170: return 78;
+		case 0x01f0: return 93;
+		case 0x0170: return 94;
 		default:
 			return 0;
 	}
diff -urN linux-2.4.10-pre5/include/asm-sh/io.h linux/include/asm-sh/io.h
--- linux-2.4.10-pre5/include/asm-sh/io.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/io.h	Mon Dec  3 23:08:14 2001
@@ -21,7 +21,7 @@
  *  __inb expands to an inline function call (which either calls via the
  *        mach_vec if generic, or a machine specific implementation)
  *  _inb  is a real function call (note ___raw fns are _ version of __raw)
- *  inb   by default expands to _inb, but the machine specif code may
+ *  inb   by default expands to _inb, but the machine specific code may
  *        define it to __inb if it chooses.
  */
 
@@ -109,7 +109,7 @@
 
 # if defined(CONFIG_SH_HP600)
 #  include <asm/io_hd64461.h>
-# elif (defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_7751_SOLUTION_ENGINE))
+# elif defined(CONFIG_SH_SOLUTION_ENGINE)
 #  include <asm/io_se.h>
 # elif defined(CONFIG_SH_SH2000)
 #  include <asm/io_sh2000.h>
@@ -125,6 +125,10 @@
 #  include <asm/io_cat68701.h>
 # elif defined(CONFIG_SH_BIGSUR)
 #  include <asm/io_bigsur.h>
+# elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
+#  include <asm/io_7751se.h>
+# elif defined(CONFIG_SH_ADX)
+#  include <asm/io_adx.h>
 # elif defined(CONFIG_SH_UNKNOWN)
 #  include <asm/io_unknown.h>
 # else
@@ -327,7 +331,7 @@
  * If the platform has PC-like I/O, this function converts the offset into
  * an address.
  */
-extern __inline__ unsigned long isa_port2addr(unsigned long offset)
+static __inline__ unsigned long isa_port2addr(unsigned long offset)
 {
 	return __isa_port2addr(offset);
 }
@@ -351,32 +355,32 @@
 extern void memset_io(unsigned long, int, unsigned long);
 
 /* SuperH on-chip I/O functions */
-extern __inline__ unsigned char ctrl_inb(unsigned long addr)
+static __inline__ unsigned char ctrl_inb(unsigned long addr)
 {
 	return *(volatile unsigned char*)addr;
 }
 
-extern __inline__ unsigned short ctrl_inw(unsigned long addr)
+static __inline__ unsigned short ctrl_inw(unsigned long addr)
 {
 	return *(volatile unsigned short*)addr;
 }
 
-extern __inline__ unsigned int ctrl_inl(unsigned long addr)
+static __inline__ unsigned int ctrl_inl(unsigned long addr)
 {
 	return *(volatile unsigned long*)addr;
 }
 
-extern __inline__ void ctrl_outb(unsigned char b, unsigned long addr)
+static __inline__ void ctrl_outb(unsigned char b, unsigned long addr)
 {
 	*(volatile unsigned char*)addr = b;
 }
 
-extern __inline__ void ctrl_outw(unsigned short b, unsigned long addr)
+static __inline__ void ctrl_outw(unsigned short b, unsigned long addr)
 {
 	*(volatile unsigned short*)addr = b;
 }
 
-extern __inline__ void ctrl_outl(unsigned int b, unsigned long addr)
+static __inline__ void ctrl_outl(unsigned int b, unsigned long addr)
 {
         *(volatile unsigned long*)addr = b;
 }
@@ -389,18 +393,19 @@
  * Change virtual addresses to physical addresses and vv.
  * These are trivial on the 1:1 Linux/SuperH mapping
  */
-extern __inline__ unsigned long virt_to_phys(volatile void * address)
+static __inline__ unsigned long virt_to_phys(volatile void * address)
 {
 	return PHYSADDR(address);
 }
 
-extern __inline__ void * phys_to_virt(unsigned long address)
+static __inline__ void * phys_to_virt(unsigned long address)
 {
 	return (void *)P1SEGADDR(address);
 }
 
 #define virt_to_bus virt_to_phys
 #define bus_to_virt phys_to_virt
+#define page_to_bus page_to_phys
 
 /*
  * readX/writeX() are used to access memory mapped devices. On some
@@ -463,11 +468,11 @@
  */
 
 #define dma_cache_wback_inv(_start,_size) \
-    cache_flush_area((unsigned long)(_start),((unsigned long)(_start)+(_size)))
+    __flush_purge_region(_start,_size)
 #define dma_cache_inv(_start,_size) \
-    cache_purge_area((unsigned long)(_start),((unsigned long)(_start)+(_size)))
+    __flush_invalidate_region(_start,_size)
 #define dma_cache_wback(_start,_size) \
-    cache_wback_area((unsigned long)(_start),((unsigned long)(_start)+(_size)))
+    __flush_wback_region(_start,_size)
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_IO_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/io_7751se.h linux/include/asm-sh/io_7751se.h
--- linux-2.4.10-pre5/include/asm-sh/io_7751se.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/io_7751se.h	Mon Dec  3 23:08:14 2001
@@ -0,0 +1,80 @@
+/*
+ * include/asm-sh/io_7751se.h
+ *
+ * Modified version of io_se.h for the 7751se-specific functions.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * IO functions for an Hitachi SolutionEngine
+ */
+
+#ifndef _ASM_SH_IO_7751SE_H
+#define _ASM_SH_IO_7751SE_H
+
+#include <asm/io_generic.h>
+
+extern unsigned char sh7751se_inb(unsigned long port);
+extern unsigned short sh7751se_inw(unsigned long port);
+extern unsigned int sh7751se_inl(unsigned long port);
+
+extern void sh7751se_outb(unsigned char value, unsigned long port);
+extern void sh7751se_outw(unsigned short value, unsigned long port);
+extern void sh7751se_outl(unsigned int value, unsigned long port);
+
+extern unsigned char sh7751se_inb_p(unsigned long port);
+extern void sh7751se_outb_p(unsigned char value, unsigned long port);
+
+extern void sh7751se_insb(unsigned long port, void *addr, unsigned long count);
+extern void sh7751se_insw(unsigned long port, void *addr, unsigned long count);
+extern void sh7751se_insl(unsigned long port, void *addr, unsigned long count);
+extern void sh7751se_outsb(unsigned long port, const void *addr, unsigned long count);
+extern void sh7751se_outsw(unsigned long port, const void *addr, unsigned long count);
+extern void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count);
+
+extern unsigned char sh7751se_readb(unsigned long addr);
+extern unsigned short sh7751se_readw(unsigned long addr);
+extern unsigned int sh7751se_readl(unsigned long addr);
+extern void sh7751se_writeb(unsigned char b, unsigned long addr);
+extern void sh7751se_writew(unsigned short b, unsigned long addr);
+extern void sh7751se_writel(unsigned int b, unsigned long addr);
+
+extern unsigned long sh7751se_isa_port2addr(unsigned long offset);
+
+#ifdef __WANT_IO_DEF
+
+# define __inb			sh7751se_inb
+# define __inw			sh7751se_inw
+# define __inl			sh7751se_inl
+# define __outb			sh7751se_outb
+# define __outw			sh7751se_outw
+# define __outl			sh7751se_outl
+
+# define __inb_p		sh7751se_inb_p
+# define __inw_p		sh7751se_inw
+# define __inl_p		sh7751se_inl
+# define __outb_p		sh7751se_outb_p
+# define __outw_p		sh7751se_outw
+# define __outl_p		sh7751se_outl
+
+# define __insb			sh7751se_insb
+# define __insw			sh7751se_insw
+# define __insl			sh7751se_insl
+# define __outsb		sh7751se_outsb
+# define __outsw		sh7751se_outsw
+# define __outsl		sh7751se_outsl
+
+# define __readb		sh7751se_readb
+# define __readw		sh7751se_readw
+# define __readl		sh7751se_readl
+# define __writeb		sh7751se_writeb
+# define __writew		sh7751se_writew
+# define __writel		sh7751se_writel
+
+# define __isa_port2addr	sh7751se_isa_port2addr
+# define __ioremap		generic_ioremap
+# define __iounmap		generic_iounmap
+
+#endif
+
+#endif /* _ASM_SH_IO_7751SE_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/io_adx.h linux/include/asm-sh/io_adx.h
--- linux-2.4.10-pre5/include/asm-sh/io_adx.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sh/io_adx.h	Mon Dec  3 23:08:14 2001
@@ -0,0 +1,86 @@
+/*
+ * include/asm-sh/io_adx.h
+ *
+ * Copyright (C) 2001 A&D Co., Ltd.
+ *
+ * This file may be copied or modified under the terms of the GNU
+ * General Public License.  See linux/COPYING for more information.
+ *
+ * IO functions for an A&D ADX Board
+ */
+
+#ifndef _ASM_SH_IO_ADX_H
+#define _ASM_SH_IO_ADX_H
+
+#include <asm/io_generic.h>
+
+extern unsigned char adx_inb(unsigned long port);
+extern unsigned short adx_inw(unsigned long port);
+extern unsigned int adx_inl(unsigned long port);
+
+extern void adx_outb(unsigned char value, unsigned long port);
+extern void adx_outw(unsigned short value, unsigned long port);
+extern void adx_outl(unsigned int value, unsigned long port);
+
+extern unsigned char adx_inb_p(unsigned long port);
+extern void adx_outb_p(unsigned char value, unsigned long port);
+
+extern void adx_insb(unsigned long port, void *addr, unsigned long count);
+extern void adx_insw(unsigned long port, void *addr, unsigned long count);
+extern void adx_insl(unsigned long port, void *addr, unsigned long count);
+extern void adx_outsb(unsigned long port, const void *addr, unsigned long count);
+extern void adx_outsw(unsigned long port, const void *addr, unsigned long count);
+extern void adx_outsl(unsigned long port, const void *addr, unsigned long count);
+
+extern unsigned char adx_readb(unsigned long addr);
+extern unsigned short adx_readw(unsigned long addr);
+extern unsigned int adx_readl(unsigned long addr);
+extern void adx_writeb(unsigned char b, unsigned long addr);
+extern void adx_writew(unsigned short b, unsigned long addr);
+extern void adx_writel(unsigned int b, unsigned long addr);
+
+extern void * adx_ioremap(unsigned long offset, unsigned long size);
+extern void adx_iounmap(void *addr);
+
+extern unsigned long adx_isa_port2addr(unsigned long offset);
+
+extern void setup_adx(void);
+extern void init_adx_IRQ(void);
+
+#ifdef __WANT_IO_DEF
+
+#define __inb		adx_inb
+#define __inw		adx_inw
+#define __inl		adx_inl
+#define __outb		adx_outb
+#define __outw		adx_outw
+#define __outl		adx_outl
+
+#define __inb_p		adx_inb_p
+#define __inw_p		adx_inw
+#define __inl_p		adx_inl
+#define __outb_p	adx_outb_p
+#define __outw_p	adx_outw
+#define __outl_p	adx_outl
+
+#define __insb		adx_insb
+#define __insw		adx_insw
+#define __insl		adx_insl
+#define __outsb		adx_outsb
+#define __outsw		adx_outsw
+#define __outsl		adx_outsl
+
+#define __readb		adx_readb
+#define __readw		adx_readw
+#define __readl		adx_readl
+#define __writeb	adx_writeb
+#define __writew	adx_writew
+#define __writel	adx_writel
+
+#define __isa_port2addr	adx_isa_port2addr
+#define __ioremap	adx_ioremap
+#define __iounmap	adx_iounmap
+
+#endif
+
+#endif /* _ASM_SH_IO_AANDD_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/irq.h linux/include/asm-sh/irq.h
--- linux-2.4.10-pre5/include/asm-sh/irq.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/irq.h	Mon Dec  3 23:08:14 2001
@@ -33,6 +33,15 @@
 #define RTC_IPR_POS	 0
 #define RTC_PRIORITY	TIMER_PRIORITY
 
+#if defined(__sh3__)
+#define DMTE0_IRQ	48
+#define DMTE1_IRQ	49
+#define DMTE2_IRQ	50
+#define DMTE3_IRQ	51
+#define DMA_IPR_ADDR	INTC_IPRE
+#define DMA_IPR_POS	3
+#define DMA_PRIORITY	7
+#elif defined(__SH4__)
 #define DMTE0_IRQ	34
 #define DMTE1_IRQ	35
 #define DMTE2_IRQ	36
@@ -41,6 +50,7 @@
 #define DMA_IPR_ADDR	INTC_IPRC
 #define DMA_IPR_POS	2
 #define DMA_PRIORITY	7
+#endif
 
 #if defined (CONFIG_CPU_SUBTYPE_SH7707) || defined (CONFIG_CPU_SUBTYPE_SH7708) || \
     defined (CONFIG_CPU_SUBTYPE_SH7709) || defined (CONFIG_CPU_SUBTYPE_SH7750) || \
@@ -170,6 +180,12 @@
 extern void enable_irq(unsigned int);
 
 /*
+ * Simple Mask Register Support
+ */
+extern void make_maskreg_irq(unsigned int irq);
+extern unsigned short *irq_mask_register;
+
+/*
  * Function for "on chip support modules".
  */
 extern void make_ipr_irq(unsigned int irq, unsigned int addr,
@@ -277,7 +293,8 @@
        
 #ifdef CONFIG_SH_GENERIC
 
-extern __inline__ int irq_demux(int irq) {
+static __inline__ int irq_demux(int irq)
+{
 	if (sh_mv.mv_irq_demux) {
 		irq = sh_mv.mv_irq_demux(irq);
 	}
diff -urN linux-2.4.10-pre5/include/asm-sh/keyboard.h linux/include/asm-sh/keyboard.h
--- linux-2.4.10-pre5/include/asm-sh/keyboard.h	Wed Apr 11 21:24:52 2001
+++ linux/include/asm-sh/keyboard.h	Mon Dec  3 23:08:14 2001
@@ -1,9 +1,10 @@
 #ifndef	__ASM_SH_KEYBOARD_H
 #define	__ASM_SH_KEYBOARD_H
 /*
- *	$Id: keyboard.h,v 1.1 2000/06/10 21:45:48 yaegashi Exp $
+ *	$Id: keyboard.h,v 1.12 2001/09/06 04:01:41 gniibe Exp $
  */
 
+#include <linux/kd.h>
 #include <linux/config.h>
 #include <asm/machvec.h>
 
@@ -21,12 +22,17 @@
     return scancode > 127 ? -EINVAL : scancode;
 }
 
+#ifdef CONFIG_SH_DREAMCAST
+extern int kbd_translate(unsigned char scancode, unsigned char *keycode,
+			 char raw_mode);
+#else
 static __inline__ int kbd_translate(unsigned char scancode,
 				    unsigned char *keycode, char raw_mode)
 {
     *keycode = scancode;
     return 1;
 }
+#endif
 
 static __inline__ char kbd_unexpected_up(unsigned char keycode)
 {
diff -urN linux-2.4.10-pre5/include/asm-sh/linux_logo.h linux/include/asm-sh/linux_logo.h
--- linux-2.4.10-pre5/include/asm-sh/linux_logo.h	Mon Jun 11 19:15:27 2001
+++ linux/include/asm-sh/linux_logo.h	Mon Dec  3 23:08:14 2001
@@ -1,27 +1,1418 @@
-/* $Id: linux_logo.h,v 1.1 2000/06/10 21:45:48 yaegashi Exp $
- * include/asm-sh/linux_logo.h: This is a linux logo
- *                                to be displayed on boot.
+/* $Id: linux_logo.h,v 1.4 2001/08/08 07:39:36 gnb Exp $
+ * include/linux/linux_logo.h: This is a linux logo
+ *                             to be displayed on boot.
  *
  * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (c) 2001 Greg Banks <gnb@alphalink.com.au>
  *
  * You can put anything here, but:
  * LINUX_LOGO_COLORS has to be less than 224
  * image size has to be 80x80
  * values have to start from 0x20
  * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
+ *           linux_logo_green[0],
+ *           linux_logo_blue[0]) is color 0x20)
  * BW image has to be 80x80 as well, with MS bit
  * on the left
  * Serial_console ascii image can be any size,
  * but should contain %s to display the version
  */
- 
+
 #include <linux/init.h>
 #include <linux/version.h>
 
 #define linux_logo_banner "Linux/SuperH version " UTS_RELEASE
 
-#include <linux/linux_logo.h>
+#define __HAVE_ARCH_LINUX_LOGO 1
+#define __HAVE_ARCH_LINUX_LOGO16 1
+#define __HAVE_ARCH_LINUX_LOGOBW 1
+
+#define LINUX_LOGO_COLORS       160
+
+#ifdef INCLUDE_LINUX_LOGO_DATA
+
+unsigned char linux_logo_red[] __initdata = {
+  0x02, 0x06, 0x0A, 0x0E, 0x16, 0x1A, 0x1E, 0x22,
+  0x12, 0x2A, 0x36, 0x42, 0x4E, 0x4A, 0x56, 0x26,
+  0x46, 0x2E, 0x32, 0x52, 0x3A, 0x02, 0x66, 0x5E,
+  0x3E, 0x76, 0x8A, 0xA3, 0x9A, 0x86, 0xC6, 0xC2,
+  0x66, 0xBA, 0xD2, 0xDA, 0xD6, 0xE2, 0xF6, 0xFE,
+  0xAE, 0x7A, 0xDF, 0xEA, 0x6A, 0xAA, 0xE6, 0xBE,
+  0x59, 0xEE, 0x9E, 0x96, 0x82, 0x7A, 0x7A, 0x68,
+  0x3C, 0x9A, 0xE2, 0xF1, 0xE5, 0xBA, 0xD6, 0xB2,
+  0x26, 0xBE, 0xC3, 0xEE, 0xEA, 0xEA, 0xEE, 0xF6,
+  0xF4, 0xDA, 0xCE, 0x7A, 0xDC, 0xF6, 0xF6, 0xE0,
+  0xB5, 0xCC, 0xF6, 0x69, 0xDB, 0xEE, 0xF1, 0xC5,
+  0x9E, 0x8A, 0xD2, 0xEE, 0xCA, 0xBA, 0xD3, 0x5C,
+  0x8A, 0xBE, 0xAA, 0xD6, 0xCA, 0xB6, 0xAD, 0x9E,
+  0xC5, 0xBC, 0xBF, 0xC9, 0x92, 0xB2, 0x9A, 0xAA,
+  0xB6, 0xF2, 0xCE, 0xFA, 0x6E, 0xA6, 0x12, 0x4A,
+  0x8E, 0xF6, 0xF6, 0xEE, 0xE9, 0xF0, 0x26, 0x9A,
+  0xEA, 0xF6, 0xDE, 0x31, 0x72, 0xCE, 0x46, 0x7E,
+  0xB6, 0x62, 0xCF, 0xA3, 0x76, 0xA4, 0xA2, 0xE2,
+  0xAE, 0xC0, 0xCE, 0xE2, 0xE7, 0xFC, 0xCD, 0x03,
+  0xEF, 0xF9, 0xD4, 0xFE, 0xFE, 0xFE, 0x83, 0x5E
+};
+
+unsigned char linux_logo_green[] __initdata = {
+  0x02, 0x06, 0x0A, 0x0E, 0x16, 0x1A, 0x1E, 0x22,
+  0x12, 0x2A, 0x36, 0x42, 0x4E, 0x4A, 0x56, 0x26,
+  0x46, 0x2E, 0x32, 0x52, 0x3A, 0x02, 0x66, 0x5E,
+  0x3E, 0x76, 0x8A, 0xA3, 0x9A, 0x86, 0xC6, 0xC2,
+  0x62, 0xBA, 0xD2, 0xDA, 0xD6, 0xE2, 0xF6, 0xFE,
+  0xAE, 0x7A, 0xDE, 0xEA, 0x6A, 0xAA, 0xE6, 0xBE,
+  0x5A, 0xEE, 0x9E, 0x96, 0x82, 0x64, 0x5E, 0x4E,
+  0x28, 0x72, 0xAA, 0xBA, 0xAE, 0x92, 0xAE, 0x93,
+  0x1A, 0xA6, 0x86, 0xB6, 0xBE, 0xC4, 0xCA, 0xCE,
+  0xD4, 0xC2, 0xCE, 0x56, 0xA2, 0xD9, 0xD9, 0xBC,
+  0x7A, 0x92, 0xDA, 0x46, 0x9E, 0xB2, 0xD6, 0x97,
+  0x76, 0x5E, 0xA2, 0xBE, 0xA4, 0x86, 0x96, 0x45,
+  0x66, 0x92, 0x7A, 0x9A, 0x93, 0x9E, 0x9A, 0x6A,
+  0x8B, 0x8C, 0xB2, 0xCA, 0x92, 0xA6, 0x7A, 0x7E,
+  0xB6, 0xF2, 0xCE, 0xFA, 0x6E, 0xA6, 0x0E, 0x33,
+  0x86, 0xBE, 0xE6, 0xCE, 0xBC, 0xC6, 0x1E, 0x8E,
+  0xAE, 0xBA, 0xAF, 0x23, 0x66, 0xAA, 0x2E, 0x72,
+  0x86, 0x46, 0xA5, 0x6E, 0x52, 0x72, 0x92, 0xA6,
+  0x86, 0x94, 0xA0, 0xD2, 0xDC, 0xFB, 0xC3, 0x03,
+  0x9F, 0x64, 0x84, 0x03, 0x15, 0x38, 0x7E, 0x56
+};
+
+unsigned char linux_logo_blue[] __initdata = {
+  0x02, 0x06, 0x0A, 0x0D, 0x16, 0x1A, 0x1E, 0x22,
+  0x12, 0x2B, 0x36, 0x42, 0x4E, 0x4A, 0x56, 0x26,
+  0x46, 0x2E, 0x32, 0x52, 0x3A, 0x06, 0x66, 0x5D,
+  0x3E, 0x76, 0x8E, 0xA3, 0x9A, 0x86, 0xC4, 0xC2,
+  0x5A, 0xBA, 0xD2, 0xDA, 0xD6, 0xE2, 0xF6, 0xFE,
+  0xAE, 0x7A, 0xDE, 0xEA, 0x69, 0xAA, 0xE4, 0xBB,
+  0x5A, 0xEE, 0x9E, 0x96, 0x82, 0x42, 0x0A, 0x0A,
+  0x09, 0x0A, 0x0A, 0x0D, 0x0B, 0x11, 0x0E, 0x46,
+  0x0A, 0x72, 0x0A, 0x0E, 0x0A, 0x12, 0x15, 0x2E,
+  0x14, 0x86, 0xC2, 0x1A, 0x0A, 0x35, 0x27, 0x0E,
+  0x09, 0x0B, 0x4A, 0x07, 0x0B, 0x0E, 0x22, 0x0D,
+  0x0A, 0x06, 0x0C, 0x0A, 0x14, 0x0A, 0x0B, 0x1A,
+  0x0E, 0x0E, 0x0C, 0x0A, 0x1F, 0x6A, 0x73, 0x09,
+  0x0C, 0x22, 0x91, 0xCB, 0x92, 0x92, 0x36, 0x26,
+  0xB6, 0xF2, 0xCE, 0xFA, 0x6E, 0xA6, 0x06, 0x0B,
+  0x6A, 0x0E, 0xBE, 0x5A, 0x40, 0x0E, 0x0A, 0x5A,
+  0x0C, 0x0E, 0x3B, 0x06, 0x4E, 0x4A, 0x06, 0x5A,
+  0x26, 0x06, 0x44, 0x0A, 0x0A, 0x08, 0x5E, 0x0D,
+  0x32, 0x2C, 0x24, 0xCF, 0xDA, 0xFB, 0xBE, 0x03,
+  0x99, 0x5D, 0x35, 0x03, 0x15, 0x38, 0x74, 0x4B
+};
+
+unsigned char linux_logo[] __initdata = {
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
+  0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+  0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x21, 0x23, 0x25, 0x29, 0x2A, 0x2B, 0x2C, 0x2C,
+  0x2C, 0x2D, 0x2B, 0x2A, 0x29, 0x25, 0x28, 0x22,
+  0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+  0x24, 0x29, 0x2B, 0x2E, 0x2B, 0x2F, 0x2F, 0x24,
+  0x25, 0x27, 0x2A, 0x2B, 0x2E, 0x30, 0x31, 0x25,
+  0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+  0x32, 0x33, 0x34, 0x21, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x21, 0x2A, 0x2E, 0x2B,
+  0x2F, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x32,
+  0x2C, 0x27, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x21, 0x30,
+  0x2C, 0x31, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x29, 0x33,
+  0x25, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x23, 0x31, 0x27, 0x21, 0x35,
+  0x29, 0x2C, 0x29, 0x28, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2B, 0x34,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x25, 0x2E, 0x36, 0x31, 0x22,
+  0x35, 0x34, 0x30, 0x27, 0x22, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x23, 0x29, 0x2E, 0x22,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x26, 0x37, 0x37, 0x34, 0x25,
+  0x35, 0x21, 0x2C, 0x2A, 0x24, 0x21, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x21, 0x24, 0x38, 0x38, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x25, 0x2A, 0x2F, 0x28, 0x22,
+  0x35, 0x35, 0x27, 0x33, 0x2F, 0x23, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x21, 0x26, 0x2C, 0x26, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x22, 0x22, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x2C, 0x32, 0x28, 0x21, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x2F, 0x2E, 0x23, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x2A, 0x2B, 0x25, 0x21, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x29, 0x33, 0x35, 0x35,
+  0x35, 0x21, 0x22, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x21, 0x23, 0x22, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x28, 0x33, 0x27, 0x22, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x31, 0x2E, 0x35, 0x35,
+  0x21, 0x21, 0x24, 0x27, 0x21, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x28, 0x27, 0x22, 0x32, 0x24, 0x35,
+  0x35, 0x35, 0x35, 0x22, 0x2E, 0x29, 0x23, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x31, 0x2E, 0x35, 0x35,
+  0x2F, 0x39, 0x37, 0x24, 0x24, 0x35, 0x35, 0x35,
+  0x23, 0x2E, 0x3A, 0x3B, 0x3C, 0x2F, 0x25, 0x21,
+  0x35, 0x35, 0x35, 0x35, 0x2E, 0x31, 0x23, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x31, 0x2E, 0x35, 0x23,
+  0x3D, 0x3E, 0x3F, 0x39, 0x22, 0x35, 0x35, 0x21,
+  0x40, 0x41, 0x42, 0x43, 0x44, 0x3D, 0x23, 0x21,
+  0x35, 0x35, 0x35, 0x35, 0x2E, 0x32, 0x28, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x31, 0x2E, 0x35, 0x2A,
+  0x43, 0x3F, 0x45, 0x46, 0x34, 0x35, 0x35, 0x26,
+  0x42, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x2D, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x30, 0x34, 0x24, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x31, 0x33, 0x35, 0x4C,
+  0x4D, 0x25, 0x2E, 0x45, 0x49, 0x22, 0x23, 0x31,
+  0x4E, 0x4F, 0x21, 0x30, 0x50, 0x51, 0x52, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x30, 0x34, 0x24, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x29, 0x2E, 0x21, 0x39,
+  0x4C, 0x21, 0x30, 0x53, 0x54, 0x28, 0x2F, 0x2A,
+  0x4A, 0x4C, 0x35, 0x23, 0x31, 0x4F, 0x3E, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x2D, 0x38, 0x24, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x29, 0x37, 0x23, 0x36,
+  0x54, 0x35, 0x28, 0x39, 0x55, 0x56, 0x56, 0x57,
+  0x3B, 0x4C, 0x35, 0x35, 0x35, 0x3F, 0x3F, 0x21,
+  0x35, 0x35, 0x35, 0x35, 0x2D, 0x38, 0x24, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x2F, 0x50, 0x23, 0x34,
+  0x42, 0x25, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D,
+  0x5E, 0x5F, 0x60, 0x35, 0x30, 0x46, 0x3A, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x30, 0x2B, 0x25, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x2F, 0x2E, 0x23, 0x22,
+  0x3F, 0x61, 0x62, 0x5C, 0x63, 0x64, 0x65, 0x66,
+  0x67, 0x68, 0x65, 0x5D, 0x69, 0x6A, 0x29, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x32, 0x2D, 0x26, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x27, 0x2E, 0x23, 0x35,
+  0x6B, 0x62, 0x6C, 0x63, 0x5B, 0x65, 0x68, 0x6D,
+  0x6D, 0x6E, 0x68, 0x68, 0x68, 0x6F, 0x6B, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x32, 0x33, 0x27, 0x22,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x27, 0x33, 0x26, 0x58,
+  0x70, 0x71, 0x5C, 0x63, 0x64, 0x66, 0x68, 0x72,
+  0x6E, 0x68, 0x68, 0x68, 0x6F, 0x5E, 0x5D, 0x21,
+  0x35, 0x35, 0x35, 0x35, 0x25, 0x37, 0x29, 0x23,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x26, 0x2C, 0x32, 0x73,
+  0x62, 0x74, 0x75, 0x5B, 0x65, 0x68, 0x6D, 0x76,
+  0x68, 0x68, 0x68, 0x77, 0x71, 0x74, 0x78, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x21, 0x50, 0x2A, 0x28,
+  0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x26, 0x2C, 0x31, 0x24,
+  0x79, 0x7A, 0x63, 0x7B, 0x66, 0x68, 0x68, 0x68,
+  0x68, 0x7C, 0x7D, 0x7E, 0x74, 0x7E, 0x57, 0x35,
+  0x21, 0x2A, 0x23, 0x35, 0x35, 0x38, 0x2D, 0x26,
+  0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x27, 0x2C, 0x32, 0x21,
+  0x7F, 0x80, 0x81, 0x6F, 0x66, 0x65, 0x5E, 0x81,
+  0x82, 0x62, 0x7E, 0x83, 0x84, 0x85, 0x40, 0x35,
+  0x35, 0x2C, 0x39, 0x34, 0x35, 0x24, 0x50, 0x31,
+  0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x2F, 0x2E, 0x32, 0x21,
+  0x54, 0x86, 0x87, 0x82, 0x77, 0x5D, 0x88, 0x71,
+  0x71, 0x71, 0x88, 0x61, 0x3F, 0x3E, 0x48, 0x23,
+  0x35, 0x24, 0x39, 0x39, 0x24, 0x35, 0x2D, 0x30,
+  0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x21, 0x28, 0x32, 0x36, 0x25, 0x22,
+  0x3A, 0x4F, 0x86, 0x87, 0x88, 0x71, 0x88, 0x62,
+  0x70, 0x89, 0x8A, 0x41, 0x8B, 0x4A, 0x44, 0x2B,
+  0x35, 0x35, 0x32, 0x38, 0x21, 0x35, 0x22, 0x50,
+  0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x22, 0x27, 0x2D, 0x2D, 0x35, 0x21,
+  0x8C, 0x3E, 0x4F, 0x8D, 0x8E, 0x87, 0x87, 0x8F,
+  0x86, 0x41, 0x4F, 0x42, 0x46, 0x47, 0x47, 0x90,
+  0x21, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x38,
+  0x2D, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x22, 0x24, 0x2A, 0x37, 0x28, 0x35, 0x31,
+  0x4B, 0x4A, 0x4F, 0x4F, 0x4F, 0x41, 0x41, 0x4F,
+  0x4F, 0x3F, 0x44, 0x91, 0x47, 0x47, 0x47, 0x47,
+  0x33, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x23,
+  0x2E, 0x2A, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x21, 0x28, 0x31, 0x50, 0x31, 0x28, 0x21, 0x90,
+  0x47, 0x46, 0x92, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F,
+  0x92, 0x4E, 0x93, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x8B, 0x23, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x29, 0x2E, 0x29, 0x28, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+  0x23, 0x2F, 0x2D, 0x2B, 0x35, 0x21, 0x50, 0x93,
+  0x47, 0x47, 0x51, 0x3E, 0x4F, 0x4F, 0x3F, 0x4A,
+  0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x33, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x2C, 0x30, 0x27, 0x23, 0x21, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+  0x27, 0x2B, 0x2C, 0x21, 0x35, 0x28, 0x43, 0x47,
+  0x47, 0x47, 0x47, 0x46, 0x45, 0x4E, 0x46, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x48, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x28, 0x50, 0x38, 0x26, 0x22, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
+  0x34, 0x50, 0x28, 0x35, 0x35, 0x94, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x93, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x4E, 0x28, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x28, 0x37, 0x2A, 0x25, 0x22, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x32,
+  0x50, 0x25, 0x35, 0x35, 0x23, 0x3F, 0x93, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x93, 0x91, 0x2A, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x2F, 0x2E, 0x32, 0x24, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x2F, 0x33,
+  0x27, 0x35, 0x35, 0x35, 0x29, 0x3F, 0x46, 0x47,
+  0x47, 0x47, 0x47, 0x93, 0x91, 0x91, 0x93, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x93, 0x46, 0x51,
+  0x45, 0x4E, 0x36, 0x21, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x2F, 0x33, 0x29, 0x23,
+  0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x38, 0x2B,
+  0x35, 0x35, 0x35, 0x21, 0x30, 0x4D, 0x92, 0x4B,
+  0x46, 0x93, 0x93, 0x51, 0x45, 0x4E, 0x51, 0x93,
+  0x93, 0x93, 0x46, 0x4E, 0x44, 0x92, 0x8B, 0x8B,
+  0x3E, 0x8B, 0x90, 0x28, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x38, 0x2B, 0x26,
+  0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x23, 0x29, 0x33, 0x28,
+  0x35, 0x35, 0x35, 0x22, 0x37, 0x90, 0x43, 0x91,
+  0x93, 0x47, 0x47, 0x93, 0x4B, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x46, 0x51, 0x45, 0x42, 0x8B,
+  0x3F, 0x3F, 0x42, 0x52, 0x21, 0x23, 0x32, 0x23,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x21, 0x2E, 0x31,
+  0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x21, 0x24, 0x2A, 0x30, 0x35,
+  0x35, 0x22, 0x35, 0x24, 0x95, 0x4E, 0x93, 0x47,
+  0x47, 0x47, 0x47, 0x93, 0x91, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x46,
+  0x4E, 0x92, 0x3E, 0x45, 0x37, 0x35, 0x21, 0x2F,
+  0x26, 0x35, 0x35, 0x35, 0x35, 0x35, 0x38, 0x2B,
+  0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x22, 0x26, 0x2D, 0x32, 0x35,
+  0x25, 0x25, 0x35, 0x4C, 0x51, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x46, 0x43, 0x8B, 0x42, 0x23, 0x35, 0x35,
+  0x26, 0x24, 0x35, 0x35, 0x35, 0x35, 0x28, 0x2E,
+  0x29, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x23, 0x29, 0x50, 0x24, 0x35,
+  0x29, 0x35, 0x28, 0x43, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x93, 0x4A, 0x43, 0x36, 0x35, 0x23,
+  0x28, 0x2F, 0x22, 0x35, 0x35, 0x35, 0x35, 0x2C,
+  0x34, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x21, 0x28, 0x2A, 0x33, 0x35, 0x25,
+  0x24, 0x35, 0x49, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x93, 0x51, 0x3E, 0x21, 0x2F,
+  0x34, 0x25, 0x2F, 0x35, 0x35, 0x35, 0x35, 0x31,
+  0x2C, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x22, 0x26, 0x2D, 0x34, 0x35, 0x29,
+  0x35, 0x24, 0x4E, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x93, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x46, 0x31, 0x2F,
+  0x29, 0x23, 0x2F, 0x23, 0x35, 0x35, 0x35, 0x21,
+  0x2E, 0x31, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x21, 0x23, 0x29, 0x50, 0x28, 0x28, 0x25,
+  0x35, 0x39, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x93, 0x51, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x37, 0x21,
+  0x35, 0x35, 0x22, 0x27, 0x35, 0x35, 0x35, 0x35,
+  0x2D, 0x34, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x22, 0x25, 0x2B, 0x33, 0x35, 0x2F, 0x21,
+  0x23, 0x42, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x46, 0x91, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x8C, 0x35,
+  0x35, 0x35, 0x35, 0x31, 0x35, 0x35, 0x35, 0x35,
+  0x29, 0x2D, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x21, 0x23, 0x29, 0x50, 0x25, 0x21, 0x29, 0x35,
+  0x2D, 0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x91, 0x91, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x90, 0x35,
+  0x35, 0x35, 0x35, 0x31, 0x35, 0x35, 0x35, 0x35,
+  0x22, 0x2E, 0x2F, 0x22, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x22, 0x25, 0x2B, 0x33, 0x35, 0x24, 0x28, 0x35,
+  0x53, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4B, 0x91, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x92, 0x35,
+  0x35, 0x35, 0x35, 0x2F, 0x35, 0x35, 0x35, 0x35,
+  0x21, 0x2E, 0x31, 0x23, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+  0x28, 0x31, 0x2E, 0x28, 0x35, 0x27, 0x22, 0x21,
+  0x42, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4B, 0x91, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4A, 0x21,
+  0x35, 0x35, 0x21, 0x26, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x33, 0x2A, 0x28, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+  0x25, 0x2B, 0x38, 0x35, 0x35, 0x2F, 0x22, 0x25,
+  0x51, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4E, 0x51, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4E, 0x21,
+  0x35, 0x35, 0x22, 0x26, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x2B, 0x34, 0x24, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+  0x2F, 0x2C, 0x21, 0x35, 0x35, 0x31, 0x23, 0x29,
+  0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4E, 0x91, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4B, 0x22,
+  0x35, 0x35, 0x24, 0x23, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x2B, 0x38, 0x24, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+  0x32, 0x2D, 0x35, 0x35, 0x23, 0x30, 0x27, 0x38,
+  0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4E, 0x46, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4B, 0x23,
+  0x35, 0x35, 0x26, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x2B, 0x38, 0x24, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+  0x2A, 0x38, 0x35, 0x35, 0x35, 0x26, 0x31, 0x30,
+  0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4E, 0x46, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x45, 0x22,
+  0x35, 0x21, 0x26, 0x35, 0x35, 0x35, 0x35, 0x35,
+  0x35, 0x2B, 0x34, 0x24, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
+  0x34, 0x38, 0x35, 0x35, 0x35, 0x35, 0x26, 0x2C,
+  0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4E, 0x46, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x92, 0x35,
+  0x24, 0x27, 0x96, 0x24, 0x25, 0x28, 0x21, 0x35,
+  0x35, 0x33, 0x2A, 0x28, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
+  0x38, 0x4C, 0x97, 0x7D, 0x7A, 0x56, 0x21, 0x38,
+  0x51, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4E, 0x46, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x52, 0x28,
+  0x23, 0x35, 0x35, 0x35, 0x21, 0x28, 0x2B, 0x2F,
+  0x21, 0x37, 0x32, 0x28, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x2F,
+  0x2C, 0x98, 0x74, 0x5B, 0x99, 0x99, 0x78, 0x22,
+  0x50, 0x51, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4E, 0x93, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x9A, 0x9B, 0x9B, 0x89, 0x60,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x2F, 0x31,
+  0x25, 0x4C, 0x2A, 0x28, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x21, 0x23, 0x24, 0x26, 0x2F, 0x32, 0x30,
+  0x4C, 0x89, 0x5A, 0x5B, 0x99, 0x99, 0x99, 0x59,
+  0x21, 0x2D, 0x45, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4E, 0x93, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x9C, 0x9D, 0x68, 0x65, 0x9E,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x21, 0x26, 0x25,
+  0x7C, 0x9F, 0x2B, 0x25, 0x21, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x21, 0x28, 0x2F, 0x34, 0x2C, 0x2E, 0x36, 0x49,
+  0x5F, 0x7E, 0xA0, 0xA1, 0x99, 0x99, 0x99, 0x7B,
+  0x57, 0x35, 0x31, 0x3E, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x4B, 0x91, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0xA2, 0x5B, 0x9D, 0x7A, 0x28,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x21, 0x56,
+  0x66, 0x65, 0x33, 0x27, 0x22, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x23, 0x2F, 0x30, 0x8E, 0x89, 0x71, 0x88, 0x88,
+  0x83, 0x5A, 0x5B, 0x99, 0x99, 0x99, 0x99, 0x99,
+  0x5C, 0xA3, 0x35, 0x24, 0x52, 0x93, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x93, 0x91, 0xA2, 0x63, 0x5B, 0x83, 0xA3,
+  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x58, 0x5C,
+  0x7B, 0x5B, 0xA4, 0x29, 0x23, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+  0x24, 0x2A, 0x8E, 0x83, 0x5A, 0x5C, 0x5A, 0x5A,
+  0x75, 0x5B, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+  0x9D, 0x5D, 0x22, 0x35, 0x21, 0x39, 0x91, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x4E, 0x3E, 0xA5, 0x75, 0x75, 0x7E, 0x79,
+  0x96, 0x35, 0x35, 0x35, 0x21, 0xA6, 0x71, 0x75,
+  0x63, 0x63, 0xA7, 0x34, 0x24, 0x21, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+  0x26, 0x30, 0xA8, 0x5A, 0x63, 0x5B, 0x5B, 0xA1,
+  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+  0x99, 0x65, 0xA9, 0x35, 0x35, 0x35, 0x2B, 0x4A,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x92, 0x3E, 0xAA, 0x5C, 0x5C, 0x74, 0x62,
+  0xAB, 0xAC, 0x57, 0xAC, 0xAD, 0x88, 0x5A, 0x63,
+  0x5B, 0x5B, 0xAE, 0x2C, 0x27, 0x23, 0x21, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+  0x26, 0x2C, 0x89, 0x5A, 0x63, 0x99, 0x99, 0x99,
+  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+  0x99, 0x9D, 0x7C, 0x28, 0x35, 0x35, 0x35, 0x2F,
+  0x43, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x93, 0x92, 0x3E, 0xAA, 0x5A, 0x75, 0xAF, 0x7E,
+  0x71, 0x88, 0x62, 0x88, 0x7E, 0x5A, 0x5B, 0x99,
+  0x99, 0xA1, 0x5C, 0xA7, 0x38, 0x26, 0x23, 0x21,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+  0x26, 0x2C, 0xB0, 0xAF, 0x63, 0x99, 0x99, 0x99,
+  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+  0x99, 0x99, 0x9D, 0x80, 0x35, 0x35, 0x35, 0x35,
+  0x2C, 0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x93, 0x44, 0x3E, 0xB1, 0x6C, 0x75, 0xA0, 0xAF,
+  0x74, 0x83, 0x83, 0x74, 0x5A, 0x63, 0x99, 0x99,
+  0x99, 0x99, 0x5B, 0xB2, 0x36, 0x34, 0x26, 0x23,
+  0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x2E, 0x53,
+  0x4D, 0x41, 0xB3, 0xB4, 0x9A, 0x9A, 0x9A, 0x9A,
+  0x9B, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+  0x99, 0x99, 0x9D, 0x6F, 0x58, 0x35, 0x21, 0x35,
+  0x24, 0x51, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x45, 0x41, 0xA8, 0x74, 0x75, 0x63, 0x75,
+  0x5C, 0x5A, 0x5A, 0x5C, 0x75, 0x5B, 0x99, 0x99,
+  0x99, 0x9D, 0x9A, 0x9A, 0xB3, 0x41, 0x94, 0x2F,
+  0x25, 0x49, 0x3A, 0x3A, 0x3A, 0x40, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x23, 0x3C, 0x46, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x9A, 0x9B, 0x9D, 0x9D, 0x9D, 0x9D, 0x99, 0x99,
+  0x99, 0x9D, 0x9D, 0x66, 0xB2, 0x28, 0x24, 0x26,
+  0x30, 0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+  0x47, 0x4E, 0x39, 0x8F, 0x6C, 0x75, 0x5B, 0x99,
+  0x65, 0x99, 0x99, 0x65, 0x99, 0x67, 0x9B, 0x67,
+  0x9D, 0x9A, 0x47, 0x47, 0x47, 0xB5, 0xB6, 0x94,
+  0x3D, 0x91, 0x93, 0x47, 0x93, 0x3A, 0x40, 0x20,
+  0x20, 0x20, 0xB7, 0x96, 0x53, 0x91, 0xB8, 0xB9,
+  0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9,
+  0xB8, 0x72, 0x46, 0x46, 0x46, 0x46, 0x9B, 0x99,
+  0x9A, 0x46, 0x46, 0x46, 0x9A, 0x80, 0x90, 0x91,
+  0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0x47, 0xB5,
+  0xB5, 0xB5, 0x46, 0xB5, 0x47, 0xB5, 0xB5, 0x47,
+  0x47, 0xB5, 0x91, 0x51, 0x9B, 0x75, 0x5B, 0x9A,
+  0x46, 0x46, 0x46, 0x9A, 0x9A, 0x46, 0xB5, 0x9A,
+  0x9A, 0x9A, 0xB9, 0xB9, 0xB9, 0xB9, 0x69, 0x69,
+  0x4B, 0xBA, 0xB9, 0xB9, 0xB9, 0xB8, 0x3A, 0x40,
+  0x20, 0x20, 0x22, 0x53, 0x91, 0xB9, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xB8, 0x46, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
+  0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x51, 0x9A,
+  0x9A, 0x9A, 0x9A, 0x46, 0xB4, 0x69, 0x69, 0xB3,
+  0x46, 0x46, 0x46, 0xB5, 0x46, 0xB3, 0x69, 0x69,
+  0xB8, 0x69, 0xB3, 0x9A, 0x46, 0x9B, 0x9A, 0x9A,
+  0x9A, 0x9A, 0x9A, 0x9A, 0x46, 0xB3, 0xB8, 0xB3,
+  0x46, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0x69, 0x46,
+  0xB4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBA, 0x93, 0x49,
+  0x20, 0x20, 0x50, 0x46, 0xB8, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC,
+  0xB3, 0xB3, 0xBC, 0xBC, 0xBC, 0xBC, 0xB8, 0xB5,
+  0xB9, 0xBC, 0xBC, 0xBC, 0xB9, 0x46, 0xB9, 0xBC,
+  0xBC, 0xBC, 0xB9, 0xB9, 0xBC, 0xBB, 0xBB, 0xBC,
+  0xBA, 0x46, 0xB5, 0xB3, 0xBD, 0xBC, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBC, 0xB9, 0x91, 0x46, 0xB9,
+  0xBC, 0xBC, 0xBC, 0xB9, 0xB9, 0xBB, 0xBB, 0xBD,
+  0x46, 0xB9, 0xBB, 0xBB, 0xBB, 0xBC, 0x9A, 0xB5,
+  0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0x69, 0x46, 0x34,
+  0x20, 0x21, 0x90, 0xB5, 0xBD, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xB9, 0xB8, 0xB8, 0xB8, 0xBA, 0xB9, 0xB9,
+  0x46, 0xBA, 0xBB, 0xBB, 0xBB, 0xBC, 0x51, 0x9A,
+  0xBC, 0xBB, 0xBB, 0xBB, 0xB8, 0x9A, 0xBC, 0xBB,
+  0xBB, 0xBB, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xBC, 0x46, 0xB4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xB8, 0x9A, 0xBC,
+  0xBB, 0xBB, 0xBB, 0xBD, 0xBB, 0xBB, 0xBB, 0xBA,
+  0x46, 0xBC, 0xBB, 0xBB, 0xBB, 0xB9, 0x46, 0x46,
+  0xB9, 0xBB, 0xBB, 0xBB, 0xBC, 0x91, 0x44, 0x23,
+  0x20, 0x21, 0x42, 0xB5, 0xBD, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xB9, 0xB8, 0xB8, 0xB8, 0xB8, 0x51, 0x46,
+  0x46, 0xBD, 0xBB, 0xBB, 0xBB, 0xB9, 0x46, 0xB8,
+  0xBB, 0xBB, 0xBB, 0xBB, 0x9A, 0xB8, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xBB, 0x46, 0xB9, 0xBB, 0xBB, 0xBB, 0xBC, 0x69,
+  0x91, 0xB8, 0xBB, 0xBB, 0xBB, 0xB9, 0xB8, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x69,
+  0xB3, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xBC, 0xBC,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xB9, 0x47, 0x52, 0x20,
+  0x20, 0x22, 0x41, 0x46, 0xBD, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBD, 0xB5,
+  0x9A, 0xBC, 0xBB, 0xBB, 0xBB, 0xB8, 0xB5, 0xB9,
+  0xBB, 0xBB, 0xBB, 0xBD, 0xB5, 0xB9, 0xBB, 0xBB,
+  0xBB, 0xBC, 0x69, 0xB3, 0xBD, 0xBB, 0xBB, 0xBB,
+  0xBD, 0xB4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBC, 0xBD,
+  0xBD, 0xBD, 0xBB, 0xBB, 0xBB, 0xB8, 0xB9, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x46,
+  0xBA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xB8, 0xB5, 0x50, 0x20,
+  0x20, 0x21, 0x32, 0x92, 0xB3, 0xB9, 0xBD, 0xBC,
+  0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x51,
+  0xB8, 0xBB, 0xBB, 0xBB, 0xBC, 0xB3, 0x51, 0xBC,
+  0xBB, 0xBB, 0xBB, 0xBA, 0x51, 0xBD, 0xBB, 0xBB,
+  0xBB, 0xB8, 0x46, 0x46, 0xBD, 0xBB, 0xBB, 0xBB,
+  0xB9, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xB3, 0xBD, 0xBB,
+  0xBB, 0xBB, 0xBC, 0xB9, 0xB8, 0xB8, 0xB8, 0x46,
+  0xBD, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xBC, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0x9A, 0x91, 0x25, 0x20,
+  0x21, 0x32, 0x92, 0xB3, 0xB4, 0xB4, 0xB4, 0x9A,
+  0x9A, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x46,
+  0xB9, 0xBB, 0xBB, 0xBB, 0xBC, 0xB4, 0xB8, 0xBB,
+  0xBB, 0xBB, 0xBB, 0x69, 0x69, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xB8, 0x9A, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xB8, 0xBA, 0xBB, 0xBB, 0xBB, 0xBC, 0x69, 0xB4,
+  0xB4, 0xB4, 0xB3, 0x69, 0xB3, 0xB4, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBA, 0x46, 0xB5, 0xB5, 0x91, 0xB4,
+  0xBC, 0xBB, 0xBB, 0xBB, 0xB9, 0x91, 0x51, 0xBD,
+  0xBB, 0xBB, 0xBB, 0xBD, 0x46, 0x3F, 0x21, 0x20,
+  0x24, 0x42, 0x9A, 0xBD, 0xBC, 0xBC, 0xBC, 0xBC,
+  0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xB9, 0x46,
+  0xBD, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xBC, 0xBB,
+  0xBB, 0xBB, 0xBD, 0x91, 0xBA, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBD,
+  0x51, 0xBA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBD, 0xB9,
+  0xB9, 0xB9, 0xBD, 0xBD, 0x46, 0xB8, 0xBB, 0xBB,
+  0xBB, 0xBC, 0xB4, 0x46, 0xA5, 0x85, 0x46, 0xB8,
+  0xBB, 0xBB, 0xBB, 0xBB, 0x69, 0x91, 0x9A, 0xBC,
+  0xBB, 0xBB, 0xBB, 0xBA, 0xB5, 0xBE, 0x21, 0x20,
+  0x50, 0x46, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xB3, 0x46,
+  0xB9, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xBD, 0xB3, 0xB5, 0xBD, 0xBB, 0xBB, 0xBB,
+  0xBD, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x69,
+  0x51, 0xB3, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+  0xBB, 0xBB, 0xBB, 0xB8, 0xB5, 0xB9, 0xBB, 0xBB,
+  0xBB, 0xBD, 0x46, 0xB4, 0x80, 0x3E, 0xB5, 0xB9,
+  0xBB, 0xBB, 0xBB, 0xBC, 0x9A, 0xB5, 0xB8, 0xBB,
+  0xBB, 0xBB, 0xBB, 0x69, 0x91, 0x38, 0x21, 0x20,
+  0x34, 0x49, 0x69, 0xBA, 0xB9, 0xB9, 0xBD, 0xBD,
+  0xBD, 0xBD, 0xBD, 0xB9, 0xBA, 0x9A, 0x44, 0x8C,
+  0x91, 0xB8, 0xB9, 0xBD, 0xBD, 0xBD, 0xBD, 0xB9,
+  0xB8, 0x9A, 0x46, 0x9A, 0xBC, 0xBB, 0xBB, 0xBB,
+  0xB8, 0x69, 0xB9, 0xBD, 0xBD, 0xB9, 0xB3, 0x4E,
+  0x50, 0xB4, 0xB3, 0xB9, 0xB9, 0xBD, 0xBD, 0xBD,
+  0xB9, 0xB9, 0xB8, 0x51, 0x69, 0xB8, 0xBA, 0xB9,
+  0xB9, 0xB8, 0xB4, 0x9F, 0x36, 0x8C, 0x4D, 0xB8,
+  0xB9, 0xB9, 0xB9, 0xB8, 0x43, 0x54, 0xB8, 0xB9,
+  0xB9, 0xB9, 0xBA, 0x9A, 0x39, 0x96, 0x21, 0x20,
+  0x20, 0x34, 0x39, 0x91, 0x47, 0x93, 0x46, 0x46,
+  0x46, 0x46, 0x46, 0xB5, 0xB5, 0x44, 0x32, 0x28,
+  0x3A, 0x46, 0xB5, 0x46, 0x46, 0x46, 0x46, 0xB5,
+  0xB5, 0xB4, 0xB5, 0xB8, 0xBB, 0xBB, 0xBB, 0xBC,
+  0xB4, 0x51, 0xB5, 0x91, 0xB5, 0xB5, 0x4E, 0x2D,
+  0x28, 0x38, 0x45, 0x47, 0xB5, 0x46, 0x46, 0xB5,
+  0xB5, 0xB5, 0x93, 0x53, 0xAE, 0xB6, 0xB5, 0xB5,
+  0xB5, 0xB3, 0x98, 0x2E, 0x34, 0x27, 0x49, 0x3B,
+  0xB5, 0x47, 0x93, 0x4A, 0x40, 0x2C, 0x54, 0x47,
+  0x47, 0x47, 0x46, 0x39, 0x96, 0xB7, 0x20, 0x20,
+  0x20, 0x20, 0x34, 0x49, 0x53, 0x4D, 0x90, 0x4F,
+  0x8B, 0x8B, 0x4F, 0x4D, 0x39, 0x26, 0x21, 0x21,
+  0x22, 0x2E, 0x53, 0x90, 0x8B, 0x8B, 0x4F, 0x48,
+  0x3D, 0x8C, 0x4F, 0xB8, 0xB9, 0xB9, 0xB9, 0xB9,
+  0x4B, 0x3A, 0x95, 0x3E, 0x4F, 0x3A, 0x29, 0x21,
+  0xB7, 0x21, 0x32, 0x3A, 0x48, 0x3E, 0x3E, 0x90,
+  0x3B, 0x3A, 0x40, 0x30, 0xBF, 0x52, 0x8D, 0x4D,
+  0x48, 0x3A, 0x2D, 0x32, 0x25, 0x23, 0x22, 0x39,
+  0x54, 0x54, 0x54, 0x40, 0x21, 0xB7, 0x2C, 0x54,
+  0x54, 0x54, 0x39, 0x96, 0xB7, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21,
+  0x22, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20, 0x21,
+  0x21, 0x21, 0x21, 0x21, 0x23, 0x23, 0x24, 0x24,
+  0x27, 0x29, 0x49, 0x48, 0x47, 0x47, 0x47, 0x51,
+  0x3A, 0x21, 0x21, 0x22, 0x21, 0x20, 0x20, 0x21,
+  0x21, 0x21, 0x21, 0x20, 0x21, 0x22, 0x22, 0x21,
+  0x20, 0x21, 0x23, 0x26, 0x29, 0x2A, 0x38, 0x38,
+  0x2A, 0x29, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x21, 0x20, 0x21, 0x20, 0x20, 0x20, 0x20, 0x22,
+  0x22, 0x22, 0x23, 0x4C, 0x3B, 0x4D, 0x95, 0x3A,
+  0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x21, 0x28, 0x24, 0x24, 0x24,
+  0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+};
 
+
+unsigned char linux_logo_bw[] __initdata = {
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xCF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
+  0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+  0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFD, 0xFF, 0xF3, 0xDF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xF7, 0xEF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF,
+  0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
+  0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF,
+  0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
+  0x9F, 0x87, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFB, 0x0F, 0x03, 0xFB, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFB, 0x67, 0x33, 0xFB, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xE7, 0x79,
+  0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
+  0xF7, 0x79, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFB, 0xFF, 0xF9, 0xF7, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFB, 0x60, 0x3B, 0xF7, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x89, 0x07,
+  0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
+  0x00, 0x03, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFB, 0x00, 0x0D, 0xFB, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFB, 0x80, 0x33, 0xFD, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xC0, 0xC3,
+  0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
+  0xFF, 0x0D, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFB, 0x40, 0x31, 0xEE, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xF7, 0x20, 0xC1, 0xEE, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x1F, 0x00,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF,
+  0x00, 0x00, 0x7F, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xEE, 0x00, 0x00, 0x7F, 0xBF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xDE, 0x00, 0x00, 0x7F, 0xDF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0x00, 0x00,
+  0x3F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C,
+  0x00, 0x00, 0x3F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7C, 0x00, 0x00, 0x1F, 0xF7, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFE, 0xFF, 0x1C, 0x07, 0xDF, 0xFB,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFC, 0x08, 0x0F,
+  0xEF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF8,
+  0x00, 0x01, 0xEF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFB, 0xF0, 0x00, 0x00, 0x7F, 0xFE, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFB, 0xE0, 0x00, 0x00, 0x1F, 0xFE,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xE0, 0x00, 0x00,
+  0x07, 0xBF, 0x7F, 0xFF, 0xFF, 0xFF, 0xF7, 0xC0,
+  0x00, 0x00, 0x03, 0xBF, 0x7F, 0xFF, 0xFF, 0xFF,
+  0xEF, 0xC0, 0x00, 0x00, 0x03, 0xDF, 0xBF, 0xFF,
+  0xFF, 0xFF, 0xEF, 0x80, 0x00, 0x00, 0x03, 0xDF,
+  0xBF, 0xFF, 0xFF, 0xFF, 0xDF, 0x80, 0x00, 0x00,
+  0x03, 0xDF, 0xBF, 0xFF, 0xFF, 0xFF, 0xDF, 0x80,
+  0x00, 0x00, 0x01, 0xEF, 0xDF, 0xFF, 0xFF, 0xFF,
+  0xDF, 0x80, 0x00, 0x00, 0x01, 0xEF, 0xDF, 0xFF,
+  0xFF, 0xFF, 0xBF, 0x00, 0x20, 0x00, 0x01, 0xEF,
+  0xDF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0x20, 0x00,
+  0x01, 0xEF, 0xDF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00,
+  0x20, 0x00, 0x01, 0xEF, 0xDF, 0xFF, 0xFF, 0xFF,
+  0xBF, 0x00, 0x20, 0x00, 0x01, 0xEF, 0xDF, 0xFF,
+  0xFF, 0xFF, 0xBF, 0x00, 0x20, 0x00, 0x03, 0x03,
+  0xDF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0x20, 0x00,
+  0x02, 0xFD, 0xDF, 0xFF, 0xFF, 0xFF, 0xA3, 0x80,
+  0x00, 0x00, 0x1F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF,
+  0xC1, 0xC0, 0x00, 0x00, 0x11, 0xFF, 0x3F, 0xFF,
+  0xFF, 0xFF, 0x80, 0xE0, 0x00, 0x00, 0x21, 0xFE,
+  0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x70, 0x00, 0x00,
+  0x21, 0xFC, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x3C,
+  0x00, 0x00, 0x20, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0,
+  0x00, 0x3E, 0x00, 0x00, 0x20, 0x00, 0x3F, 0xFF,
+  0xFF, 0xC0, 0x00, 0x1F, 0x00, 0x00, 0x20, 0x00,
+  0x3F, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0x80, 0x00,
+  0x20, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x0F,
+  0x80, 0x00, 0x20, 0x00, 0x07, 0xFF, 0xFE, 0x00,
+  0x00, 0x07, 0x80, 0x00, 0x20, 0x00, 0x03, 0x87,
+  0xF8, 0x00, 0x00, 0x07, 0x80, 0x00, 0x60, 0x00,
+  0x01, 0x01, 0xF1, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x3C, 0x7D, 0xE7, 0xFF, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3C, 0x7C, 0xE7, 0xFF,
+  0x3E, 0x7B, 0xBE, 0x0F, 0xE1, 0xCF, 0x7C, 0x79,
+  0xCF, 0x80, 0x3E, 0x7B, 0xFF, 0x9F, 0xF9, 0xFF,
+  0x78, 0xF9, 0xCF, 0xF8, 0x7C, 0x73, 0xFF, 0xBE,
+  0x79, 0xFE, 0x7F, 0xF9, 0xCF, 0xFC, 0x7C, 0xF7,
+  0xC7, 0xBF, 0xFB, 0xFE, 0xFF, 0xF3, 0xE7, 0xFE,
+  0x78, 0xF7, 0x87, 0xBF, 0xFB, 0xF0, 0xFF, 0xF3,
+  0xC0, 0x3E, 0xF9, 0xE7, 0x8F, 0x7C, 0x03, 0xC0,
+  0xF8, 0xF3, 0x9F, 0xFE, 0xFF, 0xEF, 0xFF, 0x7F,
+  0xF3, 0xC4, 0xF1, 0xF3, 0x9F, 0xFC, 0x7F, 0xCF,
+  0xFE, 0x3F, 0xF7, 0xC9, 0xF1, 0xE7, 0x9F, 0xF8,
+  0x3F, 0x0F, 0x3C, 0x9F, 0xC7, 0x99, 0xF1, 0xE7,
+  0xC0, 0x03, 0x00, 0x1E, 0x01, 0xC0, 0x00, 0x3C,
+  0x04, 0x0F, 0xE0, 0x07, 0xC0, 0xDE, 0x03, 0xE0,
+  0x38, 0x7E, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+
+unsigned char linux_logo16[] __initdata = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
+  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x08, 0x70, 0x00, 0x00, 0x00, 0x77, 0x70, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x87, 0x77, 0x00, 0x00, 0x07, 0xFF, 0xF7, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+  0x77, 0xFF, 0x00, 0x00, 0x7F, 0x77, 0xF7, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+  0x70, 0x0F, 0x80, 0x00, 0xF7, 0x08, 0x7F, 0x70,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+  0x80, 0x07, 0x80, 0x00, 0xF8, 0x00, 0x8F, 0x70,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+  0x70, 0x07, 0x88, 0x88, 0xF8, 0x00, 0x8F, 0x70,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0xF0, 0x06, 0xE6, 0xE6, 0xE6, 0x00, 0x8F, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x77, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x77, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x06, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0x00,
+  0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x60,
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+  0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0x60,
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+  0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x66, 0x66, 0x80,
+  0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+  0x86, 0xE6, 0xE6, 0xE6, 0x66, 0x66, 0x66, 0x80,
+  0x08, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+  0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x70,
+  0x00, 0x77, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x87, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x78,
+  0x00, 0x88, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x87, 0x76, 0x66, 0x66, 0x77, 0x77, 0xFF, 0xF7,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
+  0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF,
+  0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
+  0xFF, 0x77, 0x77, 0x77, 0x7F, 0xFF, 0xFF, 0xFF,
+  0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8F,
+  0xFF, 0xF7, 0x77, 0x77, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x7F,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x87, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x77,
+  0xFF, 0xF7, 0x77, 0xFF, 0xFF, 0xFF, 0x77, 0x77,
+  0x77, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x7F,
+  0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x77,
+  0x77, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7F, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF7, 0x77, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x80, 0x08, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x77, 0x80, 0x00, 0x08, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0x78, 0x00, 0x08, 0x80, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x08, 0x00, 0x8F, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xF7, 0x08, 0x80, 0x80, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x08, 0x08, 0x7F, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xF7, 0x08, 0x80, 0x80, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x08, 0x07, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x08, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x80, 0x80, 0x0F, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x08, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x80, 0x8F, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x08, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x08, 0x08, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x08, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x08, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x08, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x08, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x08, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x88, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xF0, 0x88, 0x88, 0x80, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x08, 0x06, 0xE6, 0x00, 0x8F, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x08, 0x80,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x6E, 0x6E, 0x60, 0x08, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x88,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x06, 0xE6, 0xE6, 0xE6, 0x00, 0x8F, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFE, 0x6E, 0x60, 0x00, 0x00, 0x00, 0x00,
+  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x6E, 0x6E, 0x6E, 0x6E, 0x60, 0x08, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xF6, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x06,
+  0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xE6, 0xE6,
+  0xE6, 0xE6, 0xE6, 0xE6, 0xE0, 0x00, 0x8F, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFE, 0x6E, 0x60, 0x00, 0x00, 0x00, 0x0E,
+  0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x6E, 0x6E,
+  0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x00, 0x08, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0x76, 0xE6, 0xE6, 0x00, 0x00, 0x00, 0xE6,
+  0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xE6, 0xE6,
+  0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE0, 0x00, 0x8F,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF7, 0x7E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E,
+  0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x6E, 0x6E,
+  0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x60, 0x00, 0x08,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF7, 0x76, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+  0xE6, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xE6, 0xE6,
+  0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0x00, 0x00,
+  0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF7, 0x7E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E,
+  0x6E, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x87, 0x77, 0x7F, 0x7F, 0x7E,
+  0x7E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x60, 0x00,
+  0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF7, 0x76, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+  0xE6, 0xF7, 0xE7, 0x80, 0x08, 0x78, 0x78, 0x00,
+  0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE0, 0x00,
+  0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xF7, 0x7E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x7E,
+  0x6F, 0xFF, 0xFF, 0x88, 0x8F, 0xFF, 0xF7, 0x80,
+  0x00, 0x00, 0x7F, 0x7C, 0xCC, 0xCC, 0xCC, 0xCC,
+  0x7E, 0xFF, 0xFF, 0x7E, 0x7F, 0xFF, 0x7E, 0xFF,
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+  0xFF, 0xFF, 0xF6, 0xE7, 0xFF, 0xF7, 0xEF, 0xFF,
+  0xEF, 0xCC, 0xCC, 0x77, 0xF7, 0xCC, 0xC7, 0x78,
+  0x00, 0x07, 0xFC, 0x44, 0x44, 0x44, 0x44, 0x44,
+  0x7F, 0x7F, 0xF7, 0xF7, 0xFF, 0xFF, 0xF7, 0xFF,
+  0xF7, 0xFF, 0xF7, 0x7F, 0xFF, 0xFF, 0xF7, 0x77,
+  0x77, 0x7F, 0xFE, 0x7F, 0xFF, 0xFF, 0xF7, 0x77,
+  0xF7, 0x4C, 0x4C, 0x7F, 0x74, 0x44, 0x4C, 0xF8,
+  0x00, 0x8F, 0x74, 0x44, 0x44, 0x44, 0x44, 0x44,
+  0x7F, 0x44, 0x44, 0x7F, 0xC4, 0x44, 0xCF, 0xC4,
+  0x44, 0xCC, 0x44, 0x44, 0xCF, 0xF7, 0xC4, 0x44,
+  0x44, 0x44, 0xCF, 0xFC, 0x44, 0x4C, 0xC4, 0x4C,
+  0xFC, 0x44, 0x4C, 0xFF, 0x74, 0x44, 0xC7, 0xF8,
+  0x00, 0x7F, 0xC4, 0x44, 0x4C, 0x77, 0x7C, 0xC7,
+  0xFC, 0x44, 0x4C, 0xF7, 0x44, 0x44, 0x7F, 0x44,
+  0x44, 0xC4, 0x44, 0x44, 0x4F, 0xF4, 0x44, 0x44,
+  0xC4, 0x44, 0x47, 0xF4, 0x44, 0x4C, 0x44, 0x4C,
+  0xF4, 0x44, 0x4C, 0xFF, 0xC4, 0x44, 0x4F, 0xF0,
+  0x00, 0x7F, 0xC4, 0x44, 0x4C, 0xC7, 0x77, 0xFF,
+  0xFC, 0x44, 0x4C, 0xF7, 0x44, 0x44, 0xF7, 0x44,
+  0x44, 0x44, 0x44, 0x44, 0x4F, 0xC4, 0x44, 0x47,
+  0xF7, 0x44, 0x4C, 0x74, 0x44, 0x44, 0x44, 0x47,
+  0xF4, 0x44, 0x44, 0x44, 0x44, 0x44, 0xCF, 0x70,
+  0x00, 0x7F, 0xC4, 0x44, 0x44, 0x44, 0x44, 0xCF,
+  0xF4, 0x44, 0x4C, 0xFC, 0x44, 0x4C, 0xFC, 0x44,
+  0x4C, 0x7F, 0x44, 0x44, 0xC7, 0xC4, 0x44, 0xCC,
+  0xCC, 0x44, 0x47, 0xC4, 0x44, 0x44, 0x44, 0xCF,
+  0xC4, 0x44, 0x44, 0x44, 0x44, 0x44, 0x7F, 0x80,
+  0x00, 0x0F, 0x7C, 0xC4, 0xC4, 0x44, 0x44, 0x4F,
+  0x74, 0x44, 0xC7, 0xFC, 0x44, 0x4C, 0xFC, 0x44,
+  0x4C, 0xFF, 0xC4, 0x44, 0xC7, 0x44, 0x44, 0x44,
+  0x44, 0x44, 0x4F, 0xC4, 0x44, 0x4C, 0x7C, 0x7F,
+  0xC4, 0x44, 0x44, 0xC4, 0x44, 0x44, 0xFF, 0x00,
+  0x08, 0x77, 0xFF, 0x7F, 0xF7, 0x44, 0x44, 0x4F,
+  0xC4, 0x44, 0x4F, 0x74, 0x44, 0x47, 0x74, 0x44,
+  0x47, 0xFC, 0x44, 0x44, 0x7C, 0x44, 0x44, 0xF7,
+  0xFF, 0x7F, 0x7F, 0x44, 0x44, 0x7F, 0xFF, 0xF7,
+  0x44, 0x44, 0x7F, 0xFC, 0x44, 0x4C, 0xF7, 0x00,
+  0x0F, 0xFC, 0x44, 0x44, 0x44, 0x44, 0x44, 0xCF,
+  0xC4, 0x44, 0x44, 0x44, 0x44, 0xCF, 0xC4, 0x44,
+  0x44, 0xC4, 0x44, 0x4C, 0xF7, 0x44, 0x44, 0xCC,
+  0xCC, 0x4C, 0xF7, 0x44, 0x44, 0xFF, 0xC7, 0xF7,
+  0x44, 0x44, 0x77, 0xF4, 0x44, 0x4C, 0xF7, 0x00,
+  0x8F, 0xC4, 0x44, 0x44, 0x44, 0x44, 0x4C, 0x7F,
+  0xC4, 0x44, 0x44, 0x44, 0x4C, 0x7F, 0xC4, 0x44,
+  0xC4, 0x44, 0x44, 0x47, 0xF7, 0xC4, 0x44, 0x44,
+  0x44, 0x47, 0xFC, 0x44, 0x4C, 0xF7, 0x67, 0xFC,
+  0x44, 0x4C, 0xFF, 0x74, 0x44, 0x47, 0xF8, 0x00,
+  0x87, 0x77, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0x77,
+  0xF7, 0xCC, 0xCC, 0xCC, 0xCF, 0xFF, 0x44, 0x44,
+  0x77, 0xCC, 0xCC, 0x7F, 0x87, 0xFC, 0xCC, 0xCC,
+  0xCC, 0x7F, 0x7C, 0x7C, 0xC7, 0xE7, 0x08, 0x7C,
+  0x7C, 0xCC, 0xFC, 0x7C, 0x7C, 0x7F, 0x80, 0x00,
+  0x08, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+  0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x44, 0x44,
+  0xFF, 0xFF, 0xFF, 0xF8, 0x08, 0x7F, 0xFF, 0xFF,
+  0xFF, 0xF8, 0x7E, 0xFF, 0xFF, 0xC0, 0x00, 0x77,
+  0xFF, 0xFF, 0x88, 0x7F, 0xFF, 0xF6, 0x00, 0x00,
+  0x00, 0x88, 0x77, 0x77, 0x77, 0x77, 0x80, 0x00,
+  0x08, 0x77, 0x77, 0x77, 0x88, 0x77, 0xCC, 0xCC,
+  0xF6, 0x77, 0x77, 0x00, 0x00, 0x07, 0x77, 0x77,
+  0x78, 0x60, 0x08, 0x87, 0x88, 0x00, 0x00, 0x08,
+  0x78, 0x78, 0x00, 0x88, 0x78, 0x70, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xFF, 0xFF,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x77, 0x77,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+
+#endif /* INCLUDE_LINUX_LOGO_DATA */
+
+#include <linux/linux_logo.h>
diff -urN linux-2.4.10-pre5/include/asm-sh/machvec.h linux/include/asm-sh/machvec.h
--- linux-2.4.10-pre5/include/asm-sh/machvec.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/machvec.h	Mon Dec  3 23:08:14 2001
@@ -76,6 +76,8 @@
 	unsigned int mv_hw_hd64465 : 1;
 	unsigned int mv_hw_dreamcast : 1;
 	unsigned int mv_hw_bigsur : 1;
+	unsigned int mv_hw_7751se: 1;
+	unsigned int mv_hw_adx : 1;
 };
 
 extern struct sh_machine_vector sh_mv;
@@ -92,13 +94,19 @@
 #define MACH_SH2000	(sh_mv.mv_hw_sh2000)
 #define MACH_DREAMCAST	(sh_mv.mv_hw_dreamcast)
 #define MACH_BIGSUR	(sh_mv.mv_hw_bigsur)
+#define MACH_7751SE	(sh_mv.mv_hw_7751se)
+#define MACH_ADX	(sh_mv.mv_hw_adx)
 #else
-# if defined(CONFIG_SH_SOLUTION_ENGINE) || \
-     defined(CONFIG_SH_7751_SOLUTION_ENGINE)
+# ifdef CONFIG_SH_SOLUTION_ENGINE
 #  define MACH_SE		1
 # else
 #  define MACH_SE		0
 # endif
+# ifdef CONFIG_SH_7751_SOLUTION_ENGINE
+#  define MACH_7751SE		1
+# else
+#  define MACH_7751SE		0
+# endif
 # ifdef CONFIG_SH_HP600
 #  define MACH_HP600		1
 # else
@@ -119,7 +127,6 @@
 # else
 #  define MACH_HP690		0
 # endif
-# endif
 # ifdef CONFIG_HD64461
 #  define MACH_HD64461		1
 # else
@@ -149,6 +156,12 @@
 #  define MACH_BIGSUR		1
 # else
 #  define MACH_BIGSUR		0
+# endif
+# ifdef CONFIG_SH_ADX
+#  define MACH_ADX		1
+# else
+#  define MACH_ADX		0
+# endif
 #endif
 
 #endif /* _ASM_SH_MACHVEC_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/mmu_context.h linux/include/asm-sh/mmu_context.h
--- linux-2.4.10-pre5/include/asm-sh/mmu_context.h	Thu Jan  4 13:19:13 2001
+++ linux/include/asm-sh/mmu_context.h	Mon Dec  3 23:08:14 2001
@@ -29,7 +29,7 @@
  */
 #define MMU_VPN_MASK	0xfffff000
 
-extern __inline__ void
+static __inline__ void
 get_new_mmu_context(struct mm_struct *mm)
 {
 	extern void flush_tlb_all(void);
@@ -51,7 +51,7 @@
 /*
  * Get MMU context if needed.
  */
-extern __inline__ void
+static __inline__ void
 get_mmu_context(struct mm_struct *mm)
 {
 	if (mm) {
@@ -67,8 +67,8 @@
  * Initialize the context related info for a new mm_struct
  * instance.
  */
-extern __inline__ int init_new_context(struct task_struct *tsk,
-					struct mm_struct *mm)
+static __inline__ int init_new_context(struct task_struct *tsk,
+				       struct mm_struct *mm)
 {
 	mm->context = NO_CONTEXT;
 	return 0;
@@ -78,7 +78,7 @@
  * Destroy context related info for an mm_struct that is about
  * to be put to rest.
  */
-extern __inline__ void destroy_context(struct mm_struct *mm)
+static __inline__ void destroy_context(struct mm_struct *mm)
 {
 	/* Do nothing */
 }
@@ -126,7 +126,7 @@
 #define MMU_ITLB_VALID		0x100
 #endif
 
-extern __inline__ void set_asid(unsigned long asid)
+static __inline__ void set_asid(unsigned long asid)
 {
 	unsigned long __dummy;
 
@@ -139,7 +139,7 @@
 			        "r" (0xffffff00));
 }
 
-extern __inline__ unsigned long get_asid(void)
+static __inline__ unsigned long get_asid(void)
 {
 	unsigned long asid;
 
@@ -154,7 +154,7 @@
  * After we have set current->mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
  */
-extern __inline__ void activate_context(struct mm_struct *mm)
+static __inline__ void activate_context(struct mm_struct *mm)
 {
 	get_mmu_context(mm);
 	set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
@@ -162,7 +162,7 @@
 
 /* MMU_TTB can be used for optimizing the fault handling.
    (Currently not used) */
-extern __inline__ void switch_mm(struct mm_struct *prev,
+static __inline__ void switch_mm(struct mm_struct *prev,
 				 struct mm_struct *next,
 				 struct task_struct *tsk, unsigned int cpu)
 {
@@ -181,7 +181,7 @@
 #define activate_mm(prev, next) \
 	switch_mm((prev),(next),NULL,smp_processor_id())
 
-extern __inline__ void
+static __inline__ void
 enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
 {
 }
diff -urN linux-2.4.10-pre5/include/asm-sh/page.h linux/include/asm-sh/page.h
--- linux-2.4.10-pre5/include/asm-sh/page.h	Sun Dec  3 17:48:19 2000
+++ linux/include/asm-sh/page.h	Mon Dec  3 23:08:14 2001
@@ -24,8 +24,8 @@
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
-#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
-#define copy_page(to,from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+extern void clear_page(void *to);
+extern void copy_page(void *to, void *from);
 
 #if defined(__sh3__)
 #define clear_user_page(page, vaddr)	clear_page(page)
@@ -33,6 +33,8 @@
 #elif defined(__SH4__)
 extern void clear_user_page(void *to, unsigned long address);
 extern void copy_user_page(void *to, void *from, unsigned long address);
+extern void __clear_user_page(void *to, void *orig_to);
+extern void __copy_user_page(void *to, void *from, void *orig_to);
 #endif
 
 /*
@@ -67,12 +69,24 @@
  */
 
 #define __MEMORY_START		CONFIG_MEMORY_START
+#define __MEMORY_SIZE		CONFIG_MEMORY_SIZE
+#ifdef CONFIG_DISCONTIGMEM
+/* Just for HP690, for now.. */
+#define __MEMORY_START_2ND	(__MEMORY_START+0x02000000)
+#define __MEMORY_SIZE_2ND	0x001000000 /* 16MB */
+#endif
 
 #define PAGE_OFFSET		(0x80000000UL)
 #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
-#define virt_to_page(kaddr)	(mem_map + ((__pa(kaddr)-__MEMORY_START) >> PAGE_SHIFT))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define phys_to_page(phys)	(mem_map + (((phys)-__MEMORY_START) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+#define page_to_phys(page)	(((page - mem_map) << PAGE_SHIFT) + __MEMORY_START)
+#endif
+
+#define virt_to_page(kaddr)	phys_to_page(__pa(kaddr))
 
 #ifndef __ASSEMBLY__
 
@@ -89,7 +103,7 @@
 } while (0)
 
 /* Pure 2^n version of get_order */
-extern __inline__ int get_order(unsigned long size)
+static __inline__ int get_order(unsigned long size)
 {
 	int order;
 
diff -urN linux-2.4.10-pre5/include/asm-sh/pci.h linux/include/asm-sh/pci.h
--- linux-2.4.10-pre5/include/asm-sh/pci.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/pci.h	Mon Dec  3 23:08:14 2001
@@ -3,6 +3,8 @@
 
 #ifdef __KERNEL__
 
+#include <linux/config.h>
+
 /* Can be used to override the logic in pci_scan_bus for skipping
    already-configured bus numbers - to be used for buggy BIOSes
    or architectures with incomplete PCI setup by the loader */
@@ -24,7 +26,7 @@
 #define PCIBIOS_MIN_IO		0x2000
 #define PCIBIOS_MIN_MEM		0xFD000000
 
-#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) && defined(CONFIG_CPU_SUBTYPE_SH7751)
+#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
 #define PCIBIOS_MIN_IO          0x4000
 #define PCIBIOS_MIN_MEM         0xFD000000
 #endif
@@ -32,10 +34,6 @@
 struct pci_dev;
 
 extern void pcibios_set_master(struct pci_dev *dev);
-//static inline void pcibios_set_master(struct pci_dev *dev)
-//{
-	/* No special bus mastering setup handling */
-//}
 
 static inline void pcibios_penalize_isa_irq(int irq)
 {
@@ -80,10 +78,14 @@
  * until either pci_unmap_single or pci_dma_sync_single is performed.
  */
 static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
-					size_t size,int directoin)
+					size_t size, int direction)
 {
-  
-        flush_cache_all();
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+#ifdef CONFIG_SH_PCIDMA_NONCOHERENT
+	dma_cache_wback_inv(ptr, size);
+#endif
 	return virt_to_bus(ptr);
 }
 
@@ -116,9 +118,17 @@
  * the same here.
  */
 static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-			     int nents,int direction)
+			     int nents, int direction)
 {
-        flush_cache_all();
+#ifdef CONFIG_SH_PCIDMA_NONCOHERENT
+	int i;
+
+	for (i=0; i<nents; i++)
+		dma_cache_wback_inv(sg[i].address, sg[i].length);
+#endif
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
 	return nents;
 }
 
@@ -127,7 +137,7 @@
  * pci_unmap_single() above.
  */
 static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-				int nents,int direction)
+				int nents, int direction)
 {
 	/* Nothing to do */
 }
@@ -143,9 +153,15 @@
  */
 static inline void pci_dma_sync_single(struct pci_dev *hwdev,
 				       dma_addr_t dma_handle,
-				       size_t size,int direction)
+				       size_t size, int direction)
 {
-	/* Nothing to do */
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+#ifdef CONFIG_SH_PCIDMA_NONCOHERENT
+	dma_cache_wback_inv(bus_to_virt(dma_handle), size);
+#endif
+	
 }
 
 /* Make physical memory consistent for a set of streaming
@@ -156,9 +172,17 @@
  */
 static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
 				   struct scatterlist *sg,
-				   int nelems,int direction)
+				   int nelems, int direction)
 {
-	/* Nothing to do */
+	if (direction == PCI_DMA_NONE)
+                BUG();
+
+#ifdef CONFIG_SH_PCIDMA_NONCOHERENT
+	int i;
+
+	for (i=0; i<nelems; i++)
+		dma_cache_wback_inv(sg[i].address, sg[i].length);
+#endif
 }
 
 
@@ -167,7 +191,7 @@
  * only drive the low 24-bits during PCI bus mastering, then
  * you would pass 0x00ffffff as the mask to this function.
  */
-extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
+static inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
 {
 	return 1;
 }
diff -urN linux-2.4.10-pre5/include/asm-sh/pgalloc.h linux/include/asm-sh/pgalloc.h
--- linux-2.4.10-pre5/include/asm-sh/pgalloc.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/pgalloc.h	Mon Dec  3 23:08:14 2001
@@ -5,10 +5,10 @@
 #include <linux/threads.h>
 #include <linux/slab.h>
 
-#define pgd_quicklist (current_cpu_data.pgd_quick)
+#define pgd_quicklist ((unsigned long *)0)
 #define pmd_quicklist ((unsigned long *)0)
-#define pte_quicklist (current_cpu_data.pte_quick)
-#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
+#define pte_quicklist ((unsigned long *)0)
+#define pgtable_cache_size 0L
 
 #define pmd_populate(mm, pmd, pte) \
 		set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
@@ -17,7 +17,7 @@
  * Allocate and free page tables.
  */
 
-static inline pgd_t *get_pgd_slow(void)
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 	unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
 	pgd_t *pgd = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL);
@@ -28,36 +28,14 @@
 	return pgd;
 }
 
-static inline pgd_t *get_pgd_fast(void)
-{
-	unsigned long *ret;
-
-	if ((ret = pgd_quicklist) != NULL) {
-		pgd_quicklist = (unsigned long *)(*ret);
-		ret[0] = 0;
-		pgtable_cache_size--;
-	} else
-		ret = (unsigned long *)get_pgd_slow();
-	return (pgd_t *)ret;
-}
-
-static inline void free_pgd_fast(pgd_t *pgd)
-{
-	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
-	pgd_quicklist = (unsigned long *) pgd;
-	pgtable_cache_size++;
-}
-
-static inline void free_pgd_slow(pgd_t *pgd)
+static inline void pgd_free(pgd_t *pgd)
 {
 	kfree(pgd);
 }
 
 static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	pte_t *pte;
-
-	pte = (pte_t *) __get_free_page(GFP_KERNEL);
+	pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL);
 	if (pte)
 		clear_page(pte);
 	return pte;
@@ -65,21 +43,7 @@
 
 static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
-	unsigned long *ret;
-
-	if ((ret = (unsigned long *)pte_quicklist) != NULL) {
-		pte_quicklist = (unsigned long *)(*ret);
-		ret[0] = 0;
-		pgtable_cache_size--;
-	}
-	return (pte_t *)ret;
-}
-
-static inline void pte_free_fast(pte_t *pte)
-{
-	*(unsigned long *)pte = (unsigned long) pte_quicklist;
-	pte_quicklist = (unsigned long *) pte;
-	pgtable_cache_size++;
+	return 0;
 }
 
 static inline void pte_free_slow(pte_t *pte)
@@ -87,9 +51,7 @@
 	free_page((unsigned long)pte);
 }
 
-#define pte_free(pte)		pte_free_fast(pte)
-#define pgd_free(pgd)		free_pgd_fast(pgd)
-#define pgd_alloc(mm)		get_pgd_fast()
+#define pte_free(pte)		pte_free_slow(pte)
 
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
@@ -106,7 +68,8 @@
 #define pmd_free(x)			do { } while (0)
 #define pgd_populate(mm, pmd, pte)	BUG()
 
-extern int do_check_pgt_cache(int, int);
+/* Do nothing */
+static inline int do_check_pgt_cache(int low, int high) { }
 
 /*
  * TLB flushing:
@@ -125,10 +88,69 @@
 extern void flush_tlb_range(struct mm_struct *mm, unsigned long start,
 			    unsigned long end);
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
+extern void __flush_tlb_page(unsigned long asid, unsigned long page);
 
 static inline void flush_tlb_pgtables(struct mm_struct *mm,
 				      unsigned long start, unsigned long end)
 { /* Nothing to do */
 }
 
+#if defined(__SH4__)
+/*
+ * For SH-4, we have our own implementation for ptep_get_and_clear
+ */
+static inline pte_t ptep_get_and_clear(pte_t *ptep)
+{
+	pte_t pte = *ptep;
+
+	pte_clear(ptep);
+	if (!pte_not_present(pte)) {
+		struct page *page = pte_page(pte);
+		if (VALID_PAGE(page)&&
+		    (!page->mapping || !(page->mapping->i_mmap_shared)))
+			__clear_bit(PG_mapped, &page->flags);
+	}
+	return pte;
+}
+#else
+static inline pte_t ptep_get_and_clear(pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	pte_clear(ptep);
+	return pte;
+}
+#endif
+
+/*
+ * Following functions are same as generic ones.
+ */
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	if (!pte_young(pte))
+		return 0;
+	set_pte(ptep, pte_mkold(pte));
+	return 1;
+}
+
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	if (!pte_dirty(pte))
+		return 0;
+	set_pte(ptep, pte_mkclean(pte));
+	return 1;
+}
+
+static inline void ptep_set_wrprotect(pte_t *ptep)
+{
+	pte_t old_pte = *ptep;
+	set_pte(ptep, pte_wrprotect(old_pte));
+}
+
+static inline void ptep_mkdirty(pte_t *ptep)
+{
+	pte_t old_pte = *ptep;
+	set_pte(ptep, pte_mkdirty(old_pte));
+}
 #endif /* __ASM_SH_PGALLOC_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/pgtable-2level.h linux/include/asm-sh/pgtable-2level.h
--- linux-2.4.10-pre5/include/asm-sh/pgtable-2level.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/pgtable-2level.h	Mon Dec  3 23:08:14 2001
@@ -33,7 +33,7 @@
 static inline int pgd_none(pgd_t pgd)		{ return 0; }
 static inline int pgd_bad(pgd_t pgd)		{ return 0; }
 static inline int pgd_present(pgd_t pgd)	{ return 1; }
-static inline void pgd_clear (pgd_t * pgdp) 	{ pgd_val(*(pgdp)) = 0; }
+static inline void pgd_clear (pgd_t * pgdp) 	{ }
 
 /*
  * Certain architectures need to do special things when PTEs
diff -urN linux-2.4.10-pre5/include/asm-sh/pgtable.h linux/include/asm-sh/pgtable.h
--- linux-2.4.10-pre5/include/asm-sh/pgtable.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/pgtable.h	Mon Dec  3 23:08:14 2001
@@ -42,22 +42,46 @@
 #define flush_icache_range(start, end)		do { } while (0)
 #define flush_icache_page(vma,pg)		do { } while (0)
 #define flush_cache_sigtramp(vaddr)		do { } while (0)
+
+#define p3_cache_init()				do { } while (0)
+
 #elif defined(__SH4__)
 /*
  *  Caches are broken on SH-4, so we need them.
  */
+
+/* Page is 4K, OC size is 16K, there are four lines. */
+#define CACHE_ALIAS 0x00003000
+
 extern void flush_cache_all(void);
 extern void flush_cache_mm(struct mm_struct *mm);
 extern void flush_cache_range(struct mm_struct *mm, unsigned long start,
 			      unsigned long end);
 extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr);
-extern void flush_page_to_ram(struct page *page);
 extern void flush_dcache_page(struct page *pg);
 extern void flush_icache_range(unsigned long start, unsigned long end);
-extern void flush_icache_page(struct vm_area_struct *vma, struct page *pg);
 extern void flush_cache_sigtramp(unsigned long addr);
+
+#define flush_page_to_ram(page)			do { } while (0)
+#define flush_icache_page(vma,pg)		do { } while (0)
+
+/* Initialization of P3 area for copy_user_page */
+extern void p3_cache_init(void);
+
+#define PG_mapped	PG_arch_1
+
+/* We provide our own get_unmapped_area to avoid cache alias issue */
+#define HAVE_ARCH_UNMAPPED_AREA
 #endif
 
+/* Flush (write-back only) a region (smaller than a page) */
+extern void __flush_wback_region(void *start, int size);
+/* Flush (write-back & invalidate) a region (smaller than a page) */
+extern void __flush_purge_region(void *start, int size);
+/* Flush (invalidate only) a region (smaller than a page) */
+extern void __flush_invalidate_region(void *start, int size);
+
+
 /*
  * Basically we have the same two-level (which is the logical three level
  * Linux page table layout folded) page tables as the i386.
@@ -82,8 +106,14 @@
 #define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
 #define FIRST_USER_PGD_NR	0
 
+#define PTE_PHYS_MASK	0x1ffff000
+
 #ifndef __ASSEMBLY__
-#define VMALLOC_START	P3SEG
+/*
+ * First 1MB map is used by fixed purpose.
+ * Currently only 4-enty (16kB) is used (see arch/sh/mm/cache.c)
+ */
+#define VMALLOC_START	(P3SEG+0x00100000)
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
 #define VMALLOC_END	P4SEG
 
@@ -180,9 +210,9 @@
  * Permanent address of a page. Obviously must never be
  * called on a highmem page.
  */
-#define page_address(page)  ((page)->virtual)
-#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
-#define pte_page(x) (mem_map+(unsigned long)(((pte_val(x) -__MEMORY_START) >> PAGE_SHIFT)))
+#define page_address(page)  ((page)->virtual) /* P1 address of the page */
+#define pages_to_mb(x)	((x) >> (20-PAGE_SHIFT))
+#define pte_page(x) 	phys_to_page(pte_val(x)&PTE_PHYS_MASK)
 
 /*
  * The following only work if pte_present() is true.
@@ -193,7 +223,7 @@
 static inline int pte_dirty(pte_t pte){ return pte_val(pte) & _PAGE_DIRTY; }
 static inline int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; }
 static inline int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_RW; }
-static inline int pte_shared(pte_t pte){ return pte_val(pte) & _PAGE_SHARED; }
+static inline int pte_not_present(pte_t pte){ return !(pte_val(pte) & _PAGE_PRESENT); }
 
 static inline pte_t pte_rdprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
 static inline pte_t pte_exprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
@@ -215,9 +245,8 @@
 #define mk_pte(page,pgprot)						\
 ({	pte_t __pte;							\
 									\
-	set_pte(&__pte, __pte(((page)-mem_map) * 			\
-		(unsigned long long)PAGE_SIZE + pgprot_val(pgprot) +	\
-		__MEMORY_START));					\
+	set_pte(&__pte, __pte(PHYSADDR(page_address(page))		\
+				+pgprot_val(pgprot)));			\
 	__pte;								\
 })
 
@@ -266,8 +295,10 @@
  *
  * We just can use generic implementation, as SuperH has no SMP feature.
  * (We needed atomic implementation for SMP)
+ *
  */
-#include <asm-generic/pgtable.h>
+
+#define pte_same(A,B)	(pte_val(A) == pte_val(B))
 
 #endif /* !__ASSEMBLY__ */
 
diff -urN linux-2.4.10-pre5/include/asm-sh/processor.h linux/include/asm-sh/processor.h
--- linux-2.4.10-pre5/include/asm-sh/processor.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/processor.h	Mon Dec  3 23:08:14 2001
@@ -30,13 +30,9 @@
 
 struct sh_cpuinfo {
 	enum cpu_type type;
-	unsigned long loops_per_jiffy;
-
 	char	hard_math;
+	unsigned long loops_per_jiffy;
 
-	unsigned long *pgd_quick;
-	unsigned long *pte_quick;
-	unsigned long pgtable_cache_sz;
 	unsigned int cpu_clock, master_clock, bus_clock, module_clock;
 #ifdef CONFIG_CPU_SUBTYPE_ST40STB1
 	unsigned int memory_clock;
@@ -163,7 +159,7 @@
  * FPU lazy state save handling.
  */
 
-extern __inline__ void release_fpu(void)
+static __inline__ void release_fpu(void)
 {
 	unsigned long __dummy;
 
@@ -175,7 +171,7 @@
 			     : "r" (SR_FD));
 }
 
-extern __inline__ void grab_fpu(void)
+static __inline__ void grab_fpu(void)
 {
 	unsigned long __dummy;
 
@@ -207,7 +203,7 @@
 /*
  * Return saved PC of a blocked thread.
  */
-extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
+static __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
 {
 	return t->pc;
 }
diff -urN linux-2.4.10-pre5/include/asm-sh/ptrace.h linux/include/asm-sh/ptrace.h
--- linux-2.4.10-pre5/include/asm-sh/ptrace.h	Thu Jan  4 13:19:13 2001
+++ linux/include/asm-sh/ptrace.h	Mon Dec  3 23:08:14 2001
@@ -1,6 +1,8 @@
 #ifndef __ASM_SH_PTRACE_H
 #define __ASM_SH_PTRACE_H
 
+#include <asm/processor.h>
+
 /*
  * Copyright (C) 1999, 2000  Niibe Yutaka
  *
@@ -69,6 +71,12 @@
 
 /* User Break Controller */
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+#define UBC_TYPE_SH7729	(cpu_data->type == CPU_SH7729)
+#else
+#define UBC_TYPE_SH7729	0
+#endif
+
 #if defined(__sh3__)
 #define UBC_BARA                0xffffffb0
 #define UBC_BAMRA               0xffffffb4
@@ -106,14 +114,17 @@
 #define BBR_INST		(1 << 4)
 #define BBR_DATA		(2 << 4)
 #define BBR_READ		(1 << 2)
-#define BBR_WRITE		(2 << 4)
+#define BBR_WRITE		(2 << 2)
 #define BBR_BYTE		0x1
 #define BBR_HALF		0x2
 #define BBR_LONG		0x3
-#define BBR_QUAD		(1 << 6)
+#define BBR_QUAD		(1 << 6)	/* SH7750 */
+#define BBR_CPU			(1 << 6)	/* SH7709A,SH7729 */
+#define BBR_DMA			(2 << 6)	/* SH7709A,SH7729 */
 
 #define BRCR_CMFA		(1 << 15)
 #define BRCR_CMFB		(1 << 14)
+#define BRCR_PCTE		(1 << 11)
 #define BRCR_PCBA		(1 << 10)	/* 1: after execution */
 #define BRCR_DBEB		(1 << 7)
 #define BRCR_PCBB		(1 << 6)
diff -urN linux-2.4.10-pre5/include/asm-sh/semaphore.h linux/include/asm-sh/semaphore.h
--- linux-2.4.10-pre5/include/asm-sh/semaphore.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/semaphore.h	Mon Dec  3 23:08:14 2001
@@ -48,7 +48,7 @@
 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
 #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
 
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
 {
 /*
  *	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
diff -urN linux-2.4.10-pre5/include/asm-sh/shmparam.h linux/include/asm-sh/shmparam.h
--- linux-2.4.10-pre5/include/asm-sh/shmparam.h	Wed Nov  3 11:31:09 1999
+++ linux/include/asm-sh/shmparam.h	Mon Dec  3 23:08:14 2001
@@ -1,6 +1,13 @@
 #ifndef __ASM_SH_SHMPARAM_H
 #define __ASM_SH_SHMPARAM_H
 
+#if defined(__SH4__)
+/*
+ * SH-4 has D-cache alias issue
+ */
+#define	SHMLBA (PAGE_SIZE*4)		 /* attach addr a multiple of this */
+#else
 #define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
+#endif
 
 #endif /* __ASM_SH_SHMPARAM_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/smplock.h linux/include/asm-sh/smplock.h
--- linux-2.4.10-pre5/include/asm-sh/smplock.h	Tue Apr 25 16:53:13 2000
+++ linux/include/asm-sh/smplock.h	Mon Dec  3 23:08:14 2001
@@ -17,56 +17,7 @@
 #define reacquire_kernel_lock(task, cpu, depth)	do { } while(0)
 
 #else
-
-#error "We do not support SMP on SH yet"
-/*
- * Default SMP lock implementation
- */
-
-#include <linux/interrupt.h>
-#include <asm/spinlock.h>
-
-extern spinlock_t kernel_flag;
-
-/*
- * Getting the big kernel lock.
- *
- * This cannot happen asynchronously,
- * so we only need to worry about other
- * CPU's.
- */
-extern __inline__ void lock_kernel(void)
-{
-	if (!++current->lock_depth)
-		spin_lock(&kernel_flag);
-}
-
-extern __inline__ void unlock_kernel(void)
-{
-	if (--current->lock_depth < 0)
-		spin_unlock(&kernel_flag);
-}
-
-/*
- * Release global kernel lock and global interrupt lock
- */
-#define release_kernel_lock(task, cpu) \
-do { \
-	if (task->lock_depth >= 0) \
-		spin_unlock(&kernel_flag); \
-	release_irqlock(cpu); \
-	__sti(); \
-} while (0)
-
-/*
- * Re-acquire the kernel lock
- */
-#define reacquire_kernel_lock(task) \
-do { \
-	if (task->lock_depth >= 0) \
-		spin_lock(&kernel_flag); \
-} while (0)
-
+#error "We do not support SMP on SH"
 #endif /* CONFIG_SMP */
 
 #endif /* __ASM_SH_SMPLOCK_H */
diff -urN linux-2.4.10-pre5/include/asm-sh/softirq.h linux/include/asm-sh/softirq.h
--- linux-2.4.10-pre5/include/asm-sh/softirq.h	Mon Jul  9 16:04:24 2001
+++ linux/include/asm-sh/softirq.h	Mon Dec  3 23:08:14 2001
@@ -18,14 +18,12 @@
 
 #define local_bh_enable()				\
 do {							\
+	barrier();					\
 	if (!--local_bh_count(smp_processor_id())	\
 	    && softirq_pending(smp_processor_id())) {	\
 		do_softirq();				\
-		__sti();				\
 	}						\
 } while (0)
-
-#define __cpu_raise_softirq(cpu, nr) set_bit((nr), &softirq_pending(cpu));
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
diff -urN linux-2.4.10-pre5/include/asm-sh/string.h linux/include/asm-sh/string.h
--- linux-2.4.10-pre5/include/asm-sh/string.h	Wed Jun 27 13:55:29 2001
+++ linux/include/asm-sh/string.h	Mon Dec  3 23:08:14 2001
@@ -121,6 +121,9 @@
 #define __HAVE_ARCH_MEMCHR
 extern void *memchr(const void *__s, int __c, size_t __n);
 
+#define __HAVE_ARCH_STRLEN
+extern size_t strlen(const char *);
+
 /* Don't build bcopy at all ...  */
 #define __HAVE_ARCH_BCOPY
 
diff -urN linux-2.4.10-pre5/include/asm-sh/system.h linux/include/asm-sh/system.h
--- linux-2.4.10-pre5/include/asm-sh/system.h	Sun Jan 28 18:56:00 2001
+++ linux/include/asm-sh/system.h	Mon Dec  3 23:08:14 2001
@@ -129,29 +129,54 @@
 			     : "memory");
 }
 
-#define __save_flags(x) 			\
-x = (__extension__ ({	unsigned long __sr;	\
-	__asm__ __volatile__(			\
-		"stc	sr, %0"		\
-		: "=&r" (__sr)			\
-		: /* no inputs */		\
-		: "memory");			\
-	 (__sr & 0x000000f0);}))
-
-#define __save_and_cli(x)    				\
-x = (__extension__ ({	unsigned long __dummy,__sr;	\
-	__asm__ __volatile__(                   	\
-		"stc	sr, %1\n\t" 			\
-		"mov	%1, %0\n\t" 			\
-		"or	#0xf0, %0\n\t" 			\
-		"ldc	%0, sr"     			\
-		: "=&z" (__dummy), "=&r" (__sr)		\
-		: /* no inputs */ 			\
-		: "memory"); (__sr & 0x000000f0); }))
+#define __save_flags(x) \
+	__asm__("stc sr, %0; and #0xf0, %0" : "=&z" (x) :/**/: "memory" )
 
+static __inline__ unsigned long __save_and_cli(void)
+{
+	unsigned long flags, __dummy;
+
+	__asm__ __volatile__("stc	sr, %1\n\t"
+			     "mov	%1, %0\n\t"
+			     "or	#0xf0, %0\n\t"
+			     "ldc	%0, sr\n\t"
+			     "mov	%1, %0\n\t"
+			     "and	#0xf0, %0"
+			     : "=&z" (flags), "=&r" (__dummy)
+			     :/**/
+			     : "memory" );
+	return flags;
+}
+
+#ifdef DEBUG_CLI_STI
+static __inline__ void  __restore_flags(unsigned long x)
+{
+	if ((x & 0x000000f0) != 0x000000f0)
+		__sti();
+	else {
+		unsigned long flags;
+		__save_flags(flags);
+
+		if (flags == 0) {
+			extern void dump_stack(void);
+			printk(KERN_ERR "BUG!\n");
+			dump_stack();
+			__cli();
+		}
+	}
+}
+#else
 #define __restore_flags(x) do { 			\
-	if (x != 0x000000f0)	/* not CLI-ed? */		\
+	if ((x & 0x000000f0) != 0x000000f0)		\
+		__sti();				\
+} while (0)
+#endif
+
+#define really_restore_flags(x) do { 			\
+	if ((x & 0x000000f0) != 0x000000f0)		\
 		__sti();				\
+	else						\
+		__cli();				\
 } while (0)
 
 /*
@@ -191,7 +216,7 @@
 } while (0)
 
 /* For spinlocks etc */
-#define local_irq_save(x)	__save_and_cli(x)
+#define local_irq_save(x)	x = __save_and_cli()
 #define local_irq_restore(x)	__restore_flags(x)
 #define local_irq_disable()	__cli()
 #define local_irq_enable()	__sti()
@@ -212,7 +237,7 @@
 #define cli() __cli()
 #define sti() __sti()
 #define save_flags(x) __save_flags(x)
-#define save_and_cli(x) __save_and_cli(x)
+#define save_and_cli(x) x = __save_and_cli()
 #define restore_flags(x) __restore_flags(x)
 
 #endif
diff -urN linux-2.4.10-pre5/include/asm-sh/uaccess.h linux/include/asm-sh/uaccess.h
--- linux-2.4.10-pre5/include/asm-sh/uaccess.h	Thu Jan  4 13:19:13 2001
+++ linux/include/asm-sh/uaccess.h	Mon Dec  3 23:08:14 2001
@@ -1,4 +1,4 @@
-/* $Id: uaccess.h,v 1.10 2000/03/24 13:53:45 gniibe Exp $
+/* $Id: uaccess.h,v 1.12 2001/07/27 06:09:47 gniibe Exp $
  *
  * User space memory access functions
  *
@@ -195,7 +195,7 @@
 /* Generic arbitrary sized copy.  */
 /* Return the number of bytes NOT copied */
 /* XXX: should be such that: 4byte and the rest. */
-extern __inline__ __kernel_size_t
+static __inline__ __kernel_size_t
 __copy_user(void *__to, const void *__from, __kernel_size_t __n)
 {
 	unsigned long __dummy, _f, _t;
@@ -260,7 +260,7 @@
 
 /* XXX: Not sure it works well..
    should be such that: 4byte clear and the rest. */
-extern __inline__ __kernel_size_t
+static __inline__ __kernel_size_t
 __clear_user(void *addr, __kernel_size_t size)
 {
 	unsigned long __a;
@@ -299,7 +299,7 @@
 __cl_size = __clear_user(__cl_addr, __cl_size); \
 __cl_size; })
 
-extern __inline__ int
+static __inline__ int
 __strncpy_from_user(unsigned long __dest, unsigned long __src, int __count)
 {
 	__kernel_size_t res;
@@ -351,7 +351,7 @@
 /*
  * Return the size of a string (including the ending 0!)
  */
-extern __inline__ long __strnlen_user(const char *__s, long __n)
+static __inline__ long __strnlen_user(const char *__s, long __n)
 {
 	unsigned long res;
 	unsigned long __dummy;
@@ -384,7 +384,7 @@
 	return res;
 }
 
-extern __inline__ long strnlen_user(const char *s, long n)
+static __inline__ long strnlen_user(const char *s, long n)
 {
 	if (!__addr_ok(s))
 		return 0;
diff -urN linux-2.4.10-pre5/include/asm-sparc/softirq.h linux/include/asm-sparc/softirq.h
--- linux-2.4.10-pre5/include/asm-sparc/softirq.h	Mon Jul  9 16:31:14 2001
+++ linux/include/asm-sparc/softirq.h	Mon Dec  3 23:08:14 2001
@@ -22,13 +22,6 @@
 		__sti();			  \
      }						  \
 } while (0)
-#define __do_cpu_raise_softirq(cpu, nr)	(softirq_pending(cpu) |= (1<<nr))
-#define __cpu_raise_softirq(cpu, nr)			\
-do {	unsigned long flags;				\
-	local_irq_save(flags);				\
-	__do_cpu_raise_softirq(cpu, nr);			\
-	local_irq_restore(flags);			\
-} while (0)
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif	/* __SPARC_SOFTIRQ_H */
diff -urN linux-2.4.10-pre5/include/asm-sparc64/softirq.h linux/include/asm-sparc64/softirq.h
--- linux-2.4.10-pre5/include/asm-sparc64/softirq.h	Mon Jul  9 16:31:27 2001
+++ linux/include/asm-sparc64/softirq.h	Mon Dec  3 23:08:14 2001
@@ -20,13 +20,6 @@
      }						  \
 } while (0)
 
-#define __do_cpu_raise_softirq(cpu, nr)	(softirq_pending(cpu) |= (1<<nr))
-#define __cpu_raise_softirq(cpu,nr)			\
-do {	unsigned long flags;				\
-	local_irq_save(flags);				\
-	__do_cpu_raise_softirq(cpu, nr);			\
-	local_irq_restore(flags);			\
-} while (0)
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif /* !(__SPARC64_SOFTIRQ_H) */
diff -urN linux-2.4.10-pre5/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux-2.4.10-pre5/include/linux/blkdev.h	Wed Aug 15 14:21:30 2001
+++ linux/include/linux/blkdev.h	Mon Dec  3 23:08:14 2001
@@ -149,8 +149,7 @@
 extern void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size);
 extern void register_disk(struct gendisk *dev, kdev_t first, unsigned minors, struct block_device_operations *ops, long size);
 extern void generic_make_request(int rw, struct buffer_head * bh);
-extern request_queue_t *blk_get_queue(kdev_t dev);
-extern inline request_queue_t *__blk_get_queue(kdev_t dev);
+extern inline request_queue_t *blk_get_queue(kdev_t dev);
 extern void blkdev_release_request(struct request *);
 
 /*
diff -urN linux-2.4.10-pre5/include/linux/genhd.h linux/include/linux/genhd.h
--- linux-2.4.10-pre5/include/linux/genhd.h	Wed Aug 15 14:21:30 2001
+++ linux/include/linux/genhd.h	Mon Dec  3 23:08:14 2001
@@ -74,6 +74,14 @@
 	devfs_handle_t *de_arr;         /* one per physical disc */
 	char *flags;                    /* one per physical disc */
 };
+
+/* drivers/block/genhd.c */
+extern struct gendisk *gendisk_head;
+
+extern void add_gendisk(struct gendisk *gp);
+extern void del_gendisk(struct gendisk *gp);
+extern struct gendisk *get_gendisk(kdev_t dev);
+
 #endif  /*  __KERNEL__  */
 
 #ifdef CONFIG_SOLARIS_X86_PARTITION
@@ -230,7 +238,6 @@
 #endif /* CONFIG_MINIX_SUBPARTITION */
 
 #ifdef __KERNEL__
-extern struct gendisk *gendisk_head;	/* linked list of disks */
 
 char *disk_name (struct gendisk *hd, int minor, char *buf);
 
diff -urN linux-2.4.10-pre5/include/linux/interrupt.h linux/include/linux/interrupt.h
--- linux-2.4.10-pre5/include/linux/interrupt.h	Wed Aug 15 14:21:12 2001
+++ linux/include/linux/interrupt.h	Mon Dec  3 23:08:14 2001
@@ -74,6 +74,7 @@
 asmlinkage void do_softirq(void);
 extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data);
 extern void softirq_init(void);
+#define __cpu_raise_softirq(cpu, nr) do { softirq_pending(cpu) |= 1UL << (nr); } while (0)
 extern void FASTCALL(cpu_raise_softirq(unsigned int cpu, unsigned int nr));
 extern void FASTCALL(raise_softirq(unsigned int nr));
 
diff -urN linux-2.4.10-pre5/include/linux/mc146818rtc.h linux/include/linux/mc146818rtc.h
--- linux-2.4.10-pre5/include/linux/mc146818rtc.h	Wed Aug 15 14:21:36 2001
+++ linux/include/linux/mc146818rtc.h	Mon Dec  3 23:08:14 2001
@@ -13,6 +13,7 @@
 
 #include <asm/io.h>
 #include <linux/rtc.h>			/* get the user-level API */
+#include <linux/spinlock.h>		/* spinlock_t */
 #include <asm/mc146818rtc.h>		/* register access macros */
 
 extern spinlock_t rtc_lock;		/* serialize CMOS RAM access */
diff -urN linux-2.4.10-pre5/include/linux/ntfs_fs.h linux/include/linux/ntfs_fs.h
--- linux-2.4.10-pre5/include/linux/ntfs_fs.h	Mon Dec  3 23:08:04 2001
+++ linux/include/linux/ntfs_fs.h	Mon Dec  3 23:08:14 2001
@@ -18,4 +18,12 @@
 	ATTR_IS_SPARSE          = cpu_to_le16(0x8000),
 } __attribute__ ((__packed__)) ATTR_FLAGS;
 
+/*
+ * The two zones from which to allocate clusters.
+ */
+typedef enum {
+	MFT_ZONE,
+	DATA_ZONE
+} NTFS_CLUSTER_ALLOCATION_ZONES;
+
 #endif
diff -urN linux-2.4.10-pre5/include/linux/ntfs_fs_i.h linux/include/linux/ntfs_fs_i.h
--- linux-2.4.10-pre5/include/linux/ntfs_fs_i.h	Mon Dec  3 23:08:04 2001
+++ linux/include/linux/ntfs_fs_i.h	Mon Dec  3 23:08:14 2001
@@ -70,8 +70,7 @@
 #endif
 
 /* Definition of the NTFS in-memory inode structure. */
-struct ntfs_inode_info{
-	unsigned long mmu_private;
+struct ntfs_inode_info {
 	struct ntfs_sb_info *vol;
 	unsigned long i_number;		/* Should be really 48 bits. */
 	__u16 sequence_number;		/* The current sequence number. */
diff -urN linux-2.4.10-pre5/include/linux/ntfs_fs_sb.h linux/include/linux/ntfs_fs_sb.h
--- linux-2.4.10-pre5/include/linux/ntfs_fs_sb.h	Mon Dec  3 23:08:04 2001
+++ linux/include/linux/ntfs_fs_sb.h	Mon Dec  3 23:08:14 2001
@@ -11,7 +11,12 @@
 	void *nls_map;
 	unsigned int ngt;
 	char mft_zone_multiplier;
+	unsigned long mft_data_pos;
+	ntfs_cluster_t mft_zone_pos;
+	ntfs_cluster_t mft_zone_start;
 	ntfs_cluster_t mft_zone_end;
+	ntfs_cluster_t data1_zone_pos;
+	ntfs_cluster_t data2_zone_pos;
 	/* Configuration provided by user with the ntfstools.
 	 * FIXME: This is no longer possible. What is this good for? (AIA) */
 	ntfs_size_t partition_bias;	/* For access to underlying device. */
diff -urN linux-2.4.10-pre5/include/linux/raid/md.h linux/include/linux/raid/md.h
--- linux-2.4.10-pre5/include/linux/raid/md.h	Wed Aug 15 14:21:32 2001
+++ linux/include/linux/raid/md.h	Mon Dec  3 23:08:14 2001
@@ -78,7 +78,6 @@
 extern void md_sync_acct(kdev_t dev, unsigned long nr_sectors);
 extern void md_recover_arrays (void);
 extern int md_check_ordering (mddev_t *mddev);
-extern struct gendisk * find_gendisk (kdev_t dev);
 extern int md_notify_reboot(struct notifier_block *this,
 					unsigned long code, void *x);
 extern int md_error (mddev_t *mddev, kdev_t rdev);
diff -urN linux-2.4.10-pre5/include/linux/reiserfs_fs.h linux/include/linux/reiserfs_fs.h
--- linux-2.4.10-pre5/include/linux/reiserfs_fs.h	Mon Jul 30 13:01:08 2001
+++ linux/include/linux/reiserfs_fs.h	Mon Dec  3 23:08:14 2001
@@ -1753,17 +1753,6 @@
 			    int n_max_nr_buffers_to_return);
 */
 
-#ifndef REISERFS_FSCK
-
-//inline int is_left_mergeable (struct item_head * ih, unsigned long bsize);
-
-#else
-
-int is_left_mergeable (struct super_block * s, struct path * path);
-int is_right_mergeable (struct super_block * s, struct path * path);
-int are_items_mergeable (struct item_head * left, struct item_head * right, int bsize);
-
-#endif
 void padd_item (char * item, int total_length, int length);
 
 
diff -urN linux-2.4.10-pre5/kernel/softirq.c linux/kernel/softirq.c
--- linux-2.4.10-pre5/kernel/softirq.c	Sat Jul 28 12:59:12 2001
+++ linux/kernel/softirq.c	Mon Dec  3 23:08:14 2001
@@ -108,6 +108,9 @@
 	local_irq_restore(flags);
 }
 
+/*
+ * This function must run with irq disabled!
+ */
 inline void cpu_raise_softirq(unsigned int cpu, unsigned int nr)
 {
 	__cpu_raise_softirq(cpu, nr);
@@ -127,7 +130,11 @@
 
 void raise_softirq(unsigned int nr)
 {
+	long flags;
+
+	local_irq_save(flags);
 	cpu_raise_softirq(smp_processor_id(), nr);
+	local_irq_restore(flags);
 }
 
 void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
@@ -195,8 +202,8 @@
 		local_irq_disable();
 		t->next = tasklet_vec[cpu].list;
 		tasklet_vec[cpu].list = t;
-		local_irq_enable();
 		__cpu_raise_softirq(cpu, TASKLET_SOFTIRQ);
+		local_irq_enable();
 	}
 }
 
@@ -229,8 +236,8 @@
 		local_irq_disable();
 		t->next = tasklet_hi_vec[cpu].list;
 		tasklet_hi_vec[cpu].list = t;
-		local_irq_enable();
 		__cpu_raise_softirq(cpu, HI_SOFTIRQ);
+		local_irq_enable();
 	}
 }
 
diff -urN linux-2.4.10-pre5/mm/slab.c linux/mm/slab.c
--- linux-2.4.10-pre5/mm/slab.c	Tue May 22 10:23:16 2001
+++ linux/mm/slab.c	Mon Dec  3 23:08:14 2001
@@ -140,8 +140,7 @@
  *
  * Manages the objs in a slab. Placed either at the beginning of mem allocated
  * for a slab, or allocated from an general cache.
- * Slabs are chained into one ordered list: fully used, partial, then fully
- * free slabs.
+ * Slabs are chained into three list: fully used, partial, fully free slabs.
  */
 typedef struct slab_s {
 	struct list_head	list;
@@ -167,7 +166,7 @@
 } cpucache_t;
 
 #define cc_entry(cpucache) \
-	((void **)(((cpucache_t*)cpucache)+1))
+	((void **)(((cpucache_t*)(cpucache))+1))
 #define cc_data(cachep) \
 	((cachep)->cpudata[smp_processor_id()])
 /*
@@ -181,8 +180,9 @@
 struct kmem_cache_s {
 /* 1) each alloc & free */
 	/* full, partial first, then free */
-	struct list_head	slabs;
-	struct list_head	*firstnotfull;
+	struct list_head	slabs_full;
+	struct list_head	slabs_partial;
+	struct list_head	slabs_free;
 	unsigned int		objsize;
 	unsigned int	 	flags;	/* constant flags */
 	unsigned int		num;	/* # of objs per slab */
@@ -345,8 +345,9 @@
 
 /* internal cache of cache description objs */
 static kmem_cache_t cache_cache = {
-	slabs:		LIST_HEAD_INIT(cache_cache.slabs),
-	firstnotfull:	&cache_cache.slabs,
+	slabs_full:	LIST_HEAD_INIT(cache_cache.slabs_full),
+	slabs_partial:	LIST_HEAD_INIT(cache_cache.slabs_partial),
+	slabs_free:	LIST_HEAD_INIT(cache_cache.slabs_free),
 	objsize:	sizeof(kmem_cache_t),
 	flags:		SLAB_NO_REAP,
 	spinlock:	SPIN_LOCK_UNLOCKED,
@@ -777,8 +778,9 @@
 		cachep->gfpflags |= GFP_DMA;
 	spin_lock_init(&cachep->spinlock);
 	cachep->objsize = size;
-	INIT_LIST_HEAD(&cachep->slabs);
-	cachep->firstnotfull = &cachep->slabs;
+	INIT_LIST_HEAD(&cachep->slabs_full);
+	INIT_LIST_HEAD(&cachep->slabs_partial);
+	INIT_LIST_HEAD(&cachep->slabs_free);
 
 	if (flags & CFLGS_OFF_SLAB)
 		cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
@@ -886,23 +888,20 @@
 	while (!cachep->growing) {
 		struct list_head *p;
 
-		p = cachep->slabs.prev;
-		if (p == &cachep->slabs)
+		p = cachep->slabs_free.prev;
+		if (p == &cachep->slabs_free)
 			break;
 
-		slabp = list_entry(cachep->slabs.prev, slab_t, list);
+		slabp = list_entry(cachep->slabs_free.prev, slab_t, list);
 		if (slabp->inuse)
-			break;
-
+			BUG();
 		list_del(&slabp->list);
-		if (cachep->firstnotfull == &slabp->list)
-			cachep->firstnotfull = &cachep->slabs;
 
 		spin_unlock_irq(&cachep->spinlock);
 		kmem_slab_destroy(cachep, slabp);
 		spin_lock_irq(&cachep->spinlock);
 	}
-	ret = !list_empty(&cachep->slabs);
+	ret = !list_empty(&cachep->slabs_full) || !list_empty(&cachep->slabs_partial);
 	spin_unlock_irq(&cachep->spinlock);
 	return ret;
 }
@@ -1128,9 +1127,7 @@
 	cachep->growing--;
 
 	/* Make slab active. */
-	list_add_tail(&slabp->list,&cachep->slabs);
-	if (cachep->firstnotfull == &cachep->slabs)
-		cachep->firstnotfull = &slabp->list;
+	list_add_tail(&slabp->list, &cachep->slabs_free);
 	STATS_INC_GROWN(cachep);
 	cachep->failures = 0;
 
@@ -1187,7 +1184,7 @@
 }
 
 static inline void * kmem_cache_alloc_one_tail (kmem_cache_t *cachep,
-							 slab_t *slabp)
+						slab_t *slabp, int partial)
 {
 	void *objp;
 
@@ -1200,9 +1197,15 @@
 	objp = slabp->s_mem + slabp->free*cachep->objsize;
 	slabp->free=slab_bufctl(slabp)[slabp->free];
 
-	if (slabp->free == BUFCTL_END)
-		/* slab now full: move to next slab for next alloc */
-		cachep->firstnotfull = slabp->list.next;
+	if (slabp->free == BUFCTL_END) {
+		list_del(&slabp->list);
+		list_add(&slabp->list, &cachep->slabs_full);
+	} else {
+		if (!partial) {
+			list_del(&slabp->list);
+			list_add(&slabp->list, &cachep->slabs_partial);
+		}
+	}
 #if DEBUG
 	if (cachep->flags & SLAB_POISON)
 		if (kmem_check_poison_obj(cachep, objp))
@@ -1228,16 +1231,20 @@
  */
 #define kmem_cache_alloc_one(cachep)				\
 ({								\
-	slab_t	*slabp;					\
+	slab_t	*slabp;						\
+	struct list_head * slab_freelist;			\
+	int partial = 1;					\
 								\
-	/* Get slab alloc is to come from. */			\
-	{							\
-		struct list_head* p = cachep->firstnotfull;	\
-		if (p == &cachep->slabs)			\
+	slab_freelist = &(cachep)->slabs_partial;		\
+	if (list_empty(slab_freelist)) {			\
+		partial = 0;					\
+		slab_freelist = &(cachep)->slabs_free;		\
+		if (list_empty(slab_freelist))			\
 			goto alloc_new_slab;			\
-		slabp = list_entry(p,slab_t, list);	\
 	}							\
-	kmem_cache_alloc_one_tail(cachep, slabp);		\
+								\
+	slabp = list_entry(slab_freelist->next, slab_t, list);	\
+	kmem_cache_alloc_one_tail(cachep, slabp, partial);	\
 })
 
 #ifdef CONFIG_SMP
@@ -1245,18 +1252,25 @@
 {
 	int batchcount = cachep->batchcount;
 	cpucache_t* cc = cc_data(cachep);
+	struct list_head * slab_freelist;
+	int partial;
+	slab_t *slabp;
 
 	spin_lock(&cachep->spinlock);
 	while (batchcount--) {
 		/* Get slab alloc is to come from. */
-		struct list_head *p = cachep->firstnotfull;
-		slab_t *slabp;
+		slab_freelist = &(cachep)->slabs_partial;
+		partial = 1;
+		if (list_empty(slab_freelist)) {
+			partial = 0;
+			slab_freelist = &(cachep)->slabs_free;
+			if (list_empty(slab_freelist))
+				break;
+		}
 
-		if (p == &cachep->slabs)
-			break;
-		slabp = list_entry(p,slab_t, list);
+		slabp = list_entry(slab_freelist->next, slab_t, list);
 		cc_entry(cc)[cc->avail++] =
-				kmem_cache_alloc_one_tail(cachep, slabp);
+				kmem_cache_alloc_one_tail(cachep, slabp, partial);
 	}
 	spin_unlock(&cachep->spinlock);
 
@@ -1386,43 +1400,24 @@
 	}
 	STATS_DEC_ACTIVE(cachep);
 	
-	/* fixup slab chain */
-	if (slabp->inuse-- == cachep->num)
-		goto moveslab_partial;
-	if (!slabp->inuse)
+	/* fixup slab chains */
+	if (!--slabp->inuse)
 		goto moveslab_free;
+	if (slabp->inuse + 1 == cachep->num)
+		goto moveslab_partial;
 	return;
 
 moveslab_partial:
-    	/* was full.
-	 * Even if the page is now empty, we can set c_firstnotfull to
-	 * slabp: there are no partial slabs in this case
-	 */
-	{
-		struct list_head *t = cachep->firstnotfull;
+    	/* Was full. */
+	list_del(&slabp->list);
+	list_add(&slabp->list, &cachep->slabs_partial);
+	return;
 
-		cachep->firstnotfull = &slabp->list;
-		if (slabp->list.next == t)
-			return;
-		list_del(&slabp->list);
-		list_add_tail(&slabp->list, t);
-		return;
-	}
 moveslab_free:
-	/*
-	 * was partial, now empty.
-	 * c_firstnotfull might point to slabp
-	 * FIXME: optimize
-	 */
-	{
-		struct list_head *t = cachep->firstnotfull->prev;
-
-		list_del(&slabp->list);
-		list_add_tail(&slabp->list, &cachep->slabs);
-		if (cachep->firstnotfull == &slabp->list)
-			cachep->firstnotfull = t->next;
-		return;
-	}
+	/* Was partial, now empty. */
+	list_del(&slabp->list);
+	list_add(&slabp->list, &cachep->slabs_free);
+	return;
 }
 
 #ifdef CONFIG_SMP
@@ -1727,13 +1722,13 @@
 #endif
 
 		full_free = 0;
-		p = searchp->slabs.prev;
-		while (p != &searchp->slabs) {
+		p = searchp->slabs_free.next;
+		while (p != &searchp->slabs_free) {
 			slabp = list_entry(p, slab_t, list);
 			if (slabp->inuse)
-				break;
+				BUG();
 			full_free++;
-			p = p->prev;
+			p = p->next;
 		}
 
 		/*
@@ -1750,7 +1745,7 @@
 			best_cachep = searchp;
 			best_len = full_free;
 			best_pages = pages;
-			if (full_free >= REAP_PERFECT) {
+			if (pages >= REAP_PERFECT) {
 				clock_searchp = list_entry(searchp->next.next,
 							kmem_cache_t,next);
 				goto perfect;
@@ -1770,22 +1765,20 @@
 
 	spin_lock_irq(&best_cachep->spinlock);
 perfect:
-	/* free only 80% of the free slabs */
-	best_len = (best_len*4 + 1)/5;
+	/* free only 50% of the free slabs */
+	best_len = (best_len + 1)/2;
 	for (scan = 0; scan < best_len; scan++) {
 		struct list_head *p;
 
 		if (best_cachep->growing)
 			break;
-		p = best_cachep->slabs.prev;
-		if (p == &best_cachep->slabs)
+		p = best_cachep->slabs_free.prev;
+		if (p == &best_cachep->slabs_free)
 			break;
 		slabp = list_entry(p,slab_t,list);
 		if (slabp->inuse)
-			break;
+			BUG();
 		list_del(&slabp->list);
-		if (best_cachep->firstnotfull == &slabp->list)
-			best_cachep->firstnotfull = &best_cachep->slabs;
 		STATS_INC_REAPED(best_cachep);
 
 		/* Safe to drop the lock. The slab is no longer linked to the
@@ -1851,14 +1844,25 @@
 		spin_lock_irq(&cachep->spinlock);
 		active_objs = 0;
 		num_slabs = 0;
-		list_for_each(q,&cachep->slabs) {
+		list_for_each(q,&cachep->slabs_full) {
+			slabp = list_entry(q, slab_t, list);
+			if (slabp->inuse != cachep->num)
+				BUG();
+			active_objs += cachep->num;
+			active_slabs++;
+		}
+		list_for_each(q,&cachep->slabs_partial) {
 			slabp = list_entry(q, slab_t, list);
+			if (slabp->inuse == cachep->num || !slabp->inuse)
+				BUG();
 			active_objs += slabp->inuse;
-			num_objs += cachep->num;
+			active_slabs++;
+		}
+		list_for_each(q,&cachep->slabs_free) {
+			slabp = list_entry(q, slab_t, list);
 			if (slabp->inuse)
-				active_slabs++;
-			else
-				num_slabs++;
+				BUG();
+			num_slabs++;
 		}
 		num_slabs+=active_slabs;
 		num_objs = num_slabs*cachep->num;
diff -urN linux-2.4.10-pre5/net/core/dev.c linux/net/core/dev.c
--- linux-2.4.10-pre5/net/core/dev.c	Mon Dec  3 23:08:04 2001
+++ linux/net/core/dev.c	Mon Dec  3 23:08:14 2001
@@ -1217,10 +1217,9 @@
 enqueue:
 			dev_hold(skb->dev);
 			__skb_queue_tail(&queue->input_pkt_queue,skb);
-			local_irq_restore(flags);
-
 			/* Runs from irqs or BH's, no need to wake BH */
 			__cpu_raise_softirq(this_cpu, NET_RX_SOFTIRQ);
+			local_irq_restore(flags);
 #ifndef OFFLINE_SAMPLE
 			get_sample_stats(this_cpu);
 #endif
@@ -1529,10 +1528,9 @@
 
 	local_irq_disable();
 	netdev_rx_stat[this_cpu].time_squeeze++;
-	local_irq_enable();
-
 	/* This already runs in BH context, no need to wake up BH's */
 	__cpu_raise_softirq(this_cpu, NET_RX_SOFTIRQ);
+	local_irq_enable();
 
 	NET_PROFILE_LEAVE(softnet_process);
 	return;
diff -urN linux-2.4.10-pre5/net/irda/af_irda.c linux/net/irda/af_irda.c
--- linux-2.4.10-pre5/net/irda/af_irda.c	Wed Aug 15 01:22:18 2001
+++ linux/net/irda/af_irda.c	Mon Dec  3 23:08:14 2001
@@ -2035,7 +2035,7 @@
 	if (get_user(len, optlen))
 		return -EFAULT;
 
-	if(optlen < 0)
+	if(len < 0)
 		return -EINVAL;
 		
 	switch (optname) {
