## Automatically generated incremental diff
## From:   linux-2.5.74-bk3
## To:     linux-2.5.74-bk4
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.5.74-bk3/Makefile linux-2.5.74-bk4/Makefile
--- linux-2.5.74-bk3/Makefile	2003-07-06 09:15:34.000000000 -0700
+++ linux-2.5.74-bk4/Makefile	2003-07-06 09:15:48.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 74
-EXTRAVERSION = -bk3
+EXTRAVERSION = -bk4
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.74-bk3/arch/ppc/Kconfig linux-2.5.74-bk4/arch/ppc/Kconfig
--- linux-2.5.74-bk3/arch/ppc/Kconfig	2003-07-02 13:57:31.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/Kconfig	2003-07-06 09:15:48.000000000 -0700
@@ -450,9 +450,6 @@
 config SPRUCE
 	bool "IBM-Spruce"
 
-config MENF1
-	bool "MEN-F1"
-
 config LOPEC
 	bool "Motorola-LoPEC"
 
@@ -473,6 +470,10 @@
 
 config SANDPOINT
 	bool "Motorola-Sandpoint"
+	help
+	  Select SANDPOINT if configuring for a Motorola Sandpoint X3
+	  or X3(b).
+	  X3 (any flavor).
 
 config ADIR
 	bool "SBS-Adirondack"
@@ -490,9 +491,6 @@
 	  series Single Board Computer.  More information is available at:
 	  <http://www.synergymicro.com/PressRel/97_10_15.html>.
 
-config ZX4500
-	bool "Zynx-ZX4500"
-
 endchoice
 
 config PPC_CHRP
@@ -500,6 +498,11 @@
 	depends on PPC_MULTIPLATFORM
 	default y
 
+config PPC_GEN550
+	bool
+	depends on SANDPOINT
+	default y
+
 config PPC_PMAC
 	bool
 	depends on PPC_MULTIPLATFORM
@@ -515,10 +518,6 @@
 	depends on PPC_PMAC || PPC_CHRP
 	default y
 
-config SANDPOINT_X3
-	bool "Sandpoint X3"
-	depends on SANDPOINT
-
 config FORCE
 	bool
 	depends on 6xx && !8260 && (PCORE || POWERPMC250)
@@ -526,7 +525,7 @@
 
 config EPIC_SERIAL_MODE
 	bool
-	depends on 6xx && !8260 && (LOPEC || SANDPOINT_X3)
+	depends on 6xx && !8260 && (LOPEC || SANDPOINT)
 	default y
 
 config WILLOW
@@ -536,7 +535,7 @@
 
 config MPC10X_STORE_GATHERING
 	bool "Enable MPC10x store gathering"
-	depends on FORCE || MENF1 || SANDPOINT || ZX4500
+	depends on FORCE || SANDPOINT
 
 config GT64260
 	bool
@@ -1528,7 +1527,7 @@
 
 config SERIAL_TEXT_DEBUG
 	bool "Support for early boot texts over serial port"
-	depends on 4xx || GT64260 || LOPEC || MCPN765 || PPLUS || PRPMC800 || SANDPOINT || ZX4500
+	depends on 4xx || GT64260 || LOPEC || MCPN765 || PPLUS || PRPMC800 || SANDPOINT
 
 config OCP
 	bool
diff -urN linux-2.5.74-bk3/arch/ppc/boot/common/Makefile linux-2.5.74-bk4/arch/ppc/boot/common/Makefile
--- linux-2.5.74-bk3/arch/ppc/boot/common/Makefile	2003-07-02 13:49:13.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/boot/common/Makefile	2003-07-06 09:15:48.000000000 -0700
@@ -8,7 +8,8 @@
 # Tom Rini	January 2001
 #
 
-lib-y					:= string.o util.o misc-common.o
+lib-y					:= string.o util.o misc-common.o \
+						serial_stub.o
 lib-$(CONFIG_PPC_PREP)			+= mpc10x_memory.o
 lib-$(CONFIG_LOPEC)			+= mpc10x_memory.o
 lib-$(CONFIG_PAL4)			+= cpc700_memory.o
diff -urN linux-2.5.74-bk3/arch/ppc/boot/common/ns16550.c linux-2.5.74-bk4/arch/ppc/boot/common/ns16550.c
--- linux-2.5.74-bk3/arch/ppc/boot/common/ns16550.c	2003-07-02 13:57:13.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/boot/common/ns16550.c	2003-07-06 09:15:48.000000000 -0700
@@ -95,8 +95,3 @@
 {
 	return ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0);
 }
-
-void
-serial_close(unsigned long com_port)
-{
-}
diff -urN linux-2.5.74-bk3/arch/ppc/boot/common/serial_stub.c linux-2.5.74-bk4/arch/ppc/boot/common/serial_stub.c
--- linux-2.5.74-bk3/arch/ppc/boot/common/serial_stub.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.74-bk4/arch/ppc/boot/common/serial_stub.c	2003-07-06 09:15:48.000000000 -0700
@@ -0,0 +1,28 @@
+/*
+ * arch/ppc/boot/common/serial_stub.c
+ *
+ * This is a few stub routines to make the boot code cleaner looking when
+ * there is no serial port support doesn't need to be closed, for example.
+ *
+ * Author: Tom Rini <trini@mvista.com>
+ *
+ * 2003 (c) MontaVista, Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed "as
+ * is" without any warranty of any kind, whether express or implied.
+ */
+
+void __attribute__ ((weak))
+serial_fixups(void)
+{
+}
+
+unsigned long __attribute__ ((weak))
+serial_init(int chan, void *ignored)
+{
+	return 0;
+}
+
+void __attribute__ ((weak))
+serial_close(unsigned long com_port)
+{
+}
diff -urN linux-2.5.74-bk3/arch/ppc/boot/simple/Makefile linux-2.5.74-bk4/arch/ppc/boot/simple/Makefile
--- linux-2.5.74-bk3/arch/ppc/boot/simple/Makefile	2003-07-02 13:39:27.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/boot/simple/Makefile	2003-07-06 09:15:48.000000000 -0700
@@ -47,28 +47,20 @@
 ifeq ($(CONFIG_EBONY),y)
 ZIMAGE				:= zImage-TREE
 ZIMAGEINITRD			:= zImage.initrd-TREE
-EXTRA				:= direct.o
 END				:= ebony
 ENTRYPOINT			:= 0x01000000
 TFTPIMAGE			:= /tftpboot/zImage.$(END)
 endif
 ifeq ($(CONFIG_EV64260),y)
-EXTRA				:= direct.o misc-ev64260.o
+EXTRA				:= misc-ev64260.o
 TFTPIMAGE			:= /tftpboot/zImage.ev64260
 endif
 ifeq ($(CONFIG_GEMINI),y)
 ZIMAGE				:= zImage-STRIPELF
 ZIMAGEINITRD			:= zImage.initrd-STRIPELF
-EXTRA				:= direct.o
 END				:= gemini
 TFTPIMAGE			:= /tftpboot/zImage.$(END)
 endif
-ifeq ($(CONFIG_MENF1),y)
-ZIMAGE				:= zImage-MENF1
-ZIMAGEINITRD			:= zImage.initrd-MENF1
-EXTRA				:= chrpmap.o
-TFTPIMAGE			:= /tftpboot/zImage.menf1
-endif
 ifeq ($(CONFIG_K2),y)
 EXTRA				:= legacy.o
 TFTPIMAGE			:= /tftpboot/zImage.k2
@@ -78,7 +70,6 @@
 ifeq ($(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750)$(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS),y)
 ZIMAGE				:= zImage-PPLUS
 ZIMAGEINITRD			:= zImage.initrd-PPLUS
-EXTRA				:= direct.o
 TFTPIMAGE			:= /tftpboot/zImage.pplus
 ZNETBOOT			:= zImage.pplus
 ZNETBOOTRD			:= zImage.initrd.pplus
@@ -86,9 +77,6 @@
 ifeq ($(CONFIG_PPLUS),y)
 EXTRA				:= legacy.o
 endif
-ifeq ($(CONFIG_PAL4),y)
-EXTRA				:= direct.o
-endif
 ifeq ($(CONFIG_PCORE)$(CONFIG_POWERPMC250),y)
 ZIMAGE				:= zImage-STRIPELF
 ZIMAGEINITRD			:= zImage.initrd-STRIPELF
@@ -96,30 +84,17 @@
 END				:= pcore
 TFTPIMAGE			:= /tftpboot/zImage.$(END)
 endif
-# The PowerPMC 250 needs the dummy serial_fixups()
-ifeq ($(CONFIG_POWERPMC250),y)
-EXTRA				:= direct.o
-endif
 ifeq ($(CONFIG_SANDPOINT),y)
-EXTRA				:= direct.o
 TFTPIMAGE			:= /tftpboot/zImage.sandpoint
 endif
 ifeq ($(CONFIG_SPRUCE),y)
 ZIMAGE				:= zImage-TREE
 ZIMAGEINITRD			:= zImage.initrd-TREE
-EXTRA				:= direct.o
 END				:= spruce
 ENTRYPOINT			:= 0x00800000
 MISC				:= misc-spruce.o
 TFTPIMAGE			:= /tftpboot/zImage.$(END)
 endif
-ifeq ($(CONFIG_ZX4500),y)
-ZIMAGE				:= zImage-STRIPELF
-ZIMAGEINITRD			:= zImage.initrd-STRIPELF
-EXTRA				:= direct.o
-END				:= zx4500
-TFTPIMAGE			:= /tftpboot/zImage.$(END)
-endif
 ifeq ($(CONFIG_SMP),y)
 TFTPIMAGE			+= .smp
 endif
@@ -221,12 +196,6 @@
 	$(MKTREE) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(END) \
 		$(ENTRYPOINT)
 
-$(images)/zImage-MENF1: $(obj)/zvmlinux $(MKPREP)
-	$(MKPREP) -pbp $(obj)/zvmlinux $(images)/zImage.menf1
-
-$(images)/zImage.initrd-MENF1: $(obj)/zvmlinux.initrd $(MKPREP)
-	$(MKPREP) -pbp $(obj)/zvmlinux.initrd $(images)/zImage.initrd.menf1
-
 $(images)/zImage-PPLUS: $(obj)/zvmlinux $(MKPREP) $(MKBUGBOOT)
 	$(MKPREP) -pbp $(obj)/zvmlinux $(images)/zImage.pplus
 	$(MKBUGBOOT) $(obj)/zvmlinux $(images)/zImage.bugboot
diff -urN linux-2.5.74-bk3/arch/ppc/boot/simple/direct.S linux-2.5.74-bk4/arch/ppc/boot/simple/direct.S
--- linux-2.5.74-bk3/arch/ppc/boot/simple/direct.S	2003-07-02 13:49:21.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/boot/simple/direct.S	1969-12-31 16:00:00.000000000 -0800
@@ -1,15 +0,0 @@
-/*
- * arch/ppc/boot/simple/direct.S
- *
- * Author: Tom Rini <trini@mvista.com>
- *
- * This is an empty function for machines which use SERIAL_IO_MEM
- * and don't need ISA_io set to anything but 0, or perform any other
- * serial fixups.
- */
-
-	.text
-
-	.globl serial_fixups
-serial_fixups:
-	blr
diff -urN linux-2.5.74-bk3/arch/ppc/boot/simple/m8260_tty.c linux-2.5.74-bk4/arch/ppc/boot/simple/m8260_tty.c
--- linux-2.5.74-bk3/arch/ppc/boot/simple/m8260_tty.c	2003-07-02 13:45:07.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/boot/simple/m8260_tty.c	2003-07-06 09:15:48.000000000 -0700
@@ -311,8 +311,3 @@
 
 	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
 }
-
-void
-serial_close(unsigned long com_port)
-{
-}
diff -urN linux-2.5.74-bk3/arch/ppc/boot/simple/m8xx_tty.c linux-2.5.74-bk4/arch/ppc/boot/simple/m8xx_tty.c
--- linux-2.5.74-bk3/arch/ppc/boot/simple/m8xx_tty.c	2003-07-02 13:39:16.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/boot/simple/m8xx_tty.c	2003-07-06 09:15:48.000000000 -0700
@@ -288,8 +288,3 @@
 
 	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
 }
-
-void
-serial_close(unsigned long com_port)
-{
-}
diff -urN linux-2.5.74-bk3/arch/ppc/configs/adir_defconfig linux-2.5.74-bk4/arch/ppc/configs/adir_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/adir_defconfig	2003-07-02 13:51:53.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/adir_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ALTIVEC is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/apus_defconfig linux-2.5.74-bk4/arch/ppc/configs/apus_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/apus_defconfig	2003-07-02 13:53:37.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/apus_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -56,7 +56,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -68,7 +67,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ALTIVEC is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/common_defconfig linux-2.5.74-bk4/arch/ppc/configs/common_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/common_defconfig	2003-07-02 13:44:00.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/common_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -56,7 +56,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -68,7 +67,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_PPC_CHRP=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PREP=y
diff -urN linux-2.5.74-bk3/arch/ppc/configs/ev64260_defconfig linux-2.5.74-bk4/arch/ppc/configs/ev64260_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/ev64260_defconfig	2003-07-02 13:55:46.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/ev64260_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 CONFIG_EV64260=y
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_GT64260=y
 CONFIG_SERIAL_CONSOLE_BAUD=115200
 # CONFIG_SMP is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/gemini_defconfig linux-2.5.74-bk4/arch/ppc/configs/gemini_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/gemini_defconfig	2003-07-02 13:46:45.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/gemini_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 CONFIG_GEMINI=y
-# CONFIG_ZX4500 is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_ALTIVEC=y
diff -urN linux-2.5.74-bk3/arch/ppc/configs/ibmchrp_defconfig linux-2.5.74-bk4/arch/ppc/configs/ibmchrp_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/ibmchrp_defconfig	2003-07-02 13:46:58.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/ibmchrp_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_PPC_CHRP=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PREP=y
diff -urN linux-2.5.74-bk3/arch/ppc/configs/k2_defconfig linux-2.5.74-bk4/arch/ppc/configs/k2_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/k2_defconfig	2003-07-02 13:40:19.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/k2_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 CONFIG_K2=y
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_CPC710_DATA_GATHERING is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/lopec_defconfig linux-2.5.74-bk4/arch/ppc/configs/lopec_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/lopec_defconfig	2003-07-02 13:50:11.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/lopec_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 CONFIG_LOPEC=y
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_EPIC_SERIAL_MODE=y
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/mcpn765_defconfig linux-2.5.74-bk4/arch/ppc/configs/mcpn765_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/mcpn765_defconfig	2003-07-02 13:49:31.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/mcpn765_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -50,7 +50,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 CONFIG_MCPN765=y
 # CONFIG_MVME5100 is not set
@@ -62,7 +61,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 CONFIG_ALTIVEC=y
diff -urN linux-2.5.74-bk3/arch/ppc/configs/menf1_defconfig linux-2.5.74-bk4/arch/ppc/configs/menf1_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/menf1_defconfig	2003-07-02 13:39:18.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/menf1_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -67,7 +67,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_MPC10X_STORE_GATHERING=y
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/mvme5100_defconfig linux-2.5.74-bk4/arch/ppc/configs/mvme5100_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/mvme5100_defconfig	2003-07-02 13:41:06.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/mvme5100_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 CONFIG_MVME5100=y
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_MVME5100_IPMC761_PRESENT is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/pcore_defconfig linux-2.5.74-bk4/arch/ppc/configs/pcore_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/pcore_defconfig	2003-07-02 13:48:16.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/pcore_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_FORCE=y
 # CONFIG_MPC10X_STORE_GATHERING is not set
 # CONFIG_SMP is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/pmac_defconfig linux-2.5.74-bk4/arch/ppc/configs/pmac_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/pmac_defconfig	2003-07-02 13:55:52.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/pmac_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -57,7 +57,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -69,7 +68,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_PPC_CHRP=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PREP=y
diff -urN linux-2.5.74-bk3/arch/ppc/configs/power3_defconfig linux-2.5.74-bk4/arch/ppc/configs/power3_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/power3_defconfig	2003-07-02 13:43:30.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/power3_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_PPC_CHRP=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PREP=y
diff -urN linux-2.5.74-bk3/arch/ppc/configs/pplus_defconfig linux-2.5.74-bk4/arch/ppc/configs/pplus_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/pplus_defconfig	2003-07-02 13:49:33.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/pplus_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ALTIVEC is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/prpmc750_defconfig linux-2.5.74-bk4/arch/ppc/configs/prpmc750_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/prpmc750_defconfig	2003-07-02 13:42:43.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/prpmc750_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ALTIVEC is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/prpmc800_defconfig linux-2.5.74-bk4/arch/ppc/configs/prpmc800_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/prpmc800_defconfig	2003-07-02 13:55:46.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/prpmc800_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_ALTIVEC is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/sandpoint_defconfig linux-2.5.74-bk4/arch/ppc/configs/sandpoint_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/sandpoint_defconfig	2003-07-02 13:46:53.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/sandpoint_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,8 +66,7 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
-CONFIG_SANDPOINT_X3=y
+CONFIG_PPC_GEN550=y
 CONFIG_EPIC_SERIAL_MODE=y
 # CONFIG_MPC10X_STORE_GATHERING is not set
 # CONFIG_SMP is not set
@@ -84,8 +82,8 @@
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_KCORE_ELF=y
-CONFIG_BINFMT_ELF=y
 CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 # CONFIG_PCI_LEGACY_PROC is not set
 # CONFIG_PCI_NAMES is not set
@@ -118,6 +116,11 @@
 CONFIG_BOOT_LOAD=0x00800000
 
 #
+# Generic Driver Options
+#
+# CONFIG_FW_LOADER is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -147,7 +150,7 @@
 # CONFIG_MD is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -166,6 +169,7 @@
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_TASKFILE_IO=y
 
 #
 # IDE chipset support/bugfixes
@@ -173,7 +177,7 @@
 # CONFIG_BLK_DEV_IDEPCI is not set
 
 #
-# SCSI support
+# SCSI device support
 #
 # CONFIG_SCSI is not set
 
@@ -292,6 +296,7 @@
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
+# CONFIG_TC35815 is not set
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
@@ -413,11 +418,6 @@
 # CONFIG_LOGO is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Input device support
 #
 CONFIG_INPUT=y
@@ -443,6 +443,7 @@
 CONFIG_SERIO_I8042=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
 
 #
 # Input Device Drivers
@@ -731,6 +732,7 @@
 #
 # USB Network adaptors
 #
+# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/spruce_defconfig linux-2.5.74-bk4/arch/ppc/configs/spruce_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/spruce_defconfig	2003-07-02 13:41:51.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/spruce_defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -55,7 +55,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 CONFIG_SPRUCE=y
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -67,7 +66,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 # CONFIG_SPRUCE_BAUD_33M is not set
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
diff -urN linux-2.5.74-bk3/arch/ppc/configs/zx4500_defconfig linux-2.5.74-bk4/arch/ppc/configs/zx4500_defconfig
--- linux-2.5.74-bk3/arch/ppc/configs/zx4500_defconfig	2003-07-02 13:43:40.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/configs/zx4500_defconfig	1969-12-31 16:00:00.000000000 -0800
@@ -1,560 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_MMU=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_HAVE_DEC_LOCK=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EMBEDDED=y
-CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_PPC32=y
-CONFIG_6xx=y
-# CONFIG_40x is not set
-# CONFIG_POWER3 is not set
-# CONFIG_8xx is not set
-
-#
-# IBM 4xx options
-#
-# CONFIG_8260 is not set
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_PPC_STD_MMU=y
-# CONFIG_PPC_MULTIPLATFORM is not set
-# CONFIG_APUS is not set
-# CONFIG_WILLOW_2 is not set
-# CONFIG_PCORE is not set
-# CONFIG_POWERPMC250 is not set
-# CONFIG_EV64260 is not set
-# CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
-# CONFIG_LOPEC is not set
-# CONFIG_MCPN765 is not set
-# CONFIG_MVME5100 is not set
-# CONFIG_PPLUS is not set
-# CONFIG_PRPMC750 is not set
-# CONFIG_PRPMC800 is not set
-# CONFIG_SANDPOINT is not set
-# CONFIG_ADIR is not set
-# CONFIG_K2 is not set
-# CONFIG_PAL4 is not set
-# CONFIG_GEMINI is not set
-CONFIG_ZX4500=y
-# CONFIG_MPC10X_STORE_GATHERING is not set
-# CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_ALTIVEC is not set
-# CONFIG_TAU is not set
-# CONFIG_CPU_FREQ is not set
-
-#
-# General setup
-#
-# CONFIG_HIGHMEM is not set
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_KCORE_ELF=y
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-CONFIG_PPC601_SYNC_FIX=y
-# CONFIG_CMDLINE_BOOL is not set
-
-#
-# Advanced setup
-#
-# CONFIG_ADVANCED_OPTIONS is not set
-
-#
-# Default settings for advanced configuration options are used
-#
-CONFIG_HIGHMEM_START=0xfe000000
-CONFIG_LOWMEM_SIZE=0x30000000
-CONFIG_KERNEL_START=0xc0000000
-CONFIG_TASK_SIZE=0x80000000
-CONFIG_BOOT_LOAD=0x00800000
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_IPV6 is not set
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IPV6_SCTP__=y
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_LLC is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_OAKNET is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_DGRS is not set
-CONFIG_EEPRO100=y
-# CONFIG_EEPRO100_PIO is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices (depends on LLC=y)
-#
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN_BOOL is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Input device support
-#
-# CONFIG_INPUT is not set
-
-#
-# Userland interfaces
-#
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-
-#
-# Input Device Drivers
-#
-
-#
-# Macintosh device drivers
-#
-
-#
-# Character devices
-#
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# I2C Hardware Sensors Mainboard support
-#
-
-#
-# I2C Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_FAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_EXPORTFS=y
-CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_GSS is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-# CONFIG_USB_GADGET is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_KALLSYMS is not set
-CONFIG_SERIAL_TEXT_DEBUG=y
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
diff -urN linux-2.5.74-bk3/arch/ppc/defconfig linux-2.5.74-bk4/arch/ppc/defconfig
--- linux-2.5.74-bk3/arch/ppc/defconfig	2003-07-02 13:53:44.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/defconfig	2003-07-06 09:15:48.000000000 -0700
@@ -56,7 +56,6 @@
 # CONFIG_POWERPMC250 is not set
 # CONFIG_EV64260 is not set
 # CONFIG_SPRUCE is not set
-# CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -68,7 +67,6 @@
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_ZX4500 is not set
 CONFIG_PPC_CHRP=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PREP=y
diff -urN linux-2.5.74-bk3/arch/ppc/kernel/ppc-stub.c linux-2.5.74-bk4/arch/ppc/kernel/ppc-stub.c
--- linux-2.5.74-bk3/arch/ppc/kernel/ppc-stub.c	2003-07-02 13:55:47.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/kernel/ppc-stub.c	2003-07-06 09:15:48.000000000 -0700
@@ -851,14 +851,4 @@
 	putpacket(buffer);
 
 	return 1;
- }
-
-#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
-
-/* This is used on arches which don't have a serial driver that maps
- * the ports for us */
-void
-kgdb_map_scc(void)
-{
 }
-#endif
diff -urN linux-2.5.74-bk3/arch/ppc/kernel/ppc_ksyms.c linux-2.5.74-bk4/arch/ppc/kernel/ppc_ksyms.c
--- linux-2.5.74-bk3/arch/ppc/kernel/ppc_ksyms.c	2003-07-02 13:55:52.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/kernel/ppc_ksyms.c	2003-07-06 09:15:48.000000000 -0700
@@ -272,8 +272,10 @@
 #ifdef CONFIG_NVRAM
 EXPORT_SYMBOL(nvram_read_byte);
 EXPORT_SYMBOL(nvram_write_byte);
+#ifdef CONFIG_PPC_PMAC
 EXPORT_SYMBOL(pmac_xpram_read);
 EXPORT_SYMBOL(pmac_xpram_write);
+#endif
 #endif /* CONFIG_NVRAM */
 EXPORT_SYMBOL(to_tm);
 
diff -urN linux-2.5.74-bk3/arch/ppc/kernel/setup.c linux-2.5.74-bk4/arch/ppc/kernel/setup.c
--- linux-2.5.74-bk3/arch/ppc/kernel/setup.c	2003-07-02 13:56:08.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/kernel/setup.c	2003-07-06 09:15:48.000000000 -0700
@@ -619,6 +619,8 @@
 	if (strstr(cmd_line, "nokgdb"))
 		printk("kgdb default breakpoint deactivated on command line\n");
 	else {
+		if (ppc_md.progress)
+			ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
 		printk("kgdb default breakpoint activated\n");
 		breakpoint();
 	}
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/Makefile linux-2.5.74-bk4/arch/ppc/platforms/Makefile
--- linux-2.5.74-bk3/arch/ppc/platforms/Makefile	2003-07-02 13:58:15.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/Makefile	2003-07-06 09:15:48.000000000 -0700
@@ -43,9 +43,8 @@
 obj-$(CONFIG_PPLUS)		+= pplus_pci.o pplus_setup.o
 obj-$(CONFIG_PRPMC750)		+= prpmc750_setup.o prpmc750_pci.o
 obj-$(CONFIG_PRPMC800)		+= prpmc800_setup.o prpmc800_pci.o
-obj-$(CONFIG_SANDPOINT)		+= sandpoint_setup.o sandpoint_pci.o
+obj-$(CONFIG_SANDPOINT)		+= sandpoint.o
 obj-$(CONFIG_SPRUCE)		+= spruce_setup.o spruce_pci.o
-obj-$(CONFIG_ZX4500)		+= zx4500_setup.o zx4500_pci.o
 
 ifeq ($(CONFIG_SMP),y)
 obj-$(CONFIG_PPC_PMAC)		+= pmac_smp.o
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/menf1.h linux-2.5.74-bk4/arch/ppc/platforms/menf1.h
--- linux-2.5.74-bk3/arch/ppc/platforms/menf1.h	2003-07-02 13:39:33.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/menf1.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,24 +0,0 @@
-/*
- * arch/ppc/platforms/menf1.h
- * 
- * Definitions for MEN F1 board support
- *
- * Author: Matt Porter <mporter@mvista.com>
- *
- * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#ifndef __PPC_PLATFORMS_MENF1_H
-#define __PPC_PLATFORMS_MENF1_H
-
-#define MENF1_NVRAM_AS0			0x70
-#define MENF1_NVRAM_AS1			0x72
-#define MENF1_NVRAM_DATA		0x71    
-
-#define	MENF1_IDE0_BASE_ADDR		0x1f0
-#define MENF1_IDE1_BASE_ADDR		0x170
-
-#endif /* __PPC_PLATFORMS_MENF1_H */
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/menf1_pci.c linux-2.5.74-bk4/arch/ppc/platforms/menf1_pci.c
--- linux-2.5.74-bk3/arch/ppc/platforms/menf1_pci.c	2003-07-02 13:42:13.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/menf1_pci.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,98 +0,0 @@
-/*
- * arch/ppc/platforms/menf1_pci.c
- * 
- * PCI support for MEN F1
- *
- * Author: Matt Porter <mporter@mvista.com>
- *
- * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/mpc10x.h>
-
-#include "menf1.h"
-
-#undef DEBUG
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG */ 
-
-static inline int __init
-menf1_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
-	static char pci_irq_table[][4] =
-	/*
-	 *      PCI IDSEL/INTPIN->INTLINE
-	 *      A       B       C       D
-	 */ 
-	{
-		{10,	11,	7,	9},	/* IDSEL 26 - PCMIP 0 */
-		{0,	0,	0,	0},	/* IDSEL 27 - M5229 IDE */
-		{0,	0,	0,	0},	/* IDSEL 28 - M7101 PMU */
-		{9,	10,	11,	7},	/* IDSEL 29 - PCMIP 1 */
-		{10,	11,	7,	9},	/* IDSEL 30 - P2P Bridge */
-	};
-	const long min_idsel = 26, max_idsel = 30, irqs_per_slot = 4;
-	return PCI_IRQ_TABLE_LOOKUP;
-};
-
-static int
-menf1_exclude_device(u_char bus, u_char devfn)
-{
-	if ((bus == 0) && (devfn == 0xe0)) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	else {
-		return PCIBIOS_SUCCESSFUL;
-	}
-}
-
-void __init
-menf1_find_bridges(void)
-{
-	struct pci_controller* hose;
-
-	hose = pcibios_alloc_controller();
-	if (!hose)
-		return;
-
-	hose->first_busno = 0;
-	hose->last_busno = 0xff;
-
-	ppc_md.pci_exclude_device = menf1_exclude_device;
-
-	mpc10x_bridge_init(hose,
-			MPC10X_MEM_MAP_B,
-			MPC10X_MEM_MAP_B,
-			MPC10X_MAPB_EUMB_BASE);
-
-	hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
-
-	{
-		/* Add ISA bus wait states */
-		unsigned char isa_control;
-
-		early_read_config_byte(hose, 0, 0x90, 0x43, &isa_control);
-		isa_control |= 0x33;
-		early_write_config_byte(hose, 0, 0x90, 0x43, isa_control);
-	}
-
-	ppc_md.pci_swizzle = common_swizzle;
-	ppc_md.pci_map_irq = menf1_map_irq;
-}
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/menf1_setup.c linux-2.5.74-bk4/arch/ppc/platforms/menf1_setup.c
--- linux-2.5.74-bk3/arch/ppc/platforms/menf1_setup.c	2003-07-02 13:54:33.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/menf1_setup.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,283 +0,0 @@
-/*
- * arch/ppc/platforms/menf1_setup.c
- *
- * Board setup routines for MEN F1
- *
- * Author: Matt Porter <mporter@mvista.com>
- *
- * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/config.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/reboot.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/initrd.h>
-#include <linux/console.h>
-#include <linux/delay.h>
-#include <linux/ide.h>
-#include <linux/irq.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/machdep.h>
-#include <asm/time.h>
-#include <asm/i8259.h>
-#include <asm/mpc10x.h>
-#include <asm/todc.h>
-#include <asm/bootinfo.h>
-
-#include "menf1.h"
-
-extern void menf1_find_bridges(void);
-extern unsigned long loops_per_jiffy;
-
-/* Dummy variable to satisfy mpc10x_common.o */
-void *OpenPIC_Addr;
-
-static int
-menf1_show_cpuinfo(struct seq_file *m)
-{
-	seq_printf(m, "machine\t\t: MEN F1\n");
-
-	return 0;
-}
-
-static void __init
-menf1_setup_arch(void)
-{
-	/* init to some ~sane value until calibrate_delay() runs */
-	loops_per_jiffy = 50000000/HZ;
-
-	/* Lookup PCI host bridges */
-	menf1_find_bridges();
-
-#ifdef CONFIG_BLK_DEV_INITRD
-        if (initrd_start)
-                ROOT_DEV = Root_RAM0;
-        else
-#endif
-#ifdef CONFIG_ROOT_NFS
-		ROOT_DEV = Root_NFS;
-#else
-		ROOT_DEV = Root_HDA2;
-#endif
-
-#ifdef CONFIG_DUMMY_CONSOLE
-	conswitchp = &dummy_con;
-#endif
-
-	printk("MEN F1 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
-}
-
-static void
-menf1_restart(char *cmd)
-{
-
-       int     picr1;
-       struct pci_dev *pdev;
-
-	local_irq_disable();
-
-	/*
-	 * Firmware doesn't like re-entry using Map B (CHRP), so make sure the
-	 * PCI bridge is using MAP A (PReP).
-	 */
-
-	pdev = pci_find_slot(0, PCI_DEVFN(0,0));
-
-	while(pdev == NULL); /* paranoia */
-
-	pci_read_config_dword(pdev, MPC10X_CFG_PICR1_REG, &picr1);
-
-	picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) |
-		MPC10X_CFG_PICR1_ADDR_MAP_A;
-
-	pci_write_config_dword(pdev, MPC10X_CFG_PICR1_REG, picr1);
-
-	asm volatile("sync");
-
-	/* SRR0 has system reset vector, SRR1 has default MSR value */
-	/* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
-	__asm__ __volatile__
-	("\n\
-	lis     3,0xfff0
-	ori     3,3,0x0100
-	mtspr   26,3
-	li      3,0
-	mtspr   27,3
-	rfi
-	");
-	while(1);
-}
-
-static void
-menf1_halt(void)
-{
-	local_irq_disable();
-	while (1);
-}
-
-static void
-menf1_power_off(void)
-{
-	menf1_halt();
-}
-
-static void __init
-menf1_init_IRQ(void)
-{
-	int i;
-
-	for ( i = 0 ; i < NUM_8259_INTERRUPTS  ; i++ )
-		irq_desc[i].handler = &i8259_pic;
-	i8259_init(NULL);
-}
-
-/*
- * Set BAT 3 to map 0xF0000000.
- */
-static __inline__ void
-menf1_set_bat(void)
-{
-	static int	mapping_set = 0;
-
-	if (!mapping_set)
-	{
-
-		/* wait for all outstanding memory accesses to complete */
-		mb();
-
-		/* setup DBATs */
-		mtspr(DBAT3U, 0xf0001ffe);
-		mtspr(DBAT3L, 0xf000002a);
-
-		/* wait for updates */
-		mb();
-
-		mapping_set = 1;
-	}
-	return;
-}
-
-static unsigned long __init
-menf1_find_end_of_memory(void)
-{
-	/* Cover the I/O with a BAT */
-	menf1_set_bat();
-
-	/* Read the memory size from the MPC107 SMC */
-	return mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
-}
-
-static void __init
-menf1_map_io(void)
-{
-        io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
-}
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-/* IDE functions */
-
-static void __init
-menf1_ide_init_hwif_ports (hw_regs_t *hw, unsigned long data_port,
-		unsigned long ctrl_port, int *irq)
-{
-	unsigned long reg = data_port;
-	int i = 8;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg;
-		reg += 1;
-	}
-	if (ctrl_port)
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-	else
-		hw->io_ports[IDE_CONTROL_OFFSET] =
-			hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-
-	if (irq != NULL)
-		*irq = 0;
-}
-
-static int
-menf1_ide_default_irq(unsigned long base)
-{
-	if (base == MENF1_IDE0_BASE_ADDR)
-		return 14;
-	else if (base == MENF1_IDE1_BASE_ADDR)
-		return 15;
-	else
-		return 0;
-}
-
-static unsigned long
-menf1_ide_default_io_base(int index)
-{
-	if (index == 0)
-		return MENF1_IDE0_BASE_ADDR;
-	else if (index == 1)
-		return MENF1_IDE1_BASE_ADDR;
-	else
-		return 0;
-}
-#endif
-
-TODC_ALLOC();
-
-void __init
-platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	      unsigned long r6, unsigned long r7)
-{
-	parse_bootinfo(find_bootinfo());
-
-	isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
-	isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
-	pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
-
-	ppc_md.setup_arch	= menf1_setup_arch;
-	ppc_md.show_cpuinfo	= menf1_show_cpuinfo;
-	ppc_md.init_IRQ		= menf1_init_IRQ;
-	ppc_md.get_irq		= i8259_irq;
-
-	ppc_md.find_end_of_memory = menf1_find_end_of_memory;
-	ppc_md.setup_io_mappings = menf1_map_io;
-
-	ppc_md.restart		= menf1_restart;
-	ppc_md.power_off	= menf1_power_off;
-	ppc_md.halt		= menf1_halt;
-
-	TODC_INIT(TODC_TYPE_MK48T59,
-		  MENF1_NVRAM_AS0,
-		  MENF1_NVRAM_AS1,
-		  MENF1_NVRAM_DATA,
-		  7);
-
-	ppc_md.time_init	= todc_time_init;
-	ppc_md.get_rtc_time	= todc_get_rtc_time;
-	ppc_md.set_rtc_time	= todc_set_rtc_time;
-	ppc_md.calibrate_decr	= todc_calibrate_decr;
-
-	ppc_md.nvram_read_val   = todc_m48txx_read_val;
-	ppc_md.nvram_write_val  = todc_m48txx_write_val;
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-	ppc_ide_md.default_io_base = menf1_ide_default_io_base;
-	ppc_ide_md.default_irq = menf1_ide_default_irq;
-	ppc_ide_md.ide_init_hwif = menf1_ide_init_hwif_ports;
-#endif
-}
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/sandpoint.c linux-2.5.74-bk4/arch/ppc/platforms/sandpoint.c
--- linux-2.5.74-bk3/arch/ppc/platforms/sandpoint.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.74-bk4/arch/ppc/platforms/sandpoint.c	2003-07-06 09:15:48.000000000 -0700
@@ -0,0 +1,719 @@
+/*
+ * arch/ppc/platforms/sandpoint_setup.c
+ *
+ * Board setup routines for the Motorola SPS Sandpoint Test Platform.
+ *
+ * Author: Mark A. Greer
+ *	 mgreer@mvista.com
+ *
+ * 2000-2003 (c) MontaVista Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+/*
+ * This file adds support for the Motorola SPS Sandpoint Test Platform.
+ * These boards have a PPMC slot for the processor so any combination
+ * of cpu and host bridge can be attached.  This port is for an 8240 PPMC
+ * module from Motorola SPS and other closely related cpu/host bridge
+ * combinations (e.g., 750/755/7400 with MPC107 host bridge).
+ * The sandpoint itself has a Windbond 83c553 (PCI-ISA bridge, 2 DMA ctlrs, 2
+ * cascaded 8259 interrupt ctlrs, 8254 Timer/Counter, and an IDE ctlr), a
+ * National 87308 (RTC, 2 UARTs, Keyboard & mouse ctlrs, and a floppy ctlr),
+ * and 4 PCI slots (only 2 of which are usable; the other 2 are keyed for 3.3V
+ * but are really 5V).
+ *
+ * The firmware on the sandpoint is called DINK (not my acronym :).  This port
+ * depends on DINK to do some basic initialization (e.g., initialize the memory
+ * ctlr) and to ensure that the processor is using MAP B (CHRP map).
+ *
+ * The switch settings for the Sandpoint board MUST be as follows:
+ * 	S3: down
+ * 	S4: up
+ * 	S5: up
+ * 	S6: down
+ *
+ * 'down' is in the direction from the PCI slots towards the PPMC slot;
+ * 'up' is in the direction from the PPMC slot towards the PCI slots.
+ * Be careful, the way the sandpoint board is installed in XT chasses will
+ * make the directions reversed.
+ *
+ * Since Motorola listened to our suggestions for improvement, we now have
+ * the Sandpoint X3 board.  All of the PCI slots are available, it uses
+ * the serial interrupt interface (just a hardware thing we need to
+ * configure properly).
+ *
+ * Use the default X3 switch settings.  The interrupts are then:
+ *		EPIC	Source
+ *		  0	SIOINT 		(8259, active low)
+ *		  1	PCI #1
+ *		  2	PCI #2
+ *		  3	PCI #3
+ *		  4	PCI #4
+ *		  7	Winbond INTC	(IDE interrupt)
+ *		  8	Winbond INTD	(IDE interrupt)
+ *
+ *
+ * Motorola has finally released a version of DINK32 that correctly
+ * (seemingly) initalizes the memory controller correctly, regardless
+ * of the amount of memory in the system.  Once a method of determining
+ * what version of DINK initializes the system for us, if applicable, is
+ * found, we can hopefully stop hardcoding 32MB of RAM.
+ *
+ * It is important to note that this code only supports the Sandpoint X3
+ * (all flavors) platform, and it does not support the X2 anymore.  Code
+ * that at one time worked on the X2 can be found at:
+ * ftp://source.mvista.com/pub/linuxppc/obsolete/sandpoint/
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/initrd.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/ide.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/tty.h>	/* for linux/serial_core.h */
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/time.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/vga.h>
+#include <asm/open_pic.h>
+#include <asm/i8259.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/mpc10x.h>
+#include <asm/pci-bridge.h>
+
+#include "sandpoint.h"
+
+extern void gen550_progress(char *, unsigned short);
+extern void gen550_init(int, struct uart_port *);
+
+unsigned char __res[sizeof(bd_t)];
+
+static void sandpoint_halt(void);
+
+/*
+ * Define all of the IRQ senses and polarities.  Taken from the
+ * Sandpoint X3 User's manual.
+ */
+static u_char sandpoint_openpic_initsenses[] __initdata = {
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 0: SIOINT */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 2: PCI Slot 1 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 3: PCI Slot 2 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 4: PCI Slot 3 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 5: PCI Slot 4 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* 8: IDE (INT C) */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE)	/* 9: IDE (INT D) */
+};
+
+/*
+ * Motorola SPS Sandpoint interrupt routing.
+ */
+static inline int
+sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 * 	   A   B   C   D
+	 */
+	{
+		{ 16,  0,  0,  0 },	/* IDSEL 11 - i8259 on Winbond */
+		{  0,  0,  0,  0 },	/* IDSEL 12 - unused */
+		{ 18, 21, 20, 19 },	/* IDSEL 13 - PCI slot 1 */
+		{ 19, 18, 21, 20 },	/* IDSEL 14 - PCI slot 2 */
+		{ 20, 19, 18, 21 },	/* IDSEL 15 - PCI slot 3 */
+		{ 21, 20, 19, 18 },	/* IDSEL 16 - PCI slot 4 */
+	};
+
+	const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static void __init
+sandpoint_setup_winbond_83553(struct pci_controller *hose)
+{
+	int		devfn;
+
+	/*
+	 * Route IDE interrupts directly to the 8259's IRQ 14 & 15.
+	 * We can't route the IDE interrupt to PCI INTC# or INTD# because those
+	 * woule interfere with the PMC's INTC# and INTD# lines.
+	 */
+	/*
+	 * Winbond Fcn 0
+	 */
+	devfn = PCI_DEVFN(11,0);
+
+	early_write_config_byte(hose,
+				0,
+				devfn,
+				0x43, /* IDE Interrupt Routing Control */
+				0xef);
+	early_write_config_word(hose,
+				0,
+				devfn,
+				0x44, /* PCI Interrupt Routing Control */
+				0x0000);
+
+	/* Want ISA memory cycles to be forwarded to PCI bus */
+	early_write_config_byte(hose,
+				0,
+				devfn,
+				0x48, /* ISA-to-PCI Addr Decoder Control */
+				0xf0);
+
+	/* Enable RTC and Keyboard address locations.  */
+	early_write_config_byte(hose,
+				0,
+				devfn,
+				0x4d,	/* Chip Select Control Register */
+				0x00);
+
+	/* Enable Port 92.  */
+	early_write_config_byte(hose,
+				0,
+				devfn,
+				0x4e,	/* AT System Control Register */
+				0x06);
+	/*
+	 * Winbond Fcn 1
+	 */
+	devfn = PCI_DEVFN(11,1);
+
+	/* Put IDE controller into native mode. */
+	early_write_config_byte(hose,
+				0,
+				devfn,
+				0x09,	/* Programming interface Register */
+				0x8f);
+
+	/* Init IRQ routing, enable both ports, disable fast 16 */
+	early_write_config_dword(hose,
+				0,
+				devfn,
+				0x40,	/* IDE Control/Status Register */
+				0x00ff0011);
+	return;
+}
+
+static void __init
+sandpoint_find_bridges(void)
+{
+	struct pci_controller	*hose;
+
+	hose = pcibios_alloc_controller();
+
+	if (!hose)
+		return;
+
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	if (mpc10x_bridge_init(hose,
+			       MPC10X_MEM_MAP_B,
+			       MPC10X_MEM_MAP_B,
+			       MPC10X_MAPB_EUMB_BASE) == 0) {
+
+		/* Do early winbond init, then scan PCI bus */
+		sandpoint_setup_winbond_83553(hose);
+		hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+		ppc_md.pcibios_fixup = NULL;
+		ppc_md.pcibios_fixup_bus = NULL;
+		ppc_md.pci_swizzle = common_swizzle;
+		ppc_md.pci_map_irq = sandpoint_map_irq;
+	}
+	else {
+		if (ppc_md.progress)
+			ppc_md.progress("Bridge init failed", 0x100);
+		printk("Host bridge init failed\n");
+	}
+
+	return;
+}
+
+#if defined(CONFIG_SERIAL_8250) && \
+	(defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG))
+static void __init
+sandpoint_early_serial_map(void)
+{
+	struct uart_port serial_req;
+
+	/* Setup serial port access */
+	memset(&serial_req, 0, sizeof(serial_req));
+	serial_req.uartclk = UART_CLK;
+	serial_req.irq = 4;
+	serial_req.flags = STD_COM_FLAGS;
+	serial_req.iotype = SERIAL_IO_MEM;
+	serial_req.membase = (u_char *)SANDPOINT_SERIAL_0;
+
+	gen550_init(0, &serial_req);
+
+	if (early_serial_setup(&serial_req) != 0)
+		printk(KERN_ERR "Early serial init of port 0 failed\n");
+
+	/* Assume early_serial_setup() doesn't modify serial_req */
+	serial_req.line = 1;
+	serial_req.irq = 3; /* XXXX */
+	serial_req.membase = (u_char *)SANDPOINT_SERIAL_1;
+
+	gen550_init(1, &serial_req);
+
+	if (early_serial_setup(&serial_req) != 0)
+		printk(KERN_ERR "Early serial init of port 1 failed\n");
+}
+#endif
+
+static void __init
+sandpoint_setup_arch(void)
+{
+	loops_per_jiffy = 100000000 / HZ;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start)
+		ROOT_DEV = Root_RAM0;
+	else
+#endif
+#ifdef	CONFIG_ROOT_NFS
+		ROOT_DEV = Root_NFS;
+#else
+		ROOT_DEV = Root_HDA1;
+#endif
+
+	/* Lookup PCI host bridges */
+	sandpoint_find_bridges();
+
+#ifdef CONFIG_DUMMY_CONSOLE
+	conswitchp = &dummy_con;
+#endif
+
+	printk(KERN_INFO "Motorola SPS Sandpoint Test Platform\n");
+	printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
+
+	/* DINK32 12.3 and below do not correctly enable any caches.
+	 * We will do this now with good known values.  Future versions
+	 * of DINK32 are supposed to get this correct.
+	 */
+	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450)
+		/* 745x is different.  We only want to pass along enable. */
+		_set_L2CR(L2CR_L2E);
+	else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)
+		/* All modules have 1MB of L2.  We also assume that an
+		 * L2 divisor of 3 will work.
+		 */
+		_set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3
+				| L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);
+#if 0
+	/* Untested right now. */
+	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR) {
+		/* Magic value. */
+		_set_L3CR(0x8f032000);
+	}
+#endif
+}
+
+#define	SANDPOINT_87308_CFG_ADDR		0x15c
+#define	SANDPOINT_87308_CFG_DATA		0x15d
+
+#define	SANDPOINT_87308_CFG_INB(addr, byte) {				\
+	outb((addr), SANDPOINT_87308_CFG_ADDR);				\
+	(byte) = inb(SANDPOINT_87308_CFG_DATA);				\
+}
+
+#define	SANDPOINT_87308_CFG_OUTB(addr, byte) {				\
+	outb((addr), SANDPOINT_87308_CFG_ADDR);				\
+	outb((byte), SANDPOINT_87308_CFG_DATA);				\
+}
+
+#define SANDPOINT_87308_SELECT_DEV(dev_num) {				\
+	SANDPOINT_87308_CFG_OUTB(0x07, (dev_num));			\
+}
+
+#define	SANDPOINT_87308_DEV_ENABLE(dev_num) {				\
+	SANDPOINT_87308_SELECT_DEV(dev_num);				\
+	SANDPOINT_87308_CFG_OUTB(0x30, 0x01);				\
+}
+
+/*
+ * Initialize the ISA devices on the Nat'l PC87308VUL SuperIO chip.
+ */
+static int __init
+sandpoint_setup_natl_87308(void)
+{
+	u_char	reg;
+
+	/*
+	 * Enable all the devices on the Super I/O chip.
+	 */
+	SANDPOINT_87308_SELECT_DEV(0x00); /* Select kbd logical device */
+	SANDPOINT_87308_CFG_OUTB(0xf0, 0x00); /* Set KBC clock to 8 Mhz */
+	SANDPOINT_87308_DEV_ENABLE(0x00); /* Enable keyboard */
+	SANDPOINT_87308_DEV_ENABLE(0x01); /* Enable mouse */
+	SANDPOINT_87308_DEV_ENABLE(0x02); /* Enable rtc */
+	SANDPOINT_87308_DEV_ENABLE(0x03); /* Enable fdc (floppy) */
+	SANDPOINT_87308_DEV_ENABLE(0x04); /* Enable parallel */
+	SANDPOINT_87308_DEV_ENABLE(0x05); /* Enable UART 2 */
+	SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */
+	SANDPOINT_87308_DEV_ENABLE(0x06); /* Enable UART 1 */
+	SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */
+
+	/* Set up floppy in PS/2 mode */
+	outb(0x09, SIO_CONFIG_RA);
+	reg = inb(SIO_CONFIG_RD);
+	reg = (reg & 0x3F) | 0x40;
+	outb(reg, SIO_CONFIG_RD);
+	outb(reg, SIO_CONFIG_RD);	/* Have to write twice to change! */
+
+	return 0;
+}
+
+arch_initcall(sandpoint_setup_natl_87308);
+
+/*
+ * Fix IDE interrupts.
+ */
+static int __init
+sandpoint_fix_winbond_83553(void)
+{
+	/* Make all 8259 interrupt level sensitive */
+	outb(0xf8, 0x4d0);
+	outb(0xde, 0x4d1);
+
+	return 0;
+}
+
+arch_initcall(sandpoint_fix_winbond_83553);
+
+static int __init
+sandpoint_request_io(void)
+{
+	request_region(0x00,0x20,"dma1");
+	request_region(0x20,0x20,"pic1");
+	request_region(0x40,0x20,"timer");
+	request_region(0x80,0x10,"dma page reg");
+	request_region(0xa0,0x20,"pic2");
+	request_region(0xc0,0x20,"dma2");
+
+	return 0;
+}
+
+arch_initcall(sandpoint_request_io);
+
+/*
+ * Interrupt setup and service.  Interrrupts on the Sandpoint come
+ * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO).
+ * The 8259 is cascaded from EPIC IRQ0, IRQ1-4 map to PCI slots 1-4,
+ * IDE is on EPIC 7 and 8.
+ */
+static void __init
+sandpoint_init_IRQ(void)
+{
+	int i;
+
+	OpenPIC_InitSenses = sandpoint_openpic_initsenses;
+	OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses);
+
+	/*
+	 * We need to tell openpic_set_sources where things actually are.
+	 * mpc10x_common will setup OpenPIC_Addr at ioremap(EUMB phys base +
+	 * EPIC offset (0x40000));  The EPIC IRQ Register Address Map -
+	 * Interrupt Source Configuration Registers gives these numbers
+	 * as offsets starting at 0x50200, we need to adjust occordinly.
+	 */
+	/* Map serial interrupts 0-15 */
+	openpic_set_sources(0, 16, OpenPIC_Addr + 0x10200);
+
+	openpic_init(NUM_8259_INTERRUPTS);
+
+	/*
+	 * openpic_init() has set up irq_desc[16-31] to be openpic
+	 * interrupts.  We need to set irq_desc[0-15] to be i8259
+	 * interrupts.
+	 */
+	for(i=0; i < NUM_8259_INTERRUPTS; i++)
+		irq_desc[i].handler = &i8259_pic;
+
+	/*
+	 * The EPIC allows for a read in the range of 0xFEF00000 ->
+	 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
+	 */
+	i8259_init(0xfef00000);
+}
+
+static u32
+sandpoint_irq_canonicalize(u32 irq)
+{
+	if (irq == 2)
+		return 9;
+	else
+		return irq;
+}
+
+static unsigned long __init
+sandpoint_find_end_of_memory(void)
+{
+	bd_t *bp = (bd_t *)__res;
+
+	if (bp->bi_memsize)
+		return bp->bi_memsize;
+
+	/* DINK32 13.0 correctly initalizes things, so iff you use
+	 * this you _should_ be able to change this instead of a
+	 * hardcoded value. */
+#if 0
+	return mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
+#else
+	return 32*1024*1024;
+#endif
+}
+
+static void __init
+sandpoint_map_io(void)
+{
+	io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
+}
+
+static void
+sandpoint_restart(char *cmd)
+{
+	local_irq_disable();
+
+	/* Set exception prefix high - to the firmware */
+	_nmask_and_or_msr(0, MSR_IP);
+
+	/* Reset system via Port 92 */
+	outb(0x00, 0x92);
+	outb(0x01, 0x92);
+	for(;;);	/* Spin until reset happens */
+}
+
+static void
+sandpoint_power_off(void)
+{
+	local_irq_disable();
+	for(;;);	/* No way to shut power off with software */
+	/* NOTREACHED */
+}
+
+static void
+sandpoint_halt(void)
+{
+	sandpoint_power_off();
+	/* NOTREACHED */
+}
+
+static int
+sandpoint_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: Motorola SPS\n");
+	seq_printf(m, "machine\t\t: Sandpoint\n");
+
+	return 0;
+}
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE support.
+ */
+static int		sandpoint_ide_ports_known = 0;
+static unsigned long	sandpoint_ide_regbase[MAX_HWIFS];
+static unsigned long	sandpoint_ide_ctl_regbase[MAX_HWIFS];
+static unsigned long	sandpoint_idedma_regbase;
+
+static void
+sandpoint_ide_probe(void)
+{
+	struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+			PCI_DEVICE_ID_WINBOND_82C105, NULL);
+
+	if (pdev) {
+		sandpoint_ide_regbase[0]=pdev->resource[0].start;
+		sandpoint_ide_regbase[1]=pdev->resource[2].start;
+		sandpoint_ide_ctl_regbase[0]=pdev->resource[1].start;
+		sandpoint_ide_ctl_regbase[1]=pdev->resource[3].start;
+		sandpoint_idedma_regbase=pdev->resource[4].start;
+	}
+
+	sandpoint_ide_ports_known = 1;
+}
+
+static int
+sandpoint_ide_default_irq(unsigned long base)
+{
+	if (sandpoint_ide_ports_known == 0)
+		sandpoint_ide_probe();
+
+	if (base == sandpoint_ide_regbase[0])
+		return SANDPOINT_IDE_INT0;
+	else if (base == sandpoint_ide_regbase[1])
+		return SANDPOINT_IDE_INT1;
+	else
+		return 0;
+}
+
+static unsigned long
+sandpoint_ide_default_io_base(int index)
+{
+	if (sandpoint_ide_ports_known == 0)
+		sandpoint_ide_probe();
+
+	return sandpoint_ide_regbase[index];
+}
+
+static void __init
+sandpoint_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
+		unsigned long ctrl_port, int *irq)
+{
+	unsigned long reg = data_port;
+	uint	alt_status_base;
+	int	i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg++;
+	}
+
+	if (data_port == sandpoint_ide_regbase[0]) {
+		alt_status_base = sandpoint_ide_ctl_regbase[0] + 2;
+		hw->irq = 14;
+	}
+	else if (data_port == sandpoint_ide_regbase[1]) {
+		alt_status_base = sandpoint_ide_ctl_regbase[1] + 2;
+		hw->irq = 15;
+	}
+	else {
+		alt_status_base = 0;
+		hw->irq = 0;
+	}
+
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base;
+	}
+
+	if (irq != NULL) {
+		*irq = hw->irq;
+	}
+}
+#endif
+
+/*
+ * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1.
+ */
+static __inline__ void
+sandpoint_set_bat(void)
+{
+	unsigned long bat3u, bat3l;
+
+	__asm__ __volatile__(
+			" lis %0,0xf800\n	\
+			ori %1,%0,0x002a\n	\
+			ori %0,%0,0x0ffe\n	\
+			mtspr 0x21e,%0\n	\
+			mtspr 0x21f,%1\n	\
+			isync\n			\
+			sync "
+			: "=r" (bat3u), "=r" (bat3l));
+}
+
+TODC_ALLOC();
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+		unsigned long r6, unsigned long r7)
+{
+	parse_bootinfo(find_bootinfo());
+
+	/* ASSUMPTION:  If both r3 (bd_t pointer) and r6 (cmdline pointer)
+	 * are non-zero, then we should use the board info from the bd_t
+	 * structure and the cmdline pointed to by r6 instead of the
+	 * information from birecs, if any.  Otherwise, use the information
+	 * from birecs as discovered by the preceeding call to
+	 * parse_bootinfo().  This rule should work with both PPCBoot, which
+	 * uses a bd_t board info structure, and the kernel boot wrapper,
+	 * which uses birecs.
+	 */
+	if (r3 && r6) {
+		/* copy board info structure */
+		memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
+		/* copy command line */
+		*(char *)(r7+KERNELBASE) = 0;
+		strcpy(cmd_line, (char *)(r6+KERNELBASE));
+	}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	/* take care of initrd if we have one */
+	if (r4) {
+		initrd_start = r4 + KERNELBASE;
+		initrd_end = r5 + KERNELBASE;
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/* Map in board regs, etc. */
+	sandpoint_set_bat();
+
+	isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
+	isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
+	pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
+	ISA_DMA_THRESHOLD = 0x00ffffff;
+	DMA_MODE_READ = 0x44;
+	DMA_MODE_WRITE = 0x48;
+
+	ppc_md.setup_arch = sandpoint_setup_arch;
+	ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
+	ppc_md.irq_canonicalize = sandpoint_irq_canonicalize;
+	ppc_md.init_IRQ = sandpoint_init_IRQ;
+	ppc_md.get_irq = openpic_get_irq;
+
+	ppc_md.restart = sandpoint_restart;
+	ppc_md.power_off = sandpoint_power_off;
+	ppc_md.halt = sandpoint_halt;
+
+	ppc_md.find_end_of_memory = sandpoint_find_end_of_memory;
+	ppc_md.setup_io_mappings = sandpoint_map_io;
+
+	TODC_INIT(TODC_TYPE_PC97307, 0x70, 0x00, 0x71, 8);
+	ppc_md.time_init = todc_time_init;
+	ppc_md.set_rtc_time = todc_set_rtc_time;
+	ppc_md.get_rtc_time = todc_get_rtc_time;
+	ppc_md.calibrate_decr = todc_calibrate_decr;
+
+	ppc_md.nvram_read_val = todc_mc146818_read_val;
+	ppc_md.nvram_write_val = todc_mc146818_write_val;
+
+#if defined(CONFIG_SERIAL_8250) && \
+	(defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG))
+	sandpoint_early_serial_map();
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+	ppc_md.progress = gen550_progress;
+#endif
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+	ppc_ide_md.default_irq = sandpoint_ide_default_irq;
+	ppc_ide_md.default_io_base = sandpoint_ide_default_io_base;
+	ppc_ide_md.ide_init_hwif = sandpoint_ide_init_hwif_ports;
+#endif
+}
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/sandpoint.h linux-2.5.74-bk4/arch/ppc/platforms/sandpoint.h
--- linux-2.5.74-bk3/arch/ppc/platforms/sandpoint.h	2003-07-02 13:46:09.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/sandpoint.h	2003-07-06 09:15:48.000000000 -0700
@@ -6,7 +6,7 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * 2000-2003 (c) MontaVista, Software, Inc.  This file is licensed under
  * the terms of the GNU General Public License version 2.  This program
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
@@ -19,8 +19,8 @@
 #ifndef __PPC_PLATFORMS_SANDPOINT_H
 #define __PPC_PLATFORMS_SANDPOINT_H
 
-#ifdef CONFIG_SANDPOINT_X3
-#define SANDPOINT_SIO_SLOT      0	/* Cascaded from EPIC IRQ 0 */
+#include <asm/ppcboot.h>
+
 #if 0
 /* The Sandpoint X3 allows the IDE interrupt to be directly connected
  * from the Windbond (PCI INTC or INTD) to the serial EPIC.  Someday
@@ -28,27 +28,13 @@
  * initialization than change it to route the different interrupts :-).
  *	-- Dan
  */
-#define SANDPOINT_IDE_INT0	23	/* EPIC 7 */
-#define SANDPOINT_IDE_INT1	24	/* EPIC 8 */
-#else
-#define SANDPOINT_IDE_INT0	14	/* 8259 Test */
-#define SANDPOINT_IDE_INT1	15	/* 8259 Test */
-#endif
+#define SANDPOINT_IDE_INT0		23	/* EPIC 7 */
+#define SANDPOINT_IDE_INT1		24	/* EPIC 8 */
 #else
- /*
-  * Define the PCI slot that the 8259 is sharing interrupts with.
-  * Valid values are 1 (PCI slot 2) and 2 (PCI slot 3).
-  */
-#define SANDPOINT_SIO_SLOT      1
-
-/* ...and for the IDE from the 8259....
-*/
-#define SANDPOINT_IDE_INT0	14
-#define SANDPOINT_IDE_INT1	15
+#define SANDPOINT_IDE_INT0		14	/* 8259 Test */
+#define SANDPOINT_IDE_INT1		15	/* 8259 Test */
 #endif
 
-#define	SANDPOINT_SIO_IRQ	(SANDPOINT_SIO_SLOT + NUM_8259_INTERRUPTS)
-
 /*
  * The sandpoint boards have processor modules that either have an 8240 or
  * an MPC107 host bridge on them.  These bridges have an IDSEL line that allows
@@ -62,7 +48,33 @@
  */
 #define SANDPOINT_HOST_BRIDGE_IDSEL     12
 
+/*
+ * Serial defines.
+ */
+#define SANDPOINT_SERIAL_0		0xfe0003f8
+#define SANDPOINT_SERIAL_1		0xfe0002f8
+
+#define RS_TABLE_SIZE  2
+
+/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
+#define BASE_BAUD			( 1843200 / 16 )
+#define UART_CLK			1843200
+
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
+#else
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
+#endif
+
+#define STD_SERIAL_PORT_DFNS \
+        { 0, BASE_BAUD, SANDPOINT_SERIAL_0, 4, STD_COM_FLAGS, /* ttyS0 */ \
+		iomem_base: (u8 *)SANDPOINT_SERIAL_0,			  \
+		io_type: SERIAL_IO_MEM },				  \
+        { 0, BASE_BAUD, SANDPOINT_SERIAL_1, 3, STD_COM_FLAGS, /* ttyS1 */ \
+		iomem_base: (u8 *)SANDPOINT_SERIAL_1,			  \
+		io_type: SERIAL_IO_MEM },
 
-void sandpoint_find_bridges(void);
+#define SERIAL_PORT_DFNS \
+        STD_SERIAL_PORT_DFNS
 
 #endif /* __PPC_PLATFORMS_SANDPOINT_H */
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/sandpoint_pci.c linux-2.5.74-bk4/arch/ppc/platforms/sandpoint_pci.c
--- linux-2.5.74-bk3/arch/ppc/platforms/sandpoint_pci.c	2003-07-02 13:39:24.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/sandpoint_pci.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,181 +0,0 @@
-/*
- * arch/ppc/platforms/sandpoint_pci.c
- * 
- * PCI setup routines for the Motorola SPS Sandpoint Test Platform
- *
- * Author: Mark A. Greer
- *         mgreer@mvista.com
- *
- * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/mpc10x.h>
-
-#include "sandpoint.h"
-
-/*
- * Motorola SPS Sandpoint interrupt routing.
- */
-static inline int
-sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
-	static char pci_irq_table[][4] =
-	/*
-	 *	PCI IDSEL/INTPIN->INTLINE 
-	 * 	   A   B   C   D
-	 */
-	{
-		{ SANDPOINT_SIO_IRQ,
-		       0,  0,  0 },	/* IDSEL 11 - i8259 on Winbond */
-		{  0,  0,  0,  0 },	/* IDSEL 12 - unused */
-#ifdef CONFIG_SANDPOINT_X3
-#if 0	/* This is what it _should_ look like -- Dan */
-		{ 17, 20, 19, 18 },	/* IDSEL 13 - PCI slot 1 */
-		{ 18, 17, 20, 19 },	/* IDSEL 14 - PCI slot 2 */
-		{ 19, 18, 17, 20 },	/* IDSEL 15 - PCI slot 3 */
-		{ 20, 19, 18, 17 },	/* IDSEL 16 - PCI slot 4 */
-#else
-		{ 18, 21, 20, 19 },	/* IDSEL 13 - PCI slot 1 */
-		{ 19, 18, 21, 20 },	/* IDSEL 14 - PCI slot 2 */
-		{ 20, 19, 18, 21 },	/* IDSEL 15 - PCI slot 3 */
-		{ 21, 20, 19, 18 },	/* IDSEL 16 - PCI slot 4 */
-#endif
-#else
-		{ 16, 19, 18, 17 },	/* IDSEL 13 - PCI slot 1 */
-		{ 17, 16, 19, 18 },	/* IDSEL 14 - PCI slot 2 */
-		{ 18, 17, 16, 19 },	/* IDSEL 15 - PCI slot 3 */
-		{ 19, 18, 17, 16 },	/* IDSEL 16 - PCI slot 4 */
-#endif
-	};
-
-	const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
-	return PCI_IRQ_TABLE_LOOKUP;
-}
-
-static void __init
-sandpoint_setup_winbond_83553(struct pci_controller *hose)
-{
-	int		devfn;
-
-	/*
-	 * Route IDE interrupts directly to the 8259's IRQ 14 & 15.
-	 * We can't route the IDE interrupt to PCI INTC# or INTD# because those
-	 * woule interfere with the PMC's INTC# and INTD# lines.
-	 */
-	/*
-	 * Winbond Fcn 0
-	 */
-	devfn = PCI_DEVFN(11,0);
-
-	early_write_config_byte(hose,
-				0,
-				devfn,
-				0x43, /* IDE Interrupt Routing Control */
-				0xef);
-	early_write_config_word(hose,
-				0,
-				devfn,
-				0x44, /* PCI Interrupt Routing Control */
-				0x0000);
-
-	/* Want ISA memory cycles to be forwarded to PCI bus */
-	early_write_config_byte(hose,
-				0,
-				devfn,
-				0x48, /* ISA-to-PCI Addr Decoder Control */
-				0xf0);
-
-	/* Enable RTC and Keyboard address locations.  */
-	early_write_config_byte(hose,
-				0,
-				devfn,
-				0x4d,	/* Chip Select Control Register */
-				0x00);
-
-	/* Enable Port 92.  */
-	early_write_config_byte(hose,
-				0,
-				devfn,
-				0x4e,	/* AT System Control Register */
-				0x06);
-	/*
-	 * Winbond Fcn 1
-	 */
-	devfn = PCI_DEVFN(11,1);
-
-	/* Put IDE controller into native mode. */
-	early_write_config_byte(hose,
-				0,
-				devfn,
-				0x09,	/* Programming interface Register */
-				0x8f);
-
-	/* Init IRQ routing, enable both ports, disable fast 16 */
-	early_write_config_dword(hose,
-				0,
-				devfn,
-				0x40,	/* IDE Control/Status Register */
-				0x00ff0011);
-	return;
-}
-
-static int                     
-sandpoint_exclude_device(u_char bus, u_char devfn)
-{
-	if ((bus == 0) && (PCI_SLOT(devfn) == SANDPOINT_HOST_BRIDGE_IDSEL)) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	else {
-		return PCIBIOS_SUCCESSFUL;
-	}
-}
-
-void __init
-sandpoint_find_bridges(void)
-{
-	struct pci_controller	*hose;
-
-	hose = pcibios_alloc_controller();
-
-	if (!hose)
-		return;
-
-	hose->first_busno = 0;
-	hose->last_busno = 0xff;
-
-	if (mpc10x_bridge_init(hose,
-			       MPC10X_MEM_MAP_B,
-			       MPC10X_MEM_MAP_B,
-			       MPC10X_MAPB_EUMB_BASE) == 0) {
-
-		/* Do early winbond init, then scan PCI bus */
-		sandpoint_setup_winbond_83553(hose);
-		ppc_md.pci_exclude_device = sandpoint_exclude_device;
-		hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
-
-		ppc_md.pcibios_fixup = NULL;
-		ppc_md.pcibios_fixup_bus = NULL;
-		ppc_md.pci_swizzle = common_swizzle;
-		ppc_md.pci_map_irq = sandpoint_map_irq;
-	}
-	else {
-		if (ppc_md.progress)
-			ppc_md.progress("Bridge init failed", 0x100);
-		printk("Host bridge init failed\n");
-	}
-
-	return;
-}
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/sandpoint_serial.h linux-2.5.74-bk4/arch/ppc/platforms/sandpoint_serial.h
--- linux-2.5.74-bk3/arch/ppc/platforms/sandpoint_serial.h	2003-07-02 13:42:10.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/sandpoint_serial.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,49 +0,0 @@
-/*
- * include/asm-ppc/sandpoint_serial.h
- * 
- * Definitions for Motorola SPS Sandpoint Test Platform
- *
- * Author: Mark A. Greer
- *         mgreer@mvista.com
- *
- * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#ifndef __ASMPPC_SANDPOINT_SERIAL_H
-#define __ASMPPC_SANDPOINT_SERIAL_H
-
-#include <linux/config.h>
-
-#define SANDPOINT_SERIAL_0		0xfe0003f8
-#define SANDPOINT_SERIAL_1		0xfe0002f8
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define RS_TABLE_SIZE  64
-#else
-#define RS_TABLE_SIZE  2
-#endif
-
-/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
-#define BASE_BAUD ( 1843200 / 16 )
-
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
-#endif
-
-#define STD_SERIAL_PORT_DFNS \
-        { 0, BASE_BAUD, SANDPOINT_SERIAL_0, 4, STD_COM_FLAGS, /* ttyS0 */ \
-		iomem_base: (u8 *)SANDPOINT_SERIAL_0,			  \
-		io_type: SERIAL_IO_MEM },				  \
-        { 0, BASE_BAUD, SANDPOINT_SERIAL_1, 3, STD_COM_FLAGS, /* ttyS1 */ \
-		iomem_base: (u8 *)SANDPOINT_SERIAL_1,			  \
-		io_type: SERIAL_IO_MEM },
-
-#define SERIAL_PORT_DFNS \
-        STD_SERIAL_PORT_DFNS
-
-#endif /* __ASMPPC_SANDPOINT_SERIAL_H */
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/sandpoint_setup.c linux-2.5.74-bk4/arch/ppc/platforms/sandpoint_setup.c
--- linux-2.5.74-bk3/arch/ppc/platforms/sandpoint_setup.c	2003-07-02 13:58:10.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/sandpoint_setup.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,643 +0,0 @@
-/*
- * arch/ppc/platforms/sandpoint_setup.c
- * 
- * Board setup routines for the Motorola SPS Sandpoint Test Platform.
- *
- * Author: Mark A. Greer
- *         mgreer@mvista.com
- *
- * 2000-2002 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-/*
- * This file adds support for the Motorola SPS Sandpoint Test Platform.
- * These boards have a PPMC slot for the processor so any combination
- * of cpu and host bridge can be attached.  This port is for an 8240 PPMC
- * module from Motorola SPS and other closely related cpu/host bridge
- * combinations (e.g., 750/755/7400 with MPC107 host bridge).
- * The sandpoint itself has a Windbond 83c553 (PCI-ISA bridge, 2 DMA ctlrs, 2
- * cascaded 8259 interrupt ctlrs, 8254 Timer/Counter, and an IDE ctlr), a
- * National 87308 (RTC, 2 UARTs, Keyboard & mouse ctlrs, and a floppy ctlr),
- * and 4 PCI slots (only 2 of which are usable; the other 2 are keyed for 3.3V
- * but are really 5V).
- *
- * The firmware on the sandpoint is called DINK (not my acronym :).  This port
- * depends on DINK to do some basic initialization (e.g., initialize the memory
- * ctlr) and to ensure that the processor is using MAP B (CHRP map).
- *
- * The switch settings for the Sandpoint board MUST be as follows:
- * 	S3: down
- * 	S4: up
- * 	S5: up
- * 	S6: down
- *
- * 'down' is in the direction from the PCI slots towards the PPMC slot;
- * 'up' is in the direction from the PPMC slot towards the PCI slots.
- * Be careful, the way the sandpoint board is installed in XT chasses will
- * make the directions reversed.
- *
- * Since Motorola listened to our suggestions for improvement, we now have
- * the Sandpoint X3 board.  All of the PCI slots are available, it uses
- * the serial interrupt interface (just a hardware thing we need to
- * configure properly).
- *
- * Use the default X3 switch settings.  The interrupts are then:
- *		EPIC	Source
- *		  0	SIOINT 		(8259, active low)
- *		  1	PCI #1
- *		  2	PCI #2
- *		  3	PCI #3
- *		  4	PCI #4
- *		  7	Winbond INTC	(IDE interrupt)
- *		  8	Winbond INTD	(IDE interrupt)
- *
- */
-#include <linux/config.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/reboot.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
-#include <linux/initrd.h>
-#include <linux/console.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/ide.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/time.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/smp.h>
-#include <asm/vga.h>
-#include <asm/open_pic.h>
-#include <asm/i8259.h>
-#include <asm/todc.h>
-#include <asm/bootinfo.h>
-#include <asm/mpc10x.h>
-#include <asm/pci-bridge.h>
-
-#include "sandpoint.h"
-
-extern u_int openpic_irq(void);
-extern void openpic_eoi(void);
-
-static void	sandpoint_halt(void);
-
-
-/*
- * *** IMPORTANT ***
- *
- * The first 16 entries of 'sandpoint_openpic_initsenses[]' are there and
- * initialized to 0 on purpose.  DO NOT REMOVE THEM as the 'offset' parameter
- * of 'openpic_init()' does not work for the sandpoint because the 8259
- * interrupt is NOT routed to the EPIC's IRQ 0 AND the EPIC's IRQ 0's offset is
- * the same as a normal openpic's IRQ 16 offset.
- */
-static u_char sandpoint_openpic_initsenses[] __initdata = {
-	0,	/* 0-15 not used by EPCI but by 8259 (std PC-type IRQs) */
-	0,	/* 1 */
-	0,	/* 2 */
-	0,	/* 3 */
-	0,	/* 4 */
-	0,	/* 5 */
-	0,	/* 6 */
-	0,	/* 7 */
-	0,	/* 8 */
-	0,	/* 9 */
-	0,	/* 10 */
-	0,	/* 11 */
-	0,	/* 12 */
-	0,	/* 13 */
-	0,	/* 14 */
-	0,	/* 15 */
-#ifdef CONFIG_SANDPOINT_X3
-	1,	/* 16: EPIC IRQ 0: Active Low -- SIOINT (8259) */
- 0, /* AACK!  Shouldn't need this.....see sandpoint_pci.c for more info */
-	1,	/* 17: EPIC IRQ 1: Active Low -- PCI Slot 1 */
-	1,	/* 18: EPIC IRQ 2: Active Low -- PCI Slot 2 */
-	1,	/* 19: EPIC IRQ 3: Active Low -- PCI Slot 3 */
-	1,	/* 20: EPIC IRQ 4: Active Low -- PCI Slot 4 */
-	0,	/* 21 -- Unused */
-	0,	/* 22 -- Unused */
-	1,	/* 23 -- IDE (Winbond INT C)  */
-	1,	/* 24 -- IDE (Winbond INT D)  */
-		/* 35 - 31 (EPIC 9 - 15) Unused */
-#else
-	1,	/* 16: EPIC IRQ 0: Active Low -- PCI intrs */
-	1,	/* 17: EPIC IRQ 1: Active Low -- PCI (possibly 8259) intrs */
-	1,	/* 18: EPIC IRQ 2: Active Low -- PCI (possibly 8259) intrs  */
-	1	/* 19: EPIC IRQ 3: Active Low -- PCI intrs */
-		/* 20: EPIC IRQ 4: Not used */
-#endif
-};
-
-static void __init
-sandpoint_setup_arch(void)
-{
-	loops_per_jiffy = 100000000 / HZ;
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_start)
-		ROOT_DEV = Root_RAM0;
-	else
-#endif
-#ifdef	CONFIG_ROOT_NFS
-		ROOT_DEV = Root_NFS;
-#else
-		ROOT_DEV = Root_HDA1;
-#endif
-
-	/* Lookup PCI host bridges */
-	sandpoint_find_bridges();
-
-#ifdef CONFIG_DUMMY_CONSOLE
-	conswitchp = &dummy_con;
-#endif
-
-	printk("Motorola SPS Sandpoint Test Platform\n");
-	printk("Sandpoint port (MontaVista Software, Inc. (source@mvista.com))\n");
-
-	/* The Sandpoint rom doesn't enable any caches.  Do that now.
-	 * The 7450 portion will also set up the L3s once I get enough
-	 * information do do so.  If the processor running doesn't have
-	 * and L2, the _set_L2CR is a no-op.
-	 */
-	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) {
-		/* Just enable L2, the bits are different from others.
-		*/
-		_set_L2CR(L2CR_L2E);
-	}
-	else {
-		/* The magic number for Sandpoint/74xx PrPMCs.
-		*/
-		_set_L2CR(0xbd014000);
-	}
-}
-
-#define	SANDPOINT_87308_CFG_ADDR		0x15c
-#define	SANDPOINT_87308_CFG_DATA		0x15d
-
-#define	SANDPOINT_87308_CFG_INB(addr, byte) {				\
-	outb((addr), SANDPOINT_87308_CFG_ADDR);				\
-	(byte) = inb(SANDPOINT_87308_CFG_DATA);				\
-}
-
-#define	SANDPOINT_87308_CFG_OUTB(addr, byte) {				\
-	outb((addr), SANDPOINT_87308_CFG_ADDR);				\
-	outb((byte), SANDPOINT_87308_CFG_DATA);				\
-}
-
-#define SANDPOINT_87308_SELECT_DEV(dev_num) {				\
-	SANDPOINT_87308_CFG_OUTB(0x07, (dev_num));			\
-}
-
-#define	SANDPOINT_87308_DEV_ENABLE(dev_num) {				\
-	SANDPOINT_87308_SELECT_DEV(dev_num);				\
-	SANDPOINT_87308_CFG_OUTB(0x30, 0x01);				\
-}
-
-/*
- * Initialize the ISA devices on the Nat'l PC87308VUL SuperIO chip.
- */
-static void __init
-sandpoint_setup_natl_87308(void)
-{
-	u_char	reg;
-
-	/*
-	 * Enable all the devices on the Super I/O chip.
-	 */
-	SANDPOINT_87308_SELECT_DEV(0x00); /* Select kbd logical device */
-	SANDPOINT_87308_CFG_OUTB(0xf0, 0x00); /* Set KBC clock to 8 Mhz */
-	SANDPOINT_87308_DEV_ENABLE(0x00); /* Enable keyboard */
-	SANDPOINT_87308_DEV_ENABLE(0x01); /* Enable mouse */
-	SANDPOINT_87308_DEV_ENABLE(0x02); /* Enable rtc */
-	SANDPOINT_87308_DEV_ENABLE(0x03); /* Enable fdc (floppy) */
-	SANDPOINT_87308_DEV_ENABLE(0x04); /* Enable parallel */
-	SANDPOINT_87308_DEV_ENABLE(0x05); /* Enable UART 2 */
-	SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */
-	SANDPOINT_87308_DEV_ENABLE(0x06); /* Enable UART 1 */
-	SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */
-
-	/* Set up floppy in PS/2 mode */
-	outb(0x09, SIO_CONFIG_RA);
-	reg = inb(SIO_CONFIG_RD);
-	reg = (reg & 0x3F) | 0x40;
-	outb(reg, SIO_CONFIG_RD);
-	outb(reg, SIO_CONFIG_RD);       /* Have to write twice to change! */
-
-	return;
-}
-
-/*
- * Fix IDE interrupts.
- */
-static void __init
-sandpoint_fix_winbond_83553(void)
-{
-	/* Make all 8259 interrupt level sensitive */
-	outb(0xf8, 0x4d0);
-	outb(0xde, 0x4d1);
-
-	return;
-}
-
-static void __init
-sandpoint_init2(void)
-{
-	/* Do Sandpoint board specific initialization.  */
-	sandpoint_fix_winbond_83553();
-	sandpoint_setup_natl_87308();
-
-	request_region(0x00,0x20,"dma1");
-	request_region(0x20,0x20,"pic1");
-	request_region(0x40,0x20,"timer");
-	request_region(0x80,0x10,"dma page reg");
-	request_region(0xa0,0x20,"pic2");
-	request_region(0xc0,0x20,"dma2");
-
-	return;
-}
-
-/*
- * Interrupt setup and service.  Interrrupts on the Sandpoint come
- * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO).
- * These interrupts are sent to one of four IRQs on the EPIC.
- * The SIO shares its interrupt with either slot 2 or slot 3 (INTA#).
- * Slot numbering is confusing.  Sometimes in the documentation they
- * use 0,1,2,3 and others 1,2,3,4.  We will use slots 1,2,3,4 and
- * map this to IRQ 16, 17, 18, 19.
- * For Sandpoint X3, this has been better designed.  The 8259 is
- * cascaded from EPIC IRQ0, IRQ1-4 map to PCI slots 1-4, IDE is on
- * EPIC 7 and 8.
- */
-static void __init
-sandpoint_init_IRQ(void)
-{
-	int i;
-
-	/*
-	 * 3 things cause us to jump through some hoops:
-	 *   1) the EPIC on the 8240 & 107 are not full-blown openpic pic's
-	 *   2) the 8259 is NOT cascaded on the openpic IRQ 0
-	 *   3) the 8259 shares its interrupt line with some PCI interrupts.
-	 *
-	 * What we'll do is set up the 8259 to be level sensitive, active low
-	 * just like a PCI device.  Then, when an interrupt on the IRQ that is
-	 * shared with the 8259 comes in, we'll take a peek at the 8259 to see
-	 * it its generating an interrupt.  If it is, we'll handle the 8259
-	 * interrupt.  Otherwise, we'll handle it just like a normal PCI
-	 * interrupt.  This does give the 8259 interrupts a higher priority
-	 * than the EPIC ones--hopefully, not a problem.
-	 */
-	OpenPIC_InitSenses = sandpoint_openpic_initsenses;
-	OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses);
-
-	openpic_init(1, 0, NULL, -1);
-
-	/*
-	 * openpic_init() has set up irq_desc[0-23] to be openpic
-	 * interrupts.  We need to set irq_desc[0-15] to be 8259 interrupts.
-	 * We then need to request and enable the 8259 irq.
-	 */
-	for(i=0; i < NUM_8259_INTERRUPTS; i++) 
-		irq_desc[i].handler = &i8259_pic;
-
-	if (request_irq(SANDPOINT_SIO_IRQ, no_action, SA_INTERRUPT,
-			"8259 cascade to EPIC", NULL)) {
-	
-		printk("Unable to get OpenPIC IRQ %d for cascade\n",
-			SANDPOINT_SIO_IRQ);
-	}
-
-	i8259_init(NULL);
-}
-
-static int
-sandpoint_get_irq(struct pt_regs *regs)
-{
-        int	irq, cascade_irq;
-
-	irq = openpic_irq();
-
-	if (irq == SANDPOINT_SIO_IRQ) {
-		cascade_irq = i8259_irq(regs);
-
-		if (cascade_irq != -1) {
-			irq = cascade_irq;
-			openpic_eoi();
-		}
-	}
-	else if (irq == OPENPIC_VEC_SPURIOUS) {
-		irq = -1;
-	}
-
-	return irq;
-}
-
-static u32
-sandpoint_irq_canonicalize(u32 irq)
-{
-	if (irq == 2)
-	{
-		return 9;
-	}
-	else
-	{
-		return irq;
-	}
-}
-
-static ulong __init
-sandpoint_find_end_of_memory(void)
-{
-	ulong	size = 0;
-
-#if 0	/* Leave out until DINK sets mem ctlr correctly */
-	size = mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
-#else
-	size = 32*1024*1024;
-#endif
-
-	return size;
-}
-
-static void __init
-sandpoint_map_io(void)
-{
-	io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
-}
-
-/*
- * Due to Sandpoint X2 errata, the Port 92 will not work.
- */
-static void
-sandpoint_restart(char *cmd)
-{
-	local_irq_disable();
-
-	/* Set exception prefix high - to the firmware */
-	_nmask_and_or_msr(0, MSR_IP);
-
-	/* Reset system via Port 92 */
-	outb(0x00, 0x92);
-	outb(0x01, 0x92);
-	for(;;);	/* Spin until reset happens */
-}
-
-static void
-sandpoint_power_off(void)
-{
-	local_irq_disable();
-	for(;;);  /* No way to shut power off with software */
-	/* NOTREACHED */
-}
-
-static void
-sandpoint_halt(void)
-{
-	sandpoint_power_off();
-	/* NOTREACHED */
-}
-
-static int
-sandpoint_show_cpuinfo(struct seq_file *m)
-{
-	uint pvid;
-
-	pvid = mfspr(PVR);
-
-	seq_printf(m, "vendor\t\t: Motorola SPS\n");
-	seq_printf(m, "machine\t\t: Sandpoint\n");
-	seq_printf(m, "processor\t: PVID: 0x%x, vendor: %s\n",
-			pvid, (pvid & (1<<15) ? "IBM" : "Motorola"));
-
-	return 0;
-}
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-/*
- * IDE support.
- */
-static int		sandpoint_ide_ports_known = 0;
-static unsigned long	sandpoint_ide_regbase[MAX_HWIFS];
-static unsigned long	sandpoint_ide_ctl_regbase[MAX_HWIFS];
-static unsigned long	sandpoint_idedma_regbase;
-
-static void
-sandpoint_ide_probe(void)
-{
-        struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND,
-					       PCI_DEVICE_ID_WINBOND_82C105,
-					       NULL);
-
-        if(pdev) {
-                sandpoint_ide_regbase[0]=pdev->resource[0].start;
-                sandpoint_ide_regbase[1]=pdev->resource[2].start;
-                sandpoint_ide_ctl_regbase[0]=pdev->resource[1].start;
-                sandpoint_ide_ctl_regbase[1]=pdev->resource[3].start;
-                sandpoint_idedma_regbase=pdev->resource[4].start;
-        }
-
-        sandpoint_ide_ports_known = 1;
-	return;
-}
-
-static int
-sandpoint_ide_default_irq(unsigned long base)
-{
-        if (sandpoint_ide_ports_known == 0)
-	        sandpoint_ide_probe();
-
-	if (base == sandpoint_ide_regbase[0])
-		return SANDPOINT_IDE_INT0;
-	else if (base == sandpoint_ide_regbase[1])
-		return SANDPOINT_IDE_INT1;
-	else
-		return 0;
-}
-
-static unsigned long
-sandpoint_ide_default_io_base(int index)
-{
-        if (sandpoint_ide_ports_known == 0)
-	        sandpoint_ide_probe();
-
-	return sandpoint_ide_regbase[index];
-}
-
-static void __init
-sandpoint_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
-			      unsigned long ctrl_port, int *irq)
-{
-	unsigned long reg = data_port;
-	uint	alt_status_base;
-	int	i;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg++;
-	}
-
-	if (data_port == sandpoint_ide_regbase[0]) {
-		alt_status_base = sandpoint_ide_ctl_regbase[0] + 2;
-		hw->irq = 14;
-	}
-	else if (data_port == sandpoint_ide_regbase[1]) {
-		alt_status_base = sandpoint_ide_ctl_regbase[1] + 2;
-		hw->irq = 15;
-	}
-	else {
-		alt_status_base = 0;
-		hw->irq = 0;
-	}
-
-	if (ctrl_port) {
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-	} else {
-		hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base;
-	}
-
-	if (irq != NULL) {
-		*irq = hw->irq;
-	}
-
-	return;
-}
-#endif
-
-/*
- * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1.
- */
-static __inline__ void
-sandpoint_set_bat(void)
-{
-	unsigned long   bat3u, bat3l;
-	static int	mapping_set = 0;
-
-	if (!mapping_set) {
-
-		__asm__ __volatile__(
-		" lis %0,0xf800\n \
-		  ori %1,%0,0x002a\n \
-		  ori %0,%0,0x0ffe\n \
-		  mtspr 0x21e,%0\n \
-		  mtspr 0x21f,%1\n \
-		  isync\n \
-		  sync "
-		  : "=r" (bat3u), "=r" (bat3l));
-
-		mapping_set = 1;
-	}
-
-	return;
-}
-
-#ifdef	CONFIG_SERIAL_TEXT_DEBUG
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <asm/serial.h>
-
-static struct serial_state rs_table[RS_TABLE_SIZE] = {
-	SERIAL_PORT_DFNS	/* Defined in <asm/serial.h> */
-};
-
-static void
-sandpoint_progress(char *s, unsigned short hex)
-{
-	volatile char c;
-	volatile unsigned long com_port;
-	u16 shift;
-
-	com_port = rs_table[0].port;
-	shift = rs_table[0].iomem_reg_shift;
-
-	while ((c = *s++) != 0) {
-		while ((*((volatile unsigned char *)com_port +
-				(UART_LSR << shift)) & UART_LSR_THRE) == 0)
-		                ;
-	        *(volatile unsigned char *)com_port = c;
-		
-		if (c == '\n') {
-			while ((*((volatile unsigned char *)com_port +
-				(UART_LSR << shift)) & UART_LSR_THRE) == 0)
-					;
-	        	*(volatile unsigned char *)com_port = '\r';
-		}
-	}
-}
-#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
-
-__init void sandpoint_setup_pci_ptrs(void);
-
-TODC_ALLOC();
-
-void __init
-platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	      unsigned long r6, unsigned long r7)
-{
-	parse_bootinfo(find_bootinfo());
-
-	/* Map in board regs, etc. */
-	sandpoint_set_bat();
-
-	isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
-	isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
-	pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
-	ISA_DMA_THRESHOLD = 0x00ffffff;
-	DMA_MODE_READ = 0x44;
-	DMA_MODE_WRITE = 0x48;
-
-	ppc_md.setup_arch = sandpoint_setup_arch;
-	ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
-	ppc_md.irq_canonicalize = sandpoint_irq_canonicalize;
-	ppc_md.init_IRQ = sandpoint_init_IRQ;
-	ppc_md.get_irq = sandpoint_get_irq;
-	ppc_md.init = sandpoint_init2;
-
-	ppc_md.restart = sandpoint_restart;
-	ppc_md.power_off = sandpoint_power_off;
-	ppc_md.halt = sandpoint_halt;
-
-	ppc_md.find_end_of_memory = sandpoint_find_end_of_memory;
-	ppc_md.setup_io_mappings = sandpoint_map_io;
-
-	TODC_INIT(TODC_TYPE_PC97307, 0x70, 0x00, 0x71, 8);
-	ppc_md.time_init = todc_time_init;
-	ppc_md.set_rtc_time = todc_set_rtc_time;
-	ppc_md.get_rtc_time = todc_get_rtc_time;
-	ppc_md.calibrate_decr = todc_calibrate_decr;
-
-	ppc_md.nvram_read_val = todc_mc146818_read_val;
-	ppc_md.nvram_write_val = todc_mc146818_write_val;
-
-	ppc_md.heartbeat = NULL;
-	ppc_md.heartbeat_reset = 0;
-	ppc_md.heartbeat_count = 0;
-
-#ifdef	CONFIG_SERIAL_TEXT_DEBUG
-	ppc_md.progress = sandpoint_progress;
-#else	/* !CONFIG_SERIAL_TEXT_DEBUG */
-	ppc_md.progress = NULL;
-#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-        ppc_ide_md.default_irq = sandpoint_ide_default_irq;
-        ppc_ide_md.default_io_base = sandpoint_ide_default_io_base;
-        ppc_ide_md.ide_init_hwif = sandpoint_ide_init_hwif_ports;
-#endif
-
-	return;
-}
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/zx4500.h linux-2.5.74-bk4/arch/ppc/platforms/zx4500.h
--- linux-2.5.74-bk3/arch/ppc/platforms/zx4500.h	2003-07-02 13:49:36.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/zx4500.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,68 +0,0 @@
-/* * arch/ppc/platforms/zx4500.h
- * 
- * Board setup routines for Znyx ZX4500 cPCI board.
- *
- * Author: Mark A. Greer
- *         mgreer@mvista.com
- *
- * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#ifndef	__PPC_PLATFORMS_ZX4500_H_
-#define	__PPC_PLATFORMS_ZX4500_H_
-
-/*
- * Define the addresses of CPLD registers in CLPD area.
- */
-#define	ZX4500_CPLD_BOARD_ID		0xff800001
-#define	ZX4500_CPLD_REV			0xff800002
-#define	ZX4500_CPLD_RESET		0xff800011
-#define	ZX4500_CPLD_PHY1		0xff800014
-#define	ZX4500_CPLD_PHY2		0xff800015
-#define	ZX4500_CPLD_PHY3		0xff800016
-#define	ZX4500_CPLD_SYSCTL		0xff800017
-#define	ZX4500_CPLD_EXT_FLASH		0xff800018
-#define	ZX4500_CPLD_DUAL1		0xff800019
-#define	ZX4500_CPLD_DUAL2		0xff80001A
-#define	ZX4500_CPLD_STATUS		0xff800030
-#define	ZX4500_CPLD_STREAM		0xff800032
-#define	ZX4500_CPLD_PHY1_LED		0xff800034
-#define	ZX4500_CPLD_PHY2_LED		0xff800035
-#define	ZX4500_CPLD_PHY3_LED		0xff800036
-#define	ZX4500_CPLD_PHY1_LNK		0xff80003C
-#define	ZX4500_CPLD_PHY2_LNK		0xff80003D
-#define	ZX4500_CPLD_PHY3_LNK		0xff80003E
-
-#define	ZX4500_CPLD_RESET_SOFT		0x01	/* Soft Reset */
-#define	ZX4500_CPLD_RESET_XBUS		0x40	/* Reset entire board */
-
-#define	ZX4500_CPLD_SYSCTL_PMC		0x01	/* Enable INTA/B/C/D from PMC */
-#define	ZX4500_CPLD_SYSCTL_BCM		0x04	/* Enable INTA from BCM */
-#define	ZX4500_CPLD_SYSCTL_SINTA	0x08	/* Enable SINTA from 21554 */
-#define	ZX4500_CPLD_SYSCTL_WD		0x20	/* Enable Watchdog Timer */
-#define	ZX4500_CPLD_SYSCTL_PMC_TRI	0x80	/* Tri-state PMC EREADY */
-
-#define	ZX4500_CPLD_DUAL2_LED_PULL	0x01	/* Pull LED */
-#define	ZX4500_CPLD_DUAL2_LED_EXT_FAULT	0x02	/* External Fault LED */
-#define	ZX4500_CPLD_DUAL2_LED_INT_FAULT	0x04	/* Internal Fault LED */
-#define	ZX4500_CPLD_DUAL2_LED_OK	0x08	/* OK LED */
-#define	ZX4500_CPLD_DUAL2_LED_CLK	0x10	/* CLK LED */
-
-/*
- * Defines related to boot string stored in flash.
- */
-#define	ZX4500_BOOT_STRING_ADDR		0xfff7f000
-#define	ZX4500_BOOT_STRING_LEN		80
-
-/*
- * Define the IDSEL that the PCI bus side of the 8240 is connected to.
- * This IDSEL must not be selected from the 8240 processor side.
- */
-#define	ZX4500_HOST_BRIDGE_IDSEL	20
-
-
-void zx4500_find_bridges(void);
-
-#endif	/* __PPC_PLATFORMS_ZX4500_H_ */
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/zx4500_pci.c linux-2.5.74-bk4/arch/ppc/platforms/zx4500_pci.c
--- linux-2.5.74-bk3/arch/ppc/platforms/zx4500_pci.c	2003-07-02 13:56:00.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/zx4500_pci.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,138 +0,0 @@
-/*
- * arch/ppc/platforms/zx4500_pci.c
- * 
- * PCI setup routines for Znyx ZX4500 cPCI boards.
- *
- * Author: Mark A. Greer
- *         mgreer@mvista.com
- *
- * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-#include <asm/mpc10x.h>
-#include <asm/pci-bridge.h>
-
-#include "zx4500.h"
-
-/*
- * Znyx ZX4500 interrupt routes.
- */
-static inline int
-zx4500_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
-{
-	static char pci_irq_table[][4] =
-	/*
-	 *	PCI IDSEL/INTPIN->INTLINE 
-	 * 	   A   B   C   D
-	 */
-	{
-		{ 19,  0,  0,  0 },	/* IDSEL 21 - 21554 PCI-cPCI bridge */
-		{ 18,  0,  0,  0 },	/* IDSEL 22 - BCM5600 INTA */
-		{ 16, 20, 16, 20 },	/* IDSEL 23 - PPMC Slot */
-	};
-
-	const long min_idsel = 21, max_idsel = 23, irqs_per_slot = 4;
-	return PCI_IRQ_TABLE_LOOKUP;
-}
-
-void __init
-zx4500_board_init(struct pci_controller *hose)
-{
-	uint	val;
-	u_char	sysctl;
-
-	/*
-	 * CPLD Registers are mapped in by BAT 3 in zx4500_setup_arch().
-	 *
-	 * Turn off all interrupts routed through the CPLD.
-	 * Also, turn off watchdog timer and drive PMC EREADY low.
-	 */
-	sysctl = in_8((volatile u_char *)ZX4500_CPLD_SYSCTL);
-	sysctl &= ~(ZX4500_CPLD_SYSCTL_PMC |
-		    ZX4500_CPLD_SYSCTL_BCM |
-		    ZX4500_CPLD_SYSCTL_SINTA |
-		    ZX4500_CPLD_SYSCTL_WD |
-		    ZX4500_CPLD_SYSCTL_PMC_TRI);
-	out_8((volatile u_char *)ZX4500_CPLD_SYSCTL, sysctl);
-
-	/*
-	 * Kludge the size that BAR2 of the 21554 asks for
-	 * (i.e., set Upstream I/O or Memory 0 Setup Register).
-	 * Old versions of SROM wants 1 GB which is too large, make it ask
-	 * for 256 MB.
-	 */
-	early_read_config_dword(hose, 0, PCI_DEVFN(21,0), 0xc4, &val);
-
-	if (val != 0) {
-		early_write_config_dword(hose,
-					 0,
-					 PCI_DEVFN(21,0),
-					 0xc4,
-					 val | 0xf0000000);
-	}
-
-	return;
-}
-
-static int                     
-zx4500_exclude_device(u_char bus, u_char devfn)
-{
-	if ((bus == 0) && (PCI_SLOT(devfn) == ZX4500_HOST_BRIDGE_IDSEL)) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	else {
-		return PCIBIOS_SUCCESSFUL;
-	}
-}
-
-void __init
-zx4500_find_bridges(void)
-{
-	struct pci_controller	*hose;
-
-	hose = pcibios_alloc_controller();
-
-	if (!hose)
-		return;
-
-	hose->first_busno = 0;
-	hose->last_busno = 0xff;
-
-	if (mpc10x_bridge_init(hose,
-			       MPC10X_MEM_MAP_B,
-			       MPC10X_MEM_MAP_B,
-			       MPC10X_MAPB_EUMB_BASE) == 0) {
-
-		hose->mem_resources[0].end = 0xffffffff;
-	
-		/* Initialize the board */
-		zx4500_board_init(hose);
-
-		/* scan PCI bus */
-		ppc_md.pci_exclude_device = zx4500_exclude_device;
-		hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
-
-		ppc_md.pcibios_fixup = NULL;
-		ppc_md.pcibios_fixup_bus = NULL;
-		ppc_md.pci_swizzle = common_swizzle;
-		ppc_md.pci_map_irq = zx4500_map_irq;
-	}
-	else {
-		if (ppc_md.progress)
-			ppc_md.progress("Bridge init failed", 0x100);
-		printk("Host bridge init failed\n");
-	}
-
-	return;
-}
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/zx4500_serial.h linux-2.5.74-bk4/arch/ppc/platforms/zx4500_serial.h
--- linux-2.5.74-bk3/arch/ppc/platforms/zx4500_serial.h	2003-07-02 13:57:08.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/zx4500_serial.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,46 +0,0 @@
-/*
- * arch/ppc/platforms/zx4500_serial.h
- * 
- * Definitions for Znyx ZX4500 board support
- *
- * Author: Mark A. Greer
- *         mgreer@mvista.com
- *
- * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#ifndef __ASMPPC_ZX4500_SERIAL_H
-#define __ASMPPC_ZX4500_SERIAL_H
-
-#include <linux/config.h>
-
-/* Define the UART base address (only 1 UART) */
-#define ZX4500_SERIAL_1			0xff880000
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define RS_TABLE_SIZE  64
-#else
-#define RS_TABLE_SIZE  1
-#endif
-
-/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
-#define BASE_BAUD ( 1843200 / 16 )
-
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
-#endif
-
-#define STD_SERIAL_PORT_DFNS \
-        { 0, BASE_BAUD, ZX4500_SERIAL_1, 17, STD_COM_FLAGS, /* ttyS0 */	\
-		iomem_base: (u8 *)ZX4500_SERIAL_1,			\
-		io_type: SERIAL_IO_MEM },
-
-#define SERIAL_PORT_DFNS \
-        STD_SERIAL_PORT_DFNS
-
-#endif /* __ASMPPC_ZX4500_SERIAL_H */
diff -urN linux-2.5.74-bk3/arch/ppc/platforms/zx4500_setup.c linux-2.5.74-bk4/arch/ppc/platforms/zx4500_setup.c
--- linux-2.5.74-bk3/arch/ppc/platforms/zx4500_setup.c	2003-07-02 13:39:25.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/platforms/zx4500_setup.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,359 +0,0 @@
-/*
- * arch/ppc/platforms/zx4500_setup.c
- *
- * Board setup routines for Znyx ZX4500 family of cPCI boards.
- *
- * Author: Mark A. Greer
- *         mgreer@mvista.com
- *
- * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-/*
- * This file adds support for the Znyx ZX4500 series of cPCI boards.
- * These boards have an 8240, UART on the processor bus, a PPMC slot (for now
- * the card in this slot can _not_ be a monarch), Broadcom BCM5600, and an
- * Intel 21554 bridge.
- *
- * Currently, this port assumes that the 8240 is the master and performs PCI
- * arbitration, etc.  It is also assumed that the 8240 is wired to come up
- * using memory MAP B (CHRP map).
- *
- * Note: This board port will not work properly as it is.  You must apply the
- *	 patch that is at ftp://ftp.mvista.com/pub/Area51/zx4500/zx_patch_2_5
- */
-#include <linux/config.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/reboot.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/initrd.h>
-#include <linux/console.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/time.h>
-#include <asm/open_pic.h>
-#include <asm/mpc10x.h>
-#include <asm/pci-bridge.h>
-#include <asm/bootinfo.h>
-
-#include "zx4500.h"
-
-static u_char zx4500_openpic_initsenses[] __initdata = {
-	0,	/* 0-15 are not used on an 8240 EPIC */
-	0,	/* 1 */
-	0,	/* 2 */
-	0,	/* 3 */
-	0,	/* 4 */
-	0,	/* 5 */
-	0,	/* 6 */
-	0,	/* 7 */
-	0,	/* 8 */
-	0,	/* 9 */
-	0,	/* 10 */
-	0,	/* 11 */
-	0,	/* 12 */
-	0,	/* 13 */
-	0,	/* 14 */
-	0,	/* 15 */
-	1,	/* 16: EPIC IRQ 0: Active Low -- PMC #INTA & #INTC */
-	1,	/* 17: EPIC IRQ 1: Active Low -- UART */
-	1,	/* 18: EPIC IRQ 2: Active Low -- BCM5600 #INTA */
-	1,	/* 19: EPIC IRQ 3: Active Low -- 21554 #SINTA */
-	1,	/* 20: EPIC IRQ 4: Active Low -- PMC #INTB & #INTD */
-};
-
-
-static void __init
-zx4500_setup_arch(void)
-{
-	char		boot_string[ZX4500_BOOT_STRING_LEN + 1];
-	char		*boot_arg;
-	extern char	cmd_line[];
-
-
-	loops_per_jiffy = 50000000 / HZ;
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_start)
-		ROOT_DEV = Root_RAM0;
-	else
-#endif
-#if	defined(CONFIG_ROOT_NFS)
-		ROOT_DEV = Root_NFS;
-#else
-		ROOT_DEV = Root_SDA1;
-#endif
-
-	/* Get boot string from flash */
-	strlcpy(boot_string,
-		(char *)ZX4500_BOOT_STRING_ADDR,
-		sizeof(boot_string));
-	boot_string[ZX4500_BOOT_STRING_LEN] = '\0';
-
-	/* Can be delimited by 0xff */
-	boot_arg = strchr(boot_string, 0xff);
-
-	if (boot_arg != NULL) {
-		*boot_arg = '\0';
-	}
-
-	/* First 3 chars must be 'dev'.  If not, ignore. */
-	if (!strncmp(boot_string, "dev", 3)) {
-		/* skip 'dev?' and any blanks after it */
-		boot_arg = strchr(boot_string, ' ');
-
-		if (boot_arg != NULL) {
-			while (*boot_arg == ' ') boot_arg++;
-			strcat(cmd_line, " ");
-			strcat(cmd_line, boot_arg);
-		}
-	}
-
-	/* nothing but serial consoles... */
-	printk("Znyx ZX4500 Series High Performance Switch\n");
-	printk("ZX4500 port (C) 2000, 2001 MontaVista Software, Inc. (source@mvista.com)\n");
-
-	/* Lookup PCI host bridge */
-	zx4500_find_bridges();
-
-	printk("ZX4500 Board ID: 0x%x, Revision #: 0x%x\n",
-		in_8((volatile u_char *)ZX4500_CPLD_BOARD_ID),
-		in_8((volatile u_char *)ZX4500_CPLD_REV));
-
-	return;
-}
-
-static ulong __init
-zx4500_find_end_of_memory(void)
-{
-	return mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
-}
-
-static void __init
-zx4500_map_io(void)
-{
-	io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
-}
-
-/*
- * Enable interrupts routed thru CPLD to reach the 8240's EPIC.
- * Need to enable all 4 PMC intrs, BCM INTA, and 21554 SINTA to 8240.
- * UART intrs routed directly to 8240 (not thru CPLD).
- */
-static void __init
-zx4500_enable_cpld_intrs(void)
-{
-	u_char	sysctl;
-
-	sysctl = in_8((volatile u_char *)ZX4500_CPLD_SYSCTL);
-	sysctl |= (ZX4500_CPLD_SYSCTL_PMC |
-		   ZX4500_CPLD_SYSCTL_BCM |
-		   ZX4500_CPLD_SYSCTL_SINTA);
-	out_8((volatile u_char *)ZX4500_CPLD_SYSCTL, sysctl);
-
-	return;
-}
-
-static void __init
-zx4500_init_IRQ(void)
-{
-	OpenPIC_InitSenses = zx4500_openpic_initsenses;
-	OpenPIC_NumInitSenses = sizeof(zx4500_openpic_initsenses);
-
-	openpic_init(1, 0, NULL, -1);
-
-	zx4500_enable_cpld_intrs(); /* Allow CPLD to route intrs to 8240 */
-
-	return;
-}
-
-static void
-zx4500_restart(char *cmd)
-{
-	local_irq_disable();
-
-	out_8((volatile u_char *)ZX4500_CPLD_RESET, ZX4500_CPLD_RESET_XBUS);
-	for (;;);
-
-	panic("Restart failed.\n");
-	/* NOTREACHED */
-}
-
-static void
-zx4500_power_off(void)
-{
-	local_irq_disable();
-	for(;;);  /* No way to shut power off with software */
-	/* NOTREACHED */
-}
-
-static void
-zx4500_halt(void)
-{
-	zx4500_power_off();
-	/* NOTREACHED */
-}
-
-static int
-zx4500_get_bus_speed(void)
-{
-	int bus_speed;
-
-	bus_speed = 100000000;
-
-	return bus_speed;
-}
-
-static int
-zx4500_show_cpuinfo(struct seq_file *m)
-{
-	uint pvid;
-
-	seq_printf(m, "vendor\t\t: Znyx\n");
-	seq_printf(m, "machine\t\t: ZX4500\n");
-	seq_printf(m, "processor\t: PVID: 0x%x, vendor: %s\n",
-			pvid, (pvid & (1<<15) ? "IBM" : "Motorola"));
-	seq_printf(m, "bus speed\t: %dMhz\n",
-			zx4500_get_bus_speed()/1000000);
-
-	return 0;
-}
-
-static void __init
-zx4500_calibrate_decr(void)
-{
-	ulong freq;
-
-	freq = zx4500_get_bus_speed() / 4;
-
-	printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
-	       freq/1000000, freq%1000000);
-
-	tb_ticks_per_jiffy = freq / HZ;
-	tb_to_us = mulhwu_scale_factor(freq, 1000000);
-
-	return;
-}
-
-/*
- * Set BAT 3 to map 0xf0000000 to end of physical memory space 1-1.
- */
-static __inline__ void
-zx4500_set_bat(void)
-{
-	unsigned long   bat3u, bat3l;
-	static int	mapping_set = 0;
-
-	if (!mapping_set) {
-
-		__asm__ __volatile__(
-		" lis %0,0xf800\n \
-		  ori %1,%0,0x002a\n \
-		  ori %0,%0,0x0ffe\n \
-		  mtspr 0x21e,%0\n \
-		  mtspr 0x21f,%1\n \
-		  isync\n \
-		  sync "
-		  : "=r" (bat3u), "=r" (bat3l));
-
-		mapping_set = 1;
-	}
-
-	return;
-}
-
-#ifdef	CONFIG_SERIAL_TEXT_DEBUG
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <asm/serial.h>
-
-static struct serial_state rs_table[RS_TABLE_SIZE] = {
-	SERIAL_PORT_DFNS	/* Defined in <asm/serial.h> */
-};
-
-void
-zx4500_progress(char *s, unsigned short hex)
-{
-	volatile char c;
-	volatile unsigned long com_port;
-	u16 shift;
-
-	com_port = rs_table[0].port;
-	shift = rs_table[0].iomem_reg_shift;
-
-	while ((c = *s++) != 0) {
-		while ((*((volatile unsigned char *)com_port +
-				(UART_LSR << shift)) & UART_LSR_THRE) == 0)
-		                ;
-	        *(volatile unsigned char *)com_port = c;
-
-		if (c == '\n') {
-			while ((*((volatile unsigned char *)com_port +
-				(UART_LSR << shift)) & UART_LSR_THRE) == 0)
-					;
-	        	*(volatile unsigned char *)com_port = '\r';
-		}
-	}
-}
-#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
-
-void __init
-platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
-	      unsigned long r6, unsigned long r7)
-{
-	parse_bootinfo(find_bootinfo());
-
-	/* Map in board registers, etc. */
-	zx4500_set_bat();
-
-	isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
-	isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
-	pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
-
-	ppc_md.setup_arch = zx4500_setup_arch;
-	ppc_md.show_cpuinfo = zx4500_show_cpuinfo;
-	ppc_md.irq_canonicalize = NULL;
-	ppc_md.init_IRQ = zx4500_init_IRQ;
-	ppc_md.get_irq = openpic_get_irq;
-	ppc_md.init = NULL;
-
-	ppc_md.restart = zx4500_restart;
-	ppc_md.power_off = zx4500_power_off;
-	ppc_md.halt = zx4500_halt;
-
-	ppc_md.find_end_of_memory = zx4500_find_end_of_memory;
-	ppc_md.setup_io_mappings = zx4500_map_io;
-
-	ppc_md.calibrate_decr = zx4500_calibrate_decr;
-
-	ppc_md.heartbeat = NULL;
-	ppc_md.heartbeat_reset = 0;
-	ppc_md.heartbeat_count = 0;
-
-#ifdef	CONFIG_SERIAL_TEXT_DEBUG
-	ppc_md.progress = zx4500_progress;
-#else	/* !CONFIG_SERIAL_TEXT_DEBUG */
-	ppc_md.progress = NULL;
-#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
-
-	return;
-}
diff -urN linux-2.5.74-bk3/arch/ppc/syslib/Makefile linux-2.5.74-bk4/arch/ppc/syslib/Makefile
--- linux-2.5.74-bk3/arch/ppc/syslib/Makefile	2003-07-02 13:40:56.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/syslib/Makefile	2003-07-06 09:15:48.000000000 -0700
@@ -61,8 +61,9 @@
 					pci_auto.o indirect_pci.o todc_time.o
 obj-$(CONFIG_SPRUCE)		+= cpc700_pic.o indirect_pci.o pci_auto.o \
 				   todc_time.o
-obj-$(CONFIG_ZX4500)		+= indirect_pci.o pci_auto.o mpc10x_common.o \
-					i8259.o open_pic.o
 obj-$(CONFIG_8260)		+= m8260_setup.o ppc8260_pic.o
+ifeq ($(CONFIG_SERIAL_8250)$(CONFIG_PPC_GEN550),yy)
+obj-$(CONFIG_KGDB)		+= gen550_kgdb.o gen550_dbg.o
+obj-$(CONFIG_SERIAL_TEXT_DEBUG)	+= gen550_dbg.o
+endif
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
-
diff -urN linux-2.5.74-bk3/arch/ppc/syslib/gen550_dbg.c linux-2.5.74-bk4/arch/ppc/syslib/gen550_dbg.c
--- linux-2.5.74-bk3/arch/ppc/syslib/gen550_dbg.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.74-bk4/arch/ppc/syslib/gen550_dbg.c	2003-07-06 09:15:48.000000000 -0700
@@ -0,0 +1,174 @@
+/*
+ * arch/ppc/syslib/gen550_dbg.c
+ *
+ * A library of polled 16550 serial routines.  These are intended to
+ * be used to support progress messages, xmon, kgdb, etc. on a
+ * variety of platforms.
+ *
+ * Adapted from lots of code ripped from the arch/ppc/boot/ polled
+ * 16550 support.
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * 2002-2003 (c) MontaVista Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/tty.h>		/* For linux/serial_core.h */
+#include <linux/serial_core.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <asm/machdep.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+
+#define SERIAL_BAUD	9600
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* defined in <asm/serial.h> */
+};
+
+static void (*serial_outb)(unsigned long, unsigned char);
+static unsigned long (*serial_inb)(unsigned long);
+
+static int shift;
+
+unsigned long direct_inb(unsigned long addr)
+{
+	return readb(addr);
+}
+
+void direct_outb(unsigned long addr, unsigned char val)
+{
+	writeb(val, addr);
+}
+
+unsigned long io_inb(unsigned long port)
+{
+	return inb(port);
+}
+
+void io_outb(unsigned long port, unsigned char val)
+{
+	outb(val, port);
+}
+
+unsigned long serial_init(int chan, void *ignored)
+{
+	unsigned long com_port;
+	unsigned char lcr, dlm;
+
+	/* We need to find out which type io we're expecting.  If it's
+	 * 'SERIAL_IO_PORT', we get an offset from the isa_io_base.
+	 * If it's 'SERIAL_IO_MEM', we can the exact location.  -- Tom */
+	switch (rs_table[chan].io_type) {
+		case SERIAL_IO_PORT:
+			com_port = rs_table[chan].port;
+			serial_outb = io_outb;
+			serial_inb = io_inb;
+			break;
+		case SERIAL_IO_MEM:
+			com_port = (unsigned long)rs_table[chan].iomem_base;
+			serial_outb = direct_outb;
+			serial_inb = direct_inb;
+			break;
+		default:
+			/* We can't deal with it. */
+			return -1;
+	}
+
+	/* How far apart the registers are. */
+	shift = rs_table[chan].iomem_reg_shift;
+
+	/* save the LCR */
+	lcr = serial_inb(com_port + (UART_LCR << shift));
+	
+	/* Access baud rate */
+	serial_outb(com_port + (UART_LCR << shift), UART_LCR_DLAB);
+	dlm = serial_inb(com_port + (UART_DLM << shift));
+
+	/*
+	 * Test if serial port is unconfigured
+	 * We assume that no-one uses less than 110 baud or
+	 * less than 7 bits per character these days.
+	 *  -- paulus.
+	 */
+	if ((dlm <= 4) && (lcr & 2)) {
+		/* port is configured, put the old LCR back */
+		serial_outb(com_port + (UART_LCR << shift), lcr);
+	}
+	else {
+		/* Input clock. */
+		serial_outb(com_port + (UART_DLL << shift),
+			(rs_table[chan].baud_base / SERIAL_BAUD) & 0xFF);
+		serial_outb(com_port + (UART_DLM << shift),
+				(rs_table[chan].baud_base / SERIAL_BAUD) >> 8);
+		/* 8 data, 1 stop, no parity */
+		serial_outb(com_port + (UART_LCR << shift), 0x03);
+		/* RTS/DTR */
+		serial_outb(com_port + (UART_MCR << shift), 0x03);
+
+		/* Clear & enable FIFOs */
+		serial_outb(com_port + (UART_FCR << shift), 0x07);
+	}
+
+	return (com_port);
+}
+
+void
+serial_putc(unsigned long com_port, unsigned char c)
+{
+	while ((serial_inb(com_port + (UART_LSR << shift)) & UART_LSR_THRE) == 0)
+		;
+	serial_outb(com_port, c);
+}
+
+unsigned char
+serial_getc(unsigned long com_port)
+{
+	while ((serial_inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) == 0)
+		;
+	return serial_inb(com_port);
+}
+
+int
+serial_tstc(unsigned long com_port)
+{
+	return ((serial_inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0);
+}
+
+void
+serial_close(unsigned long com_port)
+{
+}
+
+void
+gen550_init(int i, struct uart_port *serial_req)
+{
+	rs_table[i].io_type = serial_req->iotype;
+	rs_table[i].port = serial_req->line;
+	rs_table[i].iomem_base = serial_req->membase;
+	rs_table[i].iomem_reg_shift = serial_req->regshift;
+}
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+void
+gen550_progress(char *s, unsigned short hex)
+{
+	volatile unsigned int progress_debugport;
+	volatile char c;
+
+	progress_debugport = serial_init(0, NULL);
+
+	serial_putc(progress_debugport, '\r');
+
+	while ((c = *s++) != 0)
+		serial_putc(progress_debugport, c);
+
+	serial_putc(progress_debugport, '\n');
+	serial_putc(progress_debugport, '\r');
+}
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
diff -urN linux-2.5.74-bk3/arch/ppc/syslib/gen550_kgdb.c linux-2.5.74-bk4/arch/ppc/syslib/gen550_kgdb.c
--- linux-2.5.74-bk3/arch/ppc/syslib/gen550_kgdb.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.74-bk4/arch/ppc/syslib/gen550_kgdb.c	2003-07-06 09:15:48.000000000 -0700
@@ -0,0 +1,84 @@
+/*
+ * arch/ppc/syslib/gen550_kgdb.c
+ *
+ * Generic 16550 kgdb support intended to be useful on a variety
+ * of platforms.  To enable this support, it is necessary to set
+ * the CONFIG_GEN550 option.  Any virtual mapping of the serial
+ * port(s) to be used can be accomplished by setting
+ * ppc_md.early_serial_map to a platform-specific mapping function.
+ *
+ * Adapted from ppc4xx_kgdb.c. 
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * 2002-2003 (c) MontaVista Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <asm/machdep.h>
+
+extern unsigned long serial_init(int, void *);
+extern unsigned long serial_getc(unsigned long);
+extern unsigned long serial_putc(unsigned long, unsigned char);
+
+#if defined(CONFIG_KGDB_TTYS0)
+#define KGDB_PORT 0
+#elif defined(CONFIG_KGDB_TTYS1)
+#define KGDB_PORT 1
+#elif defined(CONFIG_KGDB_TTYS2)
+#define KGDB_PORT 2
+#elif defined(CONFIG_KGDB_TTYS3)
+#define KGDB_PORT 3
+#else
+#error "invalid kgdb_tty port"
+#endif
+
+static volatile unsigned int kgdb_debugport;
+
+void putDebugChar(unsigned char c)
+{
+	if (kgdb_debugport == 0)
+		kgdb_debugport = serial_init(KGDB_PORT, NULL);
+
+	serial_putc(kgdb_debugport, c);
+}
+
+int getDebugChar(void)
+{
+	if (kgdb_debugport == 0)
+		kgdb_debugport = serial_init(KGDB_PORT, NULL);
+
+	return(serial_getc(kgdb_debugport));
+}
+
+void kgdb_interruptible(int enable)
+{
+	return;
+}
+
+void putDebugString(char* str)
+{
+	while (*str != '\0') {
+		putDebugChar(*str);
+		str++;
+	}
+	putDebugChar('\r');
+	return;
+}
+
+/*
+ * Note: gen550_init() must be called already on the port we are going
+ * to use.
+ */
+void
+kgdb_map_scc(void)
+{
+	printk(KERN_DEBUG "kgdb init\n");
+	kgdb_debugport = serial_init(KGDB_PORT, NULL);
+}
diff -urN linux-2.5.74-bk3/arch/ppc/syslib/open_pic.c linux-2.5.74-bk4/arch/ppc/syslib/open_pic.c
--- linux-2.5.74-bk3/arch/ppc/syslib/open_pic.c	2003-07-02 13:49:21.000000000 -0700
+++ linux-2.5.74-bk4/arch/ppc/syslib/open_pic.c	2003-07-06 09:15:48.000000000 -0700
@@ -33,6 +33,7 @@
 
 void* OpenPIC_Addr;
 static volatile struct OpenPIC *OpenPIC = NULL;
+
 /*
  * We define OpenPIC_InitSenses table thusly:
  * bit 0x1: sense, 0 for edge and 1 for level.
@@ -261,32 +262,32 @@
 }
 #endif /* CONFIG_SMP */
 
-#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PMAC_PBOOK)
-static void openpic_reset(void)
+#ifdef CONFIG_EPIC_SERIAL_MODE
+static void __init openpic_eicr_set_clk(u_int clkval)
 {
-	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
-			 OPENPIC_CONFIG_RESET);
-	while (openpic_readfield(&OpenPIC->Global.Global_Configuration0,
-				 OPENPIC_CONFIG_RESET))
-		mb();
+	openpic_writefield(&OpenPIC->Global.Global_Configuration1,
+			OPENPIC_EICR_S_CLK_MASK, (clkval << 28));
 }
-#endif
 
-#ifdef CONFIG_EPIC_SERIAL_MODE
-static void openpic_enable_sie(void)
+static void __init openpic_enable_sie(void)
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration1,
-			 OPENPIC_EICR_SIE);
+			OPENPIC_EICR_SIE);
 }
+#endif
 
-static void openpic_eicr_set_clk(u_int clkval)
+#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PMAC_PBOOK)
+static void openpic_reset(void)
 {
-	openpic_writefield(&OpenPIC->Global.Global_Configuration1,
-			 OPENPIC_EICR_S_CLK_MASK, (clkval << 28));
+	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
+			 OPENPIC_CONFIG_RESET);
+	while (openpic_readfield(&OpenPIC->Global.Global_Configuration0,
+				 OPENPIC_CONFIG_RESET))
+		mb();
 }
 #endif
 
-void openpic_set_sources(int first_irq, int num_irqs, void *first_ISR)
+void __init openpic_set_sources(int first_irq, int num_irqs, void *first_ISR)
 {
 	volatile OpenPIC_Source *src = first_ISR;
 	int i, last_irq;
@@ -300,7 +301,14 @@
 		ISR[i] = src;
 }
 
-void __init openpic_init(int linux_irq_offset)
+/*
+ * The `offset' parameter defines where the interrupts handled by the
+ * OpenPIC start in the space of interrupt numbers that the kernel knows
+ * about.  In other words, the OpenPIC's IRQ0 is numbered `offset' in the
+ * kernel's interrupt numbering scheme.
+ * We assume there is only one OpenPIC.
+ */
+void __init openpic_init(int offset)
 {
 	u_int t, i;
 	u_int timerfreq;
@@ -349,13 +357,13 @@
 		printk("OpenPIC timer frequency is %d.%06d MHz\n",
 		       timerfreq / 1000000, timerfreq % 1000000);
 
-	open_pic_irq_offset = linux_irq_offset;
+	open_pic_irq_offset = offset;
 
 	/* Initialize timer interrupts */
 	if ( ppc_md.progress ) ppc_md.progress("openpic: timer",0x3ba);
 	for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
 		/* Disabled, Priority 0 */
-		openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+linux_irq_offset);
+		openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+offset);
 		/* No processor */
 		openpic_maptimer(i, 0);
 	}
@@ -365,12 +373,10 @@
 	if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb);
 	for (i = 0; i < OPENPIC_NUM_IPI; i++) {
 		/* Disabled, Priority 10..13 */
-		openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+linux_irq_offset);
+		openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset);
 		/* IPIs are per-CPU */
-		irq_desc[OPENPIC_VEC_IPI+i+linux_irq_offset].status |=
-			IRQ_PER_CPU;
-		irq_desc[OPENPIC_VEC_IPI+i+linux_irq_offset].handler =
-			&open_pic_ipi;
+		irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU;
+		irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi;
 	}
 #endif
 
@@ -387,40 +393,36 @@
 			continue;
 
 		/* the bootloader may have left it enabled (bad !) */
-		openpic_disable_irq(i+linux_irq_offset);
+		openpic_disable_irq(i+offset);
 
-		/*
-		 * We find the value from either the InitSenses table
-		 * or assume a negative polarity level interrupt.
-		 */
-		sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1;
+		sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: \
+				(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE);
 
-		if ((sense & IRQ_SENSE_MASK) == 1)
-			irq_desc[i+linux_irq_offset].status = IRQ_LEVEL;
+		if (sense & IRQ_SENSE_MASK)
+			irq_desc[i+offset].status = IRQ_LEVEL;
 
 		/* Enabled, Priority 8 */
-		openpic_initirq(i, 8, i + linux_irq_offset,
-				(sense & IRQ_POLARITY_MASK),
+		openpic_initirq(i, 8, i+offset, (sense & IRQ_POLARITY_MASK),
 				(sense & IRQ_SENSE_MASK));
 		/* Processor 0 */
 		openpic_mapirq(i, 1<<0, 0);
 	}
 
 	/* Init descriptors */
-	for (i = linux_irq_offset; i < NumSources + linux_irq_offset; i++)
+	for (i = offset; i < NumSources + offset; i++)
 		irq_desc[i].handler = &open_pic;
 
 	/* Initialize the spurious interrupt */
 	if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd);
-	openpic_set_spurious(OPENPIC_VEC_SPURIOUS+linux_irq_offset);
+	openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset);
 
 	/* Initialize the cascade */
-	if (linux_irq_offset) {
-		if (request_irq(linux_irq_offset, no_action, SA_INTERRUPT,
+	if (offset) {
+		if (request_irq(offset, no_action, SA_INTERRUPT,
 				"82c59 cascade", NULL))
 			printk("Unable to get OpenPIC IRQ 0 for cascade\n");
 	}
- 	openpic_disable_8259_pass_through();
+	openpic_disable_8259_pass_through();
 #ifdef CONFIG_EPIC_SERIAL_MODE
 	openpic_eicr_set_clk(7);	/* Slowest value until we know better */
 	openpic_enable_sie();
@@ -479,7 +481,7 @@
 }
 #endif /* notused */
 
-static void openpic_set_priority(u_int pri)
+static void __init openpic_set_priority(u_int pri)
 {
 	DECL_THIS_CPU;
 
@@ -656,29 +658,18 @@
 }
 
 /*
- * Initalize the interrupt source which will generate an NMI (and disable it).
+ * Initalize the interrupt source which will generate an NMI.
+ * This raises the interrupt's priority from 8 to 9.
  *
  * irq: The logical IRQ which generates an NMI.
  */
 void __init
 openpic_init_nmi_irq(u_int irq)
 {
-	int sense;
-
-	/* If this wasn't given, assume a level, negative polarity interrupt. */
-	sense = (irq < OpenPIC_NumInitSenses) ? OpenPIC_InitSenses[irq] :
-		(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE);
-
-	openpic_safe_writefield(&ISR[irq]->Vector_Priority,
-				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
-				OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK,
-				(9 << OPENPIC_PRIORITY_SHIFT) |
-				(irq + open_pic_irq_offset) |
-				((sense & IRQ_POLARITY_MASK) ?
-				 OPENPIC_POLARITY_POSITIVE :
-				 OPENPIC_POLARITY_NEGATIVE) |
-				((sense & IRQ_SENSE_MASK) ? OPENPIC_SENSE_LEVEL
-				 : OPENPIC_SENSE_EDGE));
+	check_arg_irq(irq);
+	openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority,
+				OPENPIC_PRIORITY_MASK,
+				9 << OPENPIC_PRIORITY_SHIFT);
 }
 
 /*
@@ -752,7 +743,8 @@
  *  pol: polarity (1 for positive, 0 for negative)
  *  sense: 1 for level, 0 for edge
  */
-static void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
+static void __init
+openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
 {
 	openpic_safe_writefield(&ISR[irq]->Vector_Priority,
 				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
diff -urN linux-2.5.74-bk3/drivers/block/Makefile linux-2.5.74-bk4/drivers/block/Makefile
--- linux-2.5.74-bk3/drivers/block/Makefile	2003-07-02 13:53:43.000000000 -0700
+++ linux-2.5.74-bk4/drivers/block/Makefile	2003-07-06 09:15:48.000000000 -0700
@@ -8,7 +8,13 @@
 # In the future, some of these should be built conditionally.
 #
 
-obj-y	:= elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o deadline-iosched.o
+#
+# NOTE that ll_rw_blk.c must come early in linkage order - it starts the
+# kblockd threads
+#
+
+obj-y	:= elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o \
+	deadline-iosched.o as-iosched.o
 
 obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
 obj-$(CONFIG_BLK_DEV_FD)	+= floppy.o
diff -urN linux-2.5.74-bk3/drivers/block/as-iosched.c linux-2.5.74-bk4/drivers/block/as-iosched.c
--- linux-2.5.74-bk3/drivers/block/as-iosched.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.74-bk4/drivers/block/as-iosched.c	2003-07-06 09:15:48.000000000 -0700
@@ -0,0 +1,1837 @@
+/*
+ *  linux/drivers/block/as-iosched.c
+ *
+ *  Anticipatory & deadline i/o scheduler.
+ *
+ *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
+ *                     Nick Piggin <piggin@cyberone.com.au>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/blkdev.h>
+#include <linux/elevator.h>
+#include <linux/bio.h>
+#include <linux/blk.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/compiler.h>
+#include <linux/hash.h>
+#include <linux/rbtree.h>
+#include <linux/interrupt.h>
+
+#define REQ_SYNC	1
+#define REQ_ASYNC	0
+
+/*
+ * See Documentation/as-iosched.txt
+ */
+
+/*
+ * max time before a read is submitted.
+ */
+#define default_read_expire (HZ / 20)
+
+/*
+ * ditto for writes, these limits are not hard, even
+ * if the disk is capable of satisfying them.
+ */
+#define default_write_expire (HZ / 5)
+
+/*
+ * read_batch_expire describes how long we will allow a stream of reads to
+ * persist before looking to see whether it is time to switch over to writes.
+ */
+#define default_read_batch_expire (HZ / 5)
+
+/*
+ * write_batch_expire describes how long we want a stream of writes to run for.
+ * This is not a hard limit, but a target we set for the auto-tuning thingy.
+ * See, the problem is: we can send a lot of writes to disk cache / TCQ in
+ * a short amount of time...
+ */
+#define default_write_batch_expire (HZ / 20)
+
+/*
+ * max time we may wait to anticipate a read (default around 6ms)
+ */
+#define default_antic_expire ((HZ / 150) ? HZ / 150 : 1)
+
+/*
+ * Keep track of up to 20ms thinktimes. We can go as big as we like here,
+ * however huge values tend to interfere and not decay fast enough. A program
+ * might be in a non-io phase of operation. Waiting on user input for example,
+ * or doing a lengthy computation. A small penalty can be justified there, and
+ * will still catch out those processes that constantly have large thinktimes.
+ */
+#define MAX_THINKTIME (HZ/50UL)
+
+/* Bits in as_io_context.state */
+enum as_io_states {
+	AS_TASK_RUNNING=0,	/* Process has not exitted */
+	AS_TASK_IORUNNING,	/* Process has completed some IO */
+};
+
+enum anticipation_status {
+	ANTIC_OFF=0,		/* Not anticipating (normal operation)	*/
+	ANTIC_WAIT_REQ,		/* The last read has not yet completed  */
+	ANTIC_WAIT_NEXT,	/* Currently anticipating a request vs
+				   last read (which has completed) */
+	ANTIC_FINISHED,		/* Anticipating but have found a candidate
+				 * or timed out */
+};
+
+struct as_data {
+	/*
+	 * run time data
+	 */
+
+	struct request_queue *q;	/* the "owner" queue */
+
+	/*
+	 * requests (as_rq s) are present on both sort_list and fifo_list
+	 */
+	struct rb_root sort_list[2];
+	struct list_head fifo_list[2];
+
+	struct as_rq *next_arq[2];	/* next in sort order */
+	sector_t last_sector[2];	/* last REQ_SYNC & REQ_ASYNC sectors */
+	struct list_head *dispatch;	/* driver dispatch queue */
+	struct list_head *hash;		/* request hash */
+	unsigned long hash_valid_count;	/* barrier hash count */
+	unsigned long current_batch_expires;
+	unsigned long last_check_fifo[2];
+	int changed_batch;
+	int batch_data_dir;		/* current batch REQ_SYNC / REQ_ASYNC */
+	int write_batch_count;		/* max # of reqs in a write batch */
+	int current_write_count;	/* how many requests left this batch */
+	int write_batch_idled;		/* has the write batch gone idle? */
+	mempool_t *arq_pool;
+
+	enum anticipation_status antic_status;
+	unsigned long antic_start;	/* jiffies: when it started */
+	struct timer_list antic_timer;	/* anticipatory scheduling timer */
+	struct work_struct antic_work;	/* Deferred unplugging */
+	struct io_context *io_context;	/* Identify the expected process */
+	int ioc_finished; /* IO associated with io_context is finished */
+	int nr_dispatched;
+
+	/*
+	 * settings that change how the i/o scheduler behaves
+	 */
+	unsigned long fifo_expire[2];
+	unsigned long batch_expire[2];
+	unsigned long antic_expire;
+};
+
+#define list_entry_fifo(ptr)	list_entry((ptr), struct as_rq, fifo)
+
+/*
+ * per-request data.
+ */
+enum arq_state {
+	AS_RQ_NEW=0,		/* New - not referenced and not on any lists */
+	AS_RQ_QUEUED,		/* In the request queue. It belongs to the
+				   scheduler */
+	AS_RQ_DISPATCHED,	/* On the dispatch list. It belongs to the
+				   driver now */
+};
+
+struct as_rq {
+	/*
+	 * rbtree index, key is the starting offset
+	 */
+	struct rb_node rb_node;
+	sector_t rb_key;
+
+	struct request *request;
+
+	struct io_context *io_context;	/* The submitting task */
+
+	/*
+	 * request hash, key is the ending offset (for back merge lookup)
+	 */
+	struct list_head hash;
+	unsigned long hash_valid_count;
+
+	/*
+	 * expire fifo
+	 */
+	struct list_head fifo;
+	unsigned long expires;
+
+	int is_sync;
+	enum arq_state state; /* debug only */
+};
+
+#define RQ_DATA(rq)	((struct as_rq *) (rq)->elevator_private)
+
+static kmem_cache_t *arq_pool;
+
+/*
+ * IO Context helper functions
+ */
+/* Debug */
+static atomic_t nr_as_io_requests = ATOMIC_INIT(0);
+
+/* Called to deallocate the as_io_context */
+static void free_as_io_context(struct as_io_context *aic)
+{
+	atomic_dec(&nr_as_io_requests);
+	kfree(aic);
+}
+
+/* Called when the task exits */
+static void exit_as_io_context(struct as_io_context *aic)
+{
+	clear_bit(AS_TASK_RUNNING, &aic->state);
+}
+
+static struct as_io_context *alloc_as_io_context(void)
+{
+	struct as_io_context *ret;
+
+	ret = kmalloc(sizeof(*ret), GFP_ATOMIC);
+	if (ret) {
+		atomic_inc(&nr_as_io_requests);
+		ret->dtor = free_as_io_context;
+		ret->exit = exit_as_io_context;
+		ret->state = 1 << AS_TASK_RUNNING;
+		atomic_set(&ret->nr_queued, 0);
+		atomic_set(&ret->nr_dispatched, 0);
+		spin_lock_init(&ret->lock);
+		ret->ttime_total = 0;
+		ret->ttime_samples = 0;
+		ret->ttime_mean = 0;
+		ret->seek_total = 0;
+		ret->seek_samples = 0;
+		ret->seek_mean = 0;
+	}
+
+	return ret;
+}
+
+/*
+ * If the current task has no AS IO context then create one and initialise it.
+ * Then take a ref on the task's io context and return it.
+ */
+static struct io_context *as_get_io_context(void)
+{
+	struct io_context *ioc = get_io_context(GFP_ATOMIC);
+	if (ioc && !ioc->aic) {
+		ioc->aic = alloc_as_io_context();
+		if (!ioc->aic) {
+			put_io_context(ioc);
+			ioc = NULL;
+		}
+	}
+	return ioc;
+}
+
+/*
+ * the back merge hash support functions
+ */
+static const int as_hash_shift = 6;
+#define AS_HASH_BLOCK(sec)	((sec) >> 3)
+#define AS_HASH_FN(sec)		(hash_long(AS_HASH_BLOCK((sec)), as_hash_shift))
+#define AS_HASH_ENTRIES		(1 << as_hash_shift)
+#define rq_hash_key(rq)		((rq)->sector + (rq)->nr_sectors)
+#define list_entry_hash(ptr)	list_entry((ptr), struct as_rq, hash)
+#define ON_HASH(arq)		(arq)->hash_valid_count
+
+#define AS_INVALIDATE_HASH(ad)				\
+	do {						\
+		if (!++(ad)->hash_valid_count)		\
+			(ad)->hash_valid_count = 1;	\
+	} while (0)
+
+static inline void __as_del_arq_hash(struct as_rq *arq)
+{
+	arq->hash_valid_count = 0;
+	list_del_init(&arq->hash);
+}
+
+static inline void as_del_arq_hash(struct as_rq *arq)
+{
+	if (ON_HASH(arq))
+		__as_del_arq_hash(arq);
+}
+
+static void as_remove_merge_hints(request_queue_t *q, struct as_rq *arq)
+{
+	as_del_arq_hash(arq);
+
+	if (q->last_merge == &arq->request->queuelist)
+		q->last_merge = NULL;
+}
+
+static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq)
+{
+	struct request *rq = arq->request;
+
+	BUG_ON(ON_HASH(arq));
+
+	arq->hash_valid_count = ad->hash_valid_count;
+	list_add(&arq->hash, &ad->hash[AS_HASH_FN(rq_hash_key(rq))]);
+}
+
+/*
+ * move hot entry to front of chain
+ */
+static inline void as_hot_arq_hash(struct as_data *ad, struct as_rq *arq)
+{
+	struct request *rq = arq->request;
+	struct list_head *head = &ad->hash[AS_HASH_FN(rq_hash_key(rq))];
+
+	if (!ON_HASH(arq)) {
+		WARN_ON(1);
+		return;
+	}
+
+	if (arq->hash.prev != head) {
+		list_del(&arq->hash);
+		list_add(&arq->hash, head);
+	}
+}
+
+static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset)
+{
+	struct list_head *hash_list = &ad->hash[AS_HASH_FN(offset)];
+	struct list_head *entry, *next = hash_list->next;
+
+	while ((entry = next) != hash_list) {
+		struct as_rq *arq = list_entry_hash(entry);
+		struct request *__rq = arq->request;
+
+		next = entry->next;
+
+		BUG_ON(!ON_HASH(arq));
+
+		if (!rq_mergeable(__rq)
+		    || arq->hash_valid_count != ad->hash_valid_count) {
+			__as_del_arq_hash(arq);
+			continue;
+		}
+
+		if (rq_hash_key(__rq) == offset)
+			return __rq;
+	}
+
+	return NULL;
+}
+
+/*
+ * rb tree support functions
+ */
+#define RB_NONE		(2)
+#define RB_EMPTY(root)	((root)->rb_node == NULL)
+#define ON_RB(node)	((node)->rb_color != RB_NONE)
+#define RB_CLEAR(node)	((node)->rb_color = RB_NONE)
+#define rb_entry_arq(node)	rb_entry((node), struct as_rq, rb_node)
+#define ARQ_RB_ROOT(ad, arq)	(&(ad)->sort_list[(arq)->is_sync])
+#define rq_rb_key(rq)		(rq)->sector
+
+/*
+ * as_find_first_arq finds the first (lowest sector numbered) request
+ * for the specified data_dir. Used to sweep back to the start of the disk
+ * (1-way elevator) after we process the last (highest sector) request.
+ */
+static struct as_rq *as_find_first_arq(struct as_data *ad, int data_dir)
+{
+	struct rb_node *n = ad->sort_list[data_dir].rb_node;
+
+	if (n == NULL)
+		return NULL;
+
+	for (;;) {
+		if (n->rb_left == NULL)
+			return rb_entry_arq(n);
+
+		n = n->rb_left;
+	}
+}
+
+static struct as_rq *__as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+{
+	struct rb_node **p = &ARQ_RB_ROOT(ad, arq)->rb_node;
+	struct rb_node *parent = NULL;
+	struct as_rq *__arq;
+
+	while (*p) {
+		parent = *p;
+		__arq = rb_entry_arq(parent);
+
+		if (arq->rb_key < __arq->rb_key)
+			p = &(*p)->rb_left;
+		else if (arq->rb_key > __arq->rb_key)
+			p = &(*p)->rb_right;
+		else
+			return __arq;
+	}
+
+	rb_link_node(&arq->rb_node, parent, p);
+	return 0;
+}
+
+static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq);
+/*
+ * Add the request to the rb tree if it is unique.  If there is an alias (an
+ * existing request against the same sector), which can happen when using
+ * direct IO, then move the alias to the dispatch list and then add the
+ * request.
+ */
+static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+{
+	struct as_rq *alias;
+	struct request *rq = arq->request;
+
+	arq->rb_key = rq_rb_key(rq);
+
+	/* This can be caused by direct IO */
+	while ((alias = __as_add_arq_rb(ad, arq)))
+		as_move_to_dispatch(ad, alias);
+
+	rb_insert_color(&arq->rb_node, ARQ_RB_ROOT(ad, arq));
+}
+
+static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq)
+{
+	if (!ON_RB(&arq->rb_node)) {
+		WARN_ON(1);
+		return;
+	}
+
+	rb_erase(&arq->rb_node, ARQ_RB_ROOT(ad, arq));
+	RB_CLEAR(&arq->rb_node);
+}
+
+static struct request *
+as_find_arq_rb(struct as_data *ad, sector_t sector, int data_dir)
+{
+	struct rb_node *n = ad->sort_list[data_dir].rb_node;
+	struct as_rq *arq;
+
+	while (n) {
+		arq = rb_entry_arq(n);
+
+		if (sector < arq->rb_key)
+			n = n->rb_left;
+		else if (sector > arq->rb_key)
+			n = n->rb_right;
+		else
+			return arq->request;
+	}
+
+	return NULL;
+}
+
+/*
+ * IO Scheduler proper
+ */
+
+#define MAXBACK (1024 * 1024)	/*
+				 * Maximum distance the disk will go backward
+				 * for a request.
+				 */
+
+/*
+ * as_choose_req selects the preferred one of two requests of the same data_dir
+ * ignoring time - eg. timeouts, which is the job of as_dispatch_request
+ */
+static struct as_rq *
+as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2)
+{
+	int data_dir;
+	sector_t last, s1, s2, d1, d2;
+	int r1_wrap=0, r2_wrap=0;	/* requests are behind the disk head */
+	const sector_t maxback = MAXBACK;
+
+	if (arq1 == NULL || arq1 == arq2)
+		return arq2;
+	if (arq2 == NULL)
+		return arq1;
+
+	data_dir = arq1->is_sync;
+
+	last = ad->last_sector[data_dir];
+	s1 = arq1->request->sector;
+	s2 = arq2->request->sector;
+
+	BUG_ON(data_dir != arq2->is_sync);
+
+	/*
+	 * Strict one way elevator _except_ in the case where we allow
+	 * short backward seeks which are biased as twice the cost of a
+	 * similar forward seek.
+	 */
+	if (s1 >= last)
+		d1 = s1 - last;
+	else if (s1+maxback >= last)
+		d1 = (last - s1)*2;
+	else {
+		r1_wrap = 1;
+		d1 = 0; /* shut up, gcc */
+	}
+
+	if (s2 >= last)
+		d2 = s2 - last;
+	else if (s2+maxback >= last)
+		d2 = (last - s2)*2;
+	else {
+		r2_wrap = 1;
+		d2 = 0;
+	}
+
+	/* Found required data */
+	if (!r1_wrap && r2_wrap)
+		return arq1;
+	else if (!r2_wrap && r1_wrap)
+		return arq2;
+	else if (r1_wrap && r2_wrap) {
+		/* both behind the head */
+		if (s1 <= s2)
+			return arq1;
+		else
+			return arq2;
+	}
+
+	/* Both requests in front of the head */
+	if (d1 < d2)
+		return arq1;
+	else if (d2 < d1)
+		return arq2;
+	else {
+		if (s1 >= s2)
+			return arq1;
+		else
+			return arq2;
+	}
+}
+
+/*
+ * as_find_next_arq finds the next request after @prev in elevator order.
+ * this with as_choose_req form the basis for how the scheduler chooses
+ * what request to process next. Anticipation works on top of this.
+ */
+static struct as_rq *as_find_next_arq(struct as_data *ad, struct as_rq *last)
+{
+	const int data_dir = last->is_sync;
+	struct as_rq *ret;
+	struct rb_node *rbnext = rb_next(&last->rb_node);
+	struct rb_node *rbprev = rb_prev(&last->rb_node);
+	struct as_rq *arq_next, *arq_prev;
+
+	BUG_ON(!ON_RB(&last->rb_node));
+
+	if (rbprev)
+		arq_prev = rb_entry_arq(rbprev);
+	else
+		arq_prev = NULL;
+
+	if (rbnext)
+		arq_next = rb_entry_arq(rbnext);
+	else {
+		arq_next = as_find_first_arq(ad, data_dir);
+		if (arq_next == last)
+			arq_next = NULL;
+	}
+
+	ret = as_choose_req(ad,	arq_next, arq_prev);
+
+	return ret;
+}
+
+/*
+ * anticipatory scheduling functions follow
+ */
+
+/*
+ * as_antic_expired tells us when we have anticipated too long.
+ * The funny "absolute difference" math on the elapsed time is to handle
+ * jiffy wraps, and disks which have been idle for 0x80000000 jiffies.
+ */
+static int as_antic_expired(struct as_data *ad)
+{
+	long delta_jif;
+
+	delta_jif = jiffies - ad->antic_start;
+	if (unlikely(delta_jif < 0))
+		delta_jif = -delta_jif;
+	if (delta_jif < ad->antic_expire)
+		return 0;
+
+	return 1;
+}
+
+/*
+ * as_antic_waitnext starts anticipating that a nice request will soon be
+ * submitted. See also as_antic_waitreq
+ */
+static void as_antic_waitnext(struct as_data *ad)
+{
+	unsigned long timeout;
+
+	BUG_ON(ad->antic_status != ANTIC_OFF
+			&& ad->antic_status != ANTIC_WAIT_REQ);
+
+	timeout = ad->antic_start + ad->antic_expire;
+
+	mod_timer(&ad->antic_timer, timeout);
+
+	ad->antic_status = ANTIC_WAIT_NEXT;
+}
+
+/*
+ * as_antic_waitreq starts anticipating. We don't start timing the anticipation
+ * until the request that we're anticipating on has finished. This means we
+ * are timing from when the candidate process wakes up hopefully.
+ */
+static void as_antic_waitreq(struct as_data *ad)
+{
+	BUG_ON(ad->antic_status == ANTIC_FINISHED);
+	if (ad->antic_status == ANTIC_OFF) {
+		if (!ad->io_context || ad->ioc_finished)
+			as_antic_waitnext(ad);
+		else
+			ad->antic_status = ANTIC_WAIT_REQ;
+	}
+}
+
+/*
+ * This is called directly by the functions in this file to stop anticipation.
+ * We kill the timer and schedule a call to the request_fn asap.
+ */
+static void as_antic_stop(struct as_data *ad)
+{
+	int status = ad->antic_status;
+
+	if (status == ANTIC_WAIT_REQ || status == ANTIC_WAIT_NEXT) {
+		if (status == ANTIC_WAIT_NEXT)
+			del_timer(&ad->antic_timer);
+		ad->antic_status = ANTIC_FINISHED;
+		/* see as_work_handler */
+		kblockd_schedule_work(&ad->antic_work);
+	}
+}
+
+/*
+ * as_antic_timeout is the timer function set by as_antic_waitnext.
+ */
+static void as_antic_timeout(unsigned long data)
+{
+	struct request_queue *q = (struct request_queue *)data;
+	struct as_data *ad = q->elevator.elevator_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	if (ad->antic_status == ANTIC_WAIT_REQ
+			|| ad->antic_status == ANTIC_WAIT_NEXT) {
+		ad->antic_status = ANTIC_FINISHED;
+		kblockd_schedule_work(&ad->antic_work);
+	}
+	spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
+/*
+ * as_close_req decides if one request is considered "close" to the
+ * previous one issued.
+ */
+static int as_close_req(struct as_data *ad, struct as_rq *arq)
+{
+	unsigned long delay;	/* milliseconds */
+	sector_t last = ad->last_sector[ad->batch_data_dir];
+	sector_t next = arq->request->sector;
+	sector_t delta;	/* acceptable close offset (in sectors) */
+
+	if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
+		delay = 0;
+	else
+		delay = ((jiffies - ad->antic_start) * 1000) / HZ;
+
+	if (delay <= 1)
+		delta = 64;
+	else if (delay <= 20 && delay <= ad->antic_expire)
+		delta = 64 << (delay-1);
+	else
+		return 1;
+
+	return (last - (delta>>1) <= next) && (next <= last + delta);
+}
+
+/*
+ * as_can_break_anticipation returns true if we have been anticipating this
+ * request.
+ *
+ * It also returns true if the process against which we are anticipating
+ * submits a write - that's presumably an fsync, O_SYNC write, etc. We want to
+ * dispatch it ASAP, because we know that application will not be submitting
+ * any new reads.
+ *
+ * If the task which has submitted the request has exitted, break anticipation.
+ *
+ * If this task has queued some other IO, do not enter enticipation.
+ */
+static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
+{
+	struct io_context *ioc;
+	struct as_io_context *aic;
+
+	if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, arq)) {
+		/* close request */
+		return 1;
+	}
+
+	if (ad->ioc_finished && as_antic_expired(ad)) {
+		/*
+		 * In this situation status should really be FINISHED,
+		 * however the timer hasn't had the chance to run yet.
+		 */
+		return 1;
+	}
+
+	ioc = ad->io_context;
+	BUG_ON(!ioc);
+
+	if (arq && ioc == arq->io_context) {
+		/* request from same process */
+		return 1;
+	}
+
+	aic = ioc->aic;
+	if (!aic)
+		return 0;
+
+	if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+		/* process anticipated on has exitted */
+		return 1;
+	}
+
+	if (atomic_read(&aic->nr_queued) > 0) {
+		/* process has more requests queued */
+		return 1;
+	}
+
+	if (atomic_read(&aic->nr_dispatched) > 0) {
+		/* process has more requests dispatched */
+		return 1;
+	}
+
+	if (aic->ttime_mean > ad->antic_expire) {
+		/* the process thinks too much between requests */
+		return 1;
+	}
+
+	if (arq && aic->seek_samples) {
+		sector_t s;
+		if (ad->last_sector[REQ_SYNC] < arq->request->sector)
+			s = arq->request->sector - ad->last_sector[REQ_SYNC];
+		else
+			s = ad->last_sector[REQ_SYNC] - arq->request->sector;
+
+		if (aic->seek_mean > (s>>1)) {
+			/* this request is better than what we're expecting */
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * as_can_anticipate indicates weather we should either run arq
+ * or keep anticipating a better request.
+ */
+static int as_can_anticipate(struct as_data *ad, struct as_rq *arq)
+{
+	if (!ad->io_context)
+		/*
+		 * Last request submitted was a write
+		 */
+		return 0;
+
+	if (ad->antic_status == ANTIC_FINISHED)
+		/*
+		 * Don't restart if we have just finished. Run the next request
+		 */
+		return 0;
+
+	if (as_can_break_anticipation(ad, arq))
+		/*
+		 * This request is a good candidate. Don't keep anticipating,
+		 * run it.
+		 */
+		return 0;
+
+	/*
+	 * OK from here, we haven't finished, and don't have a decent request!
+	 * Status is either ANTIC_OFF so start waiting,
+	 * ANTIC_WAIT_REQ so continue waiting for request to finish
+	 * or ANTIC_WAIT_NEXT so continue waiting for an acceptable request.
+	 *
+	 */
+
+	return 1;
+}
+
+/*
+ * as_update_iohist keeps a decaying histogram of IO thinktimes, and
+ * updates @aic->ttime_mean based on that. It is called when a new
+ * request is queued.
+ */
+static void as_update_iohist(struct as_io_context *aic, struct request *rq)
+{
+	struct as_rq *arq = RQ_DATA(rq);
+	int data_dir = arq->is_sync;
+	unsigned long thinktime;
+	sector_t seek_dist;
+
+	if (aic == NULL)
+		return;
+
+	if (data_dir == REQ_SYNC) {
+		spin_lock(&aic->lock);
+
+		if (test_bit(AS_TASK_IORUNNING, &aic->state)
+				&& !atomic_read(&aic->nr_queued)
+				&& !atomic_read(&aic->nr_dispatched)) {
+			/* Calculate read -> read thinktime */
+			thinktime = jiffies - aic->last_end_request;
+			thinktime = min(thinktime, MAX_THINKTIME-1);
+			/* fixed point: 1.0 == 1<<8 */
+			aic->ttime_samples += 256;
+			aic->ttime_total += 256*thinktime;
+			if (aic->ttime_samples)
+				/* fixed point factor is cancelled here */
+				aic->ttime_mean = (aic->ttime_total + 128)
+							/ aic->ttime_samples;
+			aic->ttime_samples = (aic->ttime_samples>>1)
+						+ (aic->ttime_samples>>2);
+			aic->ttime_total = (aic->ttime_total>>1)
+						+ (aic->ttime_total>>2);
+		}
+
+		/* Calculate read -> read seek distance */
+		if (!aic->seek_samples)
+			seek_dist = 0;
+		else if (aic->last_request_pos < rq->sector)
+			seek_dist = rq->sector - aic->last_request_pos;
+		else
+			seek_dist = aic->last_request_pos - rq->sector;
+
+		aic->last_request_pos = rq->sector + rq->nr_sectors;
+
+		/*
+		 * Don't allow the seek distance to get too large from the
+		 * odd fragment, pagein, etc
+		 */
+		if (aic->seek_samples < 400) /* second&third seek */
+			seek_dist = min(seek_dist, (aic->seek_mean * 4)
+							+ 2*1024*1024);
+		else
+			seek_dist = min(seek_dist, (aic->seek_mean * 4)
+							+ 2*1024*64);
+
+		aic->seek_samples += 256;
+		aic->seek_total += 256*seek_dist;
+		if (aic->seek_samples) {
+			aic->seek_mean = aic->seek_total + 128;
+			do_div(aic->seek_mean, aic->seek_samples);
+		}
+		aic->seek_samples = (aic->seek_samples>>1)
+					+ (aic->seek_samples>>2);
+		aic->seek_total = (aic->seek_total>>1)
+					+ (aic->seek_total>>2);
+
+		spin_unlock(&aic->lock);
+	}
+}
+
+/*
+ * as_update_arq must be called whenever a request (arq) is added to
+ * the sort_list. This function keeps caches up to date, and checks if the
+ * request might be one we are "anticipating"
+ */
+static void as_update_arq(struct as_data *ad, struct as_rq *arq)
+{
+	const int data_dir = arq->is_sync;
+
+	/* keep the next_arq cache up to date */
+	ad->next_arq[data_dir] = as_choose_req(ad, arq, ad->next_arq[data_dir]);
+
+	/*
+	 * have we been anticipating this request?
+	 * or does it come from the same process as the one we are anticipating
+	 * for?
+	 */
+	if (ad->antic_status == ANTIC_WAIT_REQ
+			|| ad->antic_status == ANTIC_WAIT_NEXT) {
+		if (as_can_break_anticipation(ad, arq))
+			as_antic_stop(ad);
+	}
+}
+
+/*
+ * Gathers timings and resizes the write batch automatically
+ */
+void update_write_batch(struct as_data *ad)
+{
+	unsigned long batch = ad->batch_expire[REQ_ASYNC];
+	long write_time;
+
+	write_time = (jiffies - ad->current_batch_expires) + batch;
+	if (write_time < 0)
+		write_time = 0;
+
+	if (write_time > batch && !ad->write_batch_idled) {
+		if (write_time > batch * 3)
+			ad->write_batch_count /= 2;
+		else
+			ad->write_batch_count--;
+	} else if (write_time < batch && ad->current_write_count == 0) {
+		if (batch > write_time * 3)
+			ad->write_batch_count *= 2;
+		else
+			ad->write_batch_count++;
+	}
+
+	if (ad->write_batch_count < 1)
+		ad->write_batch_count = 1;
+}
+
+/*
+ * as_completed_request is to be called when a request has completed and
+ * returned something to the requesting process, be it an error or data.
+ */
+static void as_completed_request(request_queue_t *q, struct request *rq)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct as_rq *arq = RQ_DATA(rq);
+	struct as_io_context *aic;
+
+	if (unlikely(!blk_fs_request(rq)))
+		return;
+
+	WARN_ON(blk_fs_request(rq) && arq->state == AS_RQ_NEW);
+
+	if (arq->state != AS_RQ_DISPATCHED)
+		return;
+
+	if (ad->changed_batch && ad->nr_dispatched == 1) {
+		kblockd_schedule_work(&ad->antic_work);
+		ad->changed_batch = 2;
+	}
+	ad->nr_dispatched--;
+
+	/*
+	 * Start counting the batch from when a request of that direction is
+	 * actually serviced. This should help devices with big TCQ windows
+	 * and writeback caches
+	 */
+	if (ad->batch_data_dir == REQ_SYNC && ad->changed_batch
+			&& ad->batch_data_dir == arq->is_sync) {
+		update_write_batch(ad);
+		ad->current_batch_expires = jiffies +
+				ad->batch_expire[REQ_SYNC];
+		ad->changed_batch = 0;
+	}
+
+	if (!arq->io_context)
+		return;
+
+	if (ad->io_context == arq->io_context) {
+		ad->antic_start = jiffies;
+		ad->ioc_finished = 1;
+		if (ad->antic_status == ANTIC_WAIT_REQ) {
+			/*
+			 * We were waiting on this request, now anticipate
+			 * the next one
+			 */
+			as_antic_waitnext(ad);
+		}
+	}
+
+	aic = arq->io_context->aic;
+	if (!aic)
+		return;
+
+	spin_lock(&aic->lock);
+	if (arq->is_sync == REQ_SYNC) {
+		set_bit(AS_TASK_IORUNNING, &aic->state);
+		aic->last_end_request = jiffies;
+	}
+	spin_unlock(&aic->lock);
+
+	put_io_context(arq->io_context);
+}
+
+/*
+ * as_remove_queued_request removes a request from the pre dispatch queue
+ * without updating refcounts. It is expected the caller will drop the
+ * reference unless it replaces the request at somepart of the elevator
+ * (ie. the dispatch queue)
+ */
+static void as_remove_queued_request(request_queue_t *q, struct request *rq)
+{
+	struct as_rq *arq = RQ_DATA(rq);
+	const int data_dir = arq->is_sync;
+	struct as_data *ad = q->elevator.elevator_data;
+
+	WARN_ON(arq->state != AS_RQ_QUEUED);
+
+	if (arq->io_context && arq->io_context->aic) {
+		BUG_ON(!atomic_read(&arq->io_context->aic->nr_queued));
+		atomic_dec(&arq->io_context->aic->nr_queued);
+	}
+
+	/*
+	 * Update the "next_arq" cache if we are about to remove its
+	 * entry
+	 */
+	if (ad->next_arq[data_dir] == arq)
+		ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
+
+	list_del_init(&arq->fifo);
+	as_remove_merge_hints(q, arq);
+	as_del_arq_rb(ad, arq);
+}
+
+/*
+ * as_remove_dispatched_request is called to remove a request which has gone
+ * to the dispatch list.
+ */
+static void as_remove_dispatched_request(request_queue_t *q, struct request *rq)
+{
+	struct as_rq *arq = RQ_DATA(rq);
+	struct as_io_context *aic;
+
+	if (!arq) {
+		WARN_ON(1);
+		return;
+	}
+
+	WARN_ON(arq->state != AS_RQ_DISPATCHED);
+	WARN_ON(ON_RB(&arq->rb_node));
+	if (arq->io_context && arq->io_context->aic) {
+		aic = arq->io_context->aic;
+		if (aic) {
+			WARN_ON(!atomic_read(&aic->nr_dispatched));
+			atomic_dec(&aic->nr_dispatched);
+		}
+	}
+}
+/*
+ * as_remove_request is called when a driver has finished with a request.
+ * This should be only called for dispatched requests, but for some reason
+ * a POWER4 box running hwscan it does not.
+ */
+static void as_remove_request(request_queue_t *q, struct request *rq)
+{
+	struct as_rq *arq = RQ_DATA(rq);
+
+	if (unlikely(!blk_fs_request(rq)))
+		return;
+
+	if (!arq) {
+		WARN_ON(1);
+		return;
+	}
+
+	if (ON_RB(&arq->rb_node))
+		as_remove_queued_request(q, rq);
+	else
+		as_remove_dispatched_request(q, rq);
+}
+
+/*
+ * as_fifo_expired returns 0 if there are no expired reads on the fifo,
+ * 1 otherwise.  It is ratelimited so that we only perform the check once per
+ * `fifo_expire' interval.  Otherwise a large number of expired requests
+ * would create a hopeless seekstorm.
+ *
+ * See as_antic_expired comment.
+ */
+static int as_fifo_expired(struct as_data *ad, int adir)
+{
+	struct as_rq *arq;
+	long delta_jif;
+
+	delta_jif = jiffies - ad->last_check_fifo[adir];
+	if (unlikely(delta_jif < 0))
+		delta_jif = -delta_jif;
+	if (delta_jif < ad->fifo_expire[adir])
+		return 0;
+
+	ad->last_check_fifo[adir] = jiffies;
+
+	if (list_empty(&ad->fifo_list[adir]))
+		return 0;
+
+	arq = list_entry_fifo(ad->fifo_list[adir].next);
+
+	return time_after(jiffies, arq->expires);
+}
+
+/*
+ * as_batch_expired returns true if the current batch has expired. A batch
+ * is a set of reads or a set of writes.
+ */
+static inline int as_batch_expired(struct as_data *ad)
+{
+	if (ad->changed_batch)
+		return 0;
+
+	if (ad->batch_data_dir == REQ_SYNC)
+		/* TODO! add a check so a complete fifo gets written? */
+		return time_after(jiffies, ad->current_batch_expires);
+
+	return time_after(jiffies, ad->current_batch_expires)
+		|| ad->current_write_count == 0;
+}
+
+/*
+ * move an entry to dispatch queue
+ */
+static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
+{
+	const int data_dir = arq->is_sync;
+
+	BUG_ON(!ON_RB(&arq->rb_node));
+
+	as_antic_stop(ad);
+	ad->antic_status = ANTIC_OFF;
+
+	/*
+	 * This has to be set in order to be correctly updated by
+	 * as_find_next_arq
+	 */
+	ad->last_sector[data_dir] = arq->request->sector
+					+ arq->request->nr_sectors;
+
+	ad->nr_dispatched++;
+
+	if (data_dir == REQ_SYNC) {
+		/* In case we have to anticipate after this */
+		copy_io_context(&ad->io_context, &arq->io_context);
+	} else {
+		if (ad->io_context) {
+			put_io_context(ad->io_context);
+			ad->io_context = NULL;
+		}
+
+		if (ad->current_write_count != 0)
+			ad->current_write_count--;
+	}
+	ad->ioc_finished = 0;
+
+	ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
+
+	/*
+	 * take it off the sort and fifo list, add to dispatch queue
+	 */
+	as_remove_queued_request(ad->q, arq->request);
+	list_add_tail(&arq->request->queuelist, ad->dispatch);
+	if (arq->io_context && arq->io_context->aic)
+		atomic_inc(&arq->io_context->aic->nr_dispatched);
+
+	WARN_ON(arq->state != AS_RQ_QUEUED);
+	arq->state = AS_RQ_DISPATCHED;
+}
+
+/*
+ * as_dispatch_request selects the best request according to
+ * read/write expire, batch expire, etc, and moves it to the dispatch
+ * queue. Returns 1 if a request was found, 0 otherwise.
+ */
+static int as_dispatch_request(struct as_data *ad)
+{
+	struct as_rq *arq;
+	const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]);
+	const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]);
+
+	/* Signal that the write batch was uncontended, so we can't time it */
+	if (ad->batch_data_dir == REQ_ASYNC && !reads) {
+		if (ad->current_write_count == 0 || !writes)
+			ad->write_batch_idled = 1;
+	}
+
+	if (!(reads || writes)
+		|| ad->antic_status == ANTIC_WAIT_REQ
+		|| ad->antic_status == ANTIC_WAIT_NEXT
+		|| ad->changed_batch == 1)
+		return 0;
+
+	if (!(reads && writes && as_batch_expired(ad)) ) {
+		/*
+		 * batch is still running or no reads or no writes
+		 */
+		arq = ad->next_arq[ad->batch_data_dir];
+
+		if (ad->batch_data_dir == REQ_SYNC && ad->antic_expire) {
+			if (as_fifo_expired(ad, REQ_SYNC))
+				goto fifo_expired;
+
+			if (as_can_anticipate(ad, arq)) {
+				as_antic_waitreq(ad);
+				return 0;
+			}
+		}
+
+		if (arq) {
+			/* we have a "next request" */
+			if (reads && !writes)
+				ad->current_batch_expires =
+					jiffies + ad->batch_expire[REQ_SYNC];
+			goto dispatch_request;
+		}
+	}
+
+	/*
+	 * at this point we are not running a batch. select the appropriate
+	 * data direction (read / write)
+	 */
+
+	if (reads) {
+		BUG_ON(RB_EMPTY(&ad->sort_list[REQ_SYNC]));
+
+		if (writes && ad->batch_data_dir == REQ_SYNC)
+			/*
+			 * Last batch was a read, switch to writes
+			 */
+			goto dispatch_writes;
+
+ 		if (ad->batch_data_dir == REQ_ASYNC)
+ 			ad->changed_batch = 1;
+		ad->batch_data_dir = REQ_SYNC;
+		arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
+		ad->last_check_fifo[ad->batch_data_dir] = jiffies;
+		goto dispatch_request;
+	}
+
+	/*
+	 * the last batch was a read
+	 */
+
+	if (writes) {
+dispatch_writes:
+		BUG_ON(RB_EMPTY(&ad->sort_list[REQ_ASYNC]));
+
+ 		if (ad->batch_data_dir == REQ_SYNC)
+ 			ad->changed_batch = 1;
+		ad->batch_data_dir = REQ_ASYNC;
+		ad->current_write_count = ad->write_batch_count;
+		ad->write_batch_idled = 0;
+		arq = ad->next_arq[ad->batch_data_dir];
+		goto dispatch_request;
+	}
+
+	BUG();
+	return 0;
+
+dispatch_request:
+	/*
+	 * If a request has expired, service it.
+	 */
+
+	if (as_fifo_expired(ad, ad->batch_data_dir)) {
+fifo_expired:
+		arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
+		BUG_ON(arq == NULL);
+	}
+
+	if (ad->changed_batch) {
+		if (ad->changed_batch == 1 && ad->nr_dispatched)
+			return 0;
+		if (ad->batch_data_dir == REQ_ASYNC) {
+			ad->current_batch_expires = jiffies +
+					ad->batch_expire[REQ_ASYNC];
+			ad->changed_batch = 0;
+		} else
+			ad->changed_batch = 2;
+		arq->request->flags |= REQ_HARDBARRIER;
+	}
+
+	/*
+	 * arq is the selected appropriate request.
+	 */
+	as_move_to_dispatch(ad, arq);
+
+	return 1;
+}
+
+static struct request *as_next_request(request_queue_t *q)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct request *rq = NULL;
+
+	/*
+	 * if there are still requests on the dispatch queue, grab the first
+	 */
+	if (!list_empty(ad->dispatch) || as_dispatch_request(ad))
+		rq = list_entry_rq(ad->dispatch->next);
+
+	return rq;
+}
+
+/*
+ * add arq to rbtree and fifo
+ */
+static void as_add_request(struct as_data *ad, struct as_rq *arq)
+{
+	int data_dir;
+
+	if (rq_data_dir(arq->request) == READ
+			|| current->flags&PF_SYNCWRITE)
+		arq->is_sync = 1;
+	else
+		arq->is_sync = 0;
+	data_dir = arq->is_sync;
+
+	arq->io_context = as_get_io_context();
+
+	if (arq->io_context) {
+		atomic_inc(&arq->io_context->aic->nr_queued);
+		as_update_iohist(arq->io_context->aic, arq->request);
+	}
+
+	as_add_arq_rb(ad, arq);
+
+	/*
+	 * set expire time (only used for reads) and add to fifo list
+	 */
+	arq->expires = jiffies + ad->fifo_expire[data_dir];
+	list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
+	arq->state = AS_RQ_QUEUED;
+	as_update_arq(ad, arq); /* keep state machine up to date */
+}
+
+static void
+as_insert_request(request_queue_t *q, struct request *rq,
+			struct list_head *insert_here)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct as_rq *arq = RQ_DATA(rq);
+
+	if (unlikely(rq->flags & REQ_HARDBARRIER)) {
+		AS_INVALIDATE_HASH(ad);
+		q->last_merge = NULL;
+
+		while (ad->next_arq[REQ_SYNC])
+			as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
+
+		while (ad->next_arq[REQ_ASYNC])
+			as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
+	}
+
+	if (unlikely(!blk_fs_request(rq))) {
+		if (!insert_here)
+			insert_here = ad->dispatch->prev;
+
+		list_add(&rq->queuelist, insert_here);
+
+		/* Stop anticipating - let this request get through */
+		if (!list_empty(ad->dispatch)
+			&& (ad->antic_status == ANTIC_WAIT_REQ
+				|| ad->antic_status == ANTIC_WAIT_NEXT))
+			as_antic_stop(ad);
+
+		return;
+	}
+
+	if (rq_mergeable(rq)) {
+		as_add_arq_hash(ad, arq);
+
+		if (!q->last_merge)
+			q->last_merge = &rq->queuelist;
+	}
+
+	as_add_request(ad, arq);
+}
+
+/*
+ * as_queue_empty tells us if there are requests left in the device. It may
+ * not be the case that a driver can get the next request even if the queue
+ * is not empty - it is used in the block layer to check for plugging and
+ * merging opportunities
+ */
+static int as_queue_empty(request_queue_t *q)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+
+	if (!list_empty(&ad->fifo_list[REQ_ASYNC])
+		|| !list_empty(&ad->fifo_list[REQ_SYNC])
+		|| !list_empty(ad->dispatch))
+			return 0;
+
+	return 1;
+}
+
+static struct request *
+as_former_request(request_queue_t *q, struct request *rq)
+{
+	struct as_rq *arq = RQ_DATA(rq);
+	struct rb_node *rbprev = rb_prev(&arq->rb_node);
+	struct request *ret = NULL;
+
+	if (rbprev)
+		ret = rb_entry_arq(rbprev)->request;
+
+	return ret;
+}
+
+static struct request *
+as_latter_request(request_queue_t *q, struct request *rq)
+{
+	struct as_rq *arq = RQ_DATA(rq);
+	struct rb_node *rbnext = rb_next(&arq->rb_node);
+	struct request *ret = NULL;
+
+	if (rbnext)
+		ret = rb_entry_arq(rbnext)->request;
+
+	return ret;
+}
+
+static int
+as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	sector_t rb_key = bio->bi_sector + bio_sectors(bio);
+	struct request *__rq;
+	int ret;
+
+	/*
+	 * try last_merge to avoid going to hash
+	 */
+	ret = elv_try_last_merge(q, bio);
+	if (ret != ELEVATOR_NO_MERGE) {
+		__rq = list_entry_rq(q->last_merge);
+		goto out_insert;
+	}
+
+	/*
+	 * see if the merge hash can satisfy a back merge
+	 */
+	__rq = as_find_arq_hash(ad, bio->bi_sector);
+	if (__rq) {
+		BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
+
+		if (elv_rq_merge_ok(__rq, bio)) {
+			ret = ELEVATOR_BACK_MERGE;
+			goto out;
+		}
+	}
+
+	/*
+	 * check for front merge
+	 */
+	__rq = as_find_arq_rb(ad, rb_key, bio_data_dir(bio));
+	if (__rq) {
+		BUG_ON(rb_key != rq_rb_key(__rq));
+
+		if (elv_rq_merge_ok(__rq, bio)) {
+			ret = ELEVATOR_FRONT_MERGE;
+			goto out;
+		}
+	}
+
+	return ELEVATOR_NO_MERGE;
+out:
+	q->last_merge = &__rq->queuelist;
+out_insert:
+	if (ret)
+		as_hot_arq_hash(ad, RQ_DATA(__rq));
+	*insert = &__rq->queuelist;
+	return ret;
+}
+
+static void as_merged_request(request_queue_t *q, struct request *req)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct as_rq *arq = RQ_DATA(req);
+
+	/*
+	 * hash always needs to be repositioned, key is end sector
+	 */
+	as_del_arq_hash(arq);
+	as_add_arq_hash(ad, arq);
+
+	/*
+	 * if the merge was a front merge, we need to reposition request
+	 */
+	if (rq_rb_key(req) != arq->rb_key) {
+		as_del_arq_rb(ad, arq);
+		as_add_arq_rb(ad, arq);
+		/*
+		 * Note! At this stage of this and the next function, our next
+		 * request may not be optimal - eg the request may have "grown"
+		 * behind the disk head. We currently don't bother adjusting.
+		 */
+	}
+
+	q->last_merge = &req->queuelist;
+}
+
+static void
+as_merged_requests(request_queue_t *q, struct request *req,
+			 struct request *next)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct as_rq *arq = RQ_DATA(req);
+	struct as_rq *anext = RQ_DATA(next);
+
+	BUG_ON(!arq);
+	BUG_ON(!anext);
+
+	/*
+	 * reposition arq (this is the merged request) in hash, and in rbtree
+	 * in case of a front merge
+	 */
+	as_del_arq_hash(arq);
+	as_add_arq_hash(ad, arq);
+
+	if (rq_rb_key(req) != arq->rb_key) {
+		as_del_arq_rb(ad, arq);
+		as_add_arq_rb(ad, arq);
+	}
+
+	/*
+	 * if anext expires before arq, assign its expire time to arq
+	 * and move into anext position (anext will be deleted) in fifo
+	 */
+	if (!list_empty(&arq->fifo) && !list_empty(&anext->fifo)) {
+		if (time_before(anext->expires, arq->expires)) {
+			list_move(&arq->fifo, &anext->fifo);
+			arq->expires = anext->expires;
+			/*
+			 * Don't copy here but swap, because when anext is
+			 * removed below, it must contain the unused context
+			 */
+			swap_io_context(&arq->io_context, &anext->io_context);
+		}
+	}
+
+	/*
+	 * kill knowledge of next, this one is a goner
+	 */
+	as_remove_queued_request(q, next);
+	put_io_context(anext->io_context);
+}
+
+/*
+ * This is executed in a "deferred" process context, by kblockd. It calls the
+ * driver's request_fn so the driver can submit that request.
+ *
+ * IMPORTANT! This guy will reenter the elevator, so set up all queue global
+ * state before calling, and don't rely on any state over calls.
+ *
+ * FIXME! dispatch queue is not a queue at all!
+ */
+static void as_work_handler(void *data)
+{
+	struct request_queue *q = data;
+	unsigned long flags;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	if (as_next_request(q))
+		q->request_fn(q);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
+static void as_put_request(request_queue_t *q, struct request *rq)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct as_rq *arq = RQ_DATA(rq);
+
+	if (!arq) {
+		WARN_ON(1);
+		return;
+	}
+
+	mempool_free(arq, ad->arq_pool);
+	rq->elevator_private = NULL;
+}
+
+static int as_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
+{
+	struct as_data *ad = q->elevator.elevator_data;
+	struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
+
+	if (arq) {
+		RB_CLEAR(&arq->rb_node);
+		arq->request = rq;
+		arq->state = AS_RQ_NEW;
+		arq->io_context = NULL;
+		INIT_LIST_HEAD(&arq->hash);
+		arq->hash_valid_count = 0;
+		INIT_LIST_HEAD(&arq->fifo);
+		rq->elevator_private = arq;
+		return 0;
+	}
+
+	return 1;
+}
+
+static int as_may_queue(request_queue_t *q, int rw)
+{
+	int ret = 0;
+	struct as_data *ad = q->elevator.elevator_data;
+	struct io_context *ioc;
+	if (ad->antic_status == ANTIC_WAIT_REQ ||
+			ad->antic_status == ANTIC_WAIT_NEXT) {
+		ioc = as_get_io_context();
+		if (ad->io_context == ioc)
+			ret = 1;
+		put_io_context(ioc);
+	}
+
+	return ret;
+}
+
+static void as_exit(request_queue_t *q, elevator_t *e)
+{
+	struct as_data *ad = e->elevator_data;
+
+	del_timer_sync(&ad->antic_timer);
+	kblockd_flush();
+
+	BUG_ON(!list_empty(&ad->fifo_list[REQ_SYNC]));
+	BUG_ON(!list_empty(&ad->fifo_list[REQ_ASYNC]));
+
+	mempool_destroy(ad->arq_pool);
+	put_io_context(ad->io_context);
+	kfree(ad->hash);
+	kfree(ad);
+}
+
+/*
+ * initialize elevator private data (as_data), and alloc a arq for
+ * each request on the free lists
+ */
+static int as_init(request_queue_t *q, elevator_t *e)
+{
+	struct as_data *ad;
+	int i;
+
+	if (!arq_pool)
+		return -ENOMEM;
+
+	ad = kmalloc(sizeof(*ad), GFP_KERNEL);
+	if (!ad)
+		return -ENOMEM;
+	memset(ad, 0, sizeof(*ad));
+
+	ad->q = q; /* Identify what queue the data belongs to */
+
+	ad->hash = kmalloc(sizeof(struct list_head)*AS_HASH_ENTRIES,GFP_KERNEL);
+	if (!ad->hash) {
+		kfree(ad);
+		return -ENOMEM;
+	}
+
+	ad->arq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, arq_pool);
+	if (!ad->arq_pool) {
+		kfree(ad->hash);
+		kfree(ad);
+		return -ENOMEM;
+	}
+
+	/* anticipatory scheduling helpers */
+	ad->antic_timer.function = as_antic_timeout;
+	ad->antic_timer.data = (unsigned long)q;
+	init_timer(&ad->antic_timer);
+	INIT_WORK(&ad->antic_work, as_work_handler, q);
+
+	for (i = 0; i < AS_HASH_ENTRIES; i++)
+		INIT_LIST_HEAD(&ad->hash[i]);
+
+	INIT_LIST_HEAD(&ad->fifo_list[REQ_SYNC]);
+	INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]);
+	ad->sort_list[REQ_SYNC] = RB_ROOT;
+	ad->sort_list[REQ_ASYNC] = RB_ROOT;
+	ad->dispatch = &q->queue_head;
+	ad->fifo_expire[REQ_SYNC] = default_read_expire;
+	ad->fifo_expire[REQ_ASYNC] = default_write_expire;
+	ad->hash_valid_count = 1;
+	ad->antic_expire = default_antic_expire;
+	ad->batch_expire[REQ_SYNC] = default_read_batch_expire;
+	ad->batch_expire[REQ_ASYNC] = default_write_batch_expire;
+	e->elevator_data = ad;
+
+	ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC];
+	ad->write_batch_count = ad->batch_expire[REQ_ASYNC] / 10;
+	if (ad->write_batch_count < 2)
+		ad->write_batch_count = 2;
+	return 0;
+}
+
+/*
+ * sysfs parts below
+ */
+struct as_fs_entry {
+	struct attribute attr;
+	ssize_t (*show)(struct as_data *, char *);
+	ssize_t (*store)(struct as_data *, const char *, size_t);
+};
+
+static ssize_t
+as_var_show(unsigned int var, char *page)
+{
+	var = (var * 1000) / HZ;
+	return sprintf(page, "%d\n", var);
+}
+
+static ssize_t
+as_var_store(unsigned long *var, const char *page, size_t count)
+{
+	unsigned long tmp;
+	char *p = (char *) page;
+
+	tmp = simple_strtoul(p, &p, 10);
+	if (tmp != 0) {
+		tmp = (tmp * HZ) / 1000;
+		if (tmp == 0)
+			tmp = 1;
+	}
+	*var = tmp;
+	return count;
+}
+
+#define SHOW_FUNCTION(__FUNC, __VAR)					\
+static ssize_t __FUNC(struct as_data *ad, char *page)		\
+{									\
+	return as_var_show(__VAR, (page));			\
+}
+SHOW_FUNCTION(as_readexpire_show, ad->fifo_expire[REQ_SYNC]);
+SHOW_FUNCTION(as_writeexpire_show, ad->fifo_expire[REQ_ASYNC]);
+SHOW_FUNCTION(as_anticexpire_show, ad->antic_expire);
+SHOW_FUNCTION(as_read_batchexpire_show, ad->batch_expire[REQ_SYNC]);
+SHOW_FUNCTION(as_write_batchexpire_show, ad->batch_expire[REQ_ASYNC]);
+#undef SHOW_FUNCTION
+
+#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX)				\
+static ssize_t __FUNC(struct as_data *ad, const char *page, size_t count)	\
+{									\
+	int ret = as_var_store(__PTR, (page), count);		\
+	if (*(__PTR) < (MIN))						\
+		*(__PTR) = (MIN);					\
+	else if (*(__PTR) > (MAX))					\
+		*(__PTR) = (MAX);					\
+	return ret;							\
+}
+STORE_FUNCTION(as_readexpire_store, &ad->fifo_expire[REQ_SYNC], 0, INT_MAX);
+STORE_FUNCTION(as_writeexpire_store, &ad->fifo_expire[REQ_ASYNC], 0, INT_MAX);
+STORE_FUNCTION(as_anticexpire_store, &ad->antic_expire, 0, INT_MAX);
+STORE_FUNCTION(as_read_batchexpire_store,
+			&ad->batch_expire[REQ_SYNC], 0, INT_MAX);
+STORE_FUNCTION(as_write_batchexpire_store,
+			&ad->batch_expire[REQ_ASYNC], 0, INT_MAX);
+#undef STORE_FUNCTION
+
+static struct as_fs_entry as_readexpire_entry = {
+	.attr = {.name = "read_expire", .mode = S_IRUGO | S_IWUSR },
+	.show = as_readexpire_show,
+	.store = as_readexpire_store,
+};
+static struct as_fs_entry as_writeexpire_entry = {
+	.attr = {.name = "write_expire", .mode = S_IRUGO | S_IWUSR },
+	.show = as_writeexpire_show,
+	.store = as_writeexpire_store,
+};
+static struct as_fs_entry as_anticexpire_entry = {
+	.attr = {.name = "antic_expire", .mode = S_IRUGO | S_IWUSR },
+	.show = as_anticexpire_show,
+	.store = as_anticexpire_store,
+};
+static struct as_fs_entry as_read_batchexpire_entry = {
+	.attr = {.name = "read_batch_expire", .mode = S_IRUGO | S_IWUSR },
+	.show = as_read_batchexpire_show,
+	.store = as_read_batchexpire_store,
+};
+static struct as_fs_entry as_write_batchexpire_entry = {
+	.attr = {.name = "write_batch_expire", .mode = S_IRUGO | S_IWUSR },
+	.show = as_write_batchexpire_show,
+	.store = as_write_batchexpire_store,
+};
+
+static struct attribute *default_attrs[] = {
+	&as_readexpire_entry.attr,
+	&as_writeexpire_entry.attr,
+	&as_anticexpire_entry.attr,
+	&as_read_batchexpire_entry.attr,
+	&as_write_batchexpire_entry.attr,
+	NULL,
+};
+
+#define to_as(atr) container_of((atr), struct as_fs_entry, attr)
+
+static ssize_t
+as_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+	elevator_t *e = container_of(kobj, elevator_t, kobj);
+	struct as_fs_entry *entry = to_as(attr);
+
+	if (!entry->show)
+		return 0;
+
+	return entry->show(e->elevator_data, page);
+}
+
+static ssize_t
+as_attr_store(struct kobject *kobj, struct attribute *attr,
+		    const char *page, size_t length)
+{
+	elevator_t *e = container_of(kobj, elevator_t, kobj);
+	struct as_fs_entry *entry = to_as(attr);
+
+	if (!entry->store)
+		return -EINVAL;
+
+	return entry->store(e->elevator_data, page, length);
+}
+
+static struct sysfs_ops as_sysfs_ops = {
+	.show	= as_attr_show,
+	.store	= as_attr_store,
+};
+
+struct kobj_type as_ktype = {
+	.sysfs_ops	= &as_sysfs_ops,
+	.default_attrs	= default_attrs,
+};
+
+static int __init as_slab_setup(void)
+{
+	arq_pool = kmem_cache_create("as_arq", sizeof(struct as_rq),
+				     0, 0, NULL, NULL);
+
+	if (!arq_pool)
+		panic("as: can't init slab pool\n");
+
+	return 0;
+}
+
+subsys_initcall(as_slab_setup);
+
+elevator_t iosched_as = {
+	.elevator_merge_fn = 		as_merge,
+	.elevator_merged_fn =		as_merged_request,
+	.elevator_merge_req_fn =	as_merged_requests,
+	.elevator_next_req_fn =		as_next_request,
+	.elevator_add_req_fn =		as_insert_request,
+	.elevator_remove_req_fn =	as_remove_request,
+	.elevator_queue_empty_fn =	as_queue_empty,
+	.elevator_completed_req_fn =	as_completed_request,
+	.elevator_former_req_fn =	as_former_request,
+	.elevator_latter_req_fn =	as_latter_request,
+	.elevator_set_req_fn =		as_set_request,
+	.elevator_put_req_fn =		as_put_request,
+	.elevator_may_queue_fn =	as_may_queue,
+	.elevator_init_fn =		as_init,
+	.elevator_exit_fn =		as_exit,
+
+	.elevator_ktype =		&as_ktype,
+};
+
+EXPORT_SYMBOL(iosched_as);
diff -urN linux-2.5.74-bk3/drivers/block/elevator.c linux-2.5.74-bk4/drivers/block/elevator.c
--- linux-2.5.74-bk3/drivers/block/elevator.c	2003-07-02 13:52:59.000000000 -0700
+++ linux-2.5.74-bk4/drivers/block/elevator.c	2003-07-06 09:15:48.000000000 -0700
@@ -361,17 +361,31 @@
 		e->elevator_put_req_fn(q, rq);
 }
 
-int elv_register_queue(struct gendisk *disk)
+int elv_may_queue(request_queue_t *q, int rw)
 {
-	request_queue_t *q = disk->queue;
-	elevator_t *e;
+	elevator_t *e = &q->elevator;
+
+	if (e->elevator_may_queue_fn)
+		return e->elevator_may_queue_fn(q, rw);
+
+	return 0;
+}
 
-	if (!q)
-		return -ENXIO;
+void elv_completed_request(request_queue_t *q, struct request *rq)
+{
+	elevator_t *e = &q->elevator;
+
+	if (e->elevator_completed_req_fn)
+		e->elevator_completed_req_fn(q, rq);
+}
+
+int elv_register_queue(struct request_queue *q)
+{
+	elevator_t *e;
 
 	e = &q->elevator;
 
-	e->kobj.parent = kobject_get(&disk->kobj);
+	e->kobj.parent = kobject_get(&q->kobj);
 	if (!e->kobj.parent)
 		return -EBUSY;
 
@@ -381,14 +395,12 @@
 	return kobject_register(&e->kobj);
 }
 
-void elv_unregister_queue(struct gendisk *disk)
+void elv_unregister_queue(struct request_queue *q)
 {
-	request_queue_t *q = disk->queue;
-
 	if (q) {
 		elevator_t * e = &q->elevator;
 		kobject_unregister(&e->kobj);
-		kobject_put(&disk->kobj);
+		kobject_put(&q->kobj);
 	}
 }
 
@@ -408,5 +420,6 @@
 EXPORT_SYMBOL(elv_next_request);
 EXPORT_SYMBOL(elv_remove_request);
 EXPORT_SYMBOL(elv_queue_empty);
+EXPORT_SYMBOL(elv_completed_request);
 EXPORT_SYMBOL(elevator_exit);
 EXPORT_SYMBOL(elevator_init);
diff -urN linux-2.5.74-bk3/drivers/block/genhd.c linux-2.5.74-bk4/drivers/block/genhd.c
--- linux-2.5.74-bk3/drivers/block/genhd.c	2003-07-02 13:47:01.000000000 -0700
+++ linux-2.5.74-bk4/drivers/block/genhd.c	2003-07-06 09:15:48.000000000 -0700
@@ -191,7 +191,7 @@
 	blk_register_region(MKDEV(disk->major, disk->first_minor),
 			    disk->minors, NULL, exact_match, exact_lock, disk);
 	register_disk(disk);
-	elv_register_queue(disk);
+	blk_register_queue(disk);
 }
 
 EXPORT_SYMBOL(add_disk);
@@ -199,7 +199,7 @@
 
 void unlink_gendisk(struct gendisk *disk)
 {
-	elv_unregister_queue(disk);
+	blk_unregister_queue(disk);
 	blk_unregister_region(MKDEV(disk->major, disk->first_minor),
 			      disk->minors);
 }
diff -urN linux-2.5.74-bk3/drivers/block/ll_rw_blk.c linux-2.5.74-bk4/drivers/block/ll_rw_blk.c
--- linux-2.5.74-bk3/drivers/block/ll_rw_blk.c	2003-07-06 09:15:34.000000000 -0700
+++ linux-2.5.74-bk4/drivers/block/ll_rw_blk.c	2003-07-06 09:15:49.000000000 -0700
@@ -42,40 +42,50 @@
 static LIST_HEAD(blk_plug_list);
 static spinlock_t blk_plug_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 
+static wait_queue_head_t congestion_wqh[2];
+
 /*
- * Number of requests per queue.  This many for reads and for writes (twice
- * this number, total).
+ * Controlling structure to kblockd
  */
-static int queue_nr_requests;
+static struct workqueue_struct *kblockd_workqueue; 
 
 unsigned long blk_max_low_pfn, blk_max_pfn;
-static wait_queue_head_t congestion_wqh[2];
+
+/* Amount of time in which a process may batch requests */
+#define BLK_BATCH_TIME	(HZ/50UL)
+
+/* Number of requests a "batching" process may submit */
+#define BLK_BATCH_REQ	32
 
 /*
- * Return the threshold (number of free requests) at which the queue is
+ * Return the threshold (number of used requests) at which the queue is
  * considered to be congested.  It include a little hysteresis to keep the
  * context switch rate down.
  */
-static inline int queue_congestion_on_threshold(void)
+static inline int queue_congestion_on_threshold(struct request_queue *q)
 {
 	int ret;
 
-	ret = queue_nr_requests / 8 - 1;
-	if (ret < 0)
-		ret = 1;
+	ret = q->nr_requests - (q->nr_requests / 8) + 1;
+
+	if (ret > q->nr_requests)
+		ret = q->nr_requests;
+
 	return ret;
 }
 
 /*
  * The threshold at which a queue is considered to be uncongested
  */
-static inline int queue_congestion_off_threshold(void)
+static inline int queue_congestion_off_threshold(struct request_queue *q)
 {
 	int ret;
 
-	ret = queue_nr_requests / 8 + 1;
-	if (ret > queue_nr_requests)
-		ret = queue_nr_requests;
+	ret = q->nr_requests - (q->nr_requests / 8) - 1;
+
+	if (ret < 1)
+		ret = 1;
+
 	return ret;
 }
 
@@ -188,6 +198,7 @@
 	/*
 	 * set defaults
 	 */
+	q->nr_requests = BLKDEV_MAX_RQ;
 	q->max_phys_segments = MAX_PHYS_SEGMENTS;
 	q->max_hw_segments = MAX_HW_SEGMENTS;
 	q->make_request_fn = mfn;
@@ -441,13 +452,15 @@
 	q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED);
 }
 
-static int init_tag_map(struct blk_queue_tag *tags, int depth)
+static int
+init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth)
 {
 	int bits, i;
 
-	if (depth > (queue_nr_requests*2)) {
-		depth = (queue_nr_requests*2);
-		printk(KERN_ERR "%s: adjusted depth to %d\n", __FUNCTION__, depth);
+	if (depth > q->nr_requests * 2) {
+		depth = q->nr_requests * 2;
+		printk(KERN_ERR "%s: adjusted depth to %d\n",
+				__FUNCTION__, depth);
 	}
 
 	tags->tag_index = kmalloc(depth * sizeof(struct request *), GFP_ATOMIC);
@@ -476,7 +489,6 @@
 	return -ENOMEM;
 }
 
-
 /**
  * blk_queue_init_tags - initialize the queue tag info
  * @q:  the request queue for the device
@@ -490,7 +502,7 @@
 	if (!tags)
 		goto fail;
 
-	if (init_tag_map(tags, depth))
+	if (init_tag_map(q, tags, depth))
 		goto fail;
 
 	INIT_LIST_HEAD(&tags->busy_list);
@@ -540,7 +552,7 @@
 	tag_map = bqt->tag_map;
 	max_depth = bqt->real_max_depth;
 
-	if (init_tag_map(bqt, new_depth))
+	if (init_tag_map(q, bqt, new_depth))
 		return -ENOMEM;
 
 	memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *));
@@ -1022,7 +1034,7 @@
 	/*
 	 * was plugged, fire request_fn if queue has stuff to do
 	 */
-	if (!elv_queue_empty(q))
+	if (elv_next_request(q))
 		q->request_fn(q);
 }
 
@@ -1057,7 +1069,7 @@
 {
 	request_queue_t *q = (request_queue_t *)data;
 
-	schedule_work(&q->unplug_work);
+	kblockd_schedule_work(&q->unplug_work);
 }
 
 /**
@@ -1165,7 +1177,7 @@
 	elevator_exit(q);
 
 	del_timer_sync(&q->unplug_timer);
-	flush_scheduled_work();
+	kblockd_flush();
 
 	mempool_destroy(rl->rq_pool);
 
@@ -1180,6 +1192,8 @@
 	struct request_list *rl = &q->rq;
 
 	rl->count[READ] = rl->count[WRITE] = 0;
+	init_waitqueue_head(&rl->wait[READ]);
+	init_waitqueue_head(&rl->wait[WRITE]);
 
 	rl->rq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, request_cachep);
 
@@ -1191,6 +1205,18 @@
 
 static int __make_request(request_queue_t *, struct bio *);
 
+static elevator_t *chosen_elevator = &iosched_as;
+
+static int __init elevator_setup(char *str)
+{
+	if (!strcmp(str, "deadline"))
+		chosen_elevator = &iosched_deadline;
+	if (!strcmp(str, "as"))
+		chosen_elevator = &iosched_as;
+	return 1;
+}
+__setup("elevator=", elevator_setup);
+
 /**
  * blk_init_queue  - prepare a request queue for use with a block device
  * @q:    The &request_queue_t to be initialised
@@ -1222,11 +1248,20 @@
 int blk_init_queue(request_queue_t *q, request_fn_proc *rfn, spinlock_t *lock)
 {
 	int ret;
+	static int printed;
 
 	if (blk_init_free_list(q))
 		return -ENOMEM;
 
-	if ((ret = elevator_init(q, &iosched_deadline))) {
+	if (!printed) {
+		printed = 1;
+		if (chosen_elevator == &iosched_deadline)
+			printk("deadline elevator\n");
+		else if (chosen_elevator == &iosched_as)
+			printk("anticipatory scheduling elevator\n");
+	}
+
+	if ((ret = elevator_init(q, chosen_elevator))) {
 		blk_cleanup_queue(q);
 		return ret;
 	}
@@ -1271,6 +1306,60 @@
 	return NULL;
 }
 
+/*
+ * ioc_batching returns true if the ioc is a valid batching request and
+ * should be given priority access to a request.
+ */
+static inline int ioc_batching(struct io_context *ioc)
+{
+	if (!ioc)
+		return 0;
+
+	/*
+	 * Make sure the process is able to allocate at least 1 request
+	 * even if the batch times out, otherwise we could theoretically
+	 * lose wakeups.
+	 */
+	return ioc->nr_batch_requests == BLK_BATCH_REQ ||
+		(ioc->nr_batch_requests > 0
+		&& time_before(jiffies, ioc->last_waited + BLK_BATCH_TIME));
+}
+
+/*
+ * ioc_set_batching sets ioc to be a new "batcher" if it is not one. This
+ * will cause the process to be a "batcher" on all queues in the system. This
+ * is the behaviour we want though - once it gets a wakeup it should be given
+ * a nice run.
+ */
+void ioc_set_batching(struct io_context *ioc)
+{
+	if (!ioc || ioc_batching(ioc))
+		return;
+
+	ioc->nr_batch_requests = BLK_BATCH_REQ;
+	ioc->last_waited = jiffies;
+}
+
+/*
+ * A request has just been released.  Account for it, update the full and
+ * congestion status, wake up any waiters.   Called under q->queue_lock.
+ */
+static void freed_request(request_queue_t *q, int rw)
+{
+	struct request_list *rl = &q->rq;
+
+	rl->count[rw]--;
+	if (rl->count[rw] < queue_congestion_off_threshold(q))
+		clear_queue_congested(q, rw);
+	if (rl->count[rw]+1 <= q->nr_requests) {
+		smp_mb();
+		if (waitqueue_active(&rl->wait[rw]))
+			wake_up(&rl->wait[rw]);
+		if (!waitqueue_active(&rl->wait[rw]))
+			blk_clear_queue_full(q, rw);
+	}
+}
+
 #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
 /*
  * Get a free request, queue_lock must not be held
@@ -1279,26 +1368,54 @@
 {
 	struct request *rq = NULL;
 	struct request_list *rl = &q->rq;
+	struct io_context *ioc = get_io_context(gfp_mask);
 
 	spin_lock_irq(q->queue_lock);
-	if (rl->count[rw] == BLKDEV_MAX_RQ) {
+	if (rl->count[rw]+1 >= q->nr_requests) {
+		/*
+		 * The queue will fill after this allocation, so set it as
+		 * full, and mark this process as "batching". This process
+		 * will be allowed to complete a batch of requests, others
+		 * will be blocked.
+		 */
+		if (!blk_queue_full(q, rw)) {
+			ioc_set_batching(ioc);
+			blk_set_queue_full(q, rw);
+		}
+	}
+
+	if (blk_queue_full(q, rw)
+			&& !ioc_batching(ioc) && !elv_may_queue(q, rw)) {
+		/*
+		 * The queue is full and the allocating process is not a
+		 * "batcher", and not exempted by the IO scheduler
+		 */
 		spin_unlock_irq(q->queue_lock);
 		goto out;
 	}
+
 	rl->count[rw]++;
-	if ((BLKDEV_MAX_RQ - rl->count[rw]) < queue_congestion_on_threshold())
+	if (rl->count[rw] >= queue_congestion_on_threshold(q))
 		set_queue_congested(q, rw);
 	spin_unlock_irq(q->queue_lock);
 
 	rq = blk_alloc_request(q, gfp_mask);
 	if (!rq) {
+		/*
+		 * Allocation failed presumably due to memory. Undo anything
+		 * we might have messed up.
+		 *
+		 * Allocating task should really be put onto the front of the
+		 * wait queue, but this is pretty rare.
+		 */
 		spin_lock_irq(q->queue_lock);
-		rl->count[rw]--;
-		if ((BLKDEV_MAX_RQ - rl->count[rw]) >= queue_congestion_off_threshold())
-                        clear_queue_congested(q, rw);
+		freed_request(q, rw);
 		spin_unlock_irq(q->queue_lock);
 		goto out;
 	}
+
+	if (ioc_batching(ioc))
+		ioc->nr_batch_requests--;
 	
 	INIT_LIST_HEAD(&rq->queuelist);
 
@@ -1321,22 +1438,44 @@
 	rq->sense = NULL;
 
 out:
+	put_io_context(ioc);
 	return rq;
 }
 
 /*
- * No available requests for this queue, unplug the device.
+ * No available requests for this queue, unplug the device and wait for some
+ * requests to become available.
  */
 static struct request *get_request_wait(request_queue_t *q, int rw)
 {
+	DEFINE_WAIT(wait);
 	struct request *rq;
 
 	generic_unplug_device(q);
 	do {
+		struct request_list *rl = &q->rq;
+
+		prepare_to_wait_exclusive(&rl->wait[rw], &wait,
+				TASK_UNINTERRUPTIBLE);
+
 		rq = get_request(q, rw, GFP_NOIO);
 
-		if (!rq)
-			blk_congestion_wait(rw, HZ / 50);
+		if (!rq) {
+			struct io_context *ioc;
+
+			io_schedule();
+
+			/*
+			 * After sleeping, we become a "batching" process and
+			 * will be able to allocate at least one request, and
+			 * up to a big batch of them for a small period time.
+			 * See ioc_batching, ioc_set_batching
+			 */
+			ioc = get_io_context(GFP_NOIO);
+			ioc_set_batching(ioc);
+			put_io_context(ioc);
+		}
+		finish_wait(&rl->wait[rw], &wait);
 	} while (!rq);
 
 	return rq;
@@ -1348,10 +1487,10 @@
 
 	BUG_ON(rw != READ && rw != WRITE);
 
-	rq = get_request(q, rw, gfp_mask);
-
-	if (!rq && (gfp_mask & __GFP_WAIT))
+	if (gfp_mask & __GFP_WAIT)
 		rq = get_request_wait(q, rw);
+	else
+		rq = get_request(q, rw, gfp_mask);
 
 	return rq;
 }
@@ -1482,6 +1621,8 @@
 	if (unlikely(--req->ref_count))
 		return;
 
+	elv_completed_request(req->q, req);
+
 	req->rq_status = RQ_INACTIVE;
 	req->q = NULL;
 	req->rl = NULL;
@@ -1496,10 +1637,7 @@
 		BUG_ON(!list_empty(&req->queuelist));
 
 		blk_free_request(q, req);
-
-		rl->count[rw]--;
-		if ((BLKDEV_MAX_RQ - rl->count[rw]) >= queue_congestion_off_threshold())
-			clear_queue_congested(q, rw);
+		freed_request(q, rw);
 	}
 }
 
@@ -1786,13 +1924,12 @@
 		__blk_put_request(q, freereq);
 
 	if (blk_queue_plugged(q)) {
-		int nr_queued = q->rq.count[0] + q->rq.count[1];
+		int nr_queued = q->rq.count[READ] + q->rq.count[WRITE];
 
 		if (nr_queued == q->unplug_thresh)
 			__generic_unplug_device(q);
 	}
 	spin_unlock_irq(q->queue_lock);
-
 	return 0;
 
 end_io:
@@ -1800,7 +1937,6 @@
 	return 0;
 }
 
-
 /*
  * If bio->bi_dev is a partition, remap the location
  */
@@ -1850,8 +1986,7 @@
  * bio happens to be merged with someone else, and may change bi_dev and
  * bi_sector for remaps as it sees fit.  So the values of these fields
  * should NOT be depended on after the call to generic_make_request.
- *
- * */
+ */
 void generic_make_request(struct bio *bio)
 {
 	request_queue_t *q;
@@ -2282,31 +2417,287 @@
 	rq->current_nr_sectors = rq->hard_cur_sectors;
 }
 
+int kblockd_schedule_work(struct work_struct *work)
+{
+	return queue_work(kblockd_workqueue, work);
+}
+
+void kblockd_flush(void)
+{
+	flush_workqueue(kblockd_workqueue);
+}
+
 int __init blk_dev_init(void)
 {
 	int i;
 
+	kblockd_workqueue = create_workqueue("kblockd");
+	if (!kblockd_workqueue)
+		panic("Failed to create kblockd\n");
+
 	request_cachep = kmem_cache_create("blkdev_requests",
 			sizeof(struct request), 0, 0, NULL, NULL);
 	if (!request_cachep)
 		panic("Can't create request pool slab cache\n");
 
-	queue_nr_requests = BLKDEV_MAX_RQ;
-
-	printk("block request queues:\n");
-	printk(" %d/%d requests per read queue\n", BLKDEV_MIN_RQ, queue_nr_requests);
-	printk(" %d/%d requests per write queue\n", BLKDEV_MIN_RQ, queue_nr_requests);
-	printk(" enter congestion at %d\n", queue_congestion_on_threshold());
-	printk(" exit congestion at %d\n", queue_congestion_off_threshold());
-
 	blk_max_low_pfn = max_low_pfn;
 	blk_max_pfn = max_pfn;
 
 	for (i = 0; i < ARRAY_SIZE(congestion_wqh); i++)
 		init_waitqueue_head(&congestion_wqh[i]);
 	return 0;
+}
+
+static atomic_t nr_io_contexts = ATOMIC_INIT(0);
+
+/*
+ * IO Context helper functions
+ */
+void put_io_context(struct io_context *ioc)
+{
+	if (ioc == NULL)
+		return;
+
+	BUG_ON(atomic_read(&ioc->refcount) == 0);
+
+	if (atomic_dec_and_test(&ioc->refcount)) {
+		if (ioc->aic && ioc->aic->dtor)
+			ioc->aic->dtor(ioc->aic);
+		kfree(ioc);
+		atomic_dec(&nr_io_contexts);
+	}
+}
+
+/* Called by the exitting task */
+void exit_io_context(void)
+{
+	unsigned long flags;
+	struct io_context *ioc;
+
+	local_irq_save(flags);
+	ioc = current->io_context;
+	if (ioc) {
+		if (ioc->aic && ioc->aic->exit)
+			ioc->aic->exit(ioc->aic);
+		put_io_context(ioc);
+		current->io_context = NULL;
+	} else
+		WARN_ON(1);
+	local_irq_restore(flags);
+}
+
+/*
+ * If the current task has no IO context then create one and initialise it.
+ * If it does have a context, take a ref on it.
+ *
+ * This is always called in the context of the task which submitted the I/O.
+ * But weird things happen, so we disable local interrupts to ensure exclusive
+ * access to *current.
+ */
+struct io_context *get_io_context(int gfp_flags)
+{
+	struct task_struct *tsk = current;
+	unsigned long flags;
+	struct io_context *ret;
+
+	local_irq_save(flags);
+	ret = tsk->io_context;
+	if (ret == NULL) {
+		ret = kmalloc(sizeof(*ret), GFP_ATOMIC);
+		if (ret) {
+			atomic_inc(&nr_io_contexts);
+			atomic_set(&ret->refcount, 1);
+			ret->pid = tsk->pid;
+			ret->last_waited = jiffies; /* doesn't matter... */
+			ret->nr_batch_requests = 0; /* because this is 0 */
+			ret->aic = NULL;
+			tsk->io_context = ret;
+		}
+	}
+	if (ret)
+		atomic_inc(&ret->refcount);
+	local_irq_restore(flags);
+	return ret;
+}
+
+void copy_io_context(struct io_context **pdst, struct io_context **psrc)
+{
+	struct io_context *src = *psrc;
+	struct io_context *dst = *pdst;
+
+	if (src) {
+		BUG_ON(atomic_read(&src->refcount) == 0);
+		atomic_inc(&src->refcount);
+		put_io_context(dst);
+		*pdst = src;
+	}
+}
+
+void swap_io_context(struct io_context **ioc1, struct io_context **ioc2)
+{
+	struct io_context *temp;
+	temp = *ioc1;
+	*ioc1 = *ioc2;
+	*ioc2 = temp;
+}
+
+
+/*
+ * sysfs parts below
+ */
+struct queue_sysfs_entry {
+	struct attribute attr;
+	ssize_t (*show)(struct request_queue *, char *);
+	ssize_t (*store)(struct request_queue *, const char *, size_t);
 };
 
+static ssize_t
+queue_var_show(unsigned int var, char *page)
+{
+	return sprintf(page, "%d\n", var);
+}
+
+static ssize_t
+queue_var_store(unsigned long *var, const char *page, size_t count)
+{
+	char *p = (char *) page;
+
+	*var = simple_strtoul(p, &p, 10);
+	return count;
+}
+
+static ssize_t queue_requests_show(struct request_queue *q, char *page)
+{
+	return queue_var_show(q->nr_requests, (page));
+}
+
+static ssize_t
+queue_requests_store(struct request_queue *q, const char *page, size_t count)
+{
+	struct request_list *rl = &q->rq;
+
+	int ret = queue_var_store(&q->nr_requests, page, count);
+	if (q->nr_requests < BLKDEV_MIN_RQ)
+		q->nr_requests = BLKDEV_MIN_RQ;
+
+	if (rl->count[READ] >= queue_congestion_on_threshold(q))
+		set_queue_congested(q, READ);
+	else if (rl->count[READ] < queue_congestion_off_threshold(q))
+		clear_queue_congested(q, READ);
+
+	if (rl->count[WRITE] >= queue_congestion_on_threshold(q))
+		set_queue_congested(q, WRITE);
+	else if (rl->count[WRITE] < queue_congestion_off_threshold(q))
+		clear_queue_congested(q, WRITE);
+
+	if (rl->count[READ] >= q->nr_requests) {
+		blk_set_queue_full(q, READ);
+	} else if (rl->count[READ]+1 <= q->nr_requests) {
+		blk_clear_queue_full(q, READ);
+		wake_up(&rl->wait[READ]);
+	}
+
+	if (rl->count[WRITE] >= q->nr_requests) {
+		blk_set_queue_full(q, WRITE);
+	} else if (rl->count[WRITE]+1 <= q->nr_requests) {
+		blk_clear_queue_full(q, WRITE);
+		wake_up(&rl->wait[WRITE]);
+	}
+	return ret;
+}
+
+static struct queue_sysfs_entry queue_requests_entry = {
+	.attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
+	.show = queue_requests_show,
+	.store = queue_requests_store,
+};
+
+static struct attribute *default_attrs[] = {
+	&queue_requests_entry.attr,
+	NULL,
+};
+
+#define to_queue(atr) container_of((atr), struct queue_sysfs_entry, attr)
+
+static ssize_t
+queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+	struct queue_sysfs_entry *entry = to_queue(attr);
+	struct request_queue *q;
+
+	q = container_of(kobj, struct request_queue, kobj);
+	if (!entry->show)
+		return 0;
+
+	return entry->show(q, page);
+}
+
+static ssize_t
+queue_attr_store(struct kobject *kobj, struct attribute *attr,
+		    const char *page, size_t length)
+{
+	struct queue_sysfs_entry *entry = to_queue(attr);
+	struct request_queue *q;
+
+	q = container_of(kobj, struct request_queue, kobj);
+	if (!entry->store)
+		return -EINVAL;
+
+	return entry->store(q, page, length);
+}
+
+static struct sysfs_ops queue_sysfs_ops = {
+	.show	= queue_attr_show,
+	.store	= queue_attr_store,
+};
+
+struct kobj_type queue_ktype = {
+	.sysfs_ops	= &queue_sysfs_ops,
+	.default_attrs	= default_attrs,
+};
+
+int blk_register_queue(struct gendisk *disk)
+{
+	int ret;
+
+	request_queue_t *q = disk->queue;
+
+	if (!q)
+		return -ENXIO;
+
+	q->kobj.parent = kobject_get(&disk->kobj);
+	if (!q->kobj.parent)
+		return -EBUSY;
+
+	snprintf(q->kobj.name, KOBJ_NAME_LEN, "%s", "queue");
+	q->kobj.ktype = &queue_ktype;
+
+	ret = kobject_register(&q->kobj);
+	if (ret < 0)
+		return ret;
+
+	ret = elv_register_queue(q);
+	if (ret) {
+		kobject_unregister(&q->kobj);
+		return ret;
+	}
+
+	return 0;
+}
+
+void blk_unregister_queue(struct gendisk *disk)
+{
+	request_queue_t *q = disk->queue;
+
+	if (q) {
+		elv_unregister_queue(q);
+
+		kobject_unregister(&q->kobj);
+		kobject_put(&disk->kobj);
+	}
+}
+
+
 EXPORT_SYMBOL(process_that_request_first);
 EXPORT_SYMBOL(end_that_request_first);
 EXPORT_SYMBOL(end_that_request_chunk);
diff -urN linux-2.5.74-bk3/drivers/message/i2o/i2o_scsi.c linux-2.5.74-bk4/drivers/message/i2o/i2o_scsi.c
--- linux-2.5.74-bk3/drivers/message/i2o/i2o_scsi.c	2003-07-02 13:53:02.000000000 -0700
+++ linux-2.5.74-bk4/drivers/message/i2o/i2o_scsi.c	2003-07-06 09:15:49.000000000 -0700
@@ -49,6 +49,7 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/prefetch.h>
+#include <linux/pci.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
diff -urN linux-2.5.74-bk3/drivers/mtd/mtd_blkdevs.c linux-2.5.74-bk4/drivers/mtd/mtd_blkdevs.c
--- linux-2.5.74-bk3/drivers/mtd/mtd_blkdevs.c	2003-07-02 13:40:04.000000000 -0700
+++ linux-2.5.74-bk4/drivers/mtd/mtd_blkdevs.c	2003-07-06 09:15:49.000000000 -0700
@@ -211,9 +211,10 @@
 	case HDIO_GETGEO:
 		if (tr->getgeo) {
 			struct hd_geometry g;
+			int ret;
 
 			memset(&g, 0, sizeof(g));
-			int ret = tr->getgeo(dev, &g);
+			ret = tr->getgeo(dev, &g);
 			if (ret)
 				return ret;
 
diff -urN linux-2.5.74-bk3/drivers/net/wan/hdlc_generic.c linux-2.5.74-bk4/drivers/net/wan/hdlc_generic.c
--- linux-2.5.74-bk3/drivers/net/wan/hdlc_generic.c	2003-07-02 13:41:16.000000000 -0700
+++ linux-2.5.74-bk4/drivers/net/wan/hdlc_generic.c	2003-07-06 09:15:49.000000000 -0700
@@ -177,11 +177,8 @@
 
 struct packet_type hdlc_packet_type=
 {
-        __constant_htons(ETH_P_HDLC),
-        NULL,
-        hdlc_rcv,
-        NULL,
-        NULL
+	.type = __constant_htons(ETH_P_HDLC),
+	.func = hdlc_rcv,
 };
 
 
diff -urN linux-2.5.74-bk3/drivers/pci/probe.c linux-2.5.74-bk4/drivers/pci/probe.c
--- linux-2.5.74-bk3/drivers/pci/probe.c	2003-07-06 09:15:35.000000000 -0700
+++ linux-2.5.74-bk4/drivers/pci/probe.c	2003-07-06 09:15:49.000000000 -0700
@@ -637,12 +637,6 @@
 {
 	struct pci_bus *b;
 
-	if (pci_find_bus(0, bus)) {
-		/* If we already got to this bus through a different bridge, ignore it */
-		DBG("PCI: Bus %02x already known\n", bus);
-		return NULL;
-	}
-
 	b = pci_alloc_bus();
 	if (!b)
 		return NULL;
@@ -656,6 +650,14 @@
 	b->sysdata = sysdata;
 	b->ops = ops;
 
+	if (pci_find_bus(pci_domain_nr(b), bus)) {
+		/* If we already got to this bus through a different bridge, ignore it */
+		DBG("PCI: Bus %02x already known\n", bus);
+		kfree(b->dev);
+		kfree(b);
+		return NULL;
+	}
+
 	list_add_tail(&b->node, &pci_root_buses);
 
 	memset(b->dev,0,sizeof(*(b->dev)));
diff -urN linux-2.5.74-bk3/fs/buffer.c linux-2.5.74-bk4/fs/buffer.c
--- linux-2.5.74-bk3/fs/buffer.c	2003-07-06 09:15:36.000000000 -0700
+++ linux-2.5.74-bk4/fs/buffer.c	2003-07-06 09:15:50.000000000 -0700
@@ -319,6 +319,7 @@
 
 	/* We need to protect against concurrent writers.. */
 	down(&inode->i_sem);
+	current->flags |= PF_SYNCWRITE;
 	ret = filemap_fdatawrite(inode->i_mapping);
 	err = file->f_op->fsync(file, dentry, 0);
 	if (!ret)
@@ -326,6 +327,7 @@
 	err = filemap_fdatawait(inode->i_mapping);
 	if (!ret)
 		ret = err;
+	current->flags &= ~PF_SYNCWRITE;
 	up(&inode->i_sem);
 
 out_putf:
@@ -354,6 +356,7 @@
 		goto out_putf;
 
 	down(&inode->i_sem);
+	current->flags |= PF_SYNCWRITE;
 	ret = filemap_fdatawrite(inode->i_mapping);
 	err = file->f_op->fsync(file, dentry, 1);
 	if (!ret)
@@ -361,6 +364,7 @@
 	err = filemap_fdatawait(inode->i_mapping);
 	if (!ret)
 		ret = err;
+	current->flags &= ~PF_SYNCWRITE;
 	up(&inode->i_sem);
 
 out_putf:
diff -urN linux-2.5.74-bk3/fs/eventpoll.c linux-2.5.74-bk4/fs/eventpoll.c
--- linux-2.5.74-bk3/fs/eventpoll.c	2003-07-02 13:46:06.000000000 -0700
+++ linux-2.5.74-bk4/fs/eventpoll.c	2003-07-06 09:15:50.000000000 -0700
@@ -443,29 +443,17 @@
 
 
 /*
- * This is called from inside fs/file_table.c:__fput() to unlink files
- * from the eventpoll interface. We need to have this facility to cleanup
- * correctly files that are closed without being removed from the eventpoll
- * interface.
+ * This is called from eventpoll_release() to unlink files from the eventpoll
+ * interface. We need to have this facility to cleanup correctly files that are
+ * closed without being removed from the eventpoll interface.
  */
-void eventpoll_release(struct file *file)
+void eventpoll_release_file(struct file *file)
 {
 	struct list_head *lsthead = &file->f_ep_links;
 	struct eventpoll *ep;
 	struct epitem *epi;
 
 	/*
-	 * Fast check to avoid the get/release of the semaphore. Since
-	 * we're doing this outside the semaphore lock, it might return
-	 * false negatives, but we don't care. It'll help in 99.99% of cases
-	 * to avoid the semaphore lock. False positives simply cannot happen
-	 * because the file in on the way to be removed and nobody ( but
-	 * eventpoll ) has still a reference to this file.
-	 */
-	if (list_empty(lsthead))
-		return;
-
-	/*
 	 * We don't want to get "file->f_ep_lock" because it is not
 	 * necessary. It is not necessary because we're in the "struct file"
 	 * cleanup path, and this means that noone is using this file anymore.
@@ -541,7 +529,7 @@
 /*
  * The following function implement the controller interface for the eventpoll
  * file that enable the insertion/removal/change of file descriptors inside
- * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2).
+ * the interest set. It rapresents the kernel part of the user space epoll_ctl(2).
  */
 asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
 {
@@ -551,8 +539,8 @@
 	struct epitem *epi;
 	struct epoll_event epds;
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u)\n",
-		     current, epfd, op, fd, event->events));
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p)\n",
+		     current, epfd, op, fd, event));
 
 	error = -EFAULT;
 	if (copy_from_user(&epds, event, sizeof(struct epoll_event)))
@@ -633,8 +621,8 @@
 eexit_2:
 	fput(file);
 eexit_1:
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u) = %d\n",
-		     current, epfd, op, fd, event->events, error));
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p) = %d\n",
+		     current, epfd, op, fd, event, error));
 
 	return error;
 }
diff -urN linux-2.5.74-bk3/fs/exec.c linux-2.5.74-bk4/fs/exec.c
--- linux-2.5.74-bk3/fs/exec.c	2003-07-06 09:15:36.000000000 -0700
+++ linux-2.5.74-bk4/fs/exec.c	2003-07-06 09:15:50.000000000 -0700
@@ -759,12 +759,6 @@
 	char * name;
 	int i, ch, retval;
 
-	/* 
-	 * Release all of the old mmap stuff
-	 */
-	retval = exec_mmap(bprm->mm);
-	if (retval)
-		goto out;
 	/*
 	 * Make sure we have a private signal table and that
 	 * we are unassociated from the previous thread group.
@@ -773,6 +767,13 @@
 	if (retval)
 		goto out;
 
+	/*
+	 * Release all of the old mmap stuff
+	 */
+	retval = exec_mmap(bprm->mm);
+	if (retval)
+		goto out;
+
 	bprm->mm = NULL;		/* We're using it now */
 
 	/* This is the point of no return */
diff -urN linux-2.5.74-bk3/fs/fs-writeback.c linux-2.5.74-bk4/fs/fs-writeback.c
--- linux-2.5.74-bk3/fs/fs-writeback.c	2003-07-02 13:58:19.000000000 -0700
+++ linux-2.5.74-bk4/fs/fs-writeback.c	2003-07-06 09:15:51.000000000 -0700
@@ -516,6 +516,7 @@
 	int need_write_inode_now = 0;
 	int err2;
 
+	current->flags |= PF_SYNCWRITE;
 	if (what & OSYNC_DATA)
 		err = filemap_fdatawrite(inode->i_mapping);
 	if (what & (OSYNC_METADATA|OSYNC_DATA)) {
@@ -528,6 +529,7 @@
 		if (!err)
 			err = err2;
 	}
+	current->flags &= ~PF_SYNCWRITE;
 
 	spin_lock(&inode_lock);
 	if ((inode->i_state & I_DIRTY) &&
diff -urN linux-2.5.74-bk3/include/asm-ppc/serial.h linux-2.5.74-bk4/include/asm-ppc/serial.h
--- linux-2.5.74-bk3/include/asm-ppc/serial.h	2003-07-02 13:56:36.000000000 -0700
+++ linux-2.5.74-bk4/include/asm-ppc/serial.h	2003-07-06 09:15:53.000000000 -0700
@@ -25,11 +25,9 @@
 #elif defined(CONFIG_PRPMC800)
 #include <platforms/prpmc800_serial.h>
 #elif defined(CONFIG_SANDPOINT)
-#include <platforms/sandpoint_serial.h>
+#include <platforms/sandpoint.h>
 #elif defined(CONFIG_SPRUCE)
 #include <platforms/spruce_serial.h>
-#elif defined(CONFIG_ZX4500)
-#include <platforms/zx4500_serial.h>
 #elif defined(CONFIG_40x)
 #include <asm/ibm4xx.h>
 #else
diff -urN linux-2.5.74-bk3/include/linux/blkdev.h linux-2.5.74-bk4/include/linux/blkdev.h
--- linux-2.5.74-bk3/include/linux/blkdev.h	2003-07-02 13:43:27.000000000 -0700
+++ linux-2.5.74-bk4/include/linux/blkdev.h	2003-07-06 09:15:53.000000000 -0700
@@ -22,11 +22,62 @@
 struct request_pm_state;
 
 #define BLKDEV_MIN_RQ	4
-#define BLKDEV_MAX_RQ	128
+#define BLKDEV_MAX_RQ	128	/* Default maximum */
+
+/*
+ * This is the per-process anticipatory I/O scheduler state.
+ */
+struct as_io_context {
+	spinlock_t lock;
+
+	void (*dtor)(struct as_io_context *aic); /* destructor */
+	void (*exit)(struct as_io_context *aic); /* called on task exit */
+
+	unsigned long state;
+	atomic_t nr_queued; /* queued reads & sync writes */
+	atomic_t nr_dispatched; /* number of requests gone to the drivers */
+
+	/* IO History tracking */
+	/* Thinktime */
+	unsigned long last_end_request;
+	unsigned long ttime_total;
+	unsigned long ttime_samples;
+	unsigned long ttime_mean;
+	/* Layout pattern */
+	long seek_samples;
+	sector_t last_request_pos;
+	sector_t seek_total;
+	sector_t seek_mean;
+};
+
+/*
+ * This is the per-process I/O subsystem state.  It is refcounted and
+ * kmalloc'ed. Currently all fields are modified in process io context
+ * (apart from the atomic refcount), so require no locking.
+ */
+struct io_context {
+	atomic_t refcount;
+	pid_t pid;
+
+	/*
+	 * For request batching
+	 */
+	unsigned long last_waited; /* Time last woken after wait for request */
+	int nr_batch_requests;     /* Number of requests left in the batch */
+
+	struct as_io_context *aic;
+};
+
+void put_io_context(struct io_context *ioc);
+void exit_io_context(void);
+struct io_context *get_io_context(int gfp_flags);
+void copy_io_context(struct io_context **pdst, struct io_context **psrc);
+void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
 
 struct request_list {
 	int count[2];
 	mempool_t *rq_pool;
+	wait_queue_head_t wait[2];
 };
 
 /*
@@ -268,8 +319,15 @@
 	spinlock_t		*queue_lock;
 
 	/*
+	 * queue kobject
+	 */
+	struct kobject kobj;
+
+	/*
 	 * queue settings
 	 */
+	unsigned long		nr_requests;	/* Max # of requests */
+
 	unsigned short		max_sectors;
 	unsigned short		max_phys_segments;
 	unsigned short		max_hw_segments;
@@ -299,6 +357,8 @@
 #define QUEUE_FLAG_CLUSTER	0	/* cluster several segments into 1 */
 #define QUEUE_FLAG_QUEUED	1	/* uses generic tag queueing */
 #define QUEUE_FLAG_STOPPED	2	/* queue is stopped */
+#define	QUEUE_FLAG_READFULL	3	/* write queue has been filled */
+#define QUEUE_FLAG_WRITEFULL	4	/* read queue has been filled */
 
 #define blk_queue_plugged(q)	!list_empty(&(q)->plug_list)
 #define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
@@ -314,6 +374,30 @@
 
 #define rq_data_dir(rq)		((rq)->flags & 1)
 
+static inline int blk_queue_full(struct request_queue *q, int rw)
+{
+	if (rw == READ)
+		return test_bit(QUEUE_FLAG_READFULL, &q->queue_flags);
+	return test_bit(QUEUE_FLAG_WRITEFULL, &q->queue_flags);
+}
+
+static inline void blk_set_queue_full(struct request_queue *q, int rw)
+{
+	if (rw == READ)
+		set_bit(QUEUE_FLAG_READFULL, &q->queue_flags);
+	else
+		set_bit(QUEUE_FLAG_WRITEFULL, &q->queue_flags);
+}
+
+static inline void blk_clear_queue_full(struct request_queue *q, int rw)
+{
+	if (rw == READ)
+		clear_bit(QUEUE_FLAG_READFULL, &q->queue_flags);
+	else
+		clear_bit(QUEUE_FLAG_WRITEFULL, &q->queue_flags);
+}
+
+
 /*
  * mergeable request must not have _NOMERGE or _BARRIER bit set, nor may
  * it already be started by driver.
@@ -397,6 +481,8 @@
 	unsigned block_size_bits;
 };
 
+extern int blk_register_queue(struct gendisk *disk);
+extern void blk_unregister_queue(struct gendisk *disk);
 extern void register_disk(struct gendisk *dev);
 extern void generic_make_request(struct bio *bio);
 extern void blk_put_request(struct request *);
@@ -560,6 +646,10 @@
 	page_cache_release(p.v);
 }
 
+struct work_struct;
+int kblockd_schedule_work(struct work_struct *work);
+void kblockd_flush(void);
+
 #ifdef CONFIG_LBD
 # include <asm/div64.h>
 # define sector_div(a, b) do_div(a, b)
diff -urN linux-2.5.74-bk3/include/linux/elevator.h linux-2.5.74-bk4/include/linux/elevator.h
--- linux-2.5.74-bk3/include/linux/elevator.h	2003-07-02 13:40:19.000000000 -0700
+++ linux-2.5.74-bk4/include/linux/elevator.h	2003-07-06 09:15:53.000000000 -0700
@@ -15,6 +15,9 @@
 typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
 typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
 typedef struct list_head *(elevator_get_sort_head_fn) (request_queue_t *, struct request *);
+typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
+typedef int (elevator_may_queue_fn) (request_queue_t *, int);
+
 typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, int);
 typedef void (elevator_put_req_fn) (request_queue_t *, struct request *);
 
@@ -32,6 +35,7 @@
 	elevator_remove_req_fn *elevator_remove_req_fn;
 
 	elevator_queue_empty_fn *elevator_queue_empty_fn;
+	elevator_completed_req_fn *elevator_completed_req_fn;
 
 	elevator_request_list_fn *elevator_former_req_fn;
 	elevator_request_list_fn *elevator_latter_req_fn;
@@ -39,6 +43,8 @@
 	elevator_set_req_fn *elevator_set_req_fn;
 	elevator_put_req_fn *elevator_put_req_fn;
 
+	elevator_may_queue_fn *elevator_may_queue_fn;
+
 	elevator_init_fn *elevator_init_fn;
 	elevator_exit_fn *elevator_exit_fn;
 
@@ -62,8 +68,10 @@
 extern struct request *elv_next_request(struct request_queue *q);
 extern struct request *elv_former_request(request_queue_t *, struct request *);
 extern struct request *elv_latter_request(request_queue_t *, struct request *);
-extern int elv_register_queue(struct gendisk *);
-extern void elv_unregister_queue(struct gendisk *);
+extern int elv_register_queue(request_queue_t *q);
+extern void elv_unregister_queue(request_queue_t *q);
+extern int elv_may_queue(request_queue_t *, int);
+extern void elv_completed_request(request_queue_t *, struct request *);
 extern int elv_set_request(request_queue_t *, struct request *, int);
 extern void elv_put_request(request_queue_t *, struct request *);
 
@@ -81,6 +89,11 @@
  */
 extern elevator_t iosched_deadline;
 
+/*
+ * anticipatory I/O scheduler
+ */
+extern elevator_t iosched_as;
+
 extern int elevator_init(request_queue_t *, elevator_t *);
 extern void elevator_exit(request_queue_t *);
 extern inline int elv_rq_merge_ok(struct request *, struct bio *);
diff -urN linux-2.5.74-bk3/include/linux/eventpoll.h linux-2.5.74-bk4/include/linux/eventpoll.h
--- linux-2.5.74-bk3/include/linux/eventpoll.h	2003-07-02 13:46:48.000000000 -0700
+++ linux-2.5.74-bk4/include/linux/eventpoll.h	2003-07-06 09:15:53.000000000 -0700
@@ -14,6 +14,8 @@
 #ifndef _LINUX_EVENTPOLL_H
 #define _LINUX_EVENTPOLL_H
 
+#include <linux/types.h>
+
 
 /* Valid opcodes to issue to sys_epoll_ctl() */
 #define EPOLL_CTL_ADD 1
@@ -55,8 +57,37 @@
 /* Used to initialize the epoll bits inside the "struct file" */
 void eventpoll_init_file(struct file *file);
 
-/* Used in fs/file_table.c:__fput() to unlink files from the eventpoll interface */
-void eventpoll_release(struct file *file);
+/* Used to release the epoll bits inside the "struct file" */
+void eventpoll_release_file(struct file *file);
+
+/*
+ * This is called from inside fs/file_table.c:__fput() to unlink files
+ * from the eventpoll interface. We need to have this facility to cleanup
+ * correctly files that are closed without being removed from the eventpoll
+ * interface.
+ */
+static inline void eventpoll_release(struct file *file)
+{
+
+	/*
+	 * Fast check to avoid the get/release of the semaphore. Since
+	 * we're doing this outside the semaphore lock, it might return
+	 * false negatives, but we don't care. It'll help in 99.99% of cases
+	 * to avoid the semaphore lock. False positives simply cannot happen
+	 * because the file in on the way to be removed and nobody ( but
+	 * eventpoll ) has still a reference to this file.
+	 */
+	if (likely(list_empty(&file->f_ep_links)))
+		return;
+
+	/*
+	 * The file is being closed while it is still linked to an epoll
+	 * descriptor. We need to handle this by correctly unlinking it
+	 * from its containers.
+	 */
+	eventpoll_release_file(file);
+}
+
 
 #else
 
diff -urN linux-2.5.74-bk3/include/linux/sched.h linux-2.5.74-bk4/include/linux/sched.h
--- linux-2.5.74-bk3/include/linux/sched.h	2003-07-02 13:41:10.000000000 -0700
+++ linux-2.5.74-bk4/include/linux/sched.h	2003-07-06 09:15:54.000000000 -0700
@@ -321,6 +321,8 @@
 };
 
 
+struct io_context;			/* See blkdev.h */
+void exit_io_context(void);
 
 struct task_struct {
 	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
@@ -450,6 +452,8 @@
 	struct dentry *proc_dentry;
 	struct backing_dev_info *backing_dev_info;
 
+	struct io_context *io_context;
+
 	unsigned long ptrace_message;
 	siginfo_t *last_siginfo; /* For ptrace use.  */
 };
@@ -481,6 +485,7 @@
 #define PF_KSWAPD	0x00040000	/* I am kswapd */
 #define PF_SWAPOFF	0x00080000	/* I am in swapoff */
 #define PF_LESS_THROTTLE 0x01000000	/* Throttle me less: I clena memory */
+#define PF_SYNCWRITE	0x00200000	/* I am doing a sync write */
 
 #ifdef CONFIG_SMP
 extern int set_cpus_allowed(task_t *p, unsigned long new_mask);
diff -urN linux-2.5.74-bk3/include/linux/sem.h linux-2.5.74-bk4/include/linux/sem.h
--- linux-2.5.74-bk3/include/linux/sem.h	2003-07-02 13:46:08.000000000 -0700
+++ linux-2.5.74-bk4/include/linux/sem.h	2003-07-06 09:15:54.000000000 -0700
@@ -109,7 +109,6 @@
 	int			id;	 /* internal sem id */
 	struct sembuf *		sops;	 /* array of pending operations */
 	int			nsops;	 /* number of operations */
-	int			alter;	 /* operation will alter semaphore */
 };
 
 /* Each task has a list of undo requests. They are executed automatically
diff -urN linux-2.5.74-bk3/ipc/sem.c linux-2.5.74-bk4/ipc/sem.c
--- linux-2.5.74-bk3/ipc/sem.c	2003-07-02 13:45:55.000000000 -0700
+++ linux-2.5.74-bk4/ipc/sem.c	2003-07-06 09:15:54.000000000 -0700
@@ -49,6 +49,10 @@
  *      increase. If there are decrement operations in the operations
  *      array we do the same as before.
  *
+ * With the incarnation of O(1) scheduler, it becomes unnecessary to perform
+ * check/retry algorithm for waking up blocked processes as the new scheduler
+ * is better at handling thread switch than the old one.
+ *
  * /proc/sysvipc/sem support (c) 1999 Dragos Acostachioaie <dragos@iname.com>
  *
  * SMP-threaded, sysctl's added
@@ -258,8 +262,7 @@
  */
 
 static int try_atomic_semop (struct sem_array * sma, struct sembuf * sops,
-			     int nsops, struct sem_undo *un, int pid,
-			     int do_undo)
+			     int nsops, struct sem_undo *un, int pid)
 {
 	int result, sem_op;
 	struct sembuf *sop;
@@ -289,10 +292,6 @@
 		curr->semval = result;
 	}
 
-	if (do_undo) {
-		result = 0;
-		goto undo;
-	}
 	sop--;
 	while (sop >= sops) {
 		sma->sem_base[sop->sem_num].sempid = pid;
@@ -334,23 +333,14 @@
 
 	for (q = sma->sem_pending; q; q = q->next) {
 			
-		if (q->status == 1)
-			continue;	/* this one was woken up before */
-
 		error = try_atomic_semop(sma, q->sops, q->nsops,
-					 q->undo, q->pid, q->alter);
+					 q->undo, q->pid);
 
 		/* Does q->sleeper still need to sleep? */
 		if (error <= 0) {
-				/* Found one, wake it up */
-			wake_up_process(q->sleeper);
-			if (error == 0 && q->alter) {
-				/* if q-> alter let it self try */
-				q->status = 1;
-				return;
-			}
 			q->status = error;
 			remove_from_queue(sma,q);
+			wake_up_process(q->sleeper);
 		}
 	}
 }
@@ -1062,7 +1052,7 @@
 	if (error)
 		goto out_unlock_free;
 
-	error = try_atomic_semop (sma, sops, nsops, un, current->pid, 0);
+	error = try_atomic_semop (sma, sops, nsops, un, current->pid);
 	if (error <= 0)
 		goto update;
 
@@ -1075,55 +1065,46 @@
 	queue.nsops = nsops;
 	queue.undo = un;
 	queue.pid = current->pid;
-	queue.alter = decrease;
 	queue.id = semid;
 	if (alter)
 		append_to_queue(sma ,&queue);
 	else
 		prepend_to_queue(sma ,&queue);
 
-	for (;;) {
-		queue.status = -EINTR;
-		queue.sleeper = current;
-		current->state = TASK_INTERRUPTIBLE;
-		sem_unlock(sma);
+	queue.status = -EINTR;
+	queue.sleeper = current;
+	current->state = TASK_INTERRUPTIBLE;
+	sem_unlock(sma);
 
-		if (timeout)
-			jiffies_left = schedule_timeout(jiffies_left);
-		else
-			schedule();
+	if (timeout)
+		jiffies_left = schedule_timeout(jiffies_left);
+	else
+		schedule();
 
-		sma = sem_lock(semid);
-		if(sma==NULL) {
-			if(queue.prev != NULL)
-				BUG();
-			error = -EIDRM;
-			goto out_free;
-		}
-		/*
-		 * If queue.status == 1 we where woken up and
-		 * have to retry else we simply return.
-		 * If an interrupt occurred we have to clean up the
-		 * queue
-		 *
-		 */
-		if (queue.status == 1)
-		{
-			error = try_atomic_semop (sma, sops, nsops, un,
-						  current->pid,0);
-			if (error <= 0) 
-				break;
-		} else {
-			error = queue.status;
-			if (error == -EINTR && timeout && jiffies_left == 0)
-				error = -EAGAIN;
-			if (queue.prev) /* got Interrupt */
-				break;
-			/* Everything done by update_queue */
-			goto out_unlock_free;
-		}
+	sma = sem_lock(semid);
+	if(sma==NULL) {
+		if(queue.prev != NULL)
+			BUG();
+		error = -EIDRM;
+		goto out_free;
+	}
+
+	/*
+	 * If queue.status != -EINTR we are woken up by another process
+	 */
+	error = queue.status;
+	if (queue.status != -EINTR) {
+		goto out_unlock_free;
 	}
+
+	/*
+	 * If an interrupt occurred we have to clean up the queue
+	 */
+	if (timeout && jiffies_left == 0)
+		error = -EAGAIN;
 	remove_from_queue(sma,&queue);
+	goto out_unlock_free;
+
 update:
 	if (alter)
 		update_queue (sma);
diff -urN linux-2.5.74-bk3/kernel/exit.c linux-2.5.74-bk4/kernel/exit.c
--- linux-2.5.74-bk3/kernel/exit.c	2003-07-06 09:15:39.000000000 -0700
+++ linux-2.5.74-bk4/kernel/exit.c	2003-07-06 09:15:54.000000000 -0700
@@ -230,6 +230,7 @@
 	/* signals? */
 	security_task_reparent_to_init(current);
 	memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim)));
+	atomic_inc(&(INIT_USER->__count));
 	switch_uid(INIT_USER);
 
 	write_unlock_irq(&tasklist_lock);
@@ -682,6 +683,8 @@
 		panic("Attempted to kill the idle task!");
 	if (unlikely(tsk->pid == 1))
 		panic("Attempted to kill init!");
+	if (tsk->io_context)
+		exit_io_context();
 	tsk->flags |= PF_EXITING;
 	del_timer_sync(&tsk->real_timer);
 
diff -urN linux-2.5.74-bk3/kernel/fork.c linux-2.5.74-bk4/kernel/fork.c
--- linux-2.5.74-bk3/kernel/fork.c	2003-07-06 09:15:39.000000000 -0700
+++ linux-2.5.74-bk4/kernel/fork.c	2003-07-06 09:15:54.000000000 -0700
@@ -864,6 +864,7 @@
 	p->lock_depth = -1;		/* -1 = no lock */
 	p->start_time = get_jiffies_64();
 	p->security = NULL;
+	p->io_context = NULL;
 
 	retval = -ENOMEM;
 	if ((retval = security_task_alloc(p)))
diff -urN linux-2.5.74-bk3/kernel/signal.c linux-2.5.74-bk4/kernel/signal.c
--- linux-2.5.74-bk3/kernel/signal.c	2003-07-06 09:15:39.000000000 -0700
+++ linux-2.5.74-bk4/kernel/signal.c	2003-07-06 09:15:54.000000000 -0700
@@ -2082,7 +2082,7 @@
 	info.si_signo = sig;
 	info.si_errno = 0;
 	info.si_code = SI_USER;
-	info.si_pid = current->pid;
+	info.si_pid = current->tgid;
 	info.si_uid = current->uid;
 
 	return kill_something_info(sig, &info, pid);
@@ -2105,7 +2105,7 @@
 	info.si_signo = sig;
 	info.si_errno = 0;
 	info.si_code = SI_TKILL;
-	info.si_pid = current->pid;
+	info.si_pid = current->tgid;
 	info.si_uid = current->uid;
 
 	read_lock(&tasklist_lock);
diff -urN linux-2.5.74-bk3/kernel/user.c linux-2.5.74-bk4/kernel/user.c
--- linux-2.5.74-bk3/kernel/user.c	2003-07-02 13:45:20.000000000 -0700
+++ linux-2.5.74-bk4/kernel/user.c	2003-07-06 09:15:54.000000000 -0700
@@ -126,7 +126,6 @@
 	 * we should be checking for it.  -DaveM
 	 */
 	old_user = current->user;
-	atomic_inc(&new_user->__count);
 	atomic_inc(&new_user->processes);
 	atomic_dec(&old_user->processes);
 	current->user = new_user;
diff -urN linux-2.5.74-bk3/mm/bootmem.c linux-2.5.74-bk4/mm/bootmem.c
--- linux-2.5.74-bk3/mm/bootmem.c	2003-07-02 13:44:28.000000000 -0700
+++ linux-2.5.74-bk4/mm/bootmem.c	2003-07-06 09:15:54.000000000 -0700
@@ -84,10 +84,6 @@
 
 	if (!size) BUG();
 
-	if (sidx < 0)
-		BUG();
-	if (eidx < 0)
-		BUG();
 	if (sidx >= eidx)
 		BUG();
 	if ((addr >> PAGE_SHIFT) >= bdata->node_low_pfn)
@@ -202,7 +198,7 @@
 		;
 	}
 
-	if (preferred) {
+	if (preferred > offset) {
 		preferred = offset;
 		goto restart_scan;
 	}
diff -urN linux-2.5.74-bk3/mm/readahead.c linux-2.5.74-bk4/mm/readahead.c
--- linux-2.5.74-bk3/mm/readahead.c	2003-07-02 13:40:57.000000000 -0700
+++ linux-2.5.74-bk4/mm/readahead.c	2003-07-06 09:15:54.000000000 -0700
@@ -363,9 +363,9 @@
 	} else {
 		/*
 		 * A miss - lseek, pagefault, pread, etc.  Shrink the readahead
-		 * window by 25%.
+		 * window.
 		 */
-		ra->next_size -= ra->next_size / 4 + 2;
+		ra->next_size -= 2;
 	}
 
 	if ((long)ra->next_size > (long)max)
@@ -447,7 +447,7 @@
 			struct file *filp, unsigned long offset)
 {
 	if (ra->next_size != -1UL) {
-		const unsigned long min = get_min_readahead(ra) * 2;
+		const unsigned long min = get_min_readahead(ra) * 4;
 		unsigned long target;
 		unsigned long backward;
 
diff -urN linux-2.5.74-bk3/net/bluetooth/hci_sock.c linux-2.5.74-bk4/net/bluetooth/hci_sock.c
--- linux-2.5.74-bk3/net/bluetooth/hci_sock.c	2003-07-02 13:49:11.000000000 -0700
+++ linux-2.5.74-bk4/net/bluetooth/hci_sock.c	2003-07-06 09:15:54.000000000 -0700
@@ -632,6 +632,7 @@
 
 struct net_proto_family hci_sock_family_ops = {
 	.family = PF_BLUETOOTH,
+	.owner	= THIS_MODULE,
 	.create = hci_sock_create,
 };
 
diff -urN linux-2.5.74-bk3/net/bluetooth/rfcomm/sock.c linux-2.5.74-bk4/net/bluetooth/rfcomm/sock.c
--- linux-2.5.74-bk3/net/bluetooth/rfcomm/sock.c	2003-07-02 13:50:14.000000000 -0700
+++ linux-2.5.74-bk4/net/bluetooth/rfcomm/sock.c	2003-07-06 09:15:54.000000000 -0700
@@ -878,6 +878,7 @@
 
 static struct net_proto_family rfcomm_sock_family_ops = {
 	.family		= PF_BLUETOOTH,
+	.owner		= THIS_MODULE,
 	.create		= rfcomm_sock_create
 };
 
