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

diff -urN linux-2.5.70-bk9/Documentation/networking/ip-sysctl.txt linux-2.5.70-bk10/Documentation/networking/ip-sysctl.txt
--- linux-2.5.70-bk9/Documentation/networking/ip-sysctl.txt	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/Documentation/networking/ip-sysctl.txt	2003-06-05 04:41:35.000000000 -0700
@@ -31,6 +31,11 @@
 ipfrag_time - INTEGER
 	Time in seconds to keep an IP fragment in memory.	
 
+ipfrag_secret_interval - INTEGER
+	Regeneration interval (in seconds) of the hash secret (or lifetime 
+	for the hash secret) for IP fragments.
+	Default: 600
+
 INET peer storage:
 
 inet_peer_threshold - INTEGER
@@ -515,6 +520,25 @@
 
 	Default: FALSE (as specified in RFC2553bis)
 
+IPv6 Fragmentation:
+
+ip6frag_high_thresh - INTEGER
+	Maximum memory used to reassemble IPv6 fragments. When 
+	ip6frag_high_thresh bytes of memory is allocated for this purpose,
+	the fragment handler will toss packets until ip6frag_low_thresh
+	is reached.
+	
+ip6frag_low_thresh - INTEGER
+	See ip6frag_high_thresh	
+
+ip6frag_time - INTEGER
+	Time in seconds to keep an IPv6 fragment in memory.
+
+ip6frag_secret_interval - INTEGER
+	Regeneration interval (in seconds) of the hash secret (or lifetime 
+	for the hash secret) for IPv6 fragments.
+	Default: 600
+
 conf/default/*:
 	Change the interface-specific default settings.
 
diff -urN linux-2.5.70-bk9/Documentation/vm/hugetlbpage.txt linux-2.5.70-bk10/Documentation/vm/hugetlbpage.txt
--- linux-2.5.70-bk9/Documentation/vm/hugetlbpage.txt	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/Documentation/vm/hugetlbpage.txt	2003-06-05 04:41:35.000000000 -0700
@@ -67,15 +67,22 @@
 call, then it is required that system administrator mount a file system of
 type hugetlbfs:
 
-	mount none /mnt/huge -t hugetlbfs
+	mount none /mnt/huge -t hugetlbfs <uid=value> <gid=value> <mode=value>
 
 This command mounts a (pseudo) filesystem of type hugetlbfs on the directory
-/mnt/huge.  Any files created on /mnt/huge uses hugepages.  An example is
-given at the end of this document.
+/mnt/huge.  Any files created on /mnt/huge uses hugepages.  The uid and gid
+options sets the owner and group of the root of the file system.  By default
+the uid and gid of the current process are taken.  The mode option sets the
+mode of root of file system to value & 0777.  This value is given in octal.
+By default the value 0755 is picked.  An example is given at the end of this
+document.
 
 read and write system calls are not supported on files that reside on hugetlb
 file systems.
 
+A regular chown, chgrp and chmod commands (with right permissions) could be
+used to change the file attributes on hugetlbfs.
+
 Also, it is important to note that no such mount command is required if the
 applications are going to use only shmat/shmget system calls.  It is possible
 for same or different applications to use any combination of mmaps and shm*
diff -urN linux-2.5.70-bk9/Makefile linux-2.5.70-bk10/Makefile
--- linux-2.5.70-bk9/Makefile	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/Makefile	2003-06-05 04:41:35.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 70
-EXTRAVERSION = -bk9
+EXTRAVERSION = -bk10
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -36,13 +36,36 @@
 SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
 				  -e s/arm.*/arm/ -e s/sa110/arm/ \
 				  -e s/s390x/s390/ )
-ARCH := $(SUBARCH)
 
 # Remove hyphens since they have special meaning in RPM filenames
 KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE))
 
+# Cross compiling and selecting different set of gcc/bin-utils
+# ---------------------------------------------------------------------------
+#
+# When performing cross compilation for other architectures ARCH shall be set
+# to the target architecture. (See arch/* for the possibilities).
+# ARCH can be set during invocation of make:
+# make ARCH=ia64
+# Another way is to have ARCH set in the environment.
+# The default ARCH is the host where make is executed.
+
+# CROSS_COMPILE specify the prefix used for all executables used
+# during compilation. Only gcc and related bin-utils executables
+# are prefixed with $(CROSS_COMPILE).
+# CROSS_COMPILE can be set on the command line
+# make CROSS_COMPILE=ia64-linux-
+# Alternatively CROSS_COMPILE can be set in the environment.
+# Default value for CROSS_COMPILE is not to prefix executables
+# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+
+ARCH		?= $(SUBARCH)
+CROSS_COMPILE	?=
+
+# Architecture as present in compile.h
 UTS_MACHINE := $(ARCH)
 
+# SHELL used by kbuild
 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
 	  else if [ -x /bin/bash ]; then echo /bin/bash; \
 	  else echo sh; fi ; fi)
@@ -53,7 +76,6 @@
 HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
 HOSTCXXFLAGS	= -O2
 
-CROSS_COMPILE 	=
 
 # 	That's our default target when none is given on the command line
 #	Note that 'modules' will be added as a prerequisite as well, 
@@ -783,25 +805,27 @@
 
 help:
 	@echo  'Cleaning targets:'
-	@echo  '  clean		- remove most generated files but keep the config'
-	@echo  '  mrproper	- remove all generated files + config + various backup files'
+	@echo  '  clean		  - remove most generated files but keep the config'
+	@echo  '  mrproper	  - remove all generated files + config + various backup files'
 	@echo  ''
 	@echo  'Configuration targets:'
-	@echo  '  oldconfig	- Update current config utilising a line-oriented program'
-	@echo  '  menuconfig	- Update current config utilising a menu based program'
-	@echo  '  xconfig	- Update current config utilising a X-based program'
-	@echo  '  defconfig	- New config with default answer to all options'
-	@echo  '  allmodconfig	- New config selecting modules when possible'
-	@echo  '  allyesconfig	- New config where all options are accepted with yes'
-	@echo  '  allnoconfig	- New minimal config'
+	@echo  '  oldconfig	  - Update current config utilising a line-oriented program'
+	@echo  '  menuconfig	  - Update current config utilising a menu based program'
+	@echo  '  xconfig	  - Update current config utilising a QT based front-end'
+	@echo  '  gconfig	  - Update current config utilising a GTK based front-end'
+	@echo  '  defconfig	  - New config with default answer to all options'
+	@echo  '  allmodconfig	  - New config selecting modules when possible'
+	@echo  '  allyesconfig	  - New config where all options are accepted with yes'
+	@echo  '  allnoconfig	  - New minimal config'
 	@echo  ''
 	@echo  'Other generic targets:'
-	@echo  '  all		- Build all targets marked with [*]'
-	@echo  '* vmlinux	- Build the bare kernel'
-	@echo  '* modules	- Build all modules'
-	@echo  '  dir/file.[ois]- Build specified target only'
-	@echo  '  rpm		- Build a kernel as an RPM package'
-	@echo  '  tags/TAGS	- Generate tags file for editors'
+	@echo  '  all		  - Build all targets marked with [*]'
+	@echo  '* vmlinux	  - Build the bare kernel'
+	@echo  '* modules	  - Build all modules'
+	@echo  '  modules_install - Install all modules'
+	@echo  '  dir/file.[ois]  - Build specified target only'
+	@echo  '  rpm		  - Build a kernel as an RPM package'
+	@echo  '  tags/TAGS	  - Generate tags file for editors'
 	@echo  ''
 	@echo  'Documentation targets:'
 	@$(MAKE) --no-print-directory -f Documentation/DocBook/Makefile dochelp
@@ -810,6 +834,9 @@
 	@$(if $(archhelp),$(archhelp),\
 		echo '  No architecture specific help defined for $(ARCH)')
 	@echo  ''
+	@echo  '  make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
+	@echo  '  make C=1   [targets] Check all c source with checker tool'
+	@echo  ''
 	@echo  'Execute "make" or "make all" to build all targets marked with [*] '
 	@echo  'For further info browse Documentation/kbuild/*'
 
diff -urN linux-2.5.70-bk9/arch/alpha/kernel/sys_sio.c linux-2.5.70-bk10/arch/alpha/kernel/sys_sio.c
--- linux-2.5.70-bk9/arch/alpha/kernel/sys_sio.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk10/arch/alpha/kernel/sys_sio.c	2003-06-05 04:41:35.000000000 -0700
@@ -85,10 +85,10 @@
 sio_collect_irq_levels(void)
 {
 	unsigned int level_bits = 0;
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
 	/* Iterate through the devices, collecting IRQ levels.  */
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
 		    (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
 			continue;
diff -urN linux-2.5.70-bk9/arch/arm/common/Makefile linux-2.5.70-bk10/arch/arm/common/Makefile
--- linux-2.5.70-bk9/arch/arm/common/Makefile	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/common/Makefile	2003-06-05 04:41:35.000000000 -0700
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-$(CONFIG_SA1111)	+= sa1111.o sa1111-pcibuf.o sa1111-pcipool.o
-
+obj-y				+= platform.o
+obj-$(CONFIG_SA1111)		+= sa1111.o sa1111-pcibuf.o sa1111-pcipool.o
 obj-$(CONFIG_PCI_HOST_PLX90X0)	+= plx90x0.o
 obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
diff -urN linux-2.5.70-bk9/arch/arm/common/platform.c linux-2.5.70-bk10/arch/arm/common/platform.c
--- linux-2.5.70-bk9/arch/arm/common/platform.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/arch/arm/common/platform.c	2003-06-05 04:41:35.000000000 -0700
@@ -0,0 +1,35 @@
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/init.h>
+
+int __init platform_add_device(struct platform_device *dev)
+{
+	int i;
+
+	for (i = 0; i < dev->num_resources; i++) {
+		struct resource *r = &dev->resource[i];
+
+		r->name = dev->dev.name;
+
+		if (r->flags & IORESOURCE_MEM &&
+		    request_resource(&iomem_resource, r)) {
+			printk(KERN_ERR
+			       "%s%d: failed to claim resource %d\n",
+			       dev->name, dev->id, i);
+			break;
+		}
+	}
+	if (i == dev->num_resources)
+		platform_device_register(dev);
+	return 0;
+}
+
+int __init platform_add_devices(struct platform_device **devs, int num)
+{
+	int i;
+
+	for (i = 0; i < num; i++)
+		platform_add_device(devs[i]);
+
+	return 0;
+}
diff -urN linux-2.5.70-bk9/arch/arm/common/sa1111.c linux-2.5.70-bk10/arch/arm/common/sa1111.c
--- linux-2.5.70-bk9/arch/arm/common/sa1111.c	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/common/sa1111.c	2003-06-05 04:41:35.000000000 -0700
@@ -42,7 +42,7 @@
  */
 struct sa1111 {
 	struct device	*dev;
-	struct resource	res;
+	unsigned long	phys;
 	int		irq;
 	spinlock_t	lock;
 	void		*base;
@@ -60,7 +60,6 @@
 	},
 	.skpcr_mask	= SKPCR_UCLKEN,
 	.devid		= SA1111_DEVID_USB,
-	.dma_mask	= 0xffffffffLL,
 	.irq = {
 		IRQ_USBPWR,
 		IRQ_HCIM,
@@ -470,6 +469,17 @@
 
 #ifdef CONFIG_ARCH_SA1100
 
+static u32 sa1111_dma_mask[] = {
+	~0,
+	~(1 << 20),
+	~(1 << 23),
+	~(1 << 24),
+	~(1 << 25),
+	~(1 << 20),
+	~(1 << 20),
+	0,
+};
+
 /*
  * Configure the SA1111 shared memory controller.
  */
@@ -483,26 +493,43 @@
 		smcr |= SMCR_CLAT;
 
 	sa1111_writel(smcr, sachip->base + SA1111_SMCR);
+
+	/*
+	 * Now clear the bits in the DMA mask to work around the SA1111
+	 * DMA erratum (Intel StrongARM SA-1111 Microprocessor Companion
+	 * Chip Specification Update, June 2000, Erratum #7).
+	 */
+	if (sachip->dev->dma_mask)
+		*sachip->dev->dma_mask &= sa1111_dma_mask[drac >> 2];
 }
 
 #endif
 
 static void
-sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned int offset)
+sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
+		      struct sa1111_dev *sadev, unsigned int offset)
 {
 	snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id),
 		 "%4.4x", offset);
 
+	/*
+	 * If the parent device has a DMA mask associated with it,
+	 * propagate it down to the children.
+	 */
+	if (sachip->dev->dma_mask) {
+		sadev->dma_mask = *sachip->dev->dma_mask;
+		sadev->dev.dma_mask = &sadev->dma_mask;
+	}
+
 	sadev->dev.parent = sachip->dev;
 	sadev->dev.bus    = &sa1111_bus_type;
-	sadev->dev.dma_mask = &sadev->dma_mask;
-	sadev->res.start  = sachip->res.start + offset;
+	sadev->res.start  = sachip->phys + offset;
 	sadev->res.end    = sadev->res.start + 511;
 	sadev->res.name   = sadev->dev.name;
 	sadev->res.flags  = IORESOURCE_MEM;
 	sadev->mapbase    = sachip->base + offset;
 
-	if (request_resource(&sachip->res, &sadev->res)) {
+	if (request_resource(parent, &sadev->res)) {
 		printk("SA1111: failed to allocate resource for %s\n",
 			sadev->res.name);
 		return;
@@ -524,7 +551,7 @@
  *	%0		successful.
  */
 static int __init
-__sa1111_probe(struct device *me, unsigned long phys_addr, int irq)
+__sa1111_probe(struct device *me, struct resource *mem, int irq)
 {
 	struct sa1111 *sachip;
 	unsigned long id;
@@ -542,24 +569,17 @@
 	sachip->dev = me;
 	dev_set_drvdata(sachip->dev, sachip);
 
-	sachip->res.name  = me->name;
-	sachip->res.start = phys_addr;
-	sachip->res.end   = phys_addr + 0x2000;
+	sachip->phys = mem->start;
 	sachip->irq = irq;
 
-	if (request_resource(&iomem_resource, &sachip->res)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	/*
 	 * Map the whole region.  This also maps the
 	 * registers for our children.
 	 */
-	sachip->base = ioremap(phys_addr, PAGE_SIZE * 2);
+	sachip->base = ioremap(mem->start, PAGE_SIZE * 2);
 	if (!sachip->base) {
 		ret = -ENOMEM;
-		goto release;
+		goto out;
 	}
 
 	/*
@@ -611,9 +631,11 @@
 	 * The interrupt controller must be initialised before any
 	 * other device to ensure that the interrupts are available.
 	 */
-	int_dev.irq[0] = irq;
-	sa1111_init_one_child(sachip, &int_dev, SA1111_INTC);
-	sa1111_init_irq(&int_dev);
+	if (irq != NO_IRQ) {
+		int_dev.irq[0] = irq;
+		sa1111_init_one_child(sachip, mem, &int_dev, SA1111_INTC);
+		sa1111_init_irq(&int_dev);
+	}
 
 	g_sa1111 = sachip;
 
@@ -626,14 +648,12 @@
 
 	for (i = 0; i < ARRAY_SIZE(devs); i++)
 		if (has_devs & (1 << i))
-			sa1111_init_one_child(sachip, devs[i], dev_offset[i]);
+			sa1111_init_one_child(sachip, mem, devs[i], dev_offset[i]);
 
 	return 0;
 
  unmap:
 	iounmap(sachip->base);
- release:
-	release_resource(&sachip->res);
  out:
 	kfree(sachip);
 	return ret;
@@ -649,7 +669,6 @@
 	}
 
 	iounmap(sachip->base);
-	release_resource(&sachip->res);
 	kfree(sachip);
 }
 
@@ -874,7 +893,17 @@
 
 static int sa1111_probe(struct device *dev)
 {
-	return -ENODEV;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct resource *mem = NULL, *irq = NULL;
+	int i;
+
+	for (i = 0; i < pdev->num_resources; i++) {
+		if (pdev->resource[i].flags & IORESOURCE_MEM)
+			mem = &pdev->resource[i];
+		if (pdev->resource[i].flags & IORESOURCE_IRQ)
+			irq = &pdev->resource[i];
+	}
+	return __sa1111_probe(dev, mem, irq ? irq->start : NO_IRQ);
 }
 
 static int sa1111_remove(struct device *dev)
@@ -903,7 +932,7 @@
  */
 static struct device_driver sa1111_device_driver = {
 	.name		= "sa1111",
-	.bus		= &system_bus_type,
+	.bus		= &platform_bus_type,
 	.probe		= sa1111_probe,
 	.remove		= sa1111_remove,
 	.suspend	= sa1111_suspend,
@@ -921,29 +950,6 @@
 
 arch_initcall(sa1111_driver_init);
 
-static struct sys_device sa1111_device = {
-	.name		= "SA1111",
-	.id		= 0,
-	.root		= NULL,
-	.dev = {
-		.name	= "Intel Corporation SA1111",
-		.driver	= &sa1111_device_driver,
-	},
-};
-
-int sa1111_init(unsigned long phys, unsigned int irq)
-{
-	int ret;
-
-	snprintf(sa1111_device.dev.bus_id, sizeof(sa1111_device.dev.bus_id), "%8.8lx", phys);
-
-	ret = sys_device_register(&sa1111_device);
-	if (ret)
-		printk("sa1111 device_register failed: %d\n", ret);
-
-	return __sa1111_probe(&sa1111_device.dev, phys, irq);
-}
-
 /*
  *	Get the parent device driver (us) structure
  *	from a child function device
diff -urN linux-2.5.70-bk9/arch/arm/kernel/bios32.c linux-2.5.70-bk10/arch/arm/kernel/bios32.c
--- linux-2.5.70-bk9/arch/arm/kernel/bios32.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/kernel/bios32.c	2003-06-05 04:41:35.000000000 -0700
@@ -22,9 +22,9 @@
 
 void pcibios_report_status(u_int status_mask, int warn)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		u16 status;
 
 		/*
diff -urN linux-2.5.70-bk9/arch/arm/kernel/process.c linux-2.5.70-bk10/arch/arm/kernel/process.c
--- linux-2.5.70-bk9/arch/arm/kernel/process.c	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/kernel/process.c	2003-06-05 04:41:35.000000000 -0700
@@ -239,7 +239,7 @@
 #define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
 
-struct thread_info *alloc_thread_info(void)
+struct thread_info *alloc_thread_info(struct task_struct *task)
 {
 	struct thread_info *thread = NULL;
 
diff -urN linux-2.5.70-bk9/arch/arm/mach-footbridge/isa-irq.c linux-2.5.70-bk10/arch/arm/mach-footbridge/isa-irq.c
--- linux-2.5.70-bk9/arch/arm/mach-footbridge/isa-irq.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-footbridge/isa-irq.c	2003-06-05 04:41:35.000000000 -0700
@@ -84,10 +84,6 @@
 	.unmask = isa_unmask_pic_hi_irq,
 };
 
-static void no_action(int irq, void *dev_id, struct pt_regs *regs)
-{
-}
-
 static void
 isa_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 {
diff -urN linux-2.5.70-bk9/arch/arm/mach-integrator/Makefile linux-2.5.70-bk10/arch/arm/mach-integrator/Makefile
--- linux-2.5.70-bk9/arch/arm/mach-integrator/Makefile	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-integrator/Makefile	2003-06-05 04:41:35.000000000 -0700
@@ -4,10 +4,7 @@
 
 # Object file lists.
 
-obj-y			:= arch.o irq.o mm.o time.o
-obj-m			:=
-obj-n			:=
-obj-			:=
+obj-y			:= core.o time.o
 
 obj-$(CONFIG_LEDS)	+= leds.o
 obj-$(CONFIG_PCI)	+= pci_v3.o pci.o
diff -urN linux-2.5.70-bk9/arch/arm/mach-integrator/arch.c linux-2.5.70-bk10/arch/arm/mach-integrator/arch.c
--- linux-2.5.70-bk9/arch/arm/mach-integrator/arch.c	2003-05-26 18:00:44.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-integrator/arch.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,40 +0,0 @@
-/*
- *  linux/arch/arm/mach-integrator/arch.c
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-
-extern void integrator_map_io(void);
-extern void integrator_init_irq(void);
-
-MACHINE_START(INTEGRATOR, "ARM-Integrator")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(integrator_map_io)
-	INITIRQ(integrator_init_irq)
-MACHINE_END
diff -urN linux-2.5.70-bk9/arch/arm/mach-integrator/core.c linux-2.5.70-bk10/arch/arm/mach-integrator/core.c
--- linux-2.5.70-bk9/arch/arm/mach-integrator/core.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/arch/arm/mach-integrator/core.c	2003-06-05 04:41:35.000000000 -0700
@@ -0,0 +1,135 @@
+/*
+ *  linux/arch/arm/mach-integrator/arch.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+/* 
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the Integrator interrupt controller (for header #0,
+ * just for now).
+ */
+#define VA_IC_BASE	IO_ADDRESS(INTEGRATOR_IC_BASE) 
+#define VA_CMIC_BASE	IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+
+/*
+ * Logical      Physical
+ * e8000000	40000000	PCI memory		PHYS_PCI_MEM_BASE	(max 512M)
+ * ec000000	61000000	PCI config space	PHYS_PCI_CONFIG_BASE	(max 16M)
+ * ed000000	62000000	PCI V3 regs		PHYS_PCI_V3_BASE	(max 64k)
+ * ee000000	60000000	PCI IO			PHYS_PCI_IO_BASE	(max 16M)
+ * ef000000			Cache flush
+ * f1000000	10000000	Core module registers
+ * f1100000	11000000	System controller registers
+ * f1200000	12000000	EBI registers
+ * f1300000	13000000	Counter/Timer
+ * f1400000	14000000	Interrupt controller
+ * f1500000	15000000	RTC
+ * f1600000	16000000	UART 0
+ * f1700000	17000000	UART 1
+ * f1a00000	1a000000	Debug LEDs
+ * f1b00000	1b000000	GPIO
+ */
+ 
+static struct map_desc integrator_io_desc[] __initdata = {
+ { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_RTC_BASE),   INTEGRATOR_RTC_BASE,   SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
+ { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
+ { PCI_MEMORY_VADDR,                  PHYS_PCI_MEM_BASE,     SZ_16M, MT_DEVICE },
+ { PCI_CONFIG_VADDR,                  PHYS_PCI_CONFIG_BASE,  SZ_16M, MT_DEVICE },
+ { PCI_V3_VADDR,                      PHYS_PCI_V3_BASE,      SZ_64K, MT_DEVICE },
+ { PCI_IO_VADDR,                      PHYS_PCI_IO_BASE,      SZ_64K, MT_DEVICE }
+};
+
+static void __init integrator_map_io(void)
+{
+	iotable_init(integrator_io_desc, ARRAY_SIZE(integrator_io_desc));
+}
+
+#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) 
+
+static void sc_mask_irq(unsigned int irq)
+{
+	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+}
+
+static void sc_unmask_irq(unsigned int irq)
+{
+	writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
+}
+
+static struct irqchip sc_chip = {
+	.ack	= sc_mask_irq,
+	.mask	= sc_mask_irq,
+	.unmask = sc_unmask_irq,
+};
+ 
+static void __init integrator_init_irq(void)
+{
+	unsigned int i;
+
+	/* Disable all interrupts initially. */
+	/* Do the core module ones */
+	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+
+	/* do the header card stuff next */
+	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+
+	for (i = 0; i < NR_IRQS; i++) {
+		if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
+			set_irq_chip(i, &sc_chip);
+			set_irq_handler(i, do_level_IRQ);
+			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+		}
+	}
+}
+
+MACHINE_START(INTEGRATOR, "ARM-Integrator")
+	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
+	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
+	BOOT_PARAMS(0x00000100)
+	MAPIO(integrator_map_io)
+	INITIRQ(integrator_init_irq)
+MACHINE_END
diff -urN linux-2.5.70-bk9/arch/arm/mach-integrator/irq.c linux-2.5.70-bk10/arch/arm/mach-integrator/irq.c
--- linux-2.5.70-bk9/arch/arm/mach-integrator/irq.c	2003-05-26 18:01:02.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-integrator/irq.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,76 +0,0 @@
-/*
- *  linux/arch/arm/mach-integrator/irq.c
- *
- *  Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/init.h>
-#include <linux/list.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <asm/mach/irq.h>
-
-/* 
- * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
- * is the (PA >> 12).
- *
- * Setup a VA for the Integrator interrupt controller (for header #0,
- * just for now).
- */
-#define VA_IC_BASE              IO_ADDRESS(INTEGRATOR_IC_BASE) 
-#define VA_CMIC_BASE            IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
-
-#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) 
-
-static void sc_mask_irq(unsigned int irq)
-{
-        __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
-}
-
-static void sc_unmask_irq(unsigned int irq)
-{
-        __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
-}
-
-static struct irqchip sc_chip = {
-	.ack	= sc_mask_irq,
-	.mask	= sc_mask_irq,
-	.unmask = sc_unmask_irq,
-};
- 
-void __init integrator_init_irq(void)
-{
-	unsigned int i;
-
-	/* Disable all interrupts initially. */
-	/* Do the core module ones */
-	__raw_writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
-
-	/* do the header card stuff next */
-	__raw_writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
-	__raw_writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
-
-	for (i = 0; i < NR_IRQS; i++) {
-	        if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
-	        	set_irq_chip(i, &sc_chip);
-	        	set_irq_handler(i, do_level_IRQ);
-	        	set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-		}
-	}
-}
diff -urN linux-2.5.70-bk9/arch/arm/mach-integrator/mm.c linux-2.5.70-bk10/arch/arm/mach-integrator/mm.c
--- linux-2.5.70-bk9/arch/arm/mach-integrator/mm.c	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-integrator/mm.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,70 +0,0 @@
-/*
- *  linux/arch/arm/mach-integrator/mm.c
- *
- *  Extra MM routines for the ARM Integrator board
- *
- *  Copyright (C) 1999,2000 Arm Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
- 
-#include <asm/mach/map.h>
-
-/*
- * Logical      Physical
- * e8000000	40000000	PCI memory		PHYS_PCI_MEM_BASE	(max 512M)
- * ec000000	61000000	PCI config space	PHYS_PCI_CONFIG_BASE	(max 16M)
- * ed000000	62000000	PCI V3 regs		PHYS_PCI_V3_BASE	(max 64k)
- * ee000000	60000000	PCI IO			PHYS_PCI_IO_BASE	(max 16M)
- * ef000000			Cache flush
- * f1000000	10000000	Core module registers
- * f1100000	11000000	System controller registers
- * f1200000	12000000	EBI registers
- * f1300000	13000000	Counter/Timer
- * f1400000	14000000	Interrupt controller
- * f1500000	15000000	RTC
- * f1600000	16000000	UART 0
- * f1700000	17000000	UART 1
- * f1a00000	1a000000	Debug LEDs
- * f1b00000	1b000000	GPIO
- */
- 
-static struct map_desc integrator_io_desc[] __initdata = {
- { IO_ADDRESS(INTEGRATOR_HDR_BASE),   INTEGRATOR_HDR_BASE,   SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_SC_BASE),    INTEGRATOR_SC_BASE,    SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_EBI_BASE),   INTEGRATOR_EBI_BASE,   SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_CT_BASE),    INTEGRATOR_CT_BASE,    SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_IC_BASE),    INTEGRATOR_IC_BASE,    SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_RTC_BASE),   INTEGRATOR_RTC_BASE,   SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_DBG_BASE),   INTEGRATOR_DBG_BASE,   SZ_4K,  MT_DEVICE },
- { IO_ADDRESS(INTEGRATOR_GPIO_BASE),  INTEGRATOR_GPIO_BASE,  SZ_4K,  MT_DEVICE },
- { PCI_MEMORY_VADDR,                  PHYS_PCI_MEM_BASE,     SZ_16M, MT_DEVICE },
- { PCI_CONFIG_VADDR,                  PHYS_PCI_CONFIG_BASE,  SZ_16M, MT_DEVICE },
- { PCI_V3_VADDR,                      PHYS_PCI_V3_BASE,      SZ_64K, MT_DEVICE },
- { PCI_IO_VADDR,                      PHYS_PCI_IO_BASE,      SZ_64K, MT_DEVICE }
-};
-
-void __init integrator_map_io(void)
-{
-	iotable_init(integrator_io_desc, ARRAY_SIZE(integrator_io_desc));
-}
diff -urN linux-2.5.70-bk9/arch/arm/mach-integrator/pci_v3.c linux-2.5.70-bk10/arch/arm/mach-integrator/pci_v3.c
--- linux-2.5.70-bk9/arch/arm/mach-integrator/pci_v3.c	2003-05-26 18:00:44.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-integrator/pci_v3.c	2003-06-05 04:41:35.000000000 -0700
@@ -441,7 +441,7 @@
 	return 1;
 }
 
-static void v3_irq(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t v3_irq(int irq, void *devid, struct pt_regs *regs)
 {
 #ifdef CONFIG_DEBUG_LL
 	unsigned long pc = instruction_pointer(regs);
@@ -469,6 +469,7 @@
 		printascii(buf);
 	}
 #endif
+	return IRQ_HANDLED;
 }
 
 int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
diff -urN linux-2.5.70-bk9/arch/arm/mach-pxa/lubbock.c linux-2.5.70-bk10/arch/arm/mach-pxa/lubbock.c
--- linux-2.5.70-bk9/arch/arm/mach-pxa/lubbock.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-pxa/lubbock.c	2003-06-05 04:41:35.000000000 -0700
@@ -88,9 +88,36 @@
 	set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
 }
 
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start	= 0x10000000,
+		.end	= 0x10001fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= LUBBOCK_SA1111_IRQ,
+		.end	= LUBBOCK_SA1111_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+};
+
 static int __init lubbock_init(void)
 {
-	return sa1111_init(0x10000000, LUBBOCK_SA1111_IRQ);
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 subsys_initcall(lubbock_init);
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/adsbitsy.c linux-2.5.70-bk10/arch/arm/mach-sa1100/adsbitsy.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/adsbitsy.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/adsbitsy.c	2003-06-05 04:41:35.000000000 -0700
@@ -27,6 +27,36 @@
 
 #include "generic.h"
 
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start		= 0x18000000,
+		.end		= 0x18001fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= IRQ_GPIO0,
+		.end		= IRQ_GPIO0,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+		.dma_mask = &sa1111_dmamask,
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+};
+
 static int __init adsbitsy_init(void)
 {
 	int ret;
@@ -50,7 +80,7 @@
 	/*
 	 * Probe for SA1111.
 	 */
-	ret = sa1111_init(0x18000000, IRQ_GPIO0);
+	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret < 0)
 		return ret;
 
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/badge4.c linux-2.5.70-bk10/arch/arm/mach-sa1100/badge4.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/badge4.c	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/badge4.c	2003-06-05 04:41:35.000000000 -0700
@@ -35,6 +35,36 @@
 
 #include "generic.h"
 
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start		= BADGE4_SA1111_BASE,
+		.end		= BADGE4_SA1111_BASE + 0x00001fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= BADGE4_IRQ_GPIO_SA1111,
+		.end		= BADGE4_IRQ_GPIO_SA1111,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+		.dma_mask = &sa1111_dmamask;
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+};
+
 static int __init badge4_sa1111_init(void)
 {
 	/*
@@ -46,7 +76,7 @@
 	/*
 	 * Probe for SA1111.
 	 */
-	return sa1111_init(BADGE4_SA1111_BASE, BADGE4_IRQ_GPIO_SA1111);
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/dma.c linux-2.5.70-bk10/arch/arm/mach-sa1100/dma.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/dma.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/dma.c	2003-06-05 04:41:35.000000000 -0700
@@ -42,7 +42,7 @@
 static spinlock_t dma_list_lock;
 
 
-static void dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 	dma_regs_t *dma_regs = dev_id;
 	sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7);
@@ -60,6 +60,7 @@
 		if (status & DCSR_DONEB)
 			dma->callback(dma->data);
 	}
+	return IRQ_HANDLED;
 }
 
 
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/generic.c linux-2.5.70-bk10/arch/arm/mach-sa1100/generic.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/generic.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/generic.c	2003-06-05 04:41:35.000000000 -0700
@@ -16,11 +16,13 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/cpufreq.h>
+#include <linux/ioport.h>
 
 #include <asm/hardware.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
+#include <asm/irq.h>
 
 #include "generic.h"
 
@@ -128,13 +130,88 @@
 	PMCR = PMCR_SF;
 }
 
+static struct resource sa11x0udc_resources[] = {
+	[0] = {
+		.start	= 0x80000000,
+		.end	= 0x8000ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device sa11x0udc_device = {
+	.name		= "sa11x0-udc",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA11x0 [UDC]",
+	},
+	.num_resources	= ARRAY_SIZE(sa11x0udc_resources),
+	.resource	= sa11x0udc_resources,
+};
+
+static struct resource sa11x0mcp_resources[] = {
+	[0] = {
+		.start	= 0x80060000,
+		.end	= 0x8006ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device sa11x0mcp_device = {
+	.name		= "sa11x0-mcp",
+	.id		= 0,
+	.dev = {
+		.name	= "Intel Corporation SA11x0 [MCP]",
+	},
+	.num_resources	= ARRAY_SIZE(sa11x0mcp_resources),
+	.resource	= sa11x0mcp_resources,
+};
+
+static struct resource sa11x0fb_resources[] = {
+	[0] = {
+		.start	= 0xb0100000,
+		.end	= 0xb010ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_LCD,
+		.end	= IRQ_LCD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sa11x0fb_device = {
+	.name		= "sa11x0-fb",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA11x0 [LCD]",
+	},
+	.num_resources	= ARRAY_SIZE(sa11x0fb_resources),
+	.resource	= sa11x0fb_resources,
+};
+
+static struct platform_device sa11x0pcmcia_device = {
+	.name		= "sa11x0-pcmcia",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA11x0 [PCMCIA]",
+	},
+};
+
+static struct platform_device *sa11x0_devices[] __initdata = {
+	&sa11x0udc_device,
+	&sa11x0mcp_device,
+	&sa11x0pcmcia_device,
+	&sa11x0fb_device,
+};
+
 static int __init sa1100_init(void)
 {
 	pm_power_off = sa1100_power_off;
-	return 0;
+
+	return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
 }
 
-core_initcall(sa1100_init);
+arch_initcall(sa1100_init);
 
 void (*sa1100fb_backlight_power)(int on);
 void (*sa1100fb_lcd_power)(int on);
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/graphicsmaster.c linux-2.5.70-bk10/arch/arm/mach-sa1100/graphicsmaster.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/graphicsmaster.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/graphicsmaster.c	2003-06-05 04:41:35.000000000 -0700
@@ -24,6 +24,36 @@
 
 #include "generic.h"
 
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start		= 0x18000000,
+		.end		= 0x18001fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= ADS_EXT_IRQ(0),
+		.end		= ADS_EXT_IRQ(0),
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+		.dma_mask = &sa1111_dmamask,
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+};
+
 static int __init graphicsmaster_init(void)
 {
 	int ret;
@@ -40,7 +70,7 @@
 	/*
 	 * Probe for SA1111.
 	 */
-	ret = sa1111_init(0x18000000, ADS_EXT_IRQ(0));
+	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret < 0)
 		return ret;
 
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/jornada720.c linux-2.5.70-bk10/arch/arm/mach-sa1100/jornada720.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/jornada720.c	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/jornada720.c	2003-06-05 04:41:35.000000000 -0700
@@ -24,6 +24,36 @@
 
 #define JORTUCR_VAL	0x20000400
 
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start		= 0x40000000,
+		.end		= 0x40001fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= IRQ_GPIO1,
+		.end		= IRQ_GPIO1,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+		.dma_mask = &sa1111_dmamask,
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+};
+
 static int __init jornada720_init(void)
 {
 	int ret = -ENODEV;
@@ -43,7 +73,7 @@
 		PPSR &= ~(PPC_LDD3 | PPC_LDD4);
 		PPDR |= PPC_LDD3 | PPC_LDD4;
 
-		ret = sa1111_init(0x40000000, IRQ_GPIO1);
+		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
 	return ret;
 }
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/neponset.c linux-2.5.70-bk10/arch/arm/mach-sa1100/neponset.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/neponset.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/neponset.c	2003-06-05 04:41:35.000000000 -0700
@@ -79,33 +79,6 @@
 	}
 }
 
-static inline void __init neponset_init_irq(void)
-{
-	/*
-	 * Install handler for GPIO25.
-	 */
-	set_irq_type(IRQ_GPIO25, IRQT_RISING);
-	set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler);
-
-	/*
-	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but
-	 * unfortunately something on the Neponset activates
-	 * this IRQ on sleep (ethernet?)
-	 */
-#if 0
-	enable_irq_wake(IRQ_GPIO25);
-#endif
-
-	/*
-	 * Setup other Neponset IRQs.  SA1111 will be done by the
-	 * generic SA1111 code.
-	 */
-	set_irq_handler(IRQ_NEPONSET_SMC9196, do_simple_IRQ);
-	set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE);
-	set_irq_handler(IRQ_NEPONSET_USAR, do_simple_IRQ);
-	set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE);
-}
-
 static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
 {
 	u_int mdm_ctl0 = MDM_CTL_0;
@@ -164,6 +137,42 @@
 	.get_mctrl	= neponset_get_mctrl,
 };
 
+static int neponset_probe(struct device *dev)
+{
+	sa1100_register_uart_fns(&neponset_port_fns);
+
+	/*
+	 * Install handler for GPIO25.
+	 */
+	set_irq_type(IRQ_GPIO25, IRQT_RISING);
+	set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler);
+
+	/*
+	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but
+	 * unfortunately something on the Neponset activates
+	 * this IRQ on sleep (ethernet?)
+	 */
+#if 0
+	enable_irq_wake(IRQ_GPIO25);
+#endif
+
+	/*
+	 * Setup other Neponset IRQs.  SA1111 will be done by the
+	 * generic SA1111 code.
+	 */
+	set_irq_handler(IRQ_NEPONSET_SMC9196, do_simple_IRQ);
+	set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE);
+	set_irq_handler(IRQ_NEPONSET_USAR, do_simple_IRQ);
+	set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE);
+
+	/*
+	 * Disable GPIO 0/1 drivers so the buttons work on the module.
+	 */
+	NCR_0 = NCR_GP01_OFF;
+
+	return 0;
+}
+
 /*
  * LDM power management.
  */
@@ -201,27 +210,63 @@
 
 static struct device_driver neponset_device_driver = {
 	.name		= "neponset",
-	.bus		= &system_bus_type,
+	.bus		= &platform_bus_type,
+	.probe		= neponset_probe,
 	.suspend	= neponset_suspend,
 	.resume		= neponset_resume,
 };
 
-static struct sys_device neponset_device = {
-	.name		= "NEPONSET",
+static struct resource neponset_resources[] = {
+	[0] = {
+		.start	= 0x10000000,
+		.end	= 0x17ffffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device neponset_device = {
+	.name		= "neponset",
 	.id		= 0,
-	.root		= NULL,
 	.dev = {
 		.name	= "Neponset",
-		.bus_id	= "neponset",
-		.bus	= &system_bus_type,
-		.driver = &neponset_device_driver,
+	},
+	.num_resources	= ARRAY_SIZE(neponset_resources),
+	.resource	= neponset_resources,
+};
+
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start	= 0x40000000,
+		.end	= 0x40001fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_NEPONSET_SA1111,
+		.end	= IRQ_NEPONSET_SA1111,
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+		.dma_mask = &sa1111_dmamask,
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&neponset_device,
+	&sa1111_device,
+};
+
 static int __init neponset_init(void)
 {
-	int ret;
-
 	driver_register(&neponset_device_driver);
 
 	/*
@@ -248,29 +293,7 @@
 		return -ENODEV;
 	}
 
-	ret = sys_device_register(&neponset_device);
-	if (ret)
-		return ret;
-
-	sa1100_register_uart_fns(&neponset_port_fns);
-
-	neponset_init_irq();
-
-	/*
-	 * Disable GPIO 0/1 drivers so the buttons work on the module.
-	 */
-	NCR_0 = NCR_GP01_OFF;
-
-	/*
-	 * Neponset has SA1111 connected to CS4.  We know that after
-	 * reset the chip will be configured for variable latency IO.
-	 */
-	/* FIXME: setup MSC2 */
-
-	/*
-	 * Probe and initialise the SA1111.
-	 */
-	return sa1111_init(0x40000000, IRQ_NEPONSET_SA1111);
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 subsys_initcall(neponset_init);
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/pfs168.c linux-2.5.70-bk10/arch/arm/mach-sa1100/pfs168.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/pfs168.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/pfs168.c	2003-06-05 04:41:35.000000000 -0700
@@ -7,6 +7,7 @@
 #include <linux/tty.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
+#include <linux/device.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -18,6 +19,35 @@
 
 #include "generic.h"
 
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start		= 0x40000000,
+		.end		= 0x40001fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= IRQ_GPIO25,
+		.end		= IRQ_GPIO25,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+		.dma_mask = &sa1111_dmamask,
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+};
 
 static int __init pfs168_init(void)
 {
@@ -32,10 +62,7 @@
 	 */
 	sa1110_mb_disable();
 
-	/*
-	 * Probe for SA1111.
-	 */
-	return sa1111_init(0x40000000, IRQ_GPIO25);
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 arch_initcall(pfs168_init);
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/system3.c linux-2.5.70-bk10/arch/arm/mach-sa1100/system3.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/system3.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/system3.c	2003-06-05 04:41:35.000000000 -0700
@@ -373,6 +373,36 @@
 	}
 }
 
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start		= PT_SA1111_BASE,
+		.end		= PT_SA1111_BASE + 0x00001fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= IRQ_SYSTEM3_SA1111,
+		.end		= IRQ_SYSTEM3_SA1111,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+		.dma_mask = &sa1111_dmamask,
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+};
+
 static int __init system3_init(void)
 {
 	int ret = 0;
@@ -405,7 +435,7 @@
 	/*
 	 * Probe for a SA1111.
 	 */
-	ret = sa1111_init(PT_SA1111_BASE, IRQ_SYSTEM3_SA1111);
+	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret < 0) {
 		printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" );
 		goto DONE;
diff -urN linux-2.5.70-bk9/arch/arm/mach-sa1100/xp860.c linux-2.5.70-bk10/arch/arm/mach-sa1100/xp860.c
--- linux-2.5.70-bk9/arch/arm/mach-sa1100/xp860.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mach-sa1100/xp860.c	2003-06-05 04:41:35.000000000 -0700
@@ -30,6 +30,31 @@
 	while(1);
 }
 
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start		= 0x40000000,
+		.end		= 0x40001fff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA1111",
+		.dma_mask = &sa1111_dmamask,
+	},
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+};
+
 /*
  * Note: I replaced the sa1111_init() without the full SA1111 initialisation
  * because this machine doesn't appear to use the DMA features.  If this is
@@ -39,19 +64,7 @@
 {
 	pm_power_off = xp860_power_off;
 
-	/*
-	 * Probe for SA1111.
-	 */
-	ret = sa1111_probe(0x40000000);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * We found it.  Wake the chip up.
-	 */
-	sa1111_wake();
-
-	return 0;
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 arch_initcall(xp860_init);
diff -urN linux-2.5.70-bk9/arch/arm/mm/consistent.c linux-2.5.70-bk10/arch/arm/mm/consistent.c
--- linux-2.5.70-bk9/arch/arm/mm/consistent.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/arch/arm/mm/consistent.c	2003-06-05 04:41:35.000000000 -0700
@@ -10,7 +10,7 @@
  *  DMA uncached mapping support.
  */
 #include <linux/config.h>
-#include <linux/types.h>
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -145,6 +145,7 @@
 	struct vm_region *c;
 	unsigned long order, flags;
 	void *ret = NULL;
+	int res;
 
 	if (!consistent_pte) {
 		printk(KERN_ERR "consistent_alloc: not initialised\n");
@@ -177,14 +178,19 @@
 	if (!c)
 		goto no_remap;
 
-	spin_lock_irqsave(&consistent_lock, flags);
-	vm_region_dump(&consistent_head, "before alloc");
-
 	/*
 	 * Attempt to allocate a virtual address in the
 	 * consistent mapping region.
 	 */
-	if (!vm_region_alloc(&consistent_head, c, size)) {
+	spin_lock_irqsave(&consistent_lock, flags);
+	vm_region_dump(&consistent_head, "before alloc");
+
+	res = vm_region_alloc(&consistent_head, c, size);
+
+	vm_region_dump(&consistent_head, "after alloc");
+	spin_unlock_irqrestore(&consistent_lock, flags);
+
+	if (!res) {
 		pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start);
 		struct page *end = page + (1 << order);
 		pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
@@ -218,9 +224,6 @@
 		ret = (void *)c->vm_start;
 	}
 
-	vm_region_dump(&consistent_head, "after alloc");
-	spin_unlock_irqrestore(&consistent_lock, flags);
-
  no_remap:
 	if (ret == NULL) {
 		kfree(c);
@@ -231,6 +234,22 @@
 }
 
 /*
+ * Since we have the DMA mask available to us here, we could try to do
+ * a normal allocation, and only fall back to a "DMA" allocation if the
+ * resulting bus address does not satisfy the dma_mask requirements.
+ */
+void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
+{
+	if (dev == NULL || *dev->dma_mask != 0xffffffff)
+		gfp |= GFP_DMA;
+
+	return consistent_alloc(gfp, size, handle, 0);
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+/*
  * free a page as defined by the above mapping.
  */
 void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
diff -urN linux-2.5.70-bk9/arch/i386/Kconfig linux-2.5.70-bk10/arch/i386/Kconfig
--- linux-2.5.70-bk9/arch/i386/Kconfig	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/arch/i386/Kconfig	2003-06-05 04:41:35.000000000 -0700
@@ -1135,7 +1135,7 @@
 
 source "drivers/pcmcia/Kconfig"
 
-source "drivers/hotplug/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
 
 endmenu
 
diff -urN linux-2.5.70-bk9/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c linux-2.5.70-bk10/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- linux-2.5.70-bk9/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	2003-06-05 04:41:35.000000000 -0700
@@ -186,7 +186,7 @@
  **/
 static __init struct pci_dev *gx_detect_chipset(void)
 {
-	struct pci_dev *gx_pci;
+	struct pci_dev *gx_pci = NULL;
 
 	/* check if CPU is a MediaGX or a Geode. */
         if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && 
@@ -196,7 +196,7 @@
 	}
 
 	/* detect which companion chip is used */
-	pci_for_each_dev(gx_pci) {
+	while ((gx_pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) {
 		if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) {
 			return gx_pci;
 		}
diff -urN linux-2.5.70-bk9/arch/i386/pci/i386.c linux-2.5.70-bk10/arch/i386/pci/i386.c
--- linux-2.5.70-bk9/arch/i386/pci/i386.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk10/arch/i386/pci/i386.c	2003-06-05 04:41:35.000000000 -0700
@@ -121,12 +121,12 @@
 
 static void __init pcibios_allocate_resources(int pass)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int idx, disabled;
 	u16 command;
 	struct resource *r, *pr;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		for(idx = 0; idx < 6; idx++) {
 			r = &dev->resource[idx];
@@ -166,11 +166,11 @@
 
 static void __init pcibios_assign_resources(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int idx;
 	struct resource *r;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		int class = dev->class >> 8;
 
 		/* Don't touch classless devices and host bridges */
diff -urN linux-2.5.70-bk9/arch/i386/pci/irq.c linux-2.5.70-bk10/arch/i386/pci/irq.c
--- linux-2.5.70-bk9/arch/i386/pci/irq.c	2003-05-26 18:01:01.000000000 -0700
+++ linux-2.5.70-bk10/arch/i386/pci/irq.c	2003-06-05 04:41:35.000000000 -0700
@@ -573,7 +573,7 @@
 	int irq = 0;
 	u32 mask;
 	struct irq_router *r = pirq_router;
-	struct pci_dev *dev2;
+	struct pci_dev *dev2 = NULL;
 	char *msg = NULL;
 
 	/* Find IRQ pin */
@@ -665,7 +665,7 @@
 	printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
 
 	/* Update IRQ for all devices with the same pirq value */
-	pci_for_each_dev(dev2) {
+	while ((dev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
 		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
 		if (!pin)
 			continue;
@@ -693,11 +693,11 @@
 
 static void __init pcibios_fixup_irqs(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	u8 pin;
 
 	DBG("PCI: IRQ fixup\n");
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		/*
 		 * If the BIOS has set an out of range IRQ number, just ignore it.
 		 * Also keep track of which IRQ's are already in use.
@@ -712,7 +712,8 @@
 		pirq_penalty[dev->irq]++;
 	}
 
-	pci_for_each_dev(dev) {
+	dev = NULL;
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 #ifdef CONFIG_X86_IO_APIC
 		/*
diff -urN linux-2.5.70-bk9/arch/ia64/Kconfig linux-2.5.70-bk10/arch/ia64/Kconfig
--- linux-2.5.70-bk9/arch/ia64/Kconfig	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk10/arch/ia64/Kconfig	2003-06-05 04:41:35.000000000 -0700
@@ -563,7 +563,7 @@
 	  agent" (/sbin/hotplug) to load modules and set up software needed
 	  to use devices as you hotplug them.
 
-source "drivers/hotplug/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
 
diff -urN linux-2.5.70-bk9/arch/ia64/hp/common/sba_iommu.c linux-2.5.70-bk10/arch/ia64/hp/common/sba_iommu.c
--- linux-2.5.70-bk9/arch/ia64/hp/common/sba_iommu.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/arch/ia64/hp/common/sba_iommu.c	2003-06-05 04:41:35.000000000 -0700
@@ -1413,7 +1413,7 @@
 	u32 iova_space_mask;
 	int iov_order, tcnfg;
 	int agp_found = 0;
-	struct pci_dev *device;
+	struct pci_dev *device = NULL;
 #ifdef FULL_VALID_PDIR
 	unsigned long index;
 #endif
@@ -1511,7 +1511,7 @@
 	** We program the next pdir index after we stop w/ a key for
 	** the GART code to handshake on.
 	*/
-	pci_for_each_dev(device)
+	while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL)
 		agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP);
 
 	if (agp_found && reserve_sba_gart) {
diff -urN linux-2.5.70-bk9/arch/ia64/sn/io/pci_bus_cvlink.c linux-2.5.70-bk10/arch/ia64/sn/io/pci_bus_cvlink.c
--- linux-2.5.70-bk9/arch/ia64/sn/io/pci_bus_cvlink.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/arch/ia64/sn/io/pci_bus_cvlink.c	2003-06-05 04:41:35.000000000 -0700
@@ -375,7 +375,7 @@
 	/*
 	 * Initialize the device vertex in the pci_dev struct.
 	 */
-	pci_for_each_dev(device_dev) {
+	while ((device_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device_dev)) != NULL) {
 		unsigned int irq;
 		int idx;
 		u16 cmd;
diff -urN linux-2.5.70-bk9/arch/ia64/sn/io/pciba.c linux-2.5.70-bk10/arch/ia64/sn/io/pciba.c
--- linux-2.5.70-bk9/arch/ia64/sn/io/pciba.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk10/arch/ia64/sn/io/pciba.c	2003-06-05 04:41:35.000000000 -0700
@@ -286,7 +286,7 @@
 static status __init
 register_with_devfs(void)
 {
-	struct pci_dev * dev;
+	struct pci_dev * dev = NULL;
 	devfs_handle_t device_dir_handle;
 	char devfs_path[40];
 
@@ -297,7 +297,7 @@
 
 	/* FIXME: don't forget /dev/pci/mem & /dev/pci/io */
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		sprintf(devfs_path, "pci/%02x/%02x.%x",
 			dev->bus->number,
 			PCI_SLOT(dev->devfn),
@@ -325,14 +325,14 @@
 static status __init
 register_with_devfs(void)
 {
-	struct pci_dev * dev;
+	struct pci_dev * dev = NULL;
 	devfs_handle_t device_dir_handle;
 
 	TRACE();
 
 	/* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		device_dir_handle = devfn_to_vertex(dev->bus->number,
 						    dev->devfn);
 		if (device_dir_handle == NULL)
diff -urN linux-2.5.70-bk9/arch/ia64/sn/io/sn2/pci_bus_cvlink.c linux-2.5.70-bk10/arch/ia64/sn/io/sn2/pci_bus_cvlink.c
--- linux-2.5.70-bk9/arch/ia64/sn/io/sn2/pci_bus_cvlink.c	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk10/arch/ia64/sn/io/sn2/pci_bus_cvlink.c	2003-06-05 04:41:35.000000000 -0700
@@ -325,7 +325,7 @@
 	/*
 	 * Initialize the device vertex in the pci_dev struct.
 	 */
-	pci_for_each_dev(device_dev) {
+	while ((device_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device_dev)) != NULL) {
 		unsigned int irq;
 		int idx;
 		u16 cmd;
diff -urN linux-2.5.70-bk9/arch/m68knommu/Kconfig linux-2.5.70-bk10/arch/m68knommu/Kconfig
--- linux-2.5.70-bk9/arch/m68knommu/Kconfig	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk10/arch/m68knommu/Kconfig	2003-06-05 04:41:35.000000000 -0700
@@ -488,7 +488,7 @@
 
 source "drivers/pcmcia/Kconfig"
 
-source "drivers/hotplug/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
 
 endmenu
 
diff -urN linux-2.5.70-bk9/arch/mips/ddb5074/pci.c linux-2.5.70-bk10/arch/mips/ddb5074/pci.c
--- linux-2.5.70-bk9/arch/mips/ddb5074/pci.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/arch/mips/ddb5074/pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -181,9 +181,9 @@
 
 static void __init ddb5074_pci_fixup(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if (dev->vendor == PCI_VENDOR_ID_NEC &&
 		    dev->device == PCI_DEVICE_ID_NEC_NILE4) {
 			/*
@@ -227,10 +227,10 @@
 
 static void __init pcibios_fixup_irqs(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int slot_num;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		slot_num = PCI_SLOT(dev->devfn);
 		switch (slot_num) {
 		case 0:
diff -urN linux-2.5.70-bk9/arch/mips/ddb5476/pci.c linux-2.5.70-bk10/arch/mips/ddb5476/pci.c
--- linux-2.5.70-bk9/arch/mips/ddb5476/pci.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/arch/mips/ddb5476/pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -187,9 +187,9 @@
 
 static void __init ddb5476_pci_fixup(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if (dev->vendor == PCI_VENDOR_ID_NEC &&
 		    dev->device == PCI_DEVICE_ID_NEC_VRC5476) {
 			/*
@@ -256,10 +256,10 @@
 
 static void __init pcibios_fixup_irqs(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int slot_num;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		slot_num = PCI_SLOT(dev->devfn);
 		switch (slot_num) {
 		case 3:	/* re-programmed to USB */
diff -urN linux-2.5.70-bk9/arch/mips/ddb5xxx/ddb5477/pci.c linux-2.5.70-bk10/arch/mips/ddb5xxx/ddb5477/pci.c
--- linux-2.5.70-bk9/arch/mips/ddb5xxx/ddb5477/pci.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/arch/mips/ddb5xxx/ddb5477/pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -98,10 +98,10 @@
 extern int vrc5477_irq_to_irq(int irq);
 void __init pcibios_fixup_irqs(void)
 {
-        struct pci_dev *dev;
+        struct pci_dev *dev = NULL;
         int slot_num;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		slot_num = PCI_SLOT(dev->devfn);
 		MIPS_ASSERT(slot_num < MAX_SLOT_NUM);
 		MIPS_ASSERT(irq_map[slot_num] != 0xff);
diff -urN linux-2.5.70-bk9/arch/mips/mips-boards/generic/pci.c linux-2.5.70-bk10/arch/mips/mips-boards/generic/pci.c
--- linux-2.5.70-bk9/arch/mips/mips-boards/generic/pci.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/arch/mips/mips-boards/generic/pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -154,7 +154,7 @@
 void __init pcibios_init(void)
 {
 #ifdef CONFIG_MIPS_MALTA
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 	unsigned char reg_val;
 #endif
 
@@ -178,7 +178,7 @@
 	GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); 
 
 #ifdef CONFIG_MIPS_MALTA
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		if ((pdev->vendor == PCI_VENDOR_ID_INTEL)
 		    && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB)
 		    && (PCI_SLOT(pdev->devfn) == 0x0a)) {
diff -urN linux-2.5.70-bk9/arch/mips/sni/pci.c linux-2.5.70-bk10/arch/mips/sni/pci.c
--- linux-2.5.70-bk9/arch/mips/sni/pci.c	2003-05-26 18:01:04.000000000 -0700
+++ linux-2.5.70-bk10/arch/mips/sni/pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -31,9 +31,9 @@
 /* To do:  Bring this uptodate ...  */
 static void pcimt_pcibios_fixup (void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		/*
 		 * TODO: Take care of RM300 revision D boards for where the
 		 * network slot became an ordinary PCI slot.
diff -urN linux-2.5.70-bk9/arch/mips64/mips-boards/generic/pci.c linux-2.5.70-bk10/arch/mips64/mips-boards/generic/pci.c
--- linux-2.5.70-bk9/arch/mips64/mips-boards/generic/pci.c	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk10/arch/mips64/mips-boards/generic/pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -213,7 +213,7 @@
 void __init pcibios_init(void)
 {
 #ifdef CONFIG_MIPS_MALTA
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 	unsigned char reg_val;
 #endif
 
@@ -237,7 +237,7 @@
 	GT_WRITE( GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE)); 
 
 #ifdef CONFIG_MIPS_MALTA
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		if ((pdev->vendor == PCI_VENDOR_ID_INTEL)
 		    && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB)
 		    && (PCI_SLOT(pdev->devfn) == 0x0a)) {
diff -urN linux-2.5.70-bk9/arch/mips64/sgi-ip32/ip32-pci.c linux-2.5.70-bk10/arch/mips64/sgi-ip32/ip32-pci.c
--- linux-2.5.70-bk9/arch/mips64/sgi-ip32/ip32-pci.c	2003-05-26 18:01:02.000000000 -0700
+++ linux-2.5.70-bk10/arch/mips64/sgi-ip32/ip32-pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -125,7 +125,7 @@
 
 void __init pcibios_init (void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	u32 start, size;
 	u16 cmd;
 	u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */
@@ -157,7 +157,7 @@
 	pci_scan_bus (0, &macepci_ops, NULL);
 
 #ifdef DEBUG_MACE_PCI
-	pci_for_each_dev (dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n",
 			dev->bus->number, PCI_SLOT (dev->devfn),
 			PCI_FUNC (dev->devfn));
@@ -176,7 +176,8 @@
 	 * which we must assign, and a 1-page memory region which is
 	 * assigned by the system firmware.
 	 */
-	pci_for_each_dev (dev) {
+	dev = NULL;
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		switch (PCI_SLOT (dev->devfn)) {
 		case 1: /* SCSI bus 0 */
 			dev->resource[0].start = 0x1000UL;
@@ -230,7 +231,8 @@
 	printk ("Triggering PCI bridge interrupt...\n");
 	mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST);
 
-	pci_for_each_dev (dev) {
+	dev = NULL;
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		printk ("Device: %d/%d/%d final bus resource map\n",
 			dev->bus->number, PCI_SLOT (dev->devfn),
 			PCI_FUNC (dev->devfn));
diff -urN linux-2.5.70-bk9/arch/ppc/kernel/pci.c linux-2.5.70-bk10/arch/ppc/kernel/pci.c
--- linux-2.5.70-bk9/arch/ppc/kernel/pci.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc/kernel/pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -548,12 +548,12 @@
 static void __init
 pcibios_allocate_resources(int pass)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int idx, disabled;
 	u16 command;
 	struct resource *r;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		for (idx = 0; idx < 6; idx++) {
 			r = &dev->resource[idx];
@@ -586,11 +586,11 @@
 static void __init
 pcibios_assign_resources(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int idx;
 	struct resource *r;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		int class = dev->class >> 8;
 
 		/* Don't touch classless devices and host bridges */
@@ -881,7 +881,7 @@
 {
 	unsigned int *reg;
 	struct pci_controller* hose;
-	struct pci_dev* dev;
+	struct pci_dev* dev = NULL;
 		
 	if (!have_of)
 		return -ENODEV;
@@ -905,7 +905,7 @@
 	 */
 	if (!pci_to_OF_bus_map)
 		return 0;
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if (pci_to_OF_bus_map[dev->bus->number] != *bus)
 			continue;
 		if (dev->devfn != *devfn)
diff -urN linux-2.5.70-bk9/arch/ppc/platforms/chrp_pci.c linux-2.5.70-bk10/arch/ppc/platforms/chrp_pci.c
--- linux-2.5.70-bk9/arch/ppc/platforms/chrp_pci.c	2003-05-26 18:01:02.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc/platforms/chrp_pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -154,11 +154,11 @@
 void __init
 chrp_pcibios_fixup(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	struct device_node *np;
 
 	/* PCI interrupts are controlled by the OpenPIC */
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		np = pci_device_to_OF_node(dev);
 		if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
 			dev->irq = np->intrs[0].line;
diff -urN linux-2.5.70-bk9/arch/ppc/platforms/gemini_pci.c linux-2.5.70-bk10/arch/ppc/platforms/gemini_pci.c
--- linux-2.5.70-bk9/arch/ppc/platforms/gemini_pci.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc/platforms/gemini_pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -13,9 +13,9 @@
 void __init gemini_pcibios_fixup(void)
 {
 	int i;
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		for(i = 0; i < 6; i++) {
 			if (dev->resource[i].flags & IORESOURCE_IO) {
 				dev->resource[i].start |= (0xfe << 24);
diff -urN linux-2.5.70-bk9/arch/ppc/platforms/pmac_pci.c linux-2.5.70-bk10/arch/ppc/platforms/pmac_pci.c
--- linux-2.5.70-bk9/arch/ppc/platforms/pmac_pci.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc/platforms/pmac_pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -494,7 +494,7 @@
 static void __init
 pcibios_fixup_OF_interrupts(void)
 {	
-	struct pci_dev* dev;
+	struct pci_dev* dev = NULL;
 	
 	/*
 	 * Open Firmware often doesn't initialize the
@@ -502,7 +502,7 @@
 	 * should find the device node and apply the interrupt
 	 * obtained from the OF device-tree
 	 */
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		struct device_node *node;
 		node = pci_device_to_OF_node(dev);
 		/* this is the node, see if it has interrupts */
@@ -590,7 +590,7 @@
 	struct device_node* nd;
 
 #ifdef CONFIG_BLK_DEV_IDE
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
 	/* OF fails to initialize IDE controllers on macs
 	 * (and maybe other machines)
@@ -602,7 +602,7 @@
 	 * 
 	 * -- BenH
 	 */
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
 			pci_enable_device(dev);
 	}
diff -urN linux-2.5.70-bk9/arch/ppc/platforms/prep_pci.c linux-2.5.70-bk10/arch/ppc/platforms/prep_pci.c
--- linux-2.5.70-bk9/arch/ppc/platforms/prep_pci.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc/platforms/prep_pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -1171,7 +1171,7 @@
 void __init
 prep_pcibios_fixup(void)
 {
-        struct pci_dev *dev;
+        struct pci_dev *dev = NULL;
         extern unsigned char *Motherboard_map;
         extern unsigned char *Motherboard_routes;
 
@@ -1180,7 +1180,7 @@
 	printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);
 	if (OpenPIC_Addr) {
 		/* PCI interrupts are controlled by the OpenPIC */
-		pci_for_each_dev(dev) {
+		while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 			if (dev->bus->number == 0) {
                        		dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);
 				pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
@@ -1196,7 +1196,8 @@
 		return;
 	}
 
-	pci_for_each_dev(dev) {
+	dev = NULL;
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		/*
 		 * Use our old hard-coded kludge to figure out what
 		 * irq this device uses.  This is necessary on things
diff -urN linux-2.5.70-bk9/arch/ppc64/Kconfig linux-2.5.70-bk10/arch/ppc64/Kconfig
--- linux-2.5.70-bk9/arch/ppc64/Kconfig	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc64/Kconfig	2003-06-05 04:41:35.000000000 -0700
@@ -241,7 +241,7 @@
 
 source "drivers/pcmcia/Kconfig"
 
-source "drivers/hotplug/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
 
 config PROC_DEVICETREE
 	bool "Support for Open Firmware device tree in /proc"
diff -urN linux-2.5.70-bk9/arch/ppc64/kernel/iSeries_pci.c linux-2.5.70-bk10/arch/ppc64/kernel/iSeries_pci.c
--- linux-2.5.70-bk9/arch/ppc64/kernel/iSeries_pci.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc64/kernel/iSeries_pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -304,7 +304,7 @@
  ***********************************************************************/
 void __init pcibios_final_fixup(void)
 {
-	struct pci_dev* PciDev;
+	struct pci_dev* PciDev = NULL;
 	struct iSeries_Device_Node* DeviceNode;
 	char   Buffer[256];
     	int    DeviceCount = 0;
@@ -315,7 +315,7 @@
 	/******************************************************/
 	mf_displaySrc(0xC9000100);
 
-	pci_for_each_dev(PciDev) {
+	while ((PciDev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, PciDev)) != NULL) {
 		DeviceNode = find_Device_Node(PciDev);
 		if(DeviceNode != NULL) {
 			++DeviceCount;
diff -urN linux-2.5.70-bk9/arch/ppc64/kernel/pSeries_pci.c linux-2.5.70-bk10/arch/ppc64/kernel/pSeries_pci.c
--- linux-2.5.70-bk9/arch/ppc64/kernel/pSeries_pci.c	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc64/kernel/pSeries_pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -533,11 +533,11 @@
 
 void __init pcibios_final_fixup(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
 	check_s7a();
 
-	pci_for_each_dev(dev)
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
 		pci_read_irq_line(dev);
 
 	chrp_request_regions();
diff -urN linux-2.5.70-bk9/arch/ppc64/kernel/pci.c linux-2.5.70-bk10/arch/ppc64/kernel/pci.c
--- linux-2.5.70-bk9/arch/ppc64/kernel/pci.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc64/kernel/pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -117,13 +117,13 @@
  */
 struct pci_dev *pci_find_dev_by_addr(unsigned long addr)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int i;
 	unsigned long ioaddr;
 
 	ioaddr = (addr > isa_io_base) ? addr - isa_io_base : 0;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
 			continue;
 		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
diff -urN linux-2.5.70-bk9/arch/ppc64/kernel/pci_dma.c linux-2.5.70-bk10/arch/ppc64/kernel/pci_dma.c
--- linux-2.5.70-bk9/arch/ppc64/kernel/pci_dma.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/arch/ppc64/kernel/pci_dma.c	2003-06-05 04:41:35.000000000 -0700
@@ -724,7 +724,7 @@
 }
 
 void create_tce_tables(void) {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	struct device_node *dn, *mydn;
 
 	if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
@@ -737,7 +737,7 @@
 	 * pci device_node.  This means get_tce_table() won't need to search
 	 * up the device tree to find it.
 	 */
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		mydn = dn = PCI_GET_DN(dev);
 		while (dn && dn->tce_table == NULL)
 			dn = dn->parent;
diff -urN linux-2.5.70-bk9/arch/sh/kernel/pci-sh7751.c linux-2.5.70-bk10/arch/sh/kernel/pci-sh7751.c
--- linux-2.5.70-bk9/arch/sh/kernel/pci-sh7751.c	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk10/arch/sh/kernel/pci-sh7751.c	2003-06-05 04:41:35.000000000 -0700
@@ -386,13 +386,13 @@
 
 static void __init pcibios_allocate_resources(int pass)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int idx, disabled;
 	u16 command;
 	struct resource *r, *pr;
 
 	PCIDBG(2,"PCI: pcibios_allocate_resources pass %d called\n", pass);
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		for(idx = 0; idx < 6; idx++) {
 			r = &dev->resource[idx];
@@ -432,12 +432,12 @@
 
 static void __init pcibios_assign_resources(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *devn = NULL;
 	int idx;
 	struct resource *r;
 
 	PCIDBG(2,"PCI: pcibios_assign_resources called\n");
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		int class = dev->class >> 8;
 
 		/* Don't touch classless devices and host bridges */
diff -urN linux-2.5.70-bk9/arch/um/drivers/net_kern.c linux-2.5.70-bk10/arch/um/drivers/net_kern.c
--- linux-2.5.70-bk9/arch/um/drivers/net_kern.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/arch/um/drivers/net_kern.c	2003-06-05 04:41:35.000000000 -0700
@@ -304,7 +304,7 @@
 	}
 
 	memset(device, 0, sizeof(*device));
-	device->list = INIT_LIST_HEAD(device->list);
+	INIT_LIST_HEAD(&device->list);
 	device->index = n;
 
 	spin_lock(&devices_lock);
@@ -362,7 +362,7 @@
 		return 1;
 	lp = dev->priv;
 
-	lp->list = INIT_LIST_HEAD(lp->list);
+	INIT_LIST_HEAD(&lp->list);
 	spin_lock_init(&lp->lock);
 	lp->dev = dev;
 	lp->fd = -1;
@@ -537,7 +537,7 @@
 		return(1);
 	}
 
-	new->list = INIT_LIST_HEAD(new->list);
+	INIT_LIST_HEAD(&new->list);
 	new->index = n;
 	new->init = str;
 
diff -urN linux-2.5.70-bk9/arch/v850/Kconfig linux-2.5.70-bk10/arch/v850/Kconfig
--- linux-2.5.70-bk9/arch/v850/Kconfig	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/arch/v850/Kconfig	2003-06-05 04:41:35.000000000 -0700
@@ -230,7 +230,7 @@
 
 source "drivers/pcmcia/Kconfig"
 
-source "drivers/hotplug/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
 
 endmenu
 
diff -urN linux-2.5.70-bk9/arch/v850/kernel/rte_mb_a_pci.c linux-2.5.70-bk10/arch/v850/kernel/rte_mb_a_pci.c
--- linux-2.5.70-bk9/arch/v850/kernel/rte_mb_a_pci.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk10/arch/v850/kernel/rte_mb_a_pci.c	2003-06-05 04:41:35.000000000 -0700
@@ -251,10 +251,10 @@
 /* Resource allocation.  */
 static void __devinit pcibios_assign_resources (void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	struct resource *r;
 
-	pci_for_each_dev (dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		unsigned di_num;
 		unsigned class = dev->class >> 8;
 
diff -urN linux-2.5.70-bk9/arch/x86_64/Kconfig linux-2.5.70-bk10/arch/x86_64/Kconfig
--- linux-2.5.70-bk9/arch/x86_64/Kconfig	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/arch/x86_64/Kconfig	2003-06-05 04:41:35.000000000 -0700
@@ -351,7 +351,7 @@
 
 source "drivers/pcmcia/Kconfig"
 
-source "drivers/hotplug/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
 
 endmenu
 
diff -urN linux-2.5.70-bk9/arch/x86_64/kernel/bluesmoke.c linux-2.5.70-bk10/arch/x86_64/kernel/bluesmoke.c
--- linux-2.5.70-bk9/arch/x86_64/kernel/bluesmoke.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/arch/x86_64/kernel/bluesmoke.c	2003-06-05 04:41:35.000000000 -0700
@@ -125,9 +125,9 @@
 
 static struct pci_dev *find_k8_nb(void)
 { 
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int cpu = smp_processor_id(); 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
 		    PCI_SLOT(dev->devfn) == (24U+cpu))
 			return dev;
diff -urN linux-2.5.70-bk9/arch/x86_64/kernel/pci-gart.c linux-2.5.70-bk10/arch/x86_64/kernel/pci-gart.c
--- linux-2.5.70-bk9/arch/x86_64/kernel/pci-gart.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/arch/x86_64/kernel/pci-gart.c	2003-06-05 04:41:35.000000000 -0700
@@ -67,7 +67,8 @@
 #define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))
 
 #define for_all_nb(dev) \
-	pci_for_each_dev(dev) \
+	dev=NULL; \
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) \
 		if (dev->bus->number == 0 && PCI_FUNC(dev->devfn) == 3 && \
 		    (PCI_SLOT(dev->devfn) >= 24) && (PCI_SLOT(dev->devfn) <= 31))
 
diff -urN linux-2.5.70-bk9/arch/x86_64/pci/irq.c linux-2.5.70-bk10/arch/x86_64/pci/irq.c
--- linux-2.5.70-bk9/arch/x86_64/pci/irq.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/arch/x86_64/pci/irq.c	2003-06-05 04:41:35.000000000 -0700
@@ -391,7 +391,7 @@
 	int irq = 0;
 	u32 mask;
 	struct irq_router *r = pirq_router;
-	struct pci_dev *dev2;
+	struct pci_dev *dev2 = NULL;
 	char *msg = NULL;
 
 	/* Find IRQ pin */
@@ -483,7 +483,7 @@
 	printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
 
 	/* Update IRQ for all devices with the same pirq value */
-	pci_for_each_dev(dev2) {
+	while ((dev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
 		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
 		if (!pin)
 			continue;
@@ -511,11 +511,11 @@
 
 void __init pcibios_fixup_irqs(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	u8 pin;
 
 	DBG("PCI: IRQ fixup\n");
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		/*
 		 * If the BIOS has set an out of range IRQ number, just ignore it.
 		 * Also keep track of which IRQ's are already in use.
@@ -530,7 +530,8 @@
 		pirq_penalty[dev->irq]++;
 	}
 
-	pci_for_each_dev(dev) {
+	dev = NULL;
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 #ifdef CONFIG_X86_IO_APIC
 		/*
diff -urN linux-2.5.70-bk9/arch/x86_64/pci/x86-64.c linux-2.5.70-bk10/arch/x86_64/pci/x86-64.c
--- linux-2.5.70-bk9/arch/x86_64/pci/x86-64.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk10/arch/x86_64/pci/x86-64.c	2003-06-05 04:41:35.000000000 -0700
@@ -121,12 +121,12 @@
 
 static void __init pcibios_allocate_resources(int pass)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int idx, disabled;
 	u16 command;
 	struct resource *r, *pr;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		for(idx = 0; idx < 6; idx++) {
 			r = &dev->resource[idx];
@@ -166,11 +166,11 @@
 
 static void __init pcibios_assign_resources(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int idx;
 	struct resource *r;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		int class = dev->class >> 8;
 
 		/* Don't touch classless devices and host bridges */
diff -urN linux-2.5.70-bk9/crypto/Kconfig linux-2.5.70-bk10/crypto/Kconfig
--- linux-2.5.70-bk9/crypto/Kconfig	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/crypto/Kconfig	2003-06-05 04:41:35.000000000 -0700
@@ -6,16 +6,12 @@
 
 config CRYPTO
 	bool "Cryptographic API"
-	default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
-		     INET6_ESP=y || INET6_ESP=m || INET6_IPCOMP=y || INET6_IPCOMP=m || IPV6_PRIVACY=y
 	help
 	  This option provides the core Cryptographic API.
 
 config CRYPTO_HMAC
 	bool "HMAC support"
 	depends on CRYPTO
-	default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
-		     INET6_ESP=y || INET6_ESP=m
 	help
 	  HMAC: Keyed-Hashing for Message Authentication (RFC2104).
 	  This is required for IPSec.
@@ -35,16 +31,12 @@
 config CRYPTO_MD5
 	tristate "MD5 digest algorithm"
 	depends on CRYPTO
-	default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m || INET6_AH=y || INET6_AH=m || \
-	             INET6_ESP=y || INET6_ESP=m || IPV6_PRIVACY=y
 	help
 	  MD5 message digest algorithm (RFC1321).
 
 config CRYPTO_SHA1
 	tristate "SHA1 digest algorithm"
 	depends on CRYPTO
-	default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m  || INET6_AH=y || INET6_AH=m || \
-	             INET6_ESP=y || INET6_ESP=m
 	help
 	  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
 
@@ -72,7 +64,6 @@
 config CRYPTO_DES
 	tristate "DES and Triple DES EDE cipher algorithms"
 	depends on CRYPTO
-	default y if INET_ESP=y || INET_ESP=m || INET6_ESP=y || INET6_ESP=m
 	help
 	  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
 
@@ -138,7 +129,6 @@
 config CRYPTO_DEFLATE
 	tristate "Deflate compression algorithm"
 	depends on CRYPTO
-	default y if INET_IPCOMP=y || INET_IPCOMP=m || INET6_IPCOMP=y || INET6_IPCOMP=m
 	help
 	  This is the Deflate algorithm (RFC1951), specified for use in
 	  IPSec with the IPCOMP protocol (RFC3173, RFC2394).
diff -urN linux-2.5.70-bk9/drivers/Makefile linux-2.5.70-bk10/drivers/Makefile
--- linux-2.5.70-bk9/drivers/Makefile	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/drivers/Makefile	2003-06-05 04:41:35.000000000 -0700
@@ -46,7 +46,6 @@
 obj-$(CONFIG_PHONE)		+= telephony/
 obj-$(CONFIG_MD)		+= md/
 obj-$(CONFIG_BT)		+= bluetooth/
-obj-$(CONFIG_HOTPLUG_PCI)	+= hotplug/
 obj-$(CONFIG_ISDN_BOOL)		+= isdn/
 obj-$(CONFIG_MCA)		+= mca/
 obj-$(CONFIG_EISA)		+= eisa/
diff -urN linux-2.5.70-bk9/drivers/acpi/pci_irq.c linux-2.5.70-bk10/drivers/acpi/pci_irq.c
--- linux-2.5.70-bk9/drivers/acpi/pci_irq.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/drivers/acpi/pci_irq.c	2003-06-05 04:41:35.000000000 -0700
@@ -402,7 +402,7 @@
 		iosapic_parse_prt();
 #endif
 
-	pci_for_each_dev(dev)
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
 		acpi_pci_irq_enable(dev);
 
 	return_VALUE(0);
diff -urN linux-2.5.70-bk9/drivers/atm/he.c linux-2.5.70-bk10/drivers/atm/he.c
--- linux-2.5.70-bk9/drivers/atm/he.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/drivers/atm/he.c	2003-06-05 04:41:36.000000000 -0700
@@ -77,14 +77,6 @@
 #include <linux/atmdev.h>
 #include <linux/atm.h>
 #include <linux/sonet.h>
-#ifndef ATM_OC12_PCR
-#define ATM_OC12_PCR (622080000/1080*1040/8/53)
-#endif
-
-#ifdef BUS_INT_WAR
-void sn_add_polled_interrupt(int irq, int interval);
-void sn_delete_polled_interrupt(int irq);
-#endif
 
 #define USE_TASKLET
 #define USE_HE_FIND_VCC
@@ -171,22 +163,17 @@
 
 static struct atmdev_ops he_ops =
 {
-   open:	he_open,
-   close:	he_close,	
-   ioctl:	he_ioctl,	
-   send:	he_send,
-   sg_send:	he_sg_send,	
-   phy_put:	he_phy_put,
-   phy_get:	he_phy_get,
-   proc_read:	he_proc_read,
-   owner:	THIS_MODULE
+	.open =		he_open,
+	.close =	he_close,	
+	.ioctl =	he_ioctl,	
+	.send =		he_send,
+	.sg_send =	he_sg_send,	
+	.phy_put =	he_phy_put,
+	.phy_get =	he_phy_get,
+	.proc_read =	he_proc_read,
+	.owner =	THIS_MODULE
 };
 
-/* see the comments in he.h about global_lock */
-
-#define HE_SPIN_LOCK(dev, flags)	spin_lock_irqsave(&(dev)->global_lock, flags)
-#define HE_SPIN_UNLOCK(dev, flags)	spin_unlock_irqrestore(&(dev)->global_lock, flags)
-
 #define he_writel(dev, val, reg)	do { writel(val, (dev)->membase + (reg)); wmb(); } while (0)
 #define he_readl(dev, reg)		readl((dev)->membase + (reg))
 
@@ -233,26 +220,26 @@
 
 /* figure 2.2 connection id */
 
-#define he_mkcid(dev, vpi, vci)		(((vpi<<(dev)->vcibits) | vci) & 0x1fff)
+#define he_mkcid(dev, vpi, vci)		(((vpi << (dev)->vcibits) | vci) & 0x1fff)
 
 /* 2.5.1 per connection transmit state registers */
 
 #define he_writel_tsr0(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 0)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 0)
 #define he_readl_tsr0(dev, cid) \
-		he_readl_tcm(dev, CONFIG_TSRA | (cid<<3) | 0)
+		he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 0)
 
 #define he_writel_tsr1(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 1)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 1)
 
 #define he_writel_tsr2(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 2)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 2)
 
 #define he_writel_tsr3(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 3)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 3)
 
 #define he_writel_tsr4(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 4)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 4)
 
 	/* from page 2-20
 	 *
@@ -263,43 +250,43 @@
 	 */
 
 #define he_writel_tsr4_upper(dev, val, cid) \
-		he_writel_internal(dev, val, CONFIG_TSRA | (cid<<3) | 4, \
+		he_writel_internal(dev, val, CONFIG_TSRA | (cid << 3) | 4, \
 							CON_CTL_TCM \
 							| CON_BYTE_DISABLE_2 \
 							| CON_BYTE_DISABLE_1 \
 							| CON_BYTE_DISABLE_0)
 
 #define he_readl_tsr4(dev, cid) \
-		he_readl_tcm(dev, CONFIG_TSRA | (cid<<3) | 4)
+		he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 4)
 
 #define he_writel_tsr5(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 5)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 5)
 
 #define he_writel_tsr6(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 6)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 6)
 
 #define he_writel_tsr7(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid<<3) | 7)
+		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 7)
 
 
 #define he_writel_tsr8(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 0)
+		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 0)
 
 #define he_writel_tsr9(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 1)
+		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 1)
 
 #define he_writel_tsr10(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 2)
+		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 2)
 
 #define he_writel_tsr11(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid<<2) | 3)
+		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 3)
 
 
 #define he_writel_tsr12(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRC | (cid<<1) | 0)
+		he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 0)
 
 #define he_writel_tsr13(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRC | (cid<<1) | 1)
+		he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 1)
 
 
 #define he_writel_tsr14(dev, val, cid) \
@@ -315,30 +302,30 @@
 /* 2.7.1 per connection receive state registers */
 
 #define he_writel_rsr0(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 0)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 0)
 #define he_readl_rsr0(dev, cid) \
-		he_readl_rcm(dev, 0x00000 | (cid<<3) | 0)
+		he_readl_rcm(dev, 0x00000 | (cid << 3) | 0)
 
 #define he_writel_rsr1(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 1)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 1)
 
 #define he_writel_rsr2(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 2)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 2)
 
 #define he_writel_rsr3(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 3)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 3)
 
 #define he_writel_rsr4(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 4)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 4)
 
 #define he_writel_rsr5(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 5)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 5)
 
 #define he_writel_rsr6(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 6)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 6)
 
 #define he_writel_rsr7(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid<<3) | 7)
+		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 7)
 
 static __inline__ struct atm_vcc*
 he_find_vcc(struct he_dev *he_dev, unsigned cid)
@@ -349,7 +336,7 @@
 	int vci;
 
 	vpi = cid >> he_dev->vcibits;
-	vci = cid & ((1<<he_dev->vcibits)-1);
+	vci = cid & ((1 << he_dev->vcibits) - 1);
 
 	spin_lock_irqsave(&he_dev->atm_dev->lock, flags);
 	for (vcc = he_dev->atm_dev->vccs; vcc; vcc = vcc->next)
@@ -443,112 +430,112 @@
 static unsigned
 rate_to_atmf(unsigned rate)		/* cps to atm forum format */
 {
-#define NONZERO (1<<14)
+#define NONZERO (1 << 14)
 
-        unsigned exp = 0;
+	unsigned exp = 0;
 
-        if (rate == 0)
-		return(0);
+	if (rate == 0)
+		return 0;
 
-        rate <<= 9;
-        while (rate > 0x3ff) {
-                ++exp;
-                rate >>= 1;
-        }
+	rate <<= 9;
+	while (rate > 0x3ff) {
+		++exp;
+		rate >>= 1;
+	}
 
-        return (NONZERO | (exp << 9) | (rate & 0x1ff));
+	return (NONZERO | (exp << 9) | (rate & 0x1ff));
 }
 
 static void __init
 he_init_rx_lbfp0(struct he_dev *he_dev)
 {
-        unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-        unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-        unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-        unsigned row_offset = he_dev->r0_startrow * he_dev->bytes_per_row;
-        
+	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
+	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
+	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
+	unsigned row_offset = he_dev->r0_startrow * he_dev->bytes_per_row;
+	
 	lbufd_index = 0;
-        lbm_offset = he_readl(he_dev, RCMLBM_BA);
+	lbm_offset = he_readl(he_dev, RCMLBM_BA);
 
 	he_writel(he_dev, lbufd_index, RLBF0_H);
 
-        for (i = 0, lbuf_count = 0; i < he_dev->r0_numbuffs; ++i) {
+	for (i = 0, lbuf_count = 0; i < he_dev->r0_numbuffs; ++i) {
 		lbufd_index += 2;
-                lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
+		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
 
 		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
 		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
 
-                if (++lbuf_count == lbufs_per_row) {
-                        lbuf_count = 0;
-                        row_offset += he_dev->bytes_per_row;
-                }
+		if (++lbuf_count == lbufs_per_row) {
+			lbuf_count = 0;
+			row_offset += he_dev->bytes_per_row;
+		}
 		lbm_offset += 4;
-        }
-                
-        he_writel(he_dev, lbufd_index - 2, RLBF0_T);
+	}
+		
+	he_writel(he_dev, lbufd_index - 2, RLBF0_T);
 	he_writel(he_dev, he_dev->r0_numbuffs, RLBF0_C);
 }
 
 static void __init
 he_init_rx_lbfp1(struct he_dev *he_dev)
 {
-        unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-        unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-        unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-        unsigned row_offset = he_dev->r1_startrow * he_dev->bytes_per_row;
-        
+	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
+	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
+	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
+	unsigned row_offset = he_dev->r1_startrow * he_dev->bytes_per_row;
+	
 	lbufd_index = 1;
-        lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
+	lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
 
 	he_writel(he_dev, lbufd_index, RLBF1_H);
 
-        for (i = 0, lbuf_count = 0; i < he_dev->r1_numbuffs; ++i) {
+	for (i = 0, lbuf_count = 0; i < he_dev->r1_numbuffs; ++i) {
 		lbufd_index += 2;
-                lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
+		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
 
 		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
 		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
 
-                if (++lbuf_count == lbufs_per_row) {
-                        lbuf_count = 0;
-                        row_offset += he_dev->bytes_per_row;
-                }
+		if (++lbuf_count == lbufs_per_row) {
+			lbuf_count = 0;
+			row_offset += he_dev->bytes_per_row;
+		}
 		lbm_offset += 4;
-        }
-                
-        he_writel(he_dev, lbufd_index - 2, RLBF1_T);
+	}
+		
+	he_writel(he_dev, lbufd_index - 2, RLBF1_T);
 	he_writel(he_dev, he_dev->r1_numbuffs, RLBF1_C);
 }
 
 static void __init
 he_init_tx_lbfp(struct he_dev *he_dev)
 {
-        unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-        unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-        unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-        unsigned row_offset = he_dev->tx_startrow * he_dev->bytes_per_row;
-        
+	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
+	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
+	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
+	unsigned row_offset = he_dev->tx_startrow * he_dev->bytes_per_row;
+	
 	lbufd_index = he_dev->r0_numbuffs + he_dev->r1_numbuffs;
-        lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
+	lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
 
 	he_writel(he_dev, lbufd_index, TLBF_H);
 
-        for (i = 0, lbuf_count = 0; i < he_dev->tx_numbuffs; ++i) {
+	for (i = 0, lbuf_count = 0; i < he_dev->tx_numbuffs; ++i) {
 		lbufd_index += 1;
-                lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
+		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
 
 		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
 		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
 
-                if (++lbuf_count == lbufs_per_row) {
-                        lbuf_count = 0;
-                        row_offset += he_dev->bytes_per_row;
-                }
+		if (++lbuf_count == lbufs_per_row) {
+			lbuf_count = 0;
+			row_offset += he_dev->bytes_per_row;
+		}
 		lbm_offset += 2;
-        }
-                
-        he_writel(he_dev, lbufd_index - 1, TLBF_T);
+	}
+		
+	he_writel(he_dev, lbufd_index - 1, TLBF_T);
 }
 
 static int __init
@@ -678,7 +665,7 @@
 
 	unsigned rate_atmf, exp, man;
 	unsigned long long rate_cps;
-        int mult, buf, buf_limit = 4;
+	int mult, buf, buf_limit = 4;
 
 	rategrid = kmalloc( sizeof(unsigned) * 16 * 16, GFP_KERNEL);
 	if (!rategrid)
@@ -757,30 +744,31 @@
 		 */
 
 #ifdef notdef
-                buf = rate_cps * he_dev->tx_numbuffs /
+		buf = rate_cps * he_dev->tx_numbuffs /
 				(he_dev->atm_dev->link_rate * 2);
 #else
 		/* this is pretty, but avoids _divdu3 and is mostly correct */
-                buf = 0;
-                mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR;
-                if (rate_cps > (68 * mult))
-			buf = 1;
-                if (rate_cps > (136 * mult))
-			buf = 2;
-                if (rate_cps > (204 * mult))
-			buf = 3;
-                if (rate_cps > (272 * mult))
+		mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR;
+		if (rate_cps > (272 * mult))
 			buf = 4;
+		else if (rate_cps > (204 * mult))
+			buf = 3;
+		else if (rate_cps > (136 * mult))
+			buf = 2;
+		else if (rate_cps > (68 * mult))
+			buf = 1;
+		else
+			buf = 0;
 #endif
-                if (buf > buf_limit)
+		if (buf > buf_limit)
 			buf = buf_limit;
-		reg = (reg<<16) | ((i<<8) | buf);
+		reg = (reg << 16) | ((i << 8) | buf);
 
 #define RTGTBL_OFFSET 0x400
 	  
 		if (rate_atmf & 0x1)
 			he_writel_rcm(he_dev, reg,
-				CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf>>1));
+				CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf >> 1));
 
 		++rate_atmf;
 	}
@@ -839,7 +827,7 @@
 		he_dev->rbps_base[i].phys = dma_handle;
 
 	}
-	he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE-1];
+	he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE - 1];
 
 	he_writel(he_dev, he_dev->rbps_phys, G0_RBPS_S + (group * 32));
 	he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail),
@@ -848,7 +836,7 @@
 						G0_RBPS_BS + (group * 32));
 	he_writel(he_dev,
 			RBP_THRESH(CONFIG_RBPS_THRESH) |
-			RBP_QSIZE(CONFIG_RBPS_SIZE-1) |
+			RBP_QSIZE(CONFIG_RBPS_SIZE - 1) |
 			RBP_INT_ENB,
 						G0_RBPS_QI + (group * 32));
 #else /* !USE_RBPS */
@@ -902,7 +890,7 @@
 		he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF);
 		he_dev->rbpl_base[i].phys = dma_handle;
 	}
-	he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE-1];
+	he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1];
 
 	he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32));
 	he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail),
@@ -911,7 +899,7 @@
 						G0_RBPL_BS + (group * 32));
 	he_writel(he_dev,
 			RBP_THRESH(CONFIG_RBPL_THRESH) |
-			RBP_QSIZE(CONFIG_RBPL_SIZE-1) |
+			RBP_QSIZE(CONFIG_RBPL_SIZE - 1) |
 			RBP_INT_ENB,
 						G0_RBPL_QI + (group * 32));
 
@@ -929,7 +917,7 @@
 	he_writel(he_dev, he_dev->rbrq_phys, G0_RBRQ_ST + (group * 16));
 	he_writel(he_dev, 0, G0_RBRQ_H + (group * 16));
 	he_writel(he_dev,
-		RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE-1),
+		RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE - 1),
 						G0_RBRQ_Q + (group * 16));
 	if (irq_coalesce) {
 		hprintk("coalescing interrupts\n");
@@ -967,7 +955,7 @@
 	/* 2.9.3.5  tail offset for each interrupt queue is located after the
 		    end of the interrupt queue */
 
-        he_dev->irq_base = pci_alloc_consistent(he_dev->pci_dev,
+	he_dev->irq_base = pci_alloc_consistent(he_dev->pci_dev,
 			(CONFIG_IRQ_SIZE+1) * sizeof(struct he_irq), &he_dev->irq_phys);
 	if (he_dev->irq_base == NULL) {
 		hprintk("failed to allocate irq\n");
@@ -979,7 +967,7 @@
 	he_dev->irq_head = he_dev->irq_base;
 	he_dev->irq_tail = he_dev->irq_base;
 
-	for (i=0; i < CONFIG_IRQ_SIZE; ++i)
+	for (i = 0; i < CONFIG_IRQ_SIZE; ++i)
 		he_dev->irq_base[i].isw = ITYPE_INVALID;
 
 	he_writel(he_dev, he_dev->irq_phys, IRQ0_BASE);
@@ -1014,23 +1002,18 @@
 	if (request_irq(he_dev->pci_dev->irq, he_irq_handler, SA_INTERRUPT|SA_SHIRQ, DEV_LABEL, he_dev)) {
 		hprintk("irq %d already in use\n", he_dev->pci_dev->irq);
 		return -EINVAL;
-        }   
+	}   
 
 	he_dev->irq = he_dev->pci_dev->irq;
 
-#ifdef BUS_INT_WAR
-        HPRINTK("sn_add_polled_interrupt(irq %d, 1)\n", he_dev->irq);
-        sn_add_polled_interrupt(he_dev->irq, 1);
-#endif
-
 	return 0;
 }
 
 static int __init
 he_start(struct atm_dev *dev)
 {
-        struct he_dev *he_dev;
-        struct pci_dev *pci_dev;
+	struct he_dev *he_dev;
+	struct pci_dev *pci_dev;
 
 	u16 command;
 	u32 gen_cntl_0, host_cntl, lb_swap;
@@ -1040,8 +1023,8 @@
 	unsigned int status, reg;
 	int i, group;
 
-        he_dev = HE_DEV(dev);
-        pci_dev = he_dev->pci_dev;
+	he_dev = HE_DEV(dev);
+	pci_dev = he_dev->pci_dev;
 
 	he_dev->membase = pci_dev->resource[0].start;
 	HPRINTK("membase = 0x%lx  irq = %d.\n", he_dev->membase, pci_dev->irq);
@@ -1108,7 +1091,7 @@
 		hprintk("can't set up page mapping\n");
 		return -EINVAL;
 	}
-	      
+
 	/* 4.4 card reset */
 	he_writel(he_dev, 0x0, RESET_CNTL);
 	he_writel(he_dev, 0xff, RESET_CNTL);
@@ -1138,12 +1121,12 @@
 	pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
 
 	/* 4.7 read prom contents */
-	for (i=0; i<PROD_ID_LEN; ++i)
+	for (i = 0; i < PROD_ID_LEN; ++i)
 		he_dev->prod_id[i] = read_prom_byte(he_dev, PROD_ID + i);
 
 	he_dev->media = read_prom_byte(he_dev, MEDIA);
 
-	for (i=0; i<6; ++i)
+	for (i = 0; i < 6; ++i)
 		dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
 
 	hprintk("%s%s, %x:%x:%x:%x:%x:%x\n",
@@ -1323,15 +1306,15 @@
 	he_writel(he_dev, 0x0, TXAAL5_PROTO);
 
 	he_writel(he_dev, PHY_INT_ENB |
-		(he_is622(he_dev) ? PTMR_PRE(67-1) : PTMR_PRE(50-1)),
+		(he_is622(he_dev) ? PTMR_PRE(67 - 1) : PTMR_PRE(50 - 1)),
 								RH_CONFIG);
 
 	/* 5.1.3 initialize connection memory */
 
-	for (i=0; i < TCM_MEM_SIZE; ++i)
+	for (i = 0; i < TCM_MEM_SIZE; ++i)
 		he_writel_tcm(he_dev, 0, i);
 
-	for (i=0; i < RCM_MEM_SIZE; ++i)
+	for (i = 0; i < RCM_MEM_SIZE; ++i)
 		he_writel_rcm(he_dev, 0, i);
 
 	/*
@@ -1512,7 +1495,7 @@
 	}
 		
 	he_dev->tpd_head = he_dev->tpd_base;
-	he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS-1];
+	he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS - 1];
 #endif
 
 	if (he_init_group(he_dev, 0) != 0)
@@ -1608,8 +1591,8 @@
 
 	he_dev->irq_peak = 0;
 	he_dev->rbrq_peak = 0;
-        he_dev->rbpl_peak = 0;
-        he_dev->tbrq_peak = 0;
+	he_dev->rbpl_peak = 0;
+	he_dev->tbrq_peak = 0;
 
 	HPRINTK("hell bent for leather!\n");
 
@@ -1652,12 +1635,8 @@
 		he_dev->atm_dev->phy->stop(he_dev->atm_dev);
 #endif /* CONFIG_ATM_HE_USE_SUNI */
 
-	if (he_dev->irq) {
-#ifdef BUS_INT_WAR
-		sn_delete_polled_interrupt(he_dev->irq);
-#endif
+	if (he_dev->irq)
 		free_irq(he_dev->irq, he_dev);
-	}
 
 	if (he_dev->irq_base)
 		pci_free_consistent(he_dev->pci_dev, (CONFIG_IRQ_SIZE+1)
@@ -1669,7 +1648,7 @@
 
 	if (he_dev->rbpl_base) {
 #ifdef USE_RBPL_POOL
-		for (i=0; i<CONFIG_RBPL_SIZE; ++i) {
+		for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
 			void *cpuaddr = he_dev->rbpl_virt[i].virt;
 			dma_addr_t dma_handle = he_dev->rbpl_base[i].phys;
 
@@ -1691,7 +1670,7 @@
 #ifdef USE_RBPS
 	if (he_dev->rbps_base) {
 #ifdef USE_RBPS_POOL
-		for (i=0; i<CONFIG_RBPS_SIZE; ++i) {
+		for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
 			void *cpuaddr = he_dev->rbps_virt[i].virt;
 			dma_addr_t dma_handle = he_dev->rbps_base[i].phys;
 
@@ -1790,7 +1769,7 @@
 }
 
 #define AAL5_LEN(buf,len) 						\
-			((((unsigned char *)(buf))[(len)-6]<<8) |	\
+			((((unsigned char *)(buf))[(len)-6] << 8) |	\
 				(((unsigned char *)(buf))[(len)-5]))
 
 /* 2.10.1.2 receive
@@ -1800,7 +1779,7 @@
  */
 
 #define TCP_CKSUM(buf,len) 						\
-			((((unsigned char *)(buf))[(len)-2]<<8) |	\
+			((((unsigned char *)(buf))[(len)-2] << 8) |	\
 				(((unsigned char *)(buf))[(len-1)]))
 
 static int
@@ -2123,7 +2102,7 @@
 	if (moved) {
 		he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T);
 #ifdef CONFIG_IA64_SGI_SN2
-                (void) he_readl(he_dev, G0_RBPL_T);
+		(void) he_readl(he_dev, G0_RBPL_T);
 #endif
 	}
 }
@@ -2155,7 +2134,7 @@
 	if (moved) {
 		he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T);
 #ifdef CONFIG_IA64_SGI_SN2
-                (void) he_readl(he_dev, G0_RBPS_T);
+		(void) he_readl(he_dev, G0_RBPS_T);
 #endif
 	}
 }
@@ -2171,7 +2150,7 @@
 
 	HPRINTK("tasklet (0x%lx)\n", data);
 #ifdef USE_TASKLET
-	HE_SPIN_LOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
 #endif
 
 	while (he_dev->irq_head != he_dev->irq_tail) {
@@ -2209,10 +2188,10 @@
 			case ITYPE_PHY:
 				HPRINTK("phy interrupt\n");
 #ifdef CONFIG_ATM_HE_USE_SUNI
-				HE_SPIN_UNLOCK(he_dev, flags);
+				spin_unlock_irqrestore(&he_dev->global_lock, flags);
 				if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->interrupt)
 					he_dev->atm_dev->phy->interrupt(he_dev->atm_dev);
-				HE_SPIN_LOCK(he_dev, flags);
+				spin_lock_irqsave(&he_dev->global_lock, flags);
 #endif
 				break;
 			case ITYPE_OTHER:
@@ -2257,7 +2236,7 @@
 		(void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata */
 	}
 #ifdef USE_TASKLET
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 #endif
 }
 
@@ -2271,7 +2250,7 @@
 	if (he_dev == NULL)
 		return IRQ_NONE;
 
-	HE_SPIN_LOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
 
 	he_dev->irq_tail = (struct he_irq *) (((unsigned long)he_dev->irq_base) |
 						(*he_dev->irq_tailoffset << 2));
@@ -2301,7 +2280,7 @@
 		(void) he_readl(he_dev, INT_FIFO);
 #endif
 	}
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 	return IRQ_RETVAL(handled);
 
 }
@@ -2416,11 +2395,11 @@
 	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
 		int pcr_goal;
 
-                pcr_goal = atm_pcr_goal(&vcc->qos.txtp);
-                if (pcr_goal == 0)
-                        pcr_goal = he_dev->atm_dev->link_rate;
-                if (pcr_goal < 0)	/* means round down, technically */
-                        pcr_goal = -pcr_goal;
+		pcr_goal = atm_pcr_goal(&vcc->qos.txtp);
+		if (pcr_goal == 0)
+			pcr_goal = he_dev->atm_dev->link_rate;
+		if (pcr_goal < 0)	/* means round down, technically */
+			pcr_goal = -pcr_goal;
 
 		HPRINTK("open tx cid 0x%x pcr_goal %d\n", cid, pcr_goal);
 
@@ -2438,9 +2417,9 @@
 				goto open_failed;
 		}
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 		tsr0 = he_readl_tsr0(he_dev, cid);
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 		if (TSR0_CONN_STATE(tsr0) != 0) {
 			hprintk("cid 0x%x not idle (tsr0 = 0x%x)\n", cid, tsr0);
@@ -2467,7 +2446,7 @@
 					goto open_failed;
 				}
 
-				HE_SPIN_LOCK(he_dev, flags);			/* also protects he_dev->cs_stper[] */
+				spin_lock_irqsave(&he_dev->global_lock, flags);			/* also protects he_dev->cs_stper[] */
 
 				/* find an unused cs_stper register */
 				for (reg = 0; reg < HE_NUM_CS_STPER; ++reg)
@@ -2477,7 +2456,7 @@
 
 				if (reg == HE_NUM_CS_STPER) {
 					err = -EBUSY;
-					HE_SPIN_UNLOCK(he_dev, flags);
+					spin_unlock_irqrestore(&he_dev->global_lock, flags);
 					goto open_failed;
 				}
 
@@ -2495,7 +2474,7 @@
 
 				he_writel_mbox(he_dev, rate_to_atmf(period/2),
 							CS_STPER0 + reg);
-				HE_SPIN_UNLOCK(he_dev, flags);
+				spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 				tsr0 = TSR0_CBR | TSR0_GROUP(0) | tsr0_aal |
 							TSR0_RC_INDEX(reg);
@@ -2506,7 +2485,7 @@
 				goto open_failed;
 		}
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 
 		he_writel_tsr0(he_dev, tsr0, cid);
 		he_writel_tsr4(he_dev, tsr4 | 1, cid);
@@ -2528,7 +2507,7 @@
 #ifdef CONFIG_IA64_SGI_SN2
 		(void) he_readl_tsr0(he_dev, cid);
 #endif
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 	}
 
 	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
@@ -2549,11 +2528,11 @@
 				goto open_failed;
 		}
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 
 		rsr0 = he_readl_rsr0(he_dev, cid);
 		if (rsr0 & RSR0_OPEN_CONN) {
-			HE_SPIN_UNLOCK(he_dev, flags);
+			spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 			hprintk("cid 0x%x not idle (rsr0 = 0x%x)\n", cid, rsr0);
 			err = -EBUSY;
@@ -2578,14 +2557,14 @@
 		he_writel_rsr4(he_dev, rsr4, cid);
 		he_writel_rsr1(he_dev, rsr1, cid);
 		/* 5.1.11 last parameter initialized should be
-		          the open/closed indication in rsr0 */
+			  the open/closed indication in rsr0 */
 		he_writel_rsr0(he_dev,
 			rsr0 | RSR0_START_PDU | RSR0_OPEN_CONN | aal, cid);
 #ifdef CONFIG_IA64_SGI_SN2
 		(void) he_readl_rsr0(he_dev, cid);
 #endif
 
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 #ifndef USE_HE_FIND_VCC
 		HE_LOOKUP_VCC(he_dev, cid) = vcc;
@@ -2631,7 +2610,7 @@
 
 		/* wait for previous close (if any) to finish */
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 		while (he_readl(he_dev, RCC_STAT) & RCC_BUSY) {
 			HPRINTK("close cid 0x%x RCC_BUSY\n", cid);
 			udelay(250);
@@ -2645,7 +2624,7 @@
 		(void) he_readl_rsr0(he_dev, cid);
 #endif
 		he_writel_mbox(he_dev, cid, RXCON_CLOSE);
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 		timeout = schedule_timeout(30*HZ);
 
@@ -2693,7 +2672,7 @@
 
 		/* 2.3.1.1 generic close operations with flush */
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 		he_writel_tsr4_upper(he_dev, TSR4_FLUSH_CONN, cid);
 					/* also clears TSR4_SESSION_ENDED */
 #ifdef CONFIG_IA64_SGI_SN2
@@ -2724,7 +2703,7 @@
 		add_wait_queue(&he_vcc->tx_waitq, &wait);
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		__enqueue_tpd(he_dev, tpd, cid);
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 		timeout = schedule_timeout(30*HZ);
 
@@ -2736,7 +2715,7 @@
 			goto close_tx_incomplete;
 		}
 
-		HE_SPIN_LOCK(he_dev, flags);
+		spin_lock_irqsave(&he_dev->global_lock, flags);
 		while (!((tsr4 = he_readl_tsr4(he_dev, cid)) & TSR4_SESSION_ENDED)) {
 			HPRINTK("close tx cid 0x%x !TSR4_SESSION_ENDED (tsr4 = 0x%x)\n", cid, tsr4);
 			udelay(250);
@@ -2761,7 +2740,7 @@
 
 			he_dev->total_bw -= he_dev->cs_stper[reg].pcr;
 		}
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 		HPRINTK("close tx cid 0x%x complete\n", cid);
 	}
@@ -2818,7 +2797,7 @@
 		return -EINVAL;
 	}
 #endif
-	HE_SPIN_LOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
 
 	tpd = __alloc_tpd(he_dev);
 	if (tpd == NULL) {
@@ -2827,7 +2806,7 @@
 		else
 			dev_kfree_skb_any(skb);
 		atomic_inc(&vcc->stats->tx_err);
-		HE_SPIN_UNLOCK(he_dev, flags);
+		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 		return -ENOMEM;
 	}
 
@@ -2869,7 +2848,7 @@
 				else
 					dev_kfree_skb_any(skb);
 				atomic_inc(&vcc->stats->tx_err);
-				HE_SPIN_UNLOCK(he_dev, flags);
+				spin_unlock_irqrestore(&he_dev->global_lock, flags);
 				return -ENOMEM;
 			}
 			tpd->status |= TPD_USERCELL;
@@ -2884,7 +2863,7 @@
 
 	}
 
-	tpd->iovec[slot-1].len |= TPD_LST;
+	tpd->iovec[slot - 1].len |= TPD_LST;
 #else
 	tpd->address0 = pci_map_single(he_dev->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
 	tpd->length0 = skb->len | TPD_LST;
@@ -2897,7 +2876,7 @@
 	ATM_SKB(skb)->vcc = vcc;
 
 	__enqueue_tpd(he_dev, tpd, cid);
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 	atomic_inc(&vcc->stats->tx);
 
@@ -2919,7 +2898,7 @@
 
 			copy_from_user(&reg, (struct he_ioctl_reg *) arg,
 						sizeof(struct he_ioctl_reg));
-			HE_SPIN_LOCK(he_dev, flags);
+			spin_lock_irqsave(&he_dev->global_lock, flags);
 			switch (reg.type) {
 				case HE_REGTYPE_PCI:
 					reg.val = he_readl(he_dev, reg.addr);
@@ -2940,7 +2919,7 @@
 					err = -EINVAL;
 					break;
 			}
-			HE_SPIN_UNLOCK(he_dev, flags);
+			spin_unlock_irqrestore(&he_dev->global_lock, flags);
 			if (err == 0)
 				copy_to_user((struct he_ioctl_reg *) arg, &reg,
 							sizeof(struct he_ioctl_reg));
@@ -2966,15 +2945,15 @@
 
 	HPRINTK("phy_put(val 0x%x, addr 0x%lx)\n", val, addr);
 
-	HE_SPIN_LOCK(he_dev, flags);
-        he_writel(he_dev, val, FRAMER + (addr*4));
+	spin_lock_irqsave(&he_dev->global_lock, flags);
+	he_writel(he_dev, val, FRAMER + (addr*4));
 #ifdef CONFIG_IA64_SGI_SN2
 	(void) he_readl(he_dev, FRAMER + (addr*4));
 #endif
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 }
  
-        
+	
 static unsigned char
 he_phy_get(struct atm_dev *atm_dev, unsigned long addr)
 { 
@@ -2982,9 +2961,9 @@
 	struct he_dev *he_dev = HE_DEV(atm_dev);
 	unsigned reg;
 
-	HE_SPIN_LOCK(he_dev, flags);
-        reg = he_readl(he_dev, FRAMER + (addr*4));
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
+	reg = he_readl(he_dev, FRAMER + (addr*4));
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 	HPRINTK("phy_get(addr 0x%lx) =0x%x\n", addr, reg);
 	return reg;
@@ -2999,7 +2978,7 @@
 #ifdef notdef
 	struct he_rbrq *rbrq_tail;
 	struct he_tpdrq *tpdrq_head;
-        int rbpl_head, rbpl_tail;
+	int rbpl_head, rbpl_tail;
 #endif
 	static long mcc = 0, oec = 0, dcc = 0, cec = 0;
 
@@ -3015,12 +2994,12 @@
 	if (!left--)
 		return sprintf(page, "Mismatched Cells  VPI/VCI Not Open  Dropped Cells  RCM Dropped Cells\n");
 
-	HE_SPIN_LOCK(he_dev, flags);
+	spin_lock_irqsave(&he_dev->global_lock, flags);
 	mcc += he_readl(he_dev, MCC);
 	oec += he_readl(he_dev, OEC);
 	dcc += he_readl(he_dev, DCC);
 	cec += he_readl(he_dev, CEC);
-	HE_SPIN_UNLOCK(he_dev, flags);
+	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
 	if (!left--)
 		return sprintf(page, "%16ld  %16ld  %13ld  %17ld\n\n", 
@@ -3044,8 +3023,8 @@
 
 
 #ifdef notdef
-        rbpl_head = RBPL_MASK(he_readl(he_dev, G0_RBPL_S));
-        rbpl_tail = RBPL_MASK(he_readl(he_dev, G0_RBPL_T));
+	rbpl_head = RBPL_MASK(he_readl(he_dev, G0_RBPL_S));
+	rbpl_tail = RBPL_MASK(he_readl(he_dev, G0_RBPL_T));
 
 	inuse = rbpl_head - rbpl_tail;
 	if (inuse < 0)
@@ -3090,32 +3069,31 @@
 	he_writel(he_dev, val, HOST_CNTL);
        
 	/* Send READ instruction */
-	for (i=0; i<sizeof(readtab)/sizeof(readtab[0]); i++) {
+	for (i = 0; i < sizeof(readtab)/sizeof(readtab[0]); i++) {
 		he_writel(he_dev, val | readtab[i], HOST_CNTL);
 		udelay(EEPROM_DELAY);
 	}
        
-        /* Next, we need to send the byte address to read from */
-	for (i=7; i>=0; i--) {
+	/* Next, we need to send the byte address to read from */
+	for (i = 7; i >= 0; i--) {
 		he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
 		udelay(EEPROM_DELAY);
 		he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
 		udelay(EEPROM_DELAY);
 	}
        
-	j=0;
+	j = 0;
 
 	val &= 0xFFFFF7FF;      /* Turn off write enable */
 	he_writel(he_dev, val, HOST_CNTL);
        
 	/* Now, we can read data from the EEPROM by clocking it in */
-	for (i=7; i>=0; i--) {
+	for (i = 7; i >= 0; i--) {
 		he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
-	        udelay(EEPROM_DELAY);
-	        tmp_read = he_readl(he_dev, HOST_CNTL);
-	        byte_read |= (unsigned char)
-	                        ((tmp_read & ID_DOUT)
-	                         >> ID_DOFFSET << i);
+		udelay(EEPROM_DELAY);
+		tmp_read = he_readl(he_dev, HOST_CNTL);
+		byte_read |= (unsigned char)
+			   ((tmp_read & ID_DOUT) >> ID_DOFFSET << i);
 		he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
 		udelay(EEPROM_DELAY);
 	}
@@ -3123,7 +3101,7 @@
 	he_writel(he_dev, val | ID_CS, HOST_CNTL);
 	udelay(EEPROM_DELAY);
 
-        return (byte_read);
+	return byte_read;
 }
 
 MODULE_LICENSE("GPL");
@@ -3145,7 +3123,7 @@
 static struct pci_device_id he_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_HE, PCI_ANY_ID, PCI_ANY_ID,
 	  0, 0, 0 },
-        { 0, }
+	{ 0, }
 };
 
 static struct pci_driver he_driver = {
@@ -3157,12 +3135,12 @@
 
 static int __init he_init(void)
 {
-        return pci_module_init(&he_driver);
+	return pci_module_init(&he_driver);
 }
 
 static void __exit he_cleanup(void)
 {
-        pci_unregister_driver(&he_driver);
+	pci_unregister_driver(&he_driver);
 }
 
 module_init(he_init);
diff -urN linux-2.5.70-bk9/drivers/block/deadline-iosched.c linux-2.5.70-bk10/drivers/block/deadline-iosched.c
--- linux-2.5.70-bk9/drivers/block/deadline-iosched.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/drivers/block/deadline-iosched.c	2003-06-05 04:41:36.000000000 -0700
@@ -121,6 +121,15 @@
 		__deadline_del_drq_hash(drq);
 }
 
+static void
+deadline_remove_merge_hints(request_queue_t *q, struct deadline_rq *drq)
+{
+	deadline_del_drq_hash(drq);
+
+	if (q->last_merge == &drq->request->queuelist)
+		q->last_merge = NULL;
+}
+
 static inline void
 deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
 {
@@ -310,7 +319,7 @@
 		struct deadline_data *dd = q->elevator.elevator_data;
 
 		list_del_init(&drq->fifo);
-		deadline_del_drq_hash(drq);
+		deadline_remove_merge_hints(q, drq);
 		deadline_del_drq_rb(dd, drq);
 	}
 }
diff -urN linux-2.5.70-bk9/drivers/char/agp/amd-k8-agp.c linux-2.5.70-bk10/drivers/char/agp/amd-k8-agp.c
--- linux-2.5.70-bk9/drivers/char/agp/amd-k8-agp.c	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk10/drivers/char/agp/amd-k8-agp.c	2003-06-05 04:41:36.000000000 -0700
@@ -244,7 +244,7 @@
 				  const struct pci_device_id *ent)
 {
 	struct agp_bridge_data *bridge;
-	struct pci_dev *loop_dev;
+	struct pci_dev *loop_dev = NULL;
 	u8 rev_id;
 	u8 cap_ptr;
 	int i = 0;
@@ -297,7 +297,7 @@
 	pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
 
 	/* cache pci_devs of northbridges. */
-	pci_for_each_dev(loop_dev) {
+	while ((loop_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, loop_dev)) != NULL) {
 		if (loop_dev->bus->number == 0 &&
 		    PCI_FUNC(loop_dev->devfn) == 3 &&
 		    PCI_SLOT(loop_dev->devfn) >=24 &&
diff -urN linux-2.5.70-bk9/drivers/char/agp/generic.c linux-2.5.70-bk10/drivers/char/agp/generic.c
--- linux-2.5.70-bk9/drivers/char/agp/generic.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk10/drivers/char/agp/generic.c	2003-06-05 04:41:36.000000000 -0700
@@ -462,12 +462,12 @@
 //We need a function we pass an agp_device to.
 u32 agp_collect_device_status(u32 mode, u32 cmd)
 {
-	struct pci_dev *device;
+	struct pci_dev *device = NULL;
 	u8 cap_ptr;
 	u32 tmp;
 	u32 agp3;
 
-	pci_for_each_dev(device) {
+	while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) {
 		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
 		if (!cap_ptr)
 			continue;
@@ -502,14 +502,14 @@
 
 void agp_device_command(u32 command, int agp_v3)
 {
-	struct pci_dev *device;
+	struct pci_dev *device = NULL;
 	int mode;
 
 	mode = command & 0x7;
 	if (agp_v3)
 		mode *= 4;
 
-	pci_for_each_dev(device) {
+	while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL) {
 		u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
 		if (!agp)
 			continue;
diff -urN linux-2.5.70-bk9/drivers/char/agp/isoch.c linux-2.5.70-bk10/drivers/char/agp/isoch.c
--- linux-2.5.70-bk9/drivers/char/agp/isoch.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk10/drivers/char/agp/isoch.c	2003-06-05 04:41:36.000000000 -0700
@@ -316,7 +316,7 @@
  */
 int agp_3_5_enable(struct agp_bridge_data *bridge)
 {
-	struct pci_dev *td = bridge->dev, *dev;
+	struct pci_dev *td = bridge->dev, *dev = NULL;
 	u8 mcapndx;
 	u32 isoch, arqsz;
 	u32 tstatus, mstatus, ncapid;
@@ -347,7 +347,7 @@
 	INIT_LIST_HEAD(head);
 
 	/* Find all AGP devices, and add them to dev_list. */
-	pci_for_each_dev(dev) { 
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP);
 		if (mcapndx == 0)
 			continue;
diff -urN linux-2.5.70-bk9/drivers/char/hw_random.c linux-2.5.70-bk10/drivers/char/hw_random.c
--- linux-2.5.70-bk9/drivers/char/hw_random.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/drivers/char/hw_random.c	2003-06-05 04:41:36.000000000 -0700
@@ -573,13 +573,13 @@
 static int __init rng_init (void)
 {
 	int rc;
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 	const struct pci_device_id *ent;
 
 	DPRINTK ("ENTER\n");
 
 	/* Probe for Intel, AMD RNGs */
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		ent = pci_match_device (rng_pci_tbl, pdev);
 		if (ent) {
 			rng_ops = &rng_vendor_ops[ent->driver_data];
diff -urN linux-2.5.70-bk9/drivers/char/n_hdlc.c linux-2.5.70-bk10/drivers/char/n_hdlc.c
--- linux-2.5.70-bk9/drivers/char/n_hdlc.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk10/drivers/char/n_hdlc.c	2003-06-05 04:41:36.000000000 -0700
@@ -6,7 +6,8 @@
  * Microgate and SyncLink are registered trademarks of Microgate Corporation
  *
  * Adapted from ppp.c, written by Michael Callahan <callahan@maths.ox.ac.uk>,
- *	Al Longyear <longyear@netcom.com>, Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
+ *	Al Longyear <longyear@netcom.com>,
+ *	Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
  *
  * Original release 01/11/99
  * $Id: n_hdlc.c,v 4.8 2003/05/06 21:18:51 paulkf Exp $
@@ -96,32 +97,19 @@
 
 #include <linux/poll.h>
 #include <linux/in.h>
+#include <linux/ioctl.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/errno.h>
 #include <linux/string.h>	/* used in new tty drivers */
 #include <linux/signal.h>	/* used in new tty drivers */
+#include <linux/if.h>
+
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/termios.h>
-#include <linux/if.h>
-
-#include <linux/ioctl.h>
-
-#ifdef CONFIG_KERNELD
-#include <linux/kerneld.h>
-#endif
-
-#define GET_USER(error,value,addr) error = get_user(value,addr)
-#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
-#define PUT_USER(error,value,addr) error = put_user(value,addr)
-#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
-
 #include <asm/uaccess.h>
 
-typedef ssize_t		rw_ret_t;
-typedef size_t		rw_count_t;
-
 /*
  * Buffers for individual HDLC frames
  */
@@ -130,91 +118,90 @@
 #define MAX_RX_BUF_COUNT 60
 #define DEFAULT_TX_BUF_COUNT 1
 
+struct n_hdlc_buf {
+	struct n_hdlc_buf *link;
+	int		  count;
+	char		  buf[1];
+};
 
-typedef struct _n_hdlc_buf
-{
-	struct _n_hdlc_buf *link;
-	int count;
-	char buf[1];
-} N_HDLC_BUF;
-
-#define	N_HDLC_BUF_SIZE	(sizeof(N_HDLC_BUF)+maxframe)
+#define	N_HDLC_BUF_SIZE	(sizeof(struct n_hdlc_buf) + maxframe)
 
-typedef struct _n_hdlc_buf_list
-{
-	N_HDLC_BUF *head;
-	N_HDLC_BUF *tail;
-	int count;
-	spinlock_t spinlock;
-	
-} N_HDLC_BUF_LIST;
+struct n_hdlc_buf_list {
+	struct n_hdlc_buf *head;
+	struct n_hdlc_buf *tail;
+	int		  count;
+	spinlock_t	  spinlock;
+};
 
-/*
- * Per device instance data structure
+/**
+ * struct n_hdlc - per device instance data structure
+ * @magic - magic value for structure
+ * @flags - miscellaneous control flags
+ * @tty - ptr to TTY structure
+ * @backup_tty - TTY to use if tty gets closed
+ * @tbusy - reentrancy flag for tx wakeup code
+ * @woke_up - FIXME: describe this field
+ * @tbuf - currently transmitting tx buffer
+ * @tx_buf_list - list of pending transmit frame buffers
+ * @rx_buf_list - list of received frame buffers
+ * @tx_free_buf_list - list unused transmit frame buffers
+ * @rx_free_buf_list - list unused received frame buffers
  */
 struct n_hdlc {
-	int		magic;		/* magic value for structure	*/
-	__u32		flags;		/* miscellaneous control flags	*/
-	
-	struct tty_struct *tty;		/* ptr to TTY structure	*/
-	struct tty_struct *backup_tty;	/* TTY to use if tty gets closed */
-	
-	int		tbusy;		/* reentrancy flag for tx wakeup code */
-	int		woke_up;
-	N_HDLC_BUF	*tbuf;		/* currently transmitting tx buffer */
-	N_HDLC_BUF_LIST tx_buf_list;	/* list of pending transmit frame buffers */	
-	N_HDLC_BUF_LIST	rx_buf_list;	/* list of received frame buffers */
-	N_HDLC_BUF_LIST tx_free_buf_list;	/* list unused transmit frame buffers */	
-	N_HDLC_BUF_LIST	rx_free_buf_list;	/* list unused received frame buffers */
+	int			magic;
+	__u32			flags;
+	struct tty_struct	*tty;
+	struct tty_struct	*backup_tty;
+	int			tbusy;
+	int			woke_up;
+	struct n_hdlc_buf	*tbuf;
+	struct n_hdlc_buf_list	tx_buf_list;
+	struct n_hdlc_buf_list	rx_buf_list;
+	struct n_hdlc_buf_list	tx_free_buf_list;
+	struct n_hdlc_buf_list	rx_free_buf_list;
 };
 
 /*
  * HDLC buffer list manipulation functions
  */
-static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list);
-static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf);
-static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list);
+static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list);
+static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
+			   struct n_hdlc_buf *buf);
+static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list);
 
 /* Local functions */
 
 static struct n_hdlc *n_hdlc_alloc (void);
 
-MODULE_PARM(debuglevel, "i");
-MODULE_PARM(maxframe, "i");
-
-
 /* debug level can be set by insmod for debugging purposes */
 #define DEBUG_LEVEL_INFO	1
 static int debuglevel;
 
 /* max frame size for memory allocations */
-static ssize_t	maxframe=4096;
+static ssize_t maxframe = 4096;
 
 /* TTY callbacks */
 
-static rw_ret_t n_hdlc_tty_read(struct tty_struct *,
-	struct file *, __u8 *, rw_count_t);
-static rw_ret_t n_hdlc_tty_write(struct tty_struct *,
-	struct file *, const __u8 *, rw_count_t);
-static int n_hdlc_tty_ioctl(struct tty_struct *,
-	struct file *, unsigned int, unsigned long);
-static unsigned int n_hdlc_tty_poll (struct tty_struct *tty, struct file *filp,
-				  poll_table * wait);
-static int n_hdlc_tty_open (struct tty_struct *);
-static void n_hdlc_tty_close (struct tty_struct *);
-static int n_hdlc_tty_room (struct tty_struct *tty);
-static void n_hdlc_tty_receive (struct tty_struct *tty,
-	const __u8 * cp, char *fp, int count);
-static void n_hdlc_tty_wakeup (struct tty_struct *tty);
+static int n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
+			   __u8 *buf, size_t nr);
+static int n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
+			    const __u8 *buf, size_t nr);
+static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
+			    unsigned int cmd, unsigned long arg);
+static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
+				    poll_table *wait);
+static int n_hdlc_tty_open(struct tty_struct *tty);
+static void n_hdlc_tty_close(struct tty_struct *tty);
+static int n_hdlc_tty_room(struct tty_struct *tty);
+static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
+			       char *fp, int count);
+static void n_hdlc_tty_wakeup(struct tty_struct *tty);
 
 #define bset(p,b)	((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
 
 #define tty2n_hdlc(tty)	((struct n_hdlc *) ((tty)->disc_data))
 #define n_hdlc2tty(n_hdlc)	((n_hdlc)->tty)
 
-/* Define this string only once for all macro invocations */
-static char szVersion[] = HDLC_VERSION;
-
 static struct tty_ldisc n_hdlc_ldisc = {
 	.owner		= THIS_MODULE,
 	.magic		= TTY_LDISC_MAGIC,
@@ -230,15 +217,14 @@
 	.write_wakeup	= n_hdlc_tty_wakeup,
 };
 
-/* n_hdlc_release()
- *
- *	release an n_hdlc per device line discipline info structure
- *
+/**
+ * n_hdlc_release - release an n_hdlc per device line discipline info structure
+ * @n_hdlc - per device line discipline info structure
  */
-static void n_hdlc_release (struct n_hdlc *n_hdlc)
+static void n_hdlc_release(struct n_hdlc *n_hdlc)
 {
 	struct tty_struct *tty = n_hdlc2tty (n_hdlc);
-	N_HDLC_BUF *buf;
+	struct n_hdlc_buf *buf;
 	
 	if (debuglevel >= DEBUG_LEVEL_INFO)	
 		printk("%s(%d)n_hdlc_release() called\n",__FILE__,__LINE__);
@@ -285,10 +271,12 @@
 	
 }	/* end of n_hdlc_release() */
 
-/* n_hdlc_tty_close()
+/**
+ * n_hdlc_tty_close - line discipline close
+ * @tty - pointer to tty info structure
  *
- *	Called when the line discipline is changed to something
- *	else, the tty is closed, or the tty detects a hangup.
+ * Called when the line discipline is changed to something
+ * else, the tty is closed, or the tty detects a hangup.
  */
 static void n_hdlc_tty_close(struct tty_struct *tty)
 {
@@ -322,12 +310,11 @@
 		
 }	/* end of n_hdlc_tty_close() */
 
-/* n_hdlc_tty_open
- * 
- * 	called when line discipline changed to n_hdlc
- * 	
- * Arguments:	tty	pointer to tty info structure
- * Return Value:	0 if success, otherwise error code
+/**
+ * n_hdlc_tty_open - called when line discipline changed to n_hdlc
+ * @tty - pointer to tty info structure
+ *
+ * Returns 0 if success, otherwise error code
  */
 static int n_hdlc_tty_open (struct tty_struct *tty)
 {
@@ -373,22 +360,20 @@
 	
 }	/* end of n_tty_hdlc_open() */
 
-/* n_hdlc_send_frames()
- * 
- * 	send frames on pending send buffer list until the
- * 	driver does not accept a frame (busy)
- * 	this function is called after adding a frame to the
- * 	send buffer list and by the tty wakeup callback
- * 	
- * Arguments:		n_hdlc		pointer to ldisc instance data
- * 			tty		pointer to tty instance data
- * Return Value:	None
+/**
+ * n_hdlc_send_frames - send frames on pending send buffer list
+ * @n_hdlc - pointer to ldisc instance data
+ * @tty - pointer to tty instance data
+ *
+ * Send frames on pending send buffer list until the driver does not accept a
+ * frame (busy) this function is called after adding a frame to the send buffer
+ * list and by the tty wakeup callback.
  */
-static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty)
+static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
 {
 	register int actual;
 	unsigned long flags;
-	N_HDLC_BUF *tbuf;
+	struct n_hdlc_buf *tbuf;
 
 	if (debuglevel >= DEBUG_LEVEL_INFO)	
 		printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__);
@@ -431,7 +416,7 @@
 					__FILE__,__LINE__,tbuf);
 					
 			/* free current transmit buffer */
-			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
+			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf);
 			
 			/* this tx buffer is done */
 			n_hdlc->tbuf = NULL;
@@ -469,17 +454,15 @@
 		
 }	/* end of n_hdlc_send_frames() */
 
-/* n_hdlc_tty_wakeup()
+/**
+ * n_hdlc_tty_wakeup - Callback for transmit wakeup
+ * @tty	- pointer to associated tty instance data
  *
- *	Callback for transmit wakeup. Called when low level
- *	device driver can accept more send data.
- *
- * Arguments:		tty	pointer to associated tty instance data
- * Return Value:	None
+ * Called when low level device driver can accept more send data.
  */
-static void n_hdlc_tty_wakeup (struct tty_struct *tty)
+static void n_hdlc_tty_wakeup(struct tty_struct *tty)
 {
-	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
+	struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
 
 	if (debuglevel >= DEBUG_LEVEL_INFO)	
 		printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__,__LINE__);
@@ -496,16 +479,14 @@
 		
 }	/* end of n_hdlc_tty_wakeup() */
 
-/* n_hdlc_tty_room()
- * 
- *	Callback function from tty driver. Return the amount of 
- *	space left in the receiver's buffer to decide if remote
- *	transmitter is to be throttled.
+/**
+ * n_hdlc_tty_room - Return the amount of space left in the receiver's buffer
+ * @tty	- pointer to associated tty instance data
  *
- * Arguments:		tty	pointer to associated tty instance data
- * Return Value:	number of bytes left in receive buffer
+ * Callback function from tty driver. Return the amount of space left in the
+ * receiver's buffer to decide if remote transmitter is to be throttled.
  */
-static int n_hdlc_tty_room (struct tty_struct *tty)
+static int n_hdlc_tty_room(struct tty_struct *tty)
 {
 	if (debuglevel >= DEBUG_LEVEL_INFO)	
 		printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__,__LINE__);
@@ -514,23 +495,21 @@
 	return 65536;
 }	/* end of n_hdlc_tty_root() */
 
-/* n_hdlc_tty_receive()
- * 
- * 	Called by tty low level driver when receive data is
- * 	available. Data is interpreted as one HDLC frame.
- * 	
- * Arguments:	 	tty		pointer to tty isntance data
- * 			data		pointer to received data
- * 			flags		pointer to flags for data
- * 			count		count of received data in bytes
- * 	
- * Return Value:	None
+/**
+ * n_hdlc_tty_receive - Called by tty driver when receive data is available
+ * @tty	- pointer to tty instance data
+ * @data - pointer to received data
+ * @flags - pointer to flags for data
+ * @count - count of received data in bytes
+ *
+ * Called by tty low level driver when receive data is available. Data is
+ * interpreted as one HDLC frame.
  */
-static void n_hdlc_tty_receive(struct tty_struct *tty,
-	const __u8 * data, char *flags, int count)
+static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
+			       char *flags, int count)
 {
 	register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
-	register N_HDLC_BUF *buf;
+	register struct n_hdlc_buf *buf;
 
 	if (debuglevel >= DEBUG_LEVEL_INFO)	
 		printk("%s(%d)n_hdlc_tty_receive() called count=%d\n",
@@ -560,7 +539,7 @@
 		/* no buffers in free list, attempt to allocate another rx buffer */
 		/* unless the maximum count has been reached */
 		if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
-			buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_ATOMIC);
+			buf = kmalloc(N_HDLC_BUF_SIZE, GFP_ATOMIC);
 	}
 	
 	if (!buf) {
@@ -575,7 +554,7 @@
 	buf->count=count;
 
 	/* add HDLC buffer to list of received frames */
-	n_hdlc_buf_put(&n_hdlc->rx_buf_list,buf);
+	n_hdlc_buf_put(&n_hdlc->rx_buf_list, buf);
 	
 	/* wake up any blocked reads and perform async signalling */
 	wake_up_interruptible (&tty->read_wait);
@@ -584,28 +563,22 @@
 
 }	/* end of n_hdlc_tty_receive() */
 
-/* n_hdlc_tty_read()
- * 
- * 	Called to retreive one frame of data (if available)
- * 	
- * Arguments:
- * 
- * 	tty		pointer to tty instance data
- * 	file		pointer to open file object
- * 	buf		pointer to returned data buffer
- * 	nr		size of returned data buffer
+/**
+ * n_hdlc_tty_read - Called to retreive one frame of data (if available)
+ * @tty - pointer to tty instance data
+ * @file - pointer to open file object
+ * @buf - pointer to returned data buffer
+ * @nr - size of returned data buffer
  * 	
- * Return Value:
- * 
- * 	Number of bytes returned or error code
+ * Returns the number of bytes returned or error code.
  */
-static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty,
-	struct file *file, __u8 * buf, rw_count_t nr)
+static int n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
+			   __u8 *buf, size_t nr)
 {
 	struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
 	int error;
-	rw_ret_t ret;
-	N_HDLC_BUF *rbuf;
+	int ret;
+	struct n_hdlc_buf *rbuf;
 
 	if (debuglevel >= DEBUG_LEVEL_INFO)	
 		printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
@@ -644,16 +617,15 @@
 			return -EINTR;
 	}
 		
-	if (rbuf->count > nr) {
+	if (rbuf->count > nr)
 		/* frame too large for caller's buffer (discard frame) */
-		ret = (rw_ret_t)-EOVERFLOW;
-	} else {
+		ret = -EOVERFLOW;
+	else {
 		/* Copy the data to the caller's buffer */
-		COPY_TO_USER(error,buf,rbuf->buf,rbuf->count);
-		if (error)
-			ret = (rw_ret_t)error;
+		if (copy_to_user(buf, rbuf->buf, rbuf->count))
+			ret = -EFAULT;
 		else
-			ret = (rw_ret_t)rbuf->count;
+			ret = rbuf->count;
 	}
 	
 	/* return HDLC buffer to free list unless the free list */
@@ -668,24 +640,22 @@
 	
 }	/* end of n_hdlc_tty_read() */
 
-/* n_hdlc_tty_write()
- * 
- * 	write a single frame of data to device
- * 	
- * Arguments:	tty	pointer to associated tty device instance data
- * 		file	pointer to file object data
- * 		data	pointer to transmit data (one frame)
- * 		count	size of transmit frame in bytes
+/**
+ * n_hdlc_tty_write - write a single frame of data to device
+ * @tty	- pointer to associated tty device instance data
+ * @file - pointer to file object data
+ * @data - pointer to transmit data (one frame)
+ * @count - size of transmit frame in bytes
  * 		
- * Return Value:	number of bytes written (or error code)
+ * Returns the number of bytes written (or error code).
  */
-static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file,
-	const __u8 * data, rw_count_t count)
+static int n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
+			    const __u8 *data, size_t count)
 {
 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 	int error = 0;
 	DECLARE_WAITQUEUE(wait, current);
-	N_HDLC_BUF *tbuf;
+	struct n_hdlc_buf *tbuf;
 
 	if (debuglevel >= DEBUG_LEVEL_INFO)	
 		printk("%s(%d)n_hdlc_tty_write() called count=%d\n",
@@ -735,10 +705,10 @@
 
 	if (!error) {		
 		/* Retrieve the user's buffer */
-		COPY_FROM_USER (error, tbuf->buf, data, count);
-		if (error) {
+		if (copy_from_user(tbuf->buf, data, count)) {
 			/* return tx buffer to free list */
 			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
+			error = -EFAULT;
 		} else {
 			/* Send the data */
 			tbuf->count = error = count;
@@ -751,21 +721,17 @@
 	
 }	/* end of n_hdlc_tty_write() */
 
-/* n_hdlc_tty_ioctl()
- *
- *	Process IOCTL system call for the tty device.
+/**
+ * n_hdlc_tty_ioctl - process IOCTL system call for the tty device.
+ * @tty - pointer to tty instance data
+ * @file - pointer to open file object for device
+ * @cmd - IOCTL command code
+ * @arg - argument for IOCTL call (cmd dependent)
  *
- * Arguments:
- *
- *	tty		pointer to tty instance data
- *	file		pointer to open file object for device
- *	cmd		IOCTL command code
- *	arg		argument for IOCTL call (cmd dependent)
- *
- * Return Value:	Command dependent
+ * Returns command dependent result.
  */
-static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file,
-               unsigned int cmd, unsigned long arg)
+static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
+			    unsigned int cmd, unsigned long arg)
 {
 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 	int error = 0;
@@ -790,7 +756,7 @@
 		else
 			count = 0;
 		spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
-		PUT_USER (error, count, (int *) arg);
+		error = put_user(count, (int *)arg);
 		break;
 
 	case TIOCOUTQ:
@@ -802,7 +768,7 @@
 		if (n_hdlc->tx_buf_list.head)
 			count += n_hdlc->tx_buf_list.head->count;
 		spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
-		PUT_USER (error, count, (int*)arg);
+		error = put_user(count, (int*)arg);
 		break;
 
 	default:
@@ -813,24 +779,18 @@
 	
 }	/* end of n_hdlc_tty_ioctl() */
 
-/* n_hdlc_tty_poll()
- * 
- * 	TTY callback for poll system call. Determine which 
- * 	operations (read/write) will not block and return
- * 	info to caller.
- * 	
- * Arguments:
- * 
- * 	tty		pointer to tty instance data
- * 	filp		pointer to open file object for device
- * 	poll_table	wait queue for operations
- * 
- * Return Value:
- * 
- * 	bit mask containing info on which ops will not block
+/**
+ * n_hdlc_tty_poll - TTY callback for poll system call
+ * @tty - pointer to tty instance data
+ * @filp - pointer to open file object for device
+ * @poll_table - wait queue for operations
+ * 
+ * Determine which operations (read/write) will not block and return info
+ * to caller.
+ * Returns a bit mask containing info on which ops will not block.
  */
-static unsigned int n_hdlc_tty_poll (struct tty_struct *tty,
-	 struct file *filp, poll_table * wait)
+static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
+				    poll_table *wait)
 {
 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 	unsigned int mask = 0;
@@ -858,20 +818,17 @@
 	return mask;
 }	/* end of n_hdlc_tty_poll() */
 
-/* n_hdlc_alloc()
- * 
- * 	Allocate an n_hdlc instance data structure
+/**
+ * n_hdlc_alloc - allocate an n_hdlc instance data structure
  *
- * Arguments:		None
- * Return Value:	pointer to structure if success, otherwise 0	
+ * Returns a pointer to newly created structure if success, otherwise %NULL
  */
-static struct n_hdlc *n_hdlc_alloc (void)
+static struct n_hdlc *n_hdlc_alloc(void)
 {
-	struct n_hdlc	*n_hdlc;
-	N_HDLC_BUF	*buf;
-	int		i;
-	
-	n_hdlc = (struct n_hdlc *)kmalloc(sizeof(struct n_hdlc), GFP_KERNEL);
+	struct n_hdlc_buf *buf;
+	int i;
+	struct n_hdlc *n_hdlc = kmalloc(sizeof(*n_hdlc), GFP_KERNEL);
+
 	if (!n_hdlc)
 		return 0;
 
@@ -884,7 +841,7 @@
 	
 	/* allocate free rx buffer list */
 	for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
-		buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL);
+		buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
 		if (buf)
 			n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
 		else if (debuglevel >= DEBUG_LEVEL_INFO)	
@@ -893,7 +850,7 @@
 	
 	/* allocate free tx buffer list */
 	for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
-		buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL);
+		buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
 		if (buf)
 			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
 		else if (debuglevel >= DEBUG_LEVEL_INFO)	
@@ -908,31 +865,23 @@
 	
 }	/* end of n_hdlc_alloc() */
 
-/* n_hdlc_buf_list_init()
- * 
- * 	initialize specified HDLC buffer list
- * 	
- * Arguments:	 	list	pointer to buffer list
- * Return Value:	None	
+/**
+ * n_hdlc_buf_list_init - initialize specified HDLC buffer list
+ * @list - pointer to buffer list
  */
-static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list)
+static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list)
 {
-	memset(list,0,sizeof(N_HDLC_BUF_LIST));
+	memset(list, 0, sizeof(*list));
 	spin_lock_init(&list->spinlock);
 }	/* end of n_hdlc_buf_list_init() */
 
-/* n_hdlc_buf_put()
- * 
- * 	add specified HDLC buffer to tail of specified list
- * 	
- * Arguments:
- * 
- * 	list	pointer to buffer list
- * 	buf	pointer to buffer
- * 
- * Return Value:	None	
+/**
+ * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
+ * @list - pointer to buffer list
+ * @buf	- pointer to buffer
  */
-static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf)
+static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
+			   struct n_hdlc_buf *buf)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&list->spinlock,flags);
@@ -949,23 +898,18 @@
 	
 }	/* end of n_hdlc_buf_put() */
 
-/* n_hdlc_buf_get()
- * 
- * 	remove and return an HDLC buffer from the
- * 	head of the specified HDLC buffer list
- * 	
- * Arguments:
- * 
- * 	list	pointer to HDLC buffer list
- * 	
- * Return Value:
- * 
- * 	pointer to HDLC buffer if available, otherwise NULL
+/**
+ * n_hdlc_buf_get - remove and return an HDLC buffer from list
+ * @list - pointer to HDLC buffer list
+ * 
+ * Remove and return an HDLC buffer from the head of the specified HDLC buffer
+ * list.
+ * Returns a pointer to HDLC buffer if available, otherwise %NULL.
  */
-static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list)
+static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list)
 {
 	unsigned long flags;
-	N_HDLC_BUF *buf;
+	struct n_hdlc_buf *buf;
 	spin_lock_irqsave(&list->spinlock,flags);
 	
 	buf = list->head;
@@ -981,42 +925,60 @@
 	
 }	/* end of n_hdlc_buf_get() */
 
+static char hdlc_banner[] __initdata =
+	KERN_INFO "HDLC line discipline: version " HDLC_VERSION
+	", maxframe=%u\n";
+static char hdlc_register_ok[] __initdata =
+	KERN_INFO "N_HDLC line discipline registered.\n";
+static char hdlc_register_fail[] __initdata =
+	KERN_ERR "error registering line discipline: %d\n";
+static char hdlc_init_fail[] __initdata =
+	KERN_INFO "N_HDLC: init failure %d\n";
+
 static int __init n_hdlc_init(void)
 {
-	int    status;
+	int status;
 
 	/* range check maxframe arg */
-	if ( maxframe<4096)
-		maxframe=4096;
-	else if ( maxframe>65535)
-		maxframe=65535;
+	if (maxframe < 4096)
+		maxframe = 4096;
+	else if (maxframe > 65535)
+		maxframe = 65535;
 
-	printk("HDLC line discipline: version %s, maxframe=%u\n", 
-		szVersion, maxframe);
+	printk(hdlc_banner, maxframe);
 
 	status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc);
 	if (!status)
-		printk (KERN_INFO"N_HDLC line discipline registered.\n");
+		printk(hdlc_register_ok);
 	else
-		printk (KERN_ERR"error registering line discipline: %d\n",status);
+		printk(hdlc_register_fail, status);
 
 	if (status)
-		printk(KERN_INFO"N_HDLC: init failure %d\n", status);
-	return (status);
+		printk(hdlc_init_fail, status);
+	return status;
 	
 }	/* end of init_module() */
 
+static char hdlc_unregister_ok[] __exitdata =
+	KERN_INFO "N_HDLC: line discipline unregistered\n";
+static char hdlc_unregister_fail[] __exitdata =
+	KERN_ERR "N_HDLC: can't unregister line discipline (err = %d)\n";
+
 static void __exit n_hdlc_exit(void)
 {
-	int status;
 	/* Release tty registration of line discipline */
-	if ((status = tty_register_ldisc(N_HDLC, NULL)))
-		printk("N_HDLC: can't unregister line discipline (err = %d)\n", status);
+	int status = tty_register_ldisc(N_HDLC, NULL);
+
+	if (status)
+		printk(hdlc_unregister_fail, status);
 	else
-		printk("N_HDLC: line discipline unregistered\n");
+		printk(hdlc_unregister_ok);
 }
 
 module_init(n_hdlc_init);
 module_exit(n_hdlc_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Paul Fulghum paulkf@microgate.com");
+MODULE_PARM(debuglevel, "i");
+MODULE_PARM(maxframe, "i");
diff -urN linux-2.5.70-bk9/drivers/char/watchdog/amd7xx_tco.c linux-2.5.70-bk10/drivers/char/watchdog/amd7xx_tco.c
--- linux-2.5.70-bk9/drivers/char/watchdog/amd7xx_tco.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk10/drivers/char/watchdog/amd7xx_tco.c	2003-06-05 04:41:36.000000000 -0700
@@ -309,7 +309,8 @@
 	sema_init(&open_sem, 1);
 	spin_lock_init(&amdtco_lock);
 
-	pci_for_each_dev(dev) {
+	dev = NULL;
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if (pci_match_device (amdtco_pci_tbl, dev) != NULL)
 			goto found_one;
 	}
diff -urN linux-2.5.70-bk9/drivers/char/watchdog/i810-tco.c linux-2.5.70-bk10/drivers/char/watchdog/i810-tco.c
--- linux-2.5.70-bk9/drivers/char/watchdog/i810-tco.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk10/drivers/char/watchdog/i810-tco.c	2003-06-05 04:41:36.000000000 -0700
@@ -315,14 +315,14 @@
 
 static unsigned char __init i810tco_getdevice (void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	u8 val1, val2;
 	u16 badr;
 	/*
 	 *      Find the PCI device
 	 */
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if (pci_match_device(i810tco_pci_tbl, dev)) {
 			i810tco_pci = dev;
 			break;
diff -urN linux-2.5.70-bk9/drivers/hotplug/Kconfig linux-2.5.70-bk10/drivers/hotplug/Kconfig
--- linux-2.5.70-bk9/drivers/hotplug/Kconfig	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/Kconfig	1969-12-31 16:00:00.000000000 -0800
@@ -1,120 +0,0 @@
-#
-# PCI Hotplug support
-#
-
-menu "PCI Hotplug Support"
-	depends on HOTPLUG
-
-config HOTPLUG_PCI
-	tristate "Support for PCI Hotplug (EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
-	---help---
-	  Say Y here if you have a motherboard with a PCI Hotplug controller.
-	  This allows you to add and remove PCI cards while the machine is
-	  powered up and running.  The file system pcihpfs must be mounted
-	  in order to interact with any PCI Hotplug controllers.
-
-	  This code is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pci_hotplug. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_COMPAQ
-	tristate "Compaq PCI Hotplug driver"
-	depends on HOTPLUG_PCI && X86
-	help
-	  Say Y here if you have a motherboard with a Compaq PCI Hotplug
-	  controller.
-
-	  This code is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpqphp. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_COMPAQ_NVRAM
-	bool "Save configuration into NVRAM on Compaq servers"
-	depends on HOTPLUG_PCI_COMPAQ
-	help
-	  Say Y here if you have a Compaq server that has a PCI Hotplug
-	  controller.  This will allow the PCI Hotplug driver to store the PCI
-	  system configuration options in NVRAM.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_IBM
-	tristate "IBM PCI Hotplug driver"
-	depends on HOTPLUG_PCI && X86_IO_APIC && X86
-	help
-	  Say Y here if you have a motherboard with a IBM PCI Hotplug
-	  controller.
-
-	  This code is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpqphp. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_ACPI
-	tristate "ACPI PCI Hotplug driver"
-	depends on ACPI_BUS && HOTPLUG_PCI
-	help
-	  Say Y here if you have a system that supports PCI Hotplug using
-	  ACPI.
-
-	  This code is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called acpiphp. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_CPCI
-	tristate "CompactPCI Hotplug driver"
-	depends on HOTPLUG_PCI
-	help
-	  Say Y here if you have a CompactPCI system card with CompactPCI
-	  hotswap support per the PICMG 2.1 specification.
-
-	  This code is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpci_hotplug. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_CPCI_ZT5550
-	tristate "Ziatech ZT5550 CompactPCI Hotplug driver"
-	depends on HOTPLUG_PCI_CPCI && X86
-	help
-	  Say Y here if you have an Performance Technologies (formerly Intel,
-          formerly just Ziatech) Ziatech ZT5550 CompactPCI system card.
-
-	  This code is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpcihp_zt5550. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_CPCI_GENERIC
-	tristate "Generic port I/O CompactPCI Hotplug driver"
-	depends on HOTPLUG_PCI_CPCI && X86
-	help
-	  Say Y here if you have a CompactPCI system card that exposes the #ENUM
-	  hotswap signal as a bit in a system register that can be read through
-	  standard port I/O.
-
-	  This code is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpcihp_generic. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-	  When in doubt, say N.
-
-endmenu
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/Makefile linux-2.5.70-bk10/drivers/hotplug/Makefile
--- linux-2.5.70-bk9/drivers/hotplug/Makefile	2003-05-26 18:00:44.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/Makefile	1969-12-31 16:00:00.000000000 -0800
@@ -1,44 +0,0 @@
-#
-# Makefile for the Linux kernel pci hotplug controller drivers.
-#
-
-obj-$(CONFIG_HOTPLUG_PCI)		+= pci_hotplug.o
-obj-$(CONFIG_HOTPLUG_PCI_COMPAQ)	+= cpqphp.o
-obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
-obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
-obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)	+= cpcihp_zt5550.o
-obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC)	+= cpcihp_generic.o
-
-pci_hotplug-objs	:=	pci_hotplug_core.o
-
-ifdef CONFIG_HOTPLUG_PCI_CPCI
-pci_hotplug-objs	+=	cpci_hotplug_core.o	\
-				cpci_hotplug_pci.o
-endif
-
-cpqphp-objs		:=	cpqphp_core.o	\
-				cpqphp_ctrl.o	\
-				cpqphp_sysfs.o	\
-				cpqphp_pci.o
-
-ibmphp-objs		:=	ibmphp_core.o	\
-				ibmphp_ebda.o	\
-				ibmphp_pci.o	\
-				ibmphp_res.o	\
-				ibmphp_hpc.o
-
-acpiphp-objs		:=	acpiphp_core.o	\
-				acpiphp_glue.o	\
-				acpiphp_pci.o	\
-				acpiphp_res.o
-
-ifdef CONFIG_HOTPLUG_PCI_ACPI
-  EXTRA_CFLAGS  += -D_LINUX -I$(TOPDIR)/drivers/acpi
-  ifdef CONFIG_ACPI_DEBUG
-    EXTRA_CFLAGS += -DACPI_DEBUG_OUTPUT
-  endif
-endif
-
-ifeq ($(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM),y)
-	cpqphp-objs += cpqphp_nvram.o
-endif
diff -urN linux-2.5.70-bk9/drivers/hotplug/acpiphp.h linux-2.5.70-bk10/drivers/hotplug/acpiphp.h
--- linux-2.5.70-bk9/drivers/hotplug/acpiphp.h	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/acpiphp.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,262 +0,0 @@
-/*
- * ACPI PCI Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
- * Copyright (c) 2002 NEC Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>,
- *		    <h-aono@ap.jp.nec.com>,
- *		    <t-kouchi@cq.jp.nec.com>
- *
- */
-
-#ifndef _ACPIPHP_H
-#define _ACPIPHP_H
-
-#include <linux/acpi.h>
-#include "pci_hotplug.h"
-
-#define dbg(format, arg...)					\
-	do {							\
-		if (acpiphp_debug)				\
-			printk(KERN_DEBUG "%s: " format,	\
-				MY_NAME , ## arg); 		\
-	} while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
-
-#define SLOT_MAGIC	0x67267322
-/* name size which is used for entries in pcihpfs */
-#define SLOT_NAME_SIZE	32		/* ACPI{_SUN}-{BUS}:{DEV} */
-
-struct acpiphp_bridge;
-struct acpiphp_slot;
-struct pci_resource;
-
-/*
- * struct slot - slot information for each *physical* slot
- */
-struct slot {
-	u32 magic;
-	u8 number;
-	struct hotplug_slot	*hotplug_slot;
-	struct list_head	slot_list;
-
-	struct acpiphp_slot	*acpi_slot;
-};
-
-/*
- * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
- */
-struct pci_resource {
-	struct pci_resource * next;
-	u64 base;
-	u32 length;
-};
-
-/**
- * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
- * @cache_line_size in DWORD
- * @latency_timer in PCI clock
- * @enable_SERR 0 or 1
- * @enable_PERR 0 or 1
- */
-struct hpp_param {
-	u8 cache_line_size;
-	u8 latency_timer;
-	u8 enable_SERR;
-	u8 enable_PERR;
-};
-
-
-/**
- * struct acpiphp_bridge - PCI bridge information
- *
- * for each bridge device in ACPI namespace
- */
-struct acpiphp_bridge {
-	struct list_head list;
-	acpi_handle handle;
-	struct acpiphp_slot *slots;
-	int type;
-	int nr_slots;
-
-	u8 seg;
-	u8 bus;
-	u8 sub;
-
-	u32 flags;
-
-	/* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
-	struct pci_bus *pci_bus;
-
-	/* PCI-to-PCI bridge device */
-	struct pci_dev *pci_dev;
-
-	/* ACPI 2.0 _HPP parameters */
-	struct hpp_param hpp;
-
-	spinlock_t res_lock;
-
-	/* available resources on this bus */
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
-};
-
-
-/**
- * struct acpiphp_slot - PCI slot information
- *
- * PCI slot information for each *physical* PCI slot
- */
-struct acpiphp_slot {
-	struct acpiphp_slot *next;
-	struct acpiphp_bridge *bridge;	/* parent */
-	struct list_head funcs;		/* one slot may have different
-					   objects (i.e. for each function) */
-	struct semaphore crit_sect;
-
-	u32		id;		/* slot id (serial #) for hotplug core */
-	u8		device;		/* pci device# */
-
-	u32		sun;		/* ACPI _SUN (slot unique number) */
-	u32		slotno;		/* slot number relative to bridge */
-	u32		flags;		/* see below */
-};
-
-
-/**
- * struct acpiphp_func - PCI function information
- *
- * PCI function information for each object in ACPI namespace
- * typically 8 objects per slot (i.e. for each PCI function)
- */
-struct acpiphp_func {
-	struct acpiphp_slot *slot;	/* parent */
-
-	struct list_head sibling;
-	struct pci_dev *pci_dev;
-
-	acpi_handle	handle;
-
-	u8		function;	/* pci function# */
-	u32		flags;		/* see below */
-
-	/* resources used for this function */
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
-};
-
-
-/* PCI bus bridge HID */
-#define ACPI_PCI_HOST_HID		"PNP0A03"
-
-/* PCI BRIDGE type */
-#define BRIDGE_TYPE_HOST		0
-#define BRIDGE_TYPE_P2P			1
-
-/* ACPI _STA method value (ignore bit 4; battery present) */
-#define ACPI_STA_PRESENT		(0x00000001)
-#define ACPI_STA_ENABLED		(0x00000002)
-#define ACPI_STA_SHOW_IN_UI		(0x00000004)
-#define ACPI_STA_FUNCTIONING		(0x00000008)
-#define ACPI_STA_ALL			(0x0000000f)
-
-/* bridge flags */
-#define BRIDGE_HAS_STA		(0x00000001)
-#define BRIDGE_HAS_EJ0		(0x00000002)
-#define BRIDGE_HAS_HPP		(0x00000004)
-#define BRIDGE_HAS_PS0		(0x00000010)
-#define BRIDGE_HAS_PS1		(0x00000020)
-#define BRIDGE_HAS_PS2		(0x00000040)
-#define BRIDGE_HAS_PS3		(0x00000080)
-
-/* slot flags */
-
-#define SLOT_POWEREDON		(0x00000001)
-#define SLOT_ENABLED		(0x00000002)
-#define SLOT_MULTIFUNCTION	(x000000004)
-
-/* function flags */
-
-#define FUNC_HAS_STA		(0x00000001)
-#define FUNC_HAS_EJ0		(0x00000002)
-#define FUNC_HAS_PS0		(0x00000010)
-#define FUNC_HAS_PS1		(0x00000020)
-#define FUNC_HAS_PS2		(0x00000040)
-#define FUNC_HAS_PS3		(0x00000080)
-
-/* not yet */
-#define SLOT_SUPPORT_66MHZ	(0x00010000)
-#define SLOT_SUPPORT_100MHZ	(0x00020000)
-#define SLOT_SUPPORT_133MHZ	(0x00040000)
-#define SLOT_SUPPORT_PCIX	(0x00080000)
-
-/* function prototypes */
-
-/* acpiphp_glue.c */
-extern int acpiphp_glue_init (void);
-extern void acpiphp_glue_exit (void);
-extern int acpiphp_get_num_slots (void);
-extern struct acpiphp_slot *get_slot_from_id (int id);
-typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
-extern int acpiphp_for_each_slot (acpiphp_callback fn, void *data);
-
-extern int acpiphp_check_bridge (struct acpiphp_bridge *bridge);
-extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
-extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
-extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot);
-extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot);
-extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
-extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
-
-/* acpiphp_pci.c */
-extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
-extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
-extern int acpiphp_configure_function (struct acpiphp_func *func);
-extern int acpiphp_unconfigure_function (struct acpiphp_func *func);
-extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
-extern int acpiphp_init_func_resource (struct acpiphp_func *func);
-
-/* acpiphp_res.c */
-extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
-extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
-extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
-extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
-extern void acpiphp_free_resource (struct pci_resource **res);
-extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
-extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
-
-/* variables */
-extern int acpiphp_debug;
-
-#endif /* _ACPIPHP_H */
diff -urN linux-2.5.70-bk9/drivers/hotplug/acpiphp_core.c linux-2.5.70-bk10/drivers/hotplug/acpiphp_core.c
--- linux-2.5.70-bk9/drivers/hotplug/acpiphp_core.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/acpiphp_core.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,505 +0,0 @@
-/*
- * ACPI PCI Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
- * Copyright (c) 2002 NEC Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>,
- *                  <h-aono@ap.jp.nec.com>,
- *		    <t-kouchi@cq.jp.nec.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-static LIST_HEAD(slot_list);
-
-#if !defined(CONFIG_HOTPLUG_PCI_ACPI_MODULE)
-	#define MY_NAME	"acpiphp"
-#else
-	#define MY_NAME	THIS_MODULE->name
-#endif
-
-static int debug;
-int acpiphp_debug;
-
-/* local variables */
-static int num_slots;
-
-#define DRIVER_VERSION	"0.4"
-#define DRIVER_AUTHOR	"Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kouchi@cq.jp.nec.com>"
-#define DRIVER_DESC	"ACPI Hot Plug PCI Controller Driver"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-
-static int enable_slot		(struct hotplug_slot *slot);
-static int disable_slot		(struct hotplug_slot *slot);
-static int set_attention_status (struct hotplug_slot *slot, u8 value);
-static int hardware_test	(struct hotplug_slot *slot, u32 value);
-static int get_power_status	(struct hotplug_slot *slot, u8 *value);
-static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
-static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
-static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
-static int get_max_bus_speed	(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
-static int get_cur_bus_speed	(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
-
-static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
-	.owner			= THIS_MODULE,
-	.enable_slot		= enable_slot,
-	.disable_slot		= disable_slot,
-	.set_attention_status	= set_attention_status,
-	.hardware_test		= hardware_test,
-	.get_power_status	= get_power_status,
-	.get_attention_status	= get_attention_status,
-	.get_latch_status	= get_latch_status,
-	.get_adapter_status	= get_adapter_status,
-	.get_max_bus_speed	= get_max_bus_speed,
-	.get_cur_bus_speed	= get_cur_bus_speed,
-};
-
-
-/* Inline functions to check the sanity of a pointer that is passed to us */
-static inline int slot_paranoia_check (struct slot *slot, const char *function)
-{
-	if (!slot) {
-		dbg("%s - slot == NULL\n", function);
-		return -1;
-	}
-	if (slot->magic != SLOT_MAGIC) {
-		dbg("%s - bad magic number for slot\n", function);
-		return -1;
-	}
-	if (!slot->hotplug_slot) {
-		dbg("%s - slot->hotplug_slot == NULL!\n", function);
-		return -1;
-	}
-	return 0;
-}
-
-
-static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
-{
-	struct slot *slot;
-
-	if (!hotplug_slot) {
-		dbg("%s - hotplug_slot == NULL\n", function);
-		return NULL;
-	}
-
-	slot = (struct slot *)hotplug_slot->private;
-	if (slot_paranoia_check(slot, function))
-                return NULL;
-	return slot;
-}
-
-
-/**
- * enable_slot - power on and enable a slot
- * @hotplug_slot: slot to enable
- *
- * Actual tasks are done in acpiphp_enable_slot()
- *
- */
-static int enable_slot (struct hotplug_slot *hotplug_slot)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-	int retval = 0;
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	/* enable the specified slot */
-	retval = acpiphp_enable_slot(slot->acpi_slot);
-
-	return retval;
-}
-
-
-/**
- * disable_slot - disable and power off a slot
- * @hotplug_slot: slot to disable
- *
- * Actual tasks are done in acpiphp_disable_slot()
- *
- */
-static int disable_slot (struct hotplug_slot *hotplug_slot)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-	int retval = 0;
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	/* disable the specified slot */
-	retval = acpiphp_disable_slot(slot->acpi_slot);
-
-	return retval;
-}
-
-
-/**
- * set_attention_status - set attention LED
- *
- * TBD:
- * ACPI doesn't have known method to manipulate
- * attention status LED.
- *
- */
-static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
-{
-	int retval = 0;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	switch (status) {
-		case 0:
-			/* FIXME turn light off */
-			hotplug_slot->info->attention_status = 0;
-			break;
-
-		case 1:
-		default:
-			/* FIXME turn light on */
-			hotplug_slot->info->attention_status = 1;
-			break;
-	}
-
-	return retval;
-}
-
-
-/**
- * hardware_test - hardware test
- *
- * We have nothing to do for now...
- *
- */
-static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-	int retval = 0;
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	err("No hardware tests are defined for this driver\n");
-	retval = -ENODEV;
-
-	return retval;
-}
-
-
-/**
- * get_power_status - get power status of a slot
- * @hotplug_slot: slot to get status
- * @value: pointer to store status
- *
- * Some platforms may not implement _STA method properly.
- * In that case, the value returned may not be reliable.
- *
- */
-static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-	int retval = 0;
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	*value = acpiphp_get_power_status(slot->acpi_slot);
-
-	return retval;
-}
-
-
-/**
- * get_attention_status - get attention LED status
- *
- * TBD:
- * ACPI doesn't provide any formal means to access attention LED status.
- *
- */
-static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	int retval = 0;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	*value = hotplug_slot->info->attention_status;
-
-	return retval;
-}
-
-
-/**
- * get_latch_status - get latch status of a slot
- * @hotplug_slot: slot to get status
- * @value: pointer to store status
- *
- * ACPI doesn't provide any formal means to access latch status.
- * Instead, we fake latch status from _STA
- *
- */
-static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-	int retval = 0;
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	*value = acpiphp_get_latch_status(slot->acpi_slot);
-
-	return retval;
-}
-
-
-/**
- * get_adapter_status - get adapter status of a slot
- * @hotplug_slot: slot to get status
- * @value: pointer to store status
- *
- * ACPI doesn't provide any formal means to access adapter status.
- * Instead, we fake adapter status from _STA
- *
- */
-static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-	int retval = 0;
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	*value = acpiphp_get_adapter_status(slot->acpi_slot);
-
-	return retval;
-}
-
-
-/* return dummy value because ACPI doesn't provide any method... */
-static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	*value = PCI_SPEED_UNKNOWN;
-
-	return 0;
-}
-
-
-/* return dummy value because ACPI doesn't provide any method... */
-static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	*value = PCI_SPEED_UNKNOWN;
-
-	return 0;
-}
-
-
-static int init_acpi (void)
-{
-	int retval;
-
-	/* initialize internal data structure etc. */
-	retval = acpiphp_glue_init();
-
-	/* read initial number of slots */
-	if (!retval) {
-		num_slots = acpiphp_get_num_slots();
-		if (num_slots == 0)
-			retval = -ENODEV;
-	}
-
-	return retval;
-}
-
-
-/**
- * make_slot_name - make a slot name that appears in pcihpfs
- * @slot: slot to name
- *
- */
-static void make_slot_name (struct slot *slot)
-{
-	snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "ACPI%d-%02x:%02x",
-		 slot->acpi_slot->sun,
-		 slot->acpi_slot->bridge->bus,
-		 slot->acpi_slot->device);
-}
-
-/**
- * init_slots - initialize 'struct slot' structures for each slot
- *
- */
-static int init_slots (void)
-{
-	struct slot *slot;
-	int retval = 0;
-	int i;
-
-	for (i = 0; i < num_slots; ++i) {
-		slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
-		if (!slot)
-			return -ENOMEM;
-		memset(slot, 0, sizeof(struct slot));
-
-		slot->hotplug_slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
-		if (!slot->hotplug_slot) {
-			kfree(slot);
-			return -ENOMEM;
-		}
-		memset(slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
-
-		slot->hotplug_slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
-		if (!slot->hotplug_slot->info) {
-			kfree(slot->hotplug_slot);
-			kfree(slot);
-			return -ENOMEM;
-		}
-		memset(slot->hotplug_slot->info, 0, sizeof(struct hotplug_slot_info));
-
-		slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
-		if (!slot->hotplug_slot->name) {
-			kfree(slot->hotplug_slot->info);
-			kfree(slot->hotplug_slot);
-			kfree(slot);
-			return -ENOMEM;
-		}
-
-		slot->magic = SLOT_MAGIC;
-		slot->number = i;
-
-		slot->hotplug_slot->private = slot;
-		slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
-
-		slot->acpi_slot = get_slot_from_id(i);
-		slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
-		slot->hotplug_slot->info->attention_status = acpiphp_get_attention_status(slot->acpi_slot);
-		slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
-		slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
-
-		make_slot_name(slot);
-
-		retval = pci_hp_register(slot->hotplug_slot);
-		if (retval) {
-			err("pci_hp_register failed with error %d\n", retval);
-			kfree(slot->hotplug_slot->info);
-			kfree(slot->hotplug_slot->name);
-			kfree(slot->hotplug_slot);
-			kfree(slot);
-			return retval;
-		}
-
-		/* add slot to our internal list */
-		list_add(&slot->slot_list, &slot_list);
-		info("Slot [%s] registered\n", slot->hotplug_slot->name);
-	}
-
-	return retval;
-}
-
-
-static void cleanup_slots (void)
-{
-	struct list_head *tmp, *n;
-	struct slot *slot;
-
-	list_for_each_safe (tmp, n, &slot_list) {
-		slot = list_entry(tmp, struct slot, slot_list);
-		list_del(&slot->slot_list);
-		pci_hp_deregister(slot->hotplug_slot);
-		kfree(slot->hotplug_slot->info);
-		kfree(slot->hotplug_slot->name);
-		kfree(slot->hotplug_slot);
-		kfree(slot);
-	}
-
-	return;
-}
-
-
-static int __init acpiphp_init(void)
-{
-	int retval;
-
-	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
-
-	acpiphp_debug = debug;
-
-	/* read all the ACPI info from the system */
-	retval = init_acpi();
-	if (retval)
-		return retval;
-
-	retval = init_slots();
-	if (retval)
-		return retval;
-
-	return 0;
-}
-
-
-static void __exit acpiphp_exit(void)
-{
-	cleanup_slots();
-	/* deallocate internal data structures etc. */
-	acpiphp_glue_exit();
-}
-
-module_init(acpiphp_init);
-module_exit(acpiphp_exit);
diff -urN linux-2.5.70-bk9/drivers/hotplug/acpiphp_glue.c linux-2.5.70-bk10/drivers/hotplug/acpiphp_glue.c
--- linux-2.5.70-bk9/drivers/hotplug/acpiphp_glue.c	2003-05-26 18:00:28.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/acpiphp_glue.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1359 +0,0 @@
-/*
- * ACPI PCI HotPlug glue functions to ACPI CA subsystem
- *
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 NEC Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <t-kouchi@cq.jp.nec.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <asm/semaphore.h>
-
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-static LIST_HEAD(bridge_list);
-
-#define MY_NAME "acpiphp_glue"
-
-static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
-static void handle_hotplug_event_func (acpi_handle, u32, void *);
-
-/*
- * initialization & terminatation routines
- */
-
-/**
- * is_ejectable - determine if a slot is ejectable
- * @handle: handle to acpi namespace
- *
- * Ejectable slot should satisfy at least these conditions:
- *
- *  1. has _ADR method
- *  2. has _EJ0 method
- *
- * optionally
- *
- *  1. has _STA method
- *  2. has _PS0 method
- *  3. has _PS3 method
- *  4. ..
- *
- */
-static int is_ejectable (acpi_handle handle)
-{
-	acpi_status status;
-	acpi_handle tmp;
-
-	status = acpi_get_handle(handle, "_ADR", &tmp);
-	if (ACPI_FAILURE(status)) {
-		return 0;
-	}
-
-	status = acpi_get_handle(handle, "_EJ0", &tmp);
-	if (ACPI_FAILURE(status)) {
-		return 0;
-	}
-
-	return 1;
-}
-
-
-/* callback routine to check the existence of ejectable slots */
-static acpi_status
-is_ejectable_slot (acpi_handle handle, u32 lvl,	void *context, void **rv)
-{
-	int *count = (int *)context;
-
-	if (is_ejectable(handle)) {
-		(*count)++;
-		/* only one ejectable slot is enough */
-		return AE_CTRL_TERMINATE;
-	} else {
-		return AE_OK;
-	}
-}
-
-
-/* callback routine to register each ACPI PCI slot object */
-static acpi_status
-register_slot (acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context;
-	struct acpiphp_slot *slot;
-	struct acpiphp_func *newfunc;
-	acpi_handle tmp;
-	acpi_status status = AE_OK;
-	unsigned long adr, sun;
-	int device, function;
-	static int num_slots = 0;	/* XXX if we support I/O node hotplug... */
-
-	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
-
-	if (ACPI_FAILURE(status))
-		return AE_OK;
-
-	status = acpi_get_handle(handle, "_EJ0", &tmp);
-
-	if (ACPI_FAILURE(status))
-		return AE_OK;
-
-	device = (adr >> 16) & 0xffff;
-	function = adr & 0xffff;
-
-	newfunc = kmalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
-	if (!newfunc)
-		return AE_NO_MEMORY;
-	memset(newfunc, 0, sizeof(struct acpiphp_func));
-
-	INIT_LIST_HEAD(&newfunc->sibling);
-	newfunc->handle = handle;
-	newfunc->function = function;
-	newfunc->flags = FUNC_HAS_EJ0;
-
-	if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp)))
-		newfunc->flags |= FUNC_HAS_STA;
-
-	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS0", &tmp)))
-		newfunc->flags |= FUNC_HAS_PS0;
-
-	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp)))
-		newfunc->flags |= FUNC_HAS_PS3;
-
-	status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
-	if (ACPI_FAILURE(status))
-		sun = -1;
-
-	/* search for objects that share the same slot */
-	for (slot = bridge->slots; slot; slot = slot->next)
-		if (slot->device == device) {
-			if (slot->sun != sun)
-				warn("sibling found, but _SUN doesn't match!\n");
-			break;
-		}
-
-	if (!slot) {
-		slot = kmalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
-		if (!slot) {
-			kfree(newfunc);
-			return AE_NO_MEMORY;
-		}
-
-		memset(slot, 0, sizeof(struct acpiphp_slot));
-		slot->bridge = bridge;
-		slot->id = num_slots++;
-		slot->device = device;
-		slot->sun = sun;
-		INIT_LIST_HEAD(&slot->funcs);
-		init_MUTEX(&slot->crit_sect);
-
-		slot->next = bridge->slots;
-		bridge->slots = slot;
-
-		bridge->nr_slots++;
-
-		dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
-		    slot->bridge->bus, slot->device, slot->sun);
-	}
-
-	newfunc->slot = slot;
-	list_add_tail(&newfunc->sibling, &slot->funcs);
-
-	/* associate corresponding pci_dev */
-	newfunc->pci_dev = pci_find_slot(bridge->bus,
-					 PCI_DEVFN(device, function));
-	if (newfunc->pci_dev) {
-		if (acpiphp_init_func_resource(newfunc) < 0) {
-			kfree(newfunc);
-			return AE_ERROR;
-		}
-		slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
-	}
-
-	/* install notify handler */
-	status = acpi_install_notify_handler(handle,
-					     ACPI_SYSTEM_NOTIFY,
-					     handle_hotplug_event_func,
-					     newfunc);
-
-	if (ACPI_FAILURE(status)) {
-		err("failed to register interrupt notify handler\n");
-		kfree(newfunc);
-		return status;
-	}
-
-	return AE_OK;
-}
-
-
-/* see if it's worth looking at this bridge */
-static int detect_ejectable_slots (acpi_handle *bridge_handle)
-{
-	acpi_status status;
-	int count;
-
-	count = 0;
-
-	/* only check slots defined directly below bridge object */
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
-				     is_ejectable_slot, (void *)&count, NULL);
-
-	return count;
-}
-
-
-/* decode ACPI _CRS data and convert into our internal resource list
- * TBD: _TRA, etc.
- */
-static acpi_status
-decode_acpi_resource (struct acpi_resource *resource, void *context)
-{
-	struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
-	struct acpi_resource_address64 address;
-	struct pci_resource *res;
-
-	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS64)
-		return AE_OK;
-
-	acpi_resource_to_address64(resource, &address);
-
-	if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
-		dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type, address.min_address_range, address.max_address_range);
-		res = acpiphp_make_resource(address.min_address_range,
-				    address.address_length);
-		if (!res) {
-			err("out of memory\n");
-			return AE_OK;
-		}
-
-		switch (address.resource_type) {
-		case ACPI_MEMORY_RANGE:
-			if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
-				res->next = bridge->p_mem_head;
-				bridge->p_mem_head = res;
-			} else {
-				res->next = bridge->mem_head;
-				bridge->mem_head = res;
-			}
-			break;
-		case ACPI_IO_RANGE:
-			res->next = bridge->io_head;
-			bridge->io_head = res;
-			break;
-		case ACPI_BUS_NUMBER_RANGE:
-			res->next = bridge->bus_head;
-			bridge->bus_head = res;
-			break;
-		default:
-			/* invalid type */
-			kfree(res);
-			break;
-		}
-	}
-
-	return AE_OK;
-}
-
-
-/* find pci_bus structure associated to specific bus number */
-static struct pci_bus *find_pci_bus(const struct list_head *list, int bus)
-{
-	const struct list_head *l;
-
-	list_for_each (l, list) {
-		struct pci_bus *b = pci_bus_b(l);
-		if (b->number == bus)
-			return b;
-
-		if (!list_empty(&b->children)) {
-			/* XXX recursive call */
-			b = find_pci_bus(&b->children, bus);
-
-			if (b)
-				return b;
-		}
-	}
-
-	return NULL;
-}
-
-
-/* decode ACPI 2.0 _HPP hot plug parameters */
-static void decode_hpp(struct acpiphp_bridge *bridge)
-{
-	acpi_status status;
-	struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
-				      .pointer = NULL};
-	union acpi_object *package;
-	int i;
-
-	/* default numbers */
-	bridge->hpp.cache_line_size = 0x10;
-	bridge->hpp.latency_timer = 0x40;
-	bridge->hpp.enable_SERR = 0;
-	bridge->hpp.enable_PERR = 0;
-
-	status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer);
-
-	if (ACPI_FAILURE(status)) {
-		dbg("_HPP evaluation failed\n");
-		return;
-	}
-
-	package = (union acpi_object *) buffer.pointer;
-
-	if (!package || package->type != ACPI_TYPE_PACKAGE ||
-	    package->package.count != 4 || !package->package.elements) {
-		err("invalid _HPP object; ignoring\n");
-		goto err_exit;
-	}
-
-	for (i = 0; i < 4; i++) {
-		if (package->package.elements[i].type != ACPI_TYPE_INTEGER) {
-			err("invalid _HPP parameter type; ignoring\n");
-			goto err_exit;
-		}
-	}
-
-	bridge->hpp.cache_line_size = package->package.elements[0].integer.value;
-	bridge->hpp.latency_timer = package->package.elements[1].integer.value;
-	bridge->hpp.enable_SERR = package->package.elements[2].integer.value;
-	bridge->hpp.enable_PERR = package->package.elements[3].integer.value;
-
-	dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n",
-	    bridge->hpp.cache_line_size,
-	    bridge->hpp.latency_timer,
-	    bridge->hpp.enable_SERR,
-	    bridge->hpp.enable_PERR);
-
-	bridge->flags |= BRIDGE_HAS_HPP;
-
- err_exit:
-	kfree(buffer.pointer);
-}
-
-
-/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
-static void init_bridge_misc (struct acpiphp_bridge *bridge)
-{
-	acpi_status status;
-
-	/* decode ACPI 2.0 _HPP (hot plug parameters) */
-	decode_hpp(bridge);
-
-	/* subtract all resources already allocated */
-	acpiphp_detect_pci_resource(bridge);
-
-	/* register all slot objects under this bridge */
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
-				     register_slot, bridge, NULL);
-
-	/* install notify handler */
-	status = acpi_install_notify_handler(bridge->handle,
-					     ACPI_SYSTEM_NOTIFY,
-					     handle_hotplug_event_bridge,
-					     bridge);
-
-	if (ACPI_FAILURE(status)) {
-		err("failed to register interrupt notify handler\n");
-	}
-
-	list_add(&bridge->list, &bridge_list);
-
-	dbg("Bridge resource:\n");
-	acpiphp_dump_resource(bridge);
-}
-
-
-/* allocate and initialize host bridge data structure */
-static void add_host_bridge (acpi_handle *handle, int seg, int bus)
-{
-	acpi_status status;
-	struct acpiphp_bridge *bridge;
-
-	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
-	if (bridge == NULL)
-		return;
-
-	memset(bridge, 0, sizeof(struct acpiphp_bridge));
-
-	bridge->type = BRIDGE_TYPE_HOST;
-	bridge->handle = handle;
-	bridge->seg = seg;
-	bridge->bus = bus;
-
-	bridge->pci_bus = find_pci_bus(&pci_root_buses, bus);
-
-	bridge->res_lock = SPIN_LOCK_UNLOCKED;
-
-	/* to be overridden when we decode _CRS	*/
-	bridge->sub = bridge->bus;
-
-	/* decode resources */
-
-	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
-		decode_acpi_resource, bridge);
-
-	if (ACPI_FAILURE(status)) {
-		err("failed to decode bridge resources\n");
-		kfree(bridge);
-		return;
-	}
-
-	acpiphp_resource_sort_and_combine(&bridge->io_head);
-	acpiphp_resource_sort_and_combine(&bridge->mem_head);
-	acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
-	acpiphp_resource_sort_and_combine(&bridge->bus_head);
-
-	dbg("ACPI _CRS resource:\n");
-	acpiphp_dump_resource(bridge);
-
-	if (bridge->bus_head) {
-		bridge->bus = bridge->bus_head->base;
-		bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
-	}
-
-	init_bridge_misc(bridge);
-}
-
-
-/* allocate and initialize PCI-to-PCI bridge data structure */
-static void add_p2p_bridge (acpi_handle *handle, int seg, int bus, int dev, int fn)
-{
-	struct acpiphp_bridge *bridge;
-	u8 tmp8;
-	u16 tmp16;
-	u64 base64, limit64;
-	u32 base, limit, base32u, limit32u;
-
-	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
-	if (bridge == NULL) {
-		err("out of memory\n");
-		return;
-	}
-
-	memset(bridge, 0, sizeof(struct acpiphp_bridge));
-
-	bridge->type = BRIDGE_TYPE_P2P;
-	bridge->handle = handle;
-	bridge->seg = seg;
-
-	bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
-	if (!bridge->pci_dev) {
-		err("Can't get pci_dev\n");
-		kfree(bridge);
-		return;
-	}
-
-	bridge->pci_bus = bridge->pci_dev->subordinate;
-	if (!bridge->pci_bus) {
-		err("This is not a PCI-to-PCI bridge!\n");
-		kfree(bridge);
-		return;
-	}
-
-	bridge->res_lock = SPIN_LOCK_UNLOCKED;
-
-	bridge->bus = bridge->pci_bus->number;
-	bridge->sub = bridge->pci_bus->subordinate;
-
-	/*
-	 * decode resources under this P2P bridge
-	 */
-
-	/* I/O resources */
-	pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
-	base = tmp8;
-	pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
-	limit = tmp8;
-
-	switch (base & PCI_IO_RANGE_TYPE_MASK) {
-	case PCI_IO_RANGE_TYPE_16:
-		base = (base << 8) & 0xf000;
-		limit = ((limit << 8) & 0xf000) + 0xfff;
-		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->io_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("16bit I/O range: %04x-%04x\n",
-		    (u32)bridge->io_head->base,
-		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
-		break;
-	case PCI_IO_RANGE_TYPE_32:
-		pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
-		base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
-		pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
-		limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
-		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->io_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("32bit I/O range: %08x-%08x\n",
-		    (u32)bridge->io_head->base,
-		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
-		break;
-	case 0x0f:
-		dbg("I/O space unsupported\n");
-		break;
-	default:
-		warn("Unknown I/O range type\n");
-	}
-
-	/* Memory resources (mandatory for P2P bridge) */
-	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
-	base = (tmp16 & 0xfff0) << 16;
-	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
-	limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
-	bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
-	if (!bridge->mem_head) {
-		err("out of memory\n");
-		kfree(bridge);
-		return;
-	}
-	dbg("32bit Memory range: %08x-%08x\n",
-	    (u32)bridge->mem_head->base,
-	    (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
-
-	/* Prefetchable Memory resources (optional) */
-	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
-	base = tmp16;
-	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
-	limit = tmp16;
-
-	switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
-	case PCI_PREF_RANGE_TYPE_32:
-		base = (base & 0xfff0) << 16;
-		limit = ((limit & 0xfff0) << 16) | 0xfffff;
-		bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->p_mem_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("32bit Prefetchable memory range: %08x-%08x\n",
-		    (u32)bridge->p_mem_head->base,
-		    (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
-		break;
-	case PCI_PREF_RANGE_TYPE_64:
-		pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
-		pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
-		base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
-		limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
-
-		bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
-		if (!bridge->p_mem_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
-		    (u32)(bridge->p_mem_head->base >> 32),
-		    (u32)(bridge->p_mem_head->base & 0xffffffff),
-		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
-		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
-		break;
-	case 0x0f:
-		break;
-	default:
-		warn("Unknown prefetchale memory type\n");
-	}
-
-	init_bridge_misc(bridge);
-}
-
-
-/* callback routine to find P2P bridges */
-static acpi_status
-find_p2p_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	acpi_handle dummy_handle;
-	unsigned long *segbus = context;
-	unsigned long tmp;
-	int seg, bus, device, function;
-	struct pci_dev *dev;
-
-	/* get PCI address */
-	seg = (*segbus >> 8) & 0xff;
-	bus = *segbus & 0xff;
-
-	status = acpi_get_handle(handle, "_ADR", &dummy_handle);
-	if (ACPI_FAILURE(status))
-		return AE_OK;		/* continue */
-
-	status = acpi_evaluate_integer(handle, "_ADR", NULL, &tmp);
-	if (ACPI_FAILURE(status)) {
-		dbg("%s: _ADR evaluation failure\n", __FUNCTION__);
-		return AE_OK;
-	}
-
-	device = (tmp >> 16) & 0xffff;
-	function = tmp & 0xffff;
-
-	dev = pci_find_slot(bus, PCI_DEVFN(device, function));
-
-	if (!dev)
-		return AE_OK;
-
-	if (!dev->subordinate)
-		return AE_OK;
-
-	/* check if this bridge has ejectable slots */
-	if (detect_ejectable_slots(handle) > 0) {
-		dbg("found PCI-to-PCI bridge at PCI %s\n", dev->slot_name);
-		add_p2p_bridge(handle, seg, bus, device, function);
-	}
-
-	return AE_OK;
-}
-
-
-/* find hot-pluggable slots, and then find P2P bridge */
-static int add_bridges(struct acpi_device *device)
-{
-	acpi_handle *handle = device->handle;
-	acpi_status status;
-	unsigned long tmp;
-	int seg, bus;
-	acpi_handle dummy_handle;
-
-	/* if the bridge doesn't have _STA, we assume it is always there */
-	status = acpi_get_handle(handle, "_STA", &dummy_handle);
-	if (ACPI_SUCCESS(status)) {
-		status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
-		if (ACPI_FAILURE(status)) {
-			dbg("%s: _STA evaluation failure\n", __FUNCTION__);
-			return 0;
-		}
-		if ((tmp & ACPI_STA_FUNCTIONING) == 0)
-			/* don't register this object */
-			return 0;
-	}
-
-	/* get PCI segment number */
-	status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
-
-	seg = ACPI_SUCCESS(status) ? tmp : 0;
-
-	/* get PCI bus number */
-	status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
-
-	if (ACPI_SUCCESS(status)) {
-		bus = tmp;
-	} else {
-		warn("can't get bus number, assuming 0\n");
-		bus = 0;
-	}
-
-	/* check if this bridge has ejectable slots */
-	if (detect_ejectable_slots(handle) > 0) {
-		dbg("found PCI host-bus bridge with hot-pluggable slots\n");
-		add_host_bridge(handle, seg, bus);
-		return 0;
-	}
-
-	tmp = seg << 8 | bus;
-
-	/* search P2P bridges under this host bridge */
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, &tmp, NULL);
-
-	if (ACPI_FAILURE(status))
-		warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
-
-	return 0;
-}
-
-
-static int power_on_slot (struct acpiphp_slot *slot)
-{
-	acpi_status status;
-	struct acpiphp_func *func;
-	struct list_head *l;
-	int retval = 0;
-
-	/* is this already enabled? */
-	if (slot->flags & SLOT_POWEREDON)
-		goto err_exit;
-
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
-		if (func->flags & FUNC_HAS_PS0) {
-			dbg("%s: executing _PS0 on %s\n", __FUNCTION__,
-			    func->pci_dev->slot_name);
-			status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
-			if (ACPI_FAILURE(status)) {
-				warn("%s: _PS0 failed\n", __FUNCTION__);
-				retval = -1;
-				goto err_exit;
-			}
-		}
-	}
-
-	/* TBD: evaluate _STA to check if the slot is enabled */
-
-	slot->flags |= SLOT_POWEREDON;
-
- err_exit:
-	return retval;
-}
-
-
-static int power_off_slot (struct acpiphp_slot *slot)
-{
-	acpi_status status;
-	struct acpiphp_func *func;
-	struct list_head *l;
-	struct acpi_object_list arg_list;
-	union acpi_object arg;
-
-	int retval = 0;
-
-	/* is this already enabled? */
-	if ((slot->flags & SLOT_POWEREDON) == 0)
-		goto err_exit;
-
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
-		if (func->flags & FUNC_HAS_PS3) {
-			dbg("%s: executing _PS3 on %s\n", __FUNCTION__,
-			    func->pci_dev->slot_name);
-			status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
-			if (ACPI_FAILURE(status)) {
-				warn("%s: _PS3 failed\n", __FUNCTION__);
-				retval = -1;
-				goto err_exit;
-			}
-		}
-	}
-
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
-		if (func->flags & FUNC_HAS_EJ0) {
-			dbg("%s: executing _EJ0 on %s\n", __FUNCTION__,
-			    func->pci_dev->slot_name);
-
-			/* _EJ0 method take one argument */
-			arg_list.count = 1;
-			arg_list.pointer = &arg;
-			arg.type = ACPI_TYPE_INTEGER;
-			arg.integer.value = 1;
-
-			status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
-			if (ACPI_FAILURE(status)) {
-				warn("%s: _EJ0 failed\n", __FUNCTION__);
-				retval = -1;
-				goto err_exit;
-			}
-		}
-	}
-
-	/* TBD: evaluate _STA to check if the slot is disabled */
-
-	slot->flags &= (~SLOT_POWEREDON);
-
- err_exit:
-	return retval;
-}
-
-
-/**
- * enable_device - enable, configure a slot
- * @slot: slot to be enabled
- *
- * This function should be called per *physical slot*,
- * not per each slot object in ACPI namespace.
- *
- */
-static int enable_device (struct acpiphp_slot *slot)
-{
-	u8 bus;
-	struct pci_dev *dev;
-	struct pci_bus *child;
-	struct list_head *l;
-	struct acpiphp_func *func;
-	int retval = 0;
-	int num;
-
-	if (slot->flags & SLOT_ENABLED)
-		goto err_exit;
-
-	/* sanity check: dev should be NULL when hot-plugged in */
-	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
-	if (dev) {
-		/* This case shouldn't happen */
-		err("pci_dev structure already exists.\n");
-		retval = -1;
-		goto err_exit;
-	}
-
-	/* allocate resources to device */
-	retval = acpiphp_configure_slot(slot);
-	if (retval)
-		goto err_exit;
-
-	/* returned `dev' is the *first function* only! */
-	num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
-	if (num)
-		pci_bus_add_devices(slot->bridge->pci_bus);
-	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
-
-	if (!dev) {
-		err("No new device found\n");
-		retval = -1;
-		goto err_exit;
-	}
-
-	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-		pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
-		child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
-		pci_do_scan_bus(child);
-	}
-
-	/* associate pci_dev to our representation */
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
-		func->pci_dev = pci_find_slot(slot->bridge->bus,
-					      PCI_DEVFN(slot->device,
-							func->function));
-		if (!func->pci_dev)
-			continue;
-
-		/* configure device */
-		retval = acpiphp_configure_function(func);
-		if (retval)
-			goto err_exit;
-	}
-
-	slot->flags |= SLOT_ENABLED;
-
-	dbg("Available resources:\n");
-	acpiphp_dump_resource(slot->bridge);
-
- err_exit:
-	return retval;
-}
-
-
-/**
- * disable_device - disable a slot
- */
-static int disable_device (struct acpiphp_slot *slot)
-{
-	int retval = 0;
-	struct acpiphp_func *func;
-	struct list_head *l;
-
-	/* is this slot already disabled? */
-	if (!(slot->flags & SLOT_ENABLED))
-		goto err_exit;
-
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
-		if (func->pci_dev) {
-			if (acpiphp_unconfigure_function(func) == 0) {
-				func->pci_dev = NULL;
-			} else {
-				err("failed to unconfigure device\n");
-				retval = -1;
-				goto err_exit;
-			}
-		}
-	}
-
-	slot->flags &= (~SLOT_ENABLED);
-
- err_exit:
-	return retval;
-}
-
-
-/**
- * get_slot_status - get ACPI slot status
- *
- * if a slot has _STA for each function and if any one of them
- * returned non-zero status, return it
- *
- * if a slot doesn't have _STA and if any one of its functions'
- * configuration space is configured, return 0x0f as a _STA
- *
- * otherwise return 0
- */
-static unsigned int get_slot_status (struct acpiphp_slot *slot)
-{
-	acpi_status status;
-	unsigned long sta = 0;
-	u32 dvid;
-	struct list_head *l;
-	struct acpiphp_func *func;
-
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
-		if (func->flags & FUNC_HAS_STA) {
-			status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta);
-			if (ACPI_SUCCESS(status) && sta)
-				break;
-		} else {
-			pci_bus_read_config_dword(slot->bridge->pci_bus,
-						  PCI_DEVFN(slot->device,
-							    func->function),
-						  PCI_VENDOR_ID, &dvid);
-			if (dvid != 0xffffffff) {
-				sta = ACPI_STA_ALL;
-				break;
-			}
-		}
-	}
-
-	return (unsigned int)sta;
-}
-
-
-/*
- * ACPI event handlers
- */
-
-/**
- * handle_hotplug_event_bridge - handle ACPI event on bridges
- *
- * @handle: Notify()'ed acpi_handle
- * @type: Notify code
- * @context: pointer to acpiphp_bridge structure
- *
- * handles ACPI event notification on {host,p2p} bridges
- *
- */
-static void handle_hotplug_event_bridge (acpi_handle handle, u32 type, void *context)
-{
-	struct acpiphp_bridge *bridge;
-	char objname[64];
-	struct acpi_buffer buffer = { .length = sizeof(objname),
-				      .pointer = objname };
-
-	bridge = (struct acpiphp_bridge *)context;
-
-	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
-
-	switch (type) {
-	case ACPI_NOTIFY_BUS_CHECK:
-		/* bus re-enumerate */
-		dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
-		acpiphp_check_bridge(bridge);
-		break;
-
-	case ACPI_NOTIFY_DEVICE_CHECK:
-		/* device check */
-		dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
-		acpiphp_check_bridge(bridge);
-		break;
-
-	case ACPI_NOTIFY_DEVICE_WAKE:
-		/* wake event */
-		dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
-		break;
-
-	case ACPI_NOTIFY_EJECT_REQUEST:
-		/* request device eject */
-		dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
-		break;
-
-	default:
-		warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
-		break;
-	}
-}
-
-
-/**
- * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
- *
- * @handle: Notify()'ed acpi_handle
- * @type: Notify code
- * @context: pointer to acpiphp_func structure
- *
- * handles ACPI event notification on slots
- *
- */
-static void handle_hotplug_event_func (acpi_handle handle, u32 type, void *context)
-{
-	struct acpiphp_func *func;
-	char objname[64];
-	struct acpi_buffer buffer = { .length = sizeof(objname),
-				      .pointer = objname };
-
-	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
-
-	func = (struct acpiphp_func *)context;
-
-	switch (type) {
-	case ACPI_NOTIFY_BUS_CHECK:
-		/* bus re-enumerate */
-		dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
-		acpiphp_enable_slot(func->slot);
-		break;
-
-	case ACPI_NOTIFY_DEVICE_CHECK:
-		/* device check : re-enumerate from parent bus */
-		dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
-		acpiphp_check_bridge(func->slot->bridge);
-		break;
-
-	case ACPI_NOTIFY_DEVICE_WAKE:
-		/* wake event */
-		dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
-		break;
-
-	case ACPI_NOTIFY_EJECT_REQUEST:
-		/* request device eject */
-		dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
-		acpiphp_disable_slot(func->slot);
-		break;
-
-	default:
-		warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
-		break;
-	}
-}
-
-static struct acpi_driver acpi_pci_hp_driver = {
-	.name =		"pci_hp",
-	.class =	"",
-	.ids =		ACPI_PCI_HOST_HID,
-	.ops =	{
-		.add =	add_bridges,
-	}
-};
-
-/**
- * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
- *
- */
-int acpiphp_glue_init (void)
-{
-	acpi_status status;
-
-	if (list_empty(&pci_root_buses))
-		return -1;
-
-	status = acpi_bus_register_driver(&acpi_pci_hp_driver);
-
-	if (ACPI_FAILURE(status)) {
-		err("%s: acpi_walk_namespace() failed\n", __FUNCTION__);
-		return -1;
-	}
-
-	return 0;
-}
-
-
-/**
- * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures
- *
- * This function frees all data allocated in acpiphp_glue_init()
- */
-void acpiphp_glue_exit (void)
-{
-	struct list_head *l1, *l2, *n1, *n2;
-	struct acpiphp_bridge *bridge;
-	struct acpiphp_slot *slot, *next;
-	struct acpiphp_func *func;
-	acpi_status status;
-
-	list_for_each_safe (l1, n1, &bridge_list) {
-		bridge = (struct acpiphp_bridge *)l1;
-		slot = bridge->slots;
-		while (slot) {
-			next = slot->next;
-			list_for_each_safe (l2, n2, &slot->funcs) {
-				func = list_entry(l2, struct acpiphp_func, sibling);
-				acpiphp_free_resource(&func->io_head);
-				acpiphp_free_resource(&func->mem_head);
-				acpiphp_free_resource(&func->p_mem_head);
-				acpiphp_free_resource(&func->bus_head);
-				status = acpi_remove_notify_handler(func->handle,
-								    ACPI_SYSTEM_NOTIFY,
-								    handle_hotplug_event_func);
-				if (ACPI_FAILURE(status))
-					err("failed to remove notify handler\n");
-				kfree(func);
-			}
-			kfree(slot);
-			slot = next;
-		}
-		status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
-						    handle_hotplug_event_bridge);
-		if (ACPI_FAILURE(status))
-			err("failed to remove notify handler\n");
-
-		acpiphp_free_resource(&bridge->io_head);
-		acpiphp_free_resource(&bridge->mem_head);
-		acpiphp_free_resource(&bridge->p_mem_head);
-		acpiphp_free_resource(&bridge->bus_head);
-
-		kfree(bridge);
-	}
-}
-
-
-/**
- * acpiphp_get_num_slots - count number of slots in a system
- */
-int acpiphp_get_num_slots (void)
-{
-	struct list_head *node;
-	struct acpiphp_bridge *bridge;
-	int num_slots;
-
-	num_slots = 0;
-
-	list_for_each (node, &bridge_list) {
-		bridge = (struct acpiphp_bridge *)node;
-		dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
-		num_slots += bridge->nr_slots;
-	}
-
-	dbg("Total %dslots\n", num_slots);
-	return num_slots;
-}
-
-
-/**
- * acpiphp_for_each_slot - call function for each slot
- * @fn: callback function
- * @data: context to be passed to callback function
- *
- */
-int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
-{
-	struct list_head *node;
-	struct acpiphp_bridge *bridge;
-	struct acpiphp_slot *slot;
-	int retval = 0;
-
-	list_for_each (node, &bridge_list) {
-		bridge = (struct acpiphp_bridge *)node;
-		for (slot = bridge->slots; slot; slot = slot->next) {
-			retval = fn(slot, data);
-			if (!retval)
-				goto err_exit;
-		}
-	}
-
- err_exit:
-	return retval;
-}
-
-
-/* search matching slot from id  */
-struct acpiphp_slot *get_slot_from_id (int id)
-{
-	struct list_head *node;
-	struct acpiphp_bridge *bridge;
-	struct acpiphp_slot *slot;
-
-	list_for_each (node, &bridge_list) {
-		bridge = (struct acpiphp_bridge *)node;
-		for (slot = bridge->slots; slot; slot = slot->next)
-			if (slot->id == id)
-				return slot;
-	}
-
-	/* should never happen! */
-	err("%s: no object for id %d\n",__FUNCTION__, id);
-	return 0;
-}
-
-
-/**
- * acpiphp_enable_slot - power on slot
- */
-int acpiphp_enable_slot (struct acpiphp_slot *slot)
-{
-	int retval;
-
-	down(&slot->crit_sect);
-
-	/* wake up all functions */
-	retval = power_on_slot(slot);
-	if (retval)
-		goto err_exit;
-
-	if (get_slot_status(slot) == ACPI_STA_ALL)
-		/* configure all functions */
-		retval = enable_device(slot);
-
- err_exit:
-	up(&slot->crit_sect);
-	return retval;
-}
-
-
-/**
- * acpiphp_disable_slot - power off slot
- */
-int acpiphp_disable_slot (struct acpiphp_slot *slot)
-{
-	int retval = 0;
-
-	down(&slot->crit_sect);
-
-	/* unconfigure all functions */
-	retval = disable_device(slot);
-	if (retval)
-		goto err_exit;
-
-	/* power off all functions */
-	retval = power_off_slot(slot);
-	if (retval)
-		goto err_exit;
-
-	acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
-	dbg("Available resources:\n");
-	acpiphp_dump_resource(slot->bridge);
-
- err_exit:
-	up(&slot->crit_sect);
-	return retval;
-}
-
-
-/**
- * acpiphp_check_bridge - re-enumerate devices
- */
-int acpiphp_check_bridge (struct acpiphp_bridge *bridge)
-{
-	struct acpiphp_slot *slot;
-	unsigned int sta;
-	int retval = 0;
-	int enabled, disabled;
-
-	enabled = disabled = 0;
-
-	for (slot = bridge->slots; slot; slot = slot->next) {
-		sta = get_slot_status(slot);
-		if (slot->flags & SLOT_ENABLED) {
-			/* if enabled but not present, disable */
-			if (sta != ACPI_STA_ALL) {
-				retval = acpiphp_disable_slot(slot);
-				if (retval) {
-					err("Error occurred in enabling\n");
-					up(&slot->crit_sect);
-					goto err_exit;
-				}
-				enabled++;
-			}
-		} else {
-			/* if disabled but present, enable */
-			if (sta == ACPI_STA_ALL) {
-				retval = acpiphp_enable_slot(slot);
-				if (retval) {
-					err("Error occurred in enabling\n");
-					up(&slot->crit_sect);
-					goto err_exit;
-				}
-				disabled++;
-			}
-		}
-	}
-
-	dbg("%s: %d enabled, %d disabled\n", __FUNCTION__, enabled, disabled);
-
- err_exit:
-	return retval;
-}
-
-
-/*
- * slot enabled:  1
- * slot disabled: 0
- */
-u8 acpiphp_get_power_status (struct acpiphp_slot *slot)
-{
-	unsigned int sta;
-
-	sta = get_slot_status(slot);
-
-	return (sta & ACPI_STA_ENABLED) ? 1 : 0;
-}
-
-
-/*
- * attention LED ON: 1
- *              OFF: 0
- *
- * TBD
- * no direct attention led status information via ACPI
- *
- */
-u8 acpiphp_get_attention_status (struct acpiphp_slot *slot)
-{
-	return 0;
-}
-
-
-/*
- * latch closed:  1
- * latch   open:  0
- */
-u8 acpiphp_get_latch_status (struct acpiphp_slot *slot)
-{
-	unsigned int sta;
-
-	sta = get_slot_status(slot);
-
-	return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0;
-}
-
-
-/*
- * adapter presence : 1
- *          absence : 0
- */
-u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot)
-{
-	unsigned int sta;
-
-	sta = get_slot_status(slot);
-
-	return (sta == 0) ? 0 : 1;
-}
diff -urN linux-2.5.70-bk9/drivers/hotplug/acpiphp_pci.c linux-2.5.70-bk10/drivers/hotplug/acpiphp_pci.c
--- linux-2.5.70-bk9/drivers/hotplug/acpiphp_pci.c	2003-05-26 18:00:19.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/acpiphp_pci.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,510 +0,0 @@
-/*
- * ACPI PCI HotPlug PCI configuration space management
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001,2002 IBM Corp.
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 NEC Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <t-kouchi@cq.jp.nec.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-#define MY_NAME "acpiphp_pci"
-
-
-/* allocate mem/pmem/io resource to a new function */
-static int init_config_space (struct acpiphp_func *func)
-{
-	u32 bar, len;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	int count;
-	struct acpiphp_bridge *bridge;
-	struct pci_resource *res;
-	struct pci_bus *pbus;
-	int bus, device, function;
-	unsigned int devfn;
-	u16 tmp;
-
-	bridge = func->slot->bridge;
-	pbus = bridge->pci_bus;
-	bus = bridge->bus;
-	device = func->slot->device;
-	function = func->function;
-	devfn = PCI_DEVFN(device, function);
-
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_bus_write_config_dword(pbus, devfn,
-					   address[count], 0xFFFFFFFF);
-		pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
-
-		if (!bar)	/* This BAR is not implemented */
-			continue;
-
-		dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
-
-		if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-
-			len = bar & 0xFFFFFFFC;
-			len = ~len + 1;
-
-			dbg("len in IO %x, BAR %d\n", len, count);
-
-			spin_lock(&bridge->res_lock);
-			res = acpiphp_get_io_resource(&bridge->io_head, len);
-			spin_unlock(&bridge->res_lock);
-
-			if (!res) {
-				err("cannot allocate requested io for %02x:%02x.%d len %x\n",
-				    bus, device, function, len);
-				return -1;
-			}
-			pci_bus_write_config_dword(pbus, devfn,
-						   address[count],
-						   (u32)res->base);
-			res->next = func->io_head;
-			func->io_head = res;
-
-		} else {
-			/* This is Memory */
-			if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len = bar & 0xFFFFFFF0;
-				len = ~len + 1;
-
-				dbg("len in PFMEM %x, BAR %d\n", len, count);
-
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource(&bridge->p_mem_head, len);
-				spin_unlock(&bridge->res_lock);
-
-				if (!res) {
-					err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
-					    bus, device, function, len);
-					return -1;
-				}
-
-				pci_bus_write_config_dword(pbus, devfn,
-							   address[count],
-							   (u32)res->base);
-
-				if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("inside the pfmem 64 case, count %d\n", count);
-					count += 1;
-					pci_bus_write_config_dword(pbus, devfn,
-								   address[count],
-								   (u32)(res->base >> 32));
-				}
-
-				res->next = func->p_mem_head;
-				func->p_mem_head = res;
-
-			} else {
-				/* regular memory */
-
-				len = bar & 0xFFFFFFF0;
-				len = ~len + 1;
-
-				dbg("len in MEM %x, BAR %d\n", len, count);
-
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource(&bridge->mem_head, len);
-				spin_unlock(&bridge->res_lock);
-
-				if (!res) {
-					err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
-					    bus, device, function, len);
-					return -1;
-				}
-
-				pci_bus_write_config_dword(pbus, devfn,
-							   address[count],
-							   (u32)res->base);
-
-				if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("inside mem 64 case, reg. mem, count %d\n", count);
-					count += 1;
-					pci_bus_write_config_dword(pbus, devfn,
-								   address[count],
-								   (u32)(res->base >> 32));
-				}
-
-				res->next = func->mem_head;
-				func->mem_head = res;
-
-			}
-		}
-	}
-
-	/* disable expansion rom */
-	pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
-
-	/* set PCI parameters from _HPP */
-	pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
-				  bridge->hpp.cache_line_size);
-	pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
-				  bridge->hpp.latency_timer);
-
-	pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
-	if (bridge->hpp.enable_SERR)
-		tmp |= PCI_COMMAND_SERR;
-	if (bridge->hpp.enable_PERR)
-		tmp |= PCI_COMMAND_PARITY;
-	pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
-
-	return 0;
-}
-
-/* detect_used_resource - subtract resource under dev from bridge */
-static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
-{
-	u32 bar, len;
-	u64 base;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	int count;
-	struct pci_resource *res;
-
-	dbg("Device %s\n", dev->slot_name);
-
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_read_config_dword(dev, address[count], &bar);
-
-		if (!bar)	/* This BAR is not implemented */
-			continue;
-
-		pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
-		pci_read_config_dword(dev, address[count], &len);
-
-		if (len & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			base = bar & 0xFFFFFFFC;
-			len &= 0xFFFFFFFC;
-			len = ~len + 1;
-
-			dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
-
-			spin_lock(&bridge->res_lock);
-			res = acpiphp_get_resource_with_base(&bridge->io_head, base, len);
-			spin_unlock(&bridge->res_lock);
-			if (res)
-				kfree(res);
-		} else {
-			/* This is Memory */
-			base = bar & 0xFFFFFFF0;
-			if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("prefetch mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource_with_base(&bridge->p_mem_head, base, len);
-				spin_unlock(&bridge->res_lock);
-				if (res)
-					kfree(res);
-			} else {
-				/* regular memory */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource_with_base(&bridge->mem_head, base, len);
-				spin_unlock(&bridge->res_lock);
-				if (res)
-					kfree(res);
-			}
-		}
-
-		pci_write_config_dword(dev, address[count], bar);
-	}
-
-	return 0;
-}
-
-
-/* detect_pci_resource_bus - subtract resource under pci_bus */
-static void detect_used_resource_bus(struct acpiphp_bridge *bridge, struct pci_bus *bus)
-{
-	struct list_head *l;
-	struct pci_dev *dev;
-
-	list_for_each (l, &bus->devices) {
-		dev = pci_dev_b(l);
-		detect_used_resource(bridge, dev);
-		/* XXX recursive call */
-		if (dev->subordinate)
-			detect_used_resource_bus(bridge, dev->subordinate);
-	}
-}
-
-
-/**
- * acpiphp_detect_pci_resource - detect resources under bridge
- * @bridge: detect all resources already used under this bridge
- *
- * collect all resources already allocated for all devices under a bridge.
- */
-int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
-{
-	detect_used_resource_bus(bridge, bridge->pci_bus);
-
-	return 0;
-}
-
-
-/**
- * acpiphp_init_slot_resource - gather resource usage information of a slot
- * @slot: ACPI slot object to be checked, should have valid pci_dev member
- *
- * TBD: PCI-to-PCI bridge case
- *      use pci_dev->resource[]
- */
-int acpiphp_init_func_resource (struct acpiphp_func *func)
-{
-	u64 base;
-	u32 bar, len;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	int count;
-	struct pci_resource *res;
-	struct pci_dev *dev;
-
-	dev = func->pci_dev;
-	dbg("Hot-pluggable device %s\n", dev->slot_name);
-
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_read_config_dword(dev, address[count], &bar);
-
-		if (!bar)	/* This BAR is not implemented */
-			continue;
-
-		pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
-		pci_read_config_dword(dev, address[count], &len);
-
-		if (len & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			base = bar & 0xFFFFFFFC;
-			len &= 0xFFFFFFFC;
-			len = ~len + 1;
-
-			dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
-
-			res = acpiphp_make_resource(base, len);
-			if (!res)
-				goto no_memory;
-
-			res->next = func->io_head;
-			func->io_head = res;
-
-		} else {
-			/* This is Memory */
-			base = bar & 0xFFFFFFF0;
-			if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("prefetch mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
-				res = acpiphp_make_resource(base, len);
-				if (!res)
-					goto no_memory;
-
-				res->next = func->p_mem_head;
-				func->p_mem_head = res;
-
-			} else {
-				/* regular memory */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
-				res = acpiphp_make_resource(base, len);
-				if (!res)
-					goto no_memory;
-
-				res->next = func->mem_head;
-				func->mem_head = res;
-
-			}
-		}
-
-		pci_write_config_dword(dev, address[count], bar);
-	}
-#if 1
-	acpiphp_dump_func_resource(func);
-#endif
-
-	return 0;
-
- no_memory:
-	err("out of memory\n");
-	acpiphp_free_resource(&func->io_head);
-	acpiphp_free_resource(&func->mem_head);
-	acpiphp_free_resource(&func->p_mem_head);
-
-	return -1;
-}
-
-
-/**
- * acpiphp_configure_slot - allocate PCI resources
- * @slot: slot to be configured
- *
- * initializes a PCI functions on a device inserted
- * into the slot
- *
- */
-int acpiphp_configure_slot (struct acpiphp_slot *slot)
-{
-	struct acpiphp_func *func;
-	struct list_head *l;
-	u8 hdr;
-	u32 dvid;
-	int retval = 0;
-	int is_multi = 0;
-
-	pci_bus_read_config_byte(slot->bridge->pci_bus,
-				 PCI_DEVFN(slot->device, 0),
-				 PCI_HEADER_TYPE, &hdr);
-
-	if (hdr & 0x80)
-		is_multi = 1;
-
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-		if (is_multi || func->function == 0) {
-			pci_bus_read_config_dword(slot->bridge->pci_bus,
-						  PCI_DEVFN(slot->device,
-							    func->function),
-						  PCI_VENDOR_ID, &dvid);
-			if (dvid != 0xffffffff) {
-				retval = init_config_space(func);
-				if (retval)
-					break;
-			}
-		}
-	}
-
-	return retval;
-}
-
-/**
- * acpiphp_configure_function - configure PCI function
- * @func: function to be configured
- *
- * initializes a PCI functions on a device inserted
- * into the slot
- *
- */
-int acpiphp_configure_function (struct acpiphp_func *func)
-{
-	/* all handled by the pci core now */
-	return 0;
-}
-
-/**
- * acpiphp_unconfigure_function - unconfigure PCI function
- * @func: function to be unconfigured
- *
- */
-int acpiphp_unconfigure_function (struct acpiphp_func *func)
-{
-	struct acpiphp_bridge *bridge;
-	int retval = 0;
-
-	/* if pci_dev is NULL, ignore it */
-	if (!func->pci_dev)
-		goto err_exit;
-
-	pci_remove_bus_device(func->pci_dev);
-
-	/* free all resources */
-	bridge = func->slot->bridge;
-
-	spin_lock(&bridge->res_lock);
-	acpiphp_move_resource(&func->io_head, &bridge->io_head);
-	acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
-	acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
-	acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
-	spin_unlock(&bridge->res_lock);
-
- err_exit:
-	return retval;
-}
diff -urN linux-2.5.70-bk9/drivers/hotplug/acpiphp_res.c linux-2.5.70-bk10/drivers/hotplug/acpiphp_res.c
--- linux-2.5.70-bk9/drivers/hotplug/acpiphp_res.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/acpiphp_res.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,699 +0,0 @@
-/*
- * ACPI PCI HotPlug Utility functions
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
- * Copyright (c) 2002 NEC Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>,<h-aono@ap.jp.nec.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#include <linux/pci.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-
-#include <linux/ioctl.h>
-#include <linux/fcntl.h>
-
-#include <linux/list.h>
-
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-#define MY_NAME "acpiphp_res"
-
-
-/*
- * sort_by_size - sort nodes by their length, smallest first
- */
-static int sort_by_size(struct pci_resource **head)
-{
-	struct pci_resource *current_res;
-	struct pci_resource *next_res;
-	int out_of_order = 1;
-
-	if (!(*head))
-		return 1;
-
-	if (!((*head)->next))
-		return 0;
-
-	while (out_of_order) {
-		out_of_order = 0;
-
-		/* Special case for swapping list head */
-		if (((*head)->next) &&
-		    ((*head)->length > (*head)->next->length)) {
-			out_of_order++;
-			current_res = *head;
-			*head = (*head)->next;
-			current_res->next = (*head)->next;
-			(*head)->next = current_res;
-		}
-
-		current_res = *head;
-
-		while (current_res->next && current_res->next->next) {
-			if (current_res->next->length > current_res->next->next->length) {
-				out_of_order++;
-				next_res = current_res->next;
-				current_res->next = current_res->next->next;
-				current_res = current_res->next;
-				next_res->next = current_res->next;
-				current_res->next = next_res;
-			} else
-				current_res = current_res->next;
-		}
-	}  /* End of out_of_order loop */
-
-	return 0;
-}
-
-
-/*
- * sort_by_max_size - sort nodes by their length, largest first
- */
-static int sort_by_max_size(struct pci_resource **head)
-{
-	struct pci_resource *current_res;
-	struct pci_resource *next_res;
-	int out_of_order = 1;
-
-	if (!(*head))
-		return 1;
-
-	if (!((*head)->next))
-		return 0;
-
-	while (out_of_order) {
-		out_of_order = 0;
-
-		/* Special case for swapping list head */
-		if (((*head)->next) &&
-		    ((*head)->length < (*head)->next->length)) {
-			out_of_order++;
-			current_res = *head;
-			*head = (*head)->next;
-			current_res->next = (*head)->next;
-			(*head)->next = current_res;
-		}
-
-		current_res = *head;
-
-		while (current_res->next && current_res->next->next) {
-			if (current_res->next->length < current_res->next->next->length) {
-				out_of_order++;
-				next_res = current_res->next;
-				current_res->next = current_res->next->next;
-				current_res = current_res->next;
-				next_res->next = current_res->next;
-				current_res->next = next_res;
-			} else
-				current_res = current_res->next;
-		}
-	}  /* End of out_of_order loop */
-
-	return 0;
-}
-
-/**
- * get_io_resource - get resource for I/O ports
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length that is not in the
- * ISA aliasing window.  If it finds a node larger than "size"
- * it will split it up.
- *
- * size must be a power of two.
- *
- * difference from get_resource is handling of ISA aliasing space.
- *
- */
-struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	if (sort_by_size(head))
-		return NULL;
-
-	for (node = *head; node; node = node->next) {
-		if (node->length < size)
-			continue;
-
-		if (node->base & (size - 1)) {
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = (node->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			node->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		} /* End of non-aligned base */
-
-		/* Don't need to check if too small since we already did */
-		if (node->length > size) {
-			/* this one is longer than we need
-			   so we'll make a new entry and split it up */
-			split_node = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			node->length = size;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}  /* End of too big on top end */
-
-		/* For IO make sure it's not in the ISA aliasing space */
-		if (node->base & 0x300L)
-			continue;
-
-		/* If we got here, then it is the right size
-		   Now take it out of the list */
-		if (*head == node) {
-			*head = node->next;
-		} else {
-			prevnode = *head;
-			while (prevnode->next != node)
-				prevnode = prevnode->next;
-
-			prevnode->next = node->next;
-		}
-		node->next = NULL;
-		/* Stop looping */
-		break;
-	}
-
-	return node;
-}
-
-
-/**
- * get_max_resource - get the largest resource
- *
- * Gets the largest node that is at least "size" big from the
- * list pointed to by head.  It aligns the node on top and bottom
- * to "size" alignment before returning it.
- */
-struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *max;
-	struct pci_resource *temp;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	if (sort_by_max_size(head))
-		return NULL;
-
-	for (max = *head;max; max = max->next) {
-
-		/* If not big enough we could probably just bail,
-		   instead we'll continue to the next. */
-		if (max->length < size)
-			continue;
-
-		if (max->base & (size - 1)) {
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = (max->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((max->length - (temp_qword - max->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
-
-			if (!split_node)
-				return NULL;
-
-			max->base = temp_qword;
-			max->length -= split_node->length;
-
-			/* Put it next in the list */
-			split_node->next = max->next;
-			max->next = split_node;
-		}
-
-		if ((max->base + max->length) & (size - 1)) {
-			/* this one isn't end aligned properly at the top
-			   so we'll make a new entry and split it up */
-			temp_qword = ((max->base + max->length) & ~(size - 1));
-
-			split_node = acpiphp_make_resource(temp_qword,
-							   max->length + max->base - temp_qword);
-
-			if (!split_node)
-				return NULL;
-
-			max->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = max->next;
-			max->next = split_node;
-		}
-
-		/* Make sure it didn't shrink too much when we aligned it */
-		if (max->length < size)
-			continue;
-
-		/* Now take it out of the list */
-		temp = (struct pci_resource*) *head;
-		if (temp == max) {
-			*head = max->next;
-		} else {
-			while (temp && temp->next != max) {
-				temp = temp->next;
-			}
-
-			temp->next = max->next;
-		}
-
-		max->next = NULL;
-		return max;
-	}
-
-	/* If we get here, we couldn't find one */
-	return NULL;
-}
-
-
-/**
- * get_resource - get resource (mem, pfmem)
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length.  If it finds a node
- * larger than "size" it will split it up.
- *
- * size must be a power of two.
- *
- */
-struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	if (sort_by_size(head))
-		return NULL;
-
-	for (node = *head; node; node = node->next) {
-		dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
-		    __FUNCTION__, size, node, (u32)node->base, node->length);
-		if (node->length < size)
-			continue;
-
-		if (node->base & (size - 1)) {
-			dbg("%s: not aligned\n", __FUNCTION__);
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = (node->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			node->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		} /* End of non-aligned base */
-
-		/* Don't need to check if too small since we already did */
-		if (node->length > size) {
-			dbg("%s: too big\n", __FUNCTION__);
-			/* this one is longer than we need
-			   so we'll make a new entry and split it up */
-			split_node = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			node->length = size;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}  /* End of too big on top end */
-
-		dbg("%s: got one!!!\n", __FUNCTION__);
-		/* If we got here, then it is the right size
-		   Now take it out of the list */
-		if (*head == node) {
-			*head = node->next;
-		} else {
-			prevnode = *head;
-			while (prevnode->next != node)
-				prevnode = prevnode->next;
-
-			prevnode->next = node->next;
-		}
-		node->next = NULL;
-		/* Stop looping */
-		break;
-	}
-	return node;
-}
-
-/**
- * get_resource_with_base - get resource with specific base address
- *
- * this function
- * returns the first node of "size" length located at specified base address.
- * If it finds a node larger than "size" it will split it up.
- *
- * size must be a power of two.
- *
- */
-struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	for (node = *head; node; node = node->next) {
-		dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
-		    (u32)base, size, node, (u32)node->base, node->length);
-		if (node->base > base)
-			continue;
-
-		if ((node->base + node->length) < (base + size))
-			continue;
-
-		if (node->base < base) {
-			dbg(": split 1\n");
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = base;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			node->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}
-
-		dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
-		    (u32)base, size, node, (u32)node->base, node->length);
-
-		/* Don't need to check if too small since we already did */
-		if (node->length > size) {
-			dbg(": split 2\n");
-			/* this one is longer than we need
-			   so we'll make a new entry and split it up */
-			split_node = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			node->length = size;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}  /* End of too big on top end */
-
-		dbg(": got one!!!\n");
-		/* If we got here, then it is the right size
-		   Now take it out of the list */
-		if (*head == node) {
-			*head = node->next;
-		} else {
-			prevnode = *head;
-			while (prevnode->next != node)
-				prevnode = prevnode->next;
-
-			prevnode->next = node->next;
-		}
-		node->next = NULL;
-		/* Stop looping */
-		break;
-	}
-	return node;
-}
-
-
-/**
- * acpiphp_resource_sort_and_combine
- *
- * Sorts all of the nodes in the list in ascending order by
- * their base addresses.  Also does garbage collection by
- * combining adjacent nodes.
- *
- * returns 0 if success
- */
-int acpiphp_resource_sort_and_combine (struct pci_resource **head)
-{
-	struct pci_resource *node1;
-	struct pci_resource *node2;
-	int out_of_order = 1;
-
-	if (!(*head))
-		return 1;
-
-	dbg("*head->next = %p\n",(*head)->next);
-
-	if (!(*head)->next)
-		return 0;	/* only one item on the list, already sorted! */
-
-	dbg("*head->base = 0x%x\n",(u32)(*head)->base);
-	dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base);
-	while (out_of_order) {
-		out_of_order = 0;
-
-		/* Special case for swapping list head */
-		if (((*head)->next) &&
-		    ((*head)->base > (*head)->next->base)) {
-			node1 = *head;
-			(*head) = (*head)->next;
-			node1->next = (*head)->next;
-			(*head)->next = node1;
-			out_of_order++;
-		}
-
-		node1 = (*head);
-
-		while (node1->next && node1->next->next) {
-			if (node1->next->base > node1->next->next->base) {
-				out_of_order++;
-				node2 = node1->next;
-				node1->next = node1->next->next;
-				node1 = node1->next;
-				node2->next = node1->next;
-				node1->next = node2;
-			} else
-				node1 = node1->next;
-		}
-	}  /* End of out_of_order loop */
-
-	node1 = *head;
-
-	while (node1 && node1->next) {
-		if ((node1->base + node1->length) == node1->next->base) {
-			/* Combine */
-			dbg("8..\n");
-			node1->length += node1->next->length;
-			node2 = node1->next;
-			node1->next = node1->next->next;
-			kfree(node2);
-		} else
-			node1 = node1->next;
-	}
-
-	return 0;
-}
-
-
-/**
- * acpiphp_make_resource - make resource structure
- * @base: base address of a resource
- * @length: length of a resource
- */
-struct pci_resource *acpiphp_make_resource (u64 base, u32 length)
-{
-	struct pci_resource *res;
-
-	res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-	if (res) {
-		memset(res, 0, sizeof(struct pci_resource));
-		res->base = base;
-		res->length = length;
-	}
-
-	return res;
-}
-
-
-/**
- * acpiphp_move_resource - move linked resources from one to another
- * @from: head of linked resource list
- * @to: head of linked resource list
- */
-void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)
-{
-	struct pci_resource *tmp;
-
-	while (*from) {
-		tmp = (*from)->next;
-		(*from)->next = *to;
-		*to = *from;
-		*from = tmp;
-	}
-
-	/* *from = NULL is guaranteed */
-}
-
-
-/**
- * acpiphp_free_resource - free all linked resources
- * @res: head of linked resource list
- */
-void acpiphp_free_resource (struct pci_resource **res)
-{
-	struct pci_resource *tmp;
-
-	while (*res) {
-		tmp = (*res)->next;
-		kfree(*res);
-		*res = tmp;
-	}
-
-	/* *res = NULL is guaranteed */
-}
-
-
-/* debug support functions;  will go away sometime :) */
-static void dump_resource(struct pci_resource *head)
-{
-	struct pci_resource *p;
-	int cnt;
-
-	p = head;
-	cnt = 0;
-
-	while (p) {
-		dbg("[%02d] %08x - %08x\n",
-		    cnt++, (u32)p->base, (u32)p->base + p->length - 1);
-		p = p->next;
-	}
-}
-
-void acpiphp_dump_resource(struct acpiphp_bridge *bridge)
-{
-	dbg("I/O resource:\n");
-	dump_resource(bridge->io_head);
-	dbg("MEM resource:\n");
-	dump_resource(bridge->mem_head);
-	dbg("PMEM resource:\n");
-	dump_resource(bridge->p_mem_head);
-	dbg("BUS resource:\n");
-	dump_resource(bridge->bus_head);
-}
-
-void acpiphp_dump_func_resource(struct acpiphp_func *func)
-{
-	dbg("I/O resource:\n");
-	dump_resource(func->io_head);
-	dbg("MEM resource:\n");
-	dump_resource(func->mem_head);
-	dbg("PMEM resource:\n");
-	dump_resource(func->p_mem_head);
-	dbg("BUS resource:\n");
-	dump_resource(func->bus_head);
-}
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpci_hotplug.h linux-2.5.70-bk10/drivers/hotplug/cpci_hotplug.h
--- linux-2.5.70-bk9/drivers/hotplug/cpci_hotplug.h	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpci_hotplug.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,100 +0,0 @@
-/*
- * CompactPCI Hot Plug Core Functions
- *
- * Copyright (c) 2002 SOMA Networks, Inc.
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <scottm@somanetworks.com>
- */
-
-#ifndef _CPCI_HOTPLUG_H
-#define _CPCI_HOTPLUG_H
-
-#include <linux/types.h>
-#include <linux/pci.h>
-
-/* PICMG 2.12 R2.0 HS CSR bits: */
-#define HS_CSR_INS	0x0080
-#define HS_CSR_EXT	0x0040
-#define HS_CSR_PI	0x0030
-#define HS_CSR_LOO	0x0008
-#define HS_CSR_PIE	0x0004
-#define HS_CSR_EIM	0x0002
-#define HS_CSR_DHA	0x0001
-
-#define SLOT_MAGIC	0x67267322
-struct slot {
-	u32 magic;
-	u8 number;
-	unsigned int devfn;
-	struct pci_bus *bus;
-	struct pci_dev *dev;
-	unsigned int extracting;
-	struct hotplug_slot *hotplug_slot;
-	struct list_head slot_list;
-};
-
-struct cpci_hp_controller_ops {
-	int (*query_enum) (void);
-	int (*enable_irq) (void);
-	int (*disable_irq) (void);
-	int (*check_irq) (void *dev_id);
-	int (*hardware_test) (struct slot* slot, u32 value);
-	u8  (*get_power) (struct slot* slot);
-	int (*set_power) (struct slot* slot, int value);
-};
-
-struct cpci_hp_controller {
-	unsigned int irq;
-	unsigned long irq_flags;
-	char *devname;
-	void *dev_id;
-	char *name;
-	struct cpci_hp_controller_ops *ops;
-};
-
-extern int cpci_hp_register_controller(struct cpci_hp_controller *controller);
-extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
-extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
-extern int cpci_hp_unregister_bus(struct pci_bus *bus);
-extern struct slot *cpci_find_slot(struct pci_bus *bus, unsigned int devfn);
-extern int cpci_hp_start(void);
-extern int cpci_hp_stop(void);
-
-/*
- * Internal function prototypes, these functions should not be used by
- * board/chassis drivers.
- */
-extern u8 cpci_get_attention_status(struct slot *slot);
-extern u8 cpci_get_latch_status(struct slot *slot);
-extern u8 cpci_get_adapter_status(struct slot *slot);
-extern u16 cpci_get_hs_csr(struct slot * slot);
-extern u16 cpci_set_hs_csr(struct slot * slot, u16 hs_csr);
-extern int cpci_set_attention_status(struct slot *slot, int status);
-extern int cpci_check_and_clear_ins(struct slot * slot);
-extern int cpci_check_ext(struct slot * slot);
-extern int cpci_clear_ext(struct slot * slot);
-extern int cpci_led_on(struct slot * slot);
-extern int cpci_led_off(struct slot * slot);
-extern int cpci_configure_slot(struct slot *slot);
-extern int cpci_unconfigure_slot(struct slot *slot);
-
-#endif	/* _CPCI_HOTPLUG_H */
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpci_hotplug_core.c linux-2.5.70-bk10/drivers/hotplug/cpci_hotplug_core.c
--- linux-2.5.70-bk9/drivers/hotplug/cpci_hotplug_core.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpci_hotplug_core.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,919 +0,0 @@
-/*
- * CompactPCI Hot Plug Driver
- *
- * Copyright (c) 2002 SOMA Networks, Inc.
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <scottm@somanetworks.com>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
-#include "pci_hotplug.h"
-#include "cpci_hotplug.h"
-
-#define DRIVER_VERSION	"0.2"
-#define DRIVER_AUTHOR	"Scott Murray <scottm@somanetworks.com>"
-#define DRIVER_DESC	"CompactPCI Hot Plug Core"
-
-#if !defined(CONFIG_HOTPLUG_CPCI_MODULE)
-#define MY_NAME	"cpci_hotplug"
-#else
-#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...)					\
-	do {							\
-		if(cpci_debug)					\
-			printk (KERN_DEBUG "%s: " format "\n",	\
-				MY_NAME , ## arg); 		\
-	} while(0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
-
-/* local variables */
-static spinlock_t list_lock;
-static LIST_HEAD(slot_list);
-static int slots;
-int cpci_debug;
-static struct cpci_hp_controller *controller;
-static struct semaphore event_semaphore;	/* mutex for process loop (up if something to process) */
-static struct semaphore thread_exit;		/* guard ensure thread has exited before calling it quits */
-static int thread_finished = 1;
-
-static int enable_slot(struct hotplug_slot *slot);
-static int disable_slot(struct hotplug_slot *slot);
-static int set_attention_status(struct hotplug_slot *slot, u8 value);
-static int get_power_status(struct hotplug_slot *slot, u8 * value);
-static int get_attention_status(struct hotplug_slot *slot, u8 * value);
-static int get_latch_status(struct hotplug_slot *slot, u8 * value);
-static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
-
-static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
-	.owner = THIS_MODULE,
-	.enable_slot = enable_slot,
-	.disable_slot = disable_slot,
-	.set_attention_status = set_attention_status,
-	.hardware_test = NULL,
-	.get_power_status = get_power_status,
-	.get_attention_status = get_attention_status,
-	.get_latch_status = get_latch_status,
-	.get_adapter_status = get_adapter_status,
-};
-
-/* Inline functions to check the sanity of a pointer that is passed to us */
-static inline int
-slot_paranoia_check(struct slot *slot, const char *function)
-{
-	if(!slot) {
-		dbg("%s - slot == NULL", function);
-		return -1;
-	}
-	if(slot->magic != SLOT_MAGIC) {
-		dbg("%s - bad magic number for slot", function);
-		return -1;
-	}
-	if(!slot->hotplug_slot) {
-		dbg("%s - slot->hotplug_slot == NULL!", function);
-		return -1;
-	}
-	return 0;
-}
-
-static inline struct slot *
-get_slot(struct hotplug_slot *hotplug_slot, const char *function)
-{
-	struct slot *slot;
-
-	if(!hotplug_slot) {
-		dbg("%s - hotplug_slot == NULL", function);
-		return NULL;
-	}
-
-	slot = (struct slot *) hotplug_slot->private;
-	if(slot_paranoia_check(slot, function))
-		return NULL;
-	return slot;
-}
-
-static int
-update_latch_status(struct hotplug_slot *hotplug_slot, u8 value)
-{
-	struct hotplug_slot_info info;
-
-	if(!(hotplug_slot && hotplug_slot->info))
-		return -EINVAL;
-	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
-	info.latch_status = value;
-	return pci_hp_change_slot_info(hotplug_slot, &info);
-}
-
-static int
-update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
-{
-	struct hotplug_slot_info info;
-
-	if(!(hotplug_slot && hotplug_slot->info))
-		return -EINVAL;
-	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
-	info.adapter_status = value;
-	return pci_hp_change_slot_info(hotplug_slot, &info);
-}
-
-static int
-enable_slot(struct hotplug_slot *hotplug_slot)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-	int retval = 0;
-
-	if(slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
-
-	if(controller->ops->set_power) {
-		retval = controller->ops->set_power(slot, 1);
-	}
-
-	return retval;
-}
-
-static int
-disable_slot(struct hotplug_slot *hotplug_slot)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-	int retval = 0;
-
-	if(slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
-
-	/* Unconfigure device */
-	dbg("%s - unconfiguring slot %s",
-	    __FUNCTION__, slot->hotplug_slot->name);
-	if((retval = cpci_unconfigure_slot(slot))) {
-		err("%s - could not unconfigure slot %s",
-		    __FUNCTION__, slot->hotplug_slot->name);
-		return retval;
-	}
-	dbg("%s - finished unconfiguring slot %s",
-	    __FUNCTION__, slot->hotplug_slot->name);
-
-	/* Clear EXT (by setting it) */
-	if(cpci_clear_ext(slot)) {
-		err("%s - could not clear EXT for slot %s",
-		    __FUNCTION__, slot->hotplug_slot->name);
-		retval = -ENODEV;
-	}
-	cpci_led_on(slot);
-
-	if(controller->ops->set_power) {
-		retval = controller->ops->set_power(slot, 0);
-	}
-
-	if(update_adapter_status(slot->hotplug_slot, 0)) {
-		warn("failure to update adapter file");
-	}
-
-	slot->extracting = 0;
-
-	return retval;
-}
-
-static u8
-cpci_get_power_status(struct slot *slot)
-{
-	u8 power = 1;
-
-	if(controller->ops->get_power) {
-		power = controller->ops->get_power(slot);
-	}
-	return power;
-}
-
-static int
-get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-
-	if(slot == NULL)
-		return -ENODEV;
-	*value = cpci_get_power_status(slot);
-	return 0;
-}
-
-static int
-get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-
-	if(slot == NULL)
-		return -ENODEV;
-	*value = cpci_get_attention_status(slot);
-	return 0;
-}
-
-static int
-set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
-{
-	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-
-	if(slot == NULL)
-		return -ENODEV;
-	switch (status) {
-	case 0:
-		cpci_set_attention_status(slot, 0);
-		break;
-
-	case 1:
-	default:
-		cpci_set_attention_status(slot, 1);
-		break;
-	}
-
-	return 0;
-}
-
-static int
-get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
-{
-	if(hotplug_slot == NULL || hotplug_slot->info == NULL)
-		return -ENODEV;
-	*value = hotplug_slot->info->latch_status;
-	return 0;
-}
-
-static int
-get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
-{
-	if(hotplug_slot == NULL || hotplug_slot->info == NULL)
-		return -ENODEV;
-	*value = hotplug_slot->info->adapter_status;
-	return 0;
-}
-
-#define SLOT_NAME_SIZE	6
-static void
-make_slot_name(struct slot *slot)
-{
-	snprintf(slot->hotplug_slot->name,
-		 SLOT_NAME_SIZE, "%02x:%02x", slot->bus->number, slot->number);
-}
-
-int
-cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
-{
-	struct slot *slot;
-	struct hotplug_slot *hotplug_slot;
-	struct hotplug_slot_info *info;
-	char *name;
-	int status = 0;
-	int i;
-
-	if(!(controller && bus)) {
-		return -ENODEV;
-	}
-	if(last < first) {
-		return -EINVAL;
-	}
-
-	/*
-	 * Create a structure for each slot, and register that slot
-	 * with the pci_hotplug subsystem.
-	 */
-	for (i = first; i <= last; ++i) {
-		slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
-		if(!slot)
-			return -ENOMEM;
-		memset(slot, 0, sizeof (struct slot));
-
-		hotplug_slot =
-		    kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
-		if(!hotplug_slot) {
-			kfree(slot);
-			return -ENOMEM;
-		}
-		memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
-		slot->hotplug_slot = hotplug_slot;
-
-		info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
-		if(!info) {
-			kfree(hotplug_slot);
-			kfree(slot);
-			return -ENOMEM;
-		}
-		memset(info, 0, sizeof (struct hotplug_slot_info));
-		hotplug_slot->info = info;
-
-		name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
-		if(!name) {
-			kfree(info);
-			kfree(hotplug_slot);
-			kfree(slot);
-			return -ENOMEM;
-		}
-		hotplug_slot->name = name;
-
-		slot->magic = SLOT_MAGIC;
-		slot->bus = bus;
-		slot->number = i;
-		slot->devfn = PCI_DEVFN(i, 0);
-
-		hotplug_slot->private = slot;
-		make_slot_name(slot);
-		hotplug_slot->ops = &cpci_hotplug_slot_ops;
-
-		/*
-		 * Initialize the slot info structure with some known
-		 * good values.
-		 */
-		dbg("initializing slot %s", slot->hotplug_slot->name);
-		info->power_status = cpci_get_power_status(slot);
-		info->attention_status = cpci_get_attention_status(slot);
-
-		dbg("registering slot %s", slot->hotplug_slot->name);
-		status = pci_hp_register(slot->hotplug_slot);
-		if(status) {
-			err("pci_hp_register failed with error %d", status);
-			kfree(info);
-			kfree(name);
-			kfree(hotplug_slot);
-			kfree(slot);
-			return status;
-		}
-
-		/* Add slot to our internal list */
-		spin_lock(&list_lock);
-		list_add(&slot->slot_list, &slot_list);
-		slots++;
-		spin_unlock(&list_lock);
-	}
-	return status;
-}
-
-int
-cpci_hp_unregister_bus(struct pci_bus *bus)
-{
-	struct slot *slot;
-	struct list_head *tmp;
-	int status;
-
-	if(!bus) {
-		return -ENODEV;
-	}
-
-	spin_lock(&list_lock);
-	if(!slots) {
-		spin_unlock(&list_lock);
-		return -1;
-	}
-	list_for_each(tmp, &slot_list) {
-		slot = list_entry(tmp, struct slot, slot_list);
-		if(slot->bus == bus) {
-			dbg("deregistering slot %s", slot->hotplug_slot->name);
-			status = pci_hp_deregister(slot->hotplug_slot);
-			if(status) {
-				err("pci_hp_deregister failed with error %d",
-				    status);
-				return status;
-			}
-
-			list_del(&slot->slot_list);
-			kfree(slot->hotplug_slot->info);
-			kfree(slot->hotplug_slot->name);
-			kfree(slot->hotplug_slot);
-			kfree(slot);
-
-			slots--;
-		}
-	}
-	spin_unlock(&list_lock);
-	return 0;
-}
-
-struct slot *
-cpci_find_slot(struct pci_bus *bus, unsigned int devfn)
-{
-	struct slot *slot;
-	struct slot *found;
-	struct list_head *tmp;
-
-	if(!bus) {
-		return NULL;
-	}
-
-	spin_lock(&list_lock);
-	if(!slots) {
-		spin_unlock(&list_lock);
-		return NULL;
-	}
-	found = NULL;
-	list_for_each(tmp, &slot_list) {
-		slot = list_entry(tmp, struct slot, slot_list);
-		if(slot->bus == bus && slot->devfn == devfn) {
-			found = slot;
-			break;
-		}
-	}
-	spin_unlock(&list_lock);
-	return found;
-}
-
-/* This is the interrupt mode interrupt handler */
-irqreturn_t
-cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
-{
-	dbg("entered cpci_hp_intr");
-
-	/* Check to see if it was our interrupt */
-	if((controller->irq_flags & SA_SHIRQ) &&
-	    !controller->ops->check_irq(controller->dev_id)) {
-		dbg("exited cpci_hp_intr, not our interrupt");
-		return IRQ_NONE;
-	}
-
-	/* Disable ENUM interrupt */
-	controller->ops->disable_irq();
-
-	/* Trigger processing by the event thread */
-	dbg("Signal event_semaphore");
-	up(&event_semaphore);
-	dbg("exited cpci_hp_intr");
-	return IRQ_HANDLED;
-}
-
-/*
- * According to PICMG 2.12 R2.0, section 6.3.2, upon
- * initialization, the system driver shall clear the
- * INS bits of the cold-inserted devices.
- */
-static int
-init_slots(void)
-{
-	struct slot *slot;
-	struct list_head *tmp;
-	struct pci_dev* dev;
-
-	dbg("%s - enter", __FUNCTION__);
-	spin_lock(&list_lock);
-	if(!slots) {
-		spin_unlock(&list_lock);
-		return -1;
-	}
-	list_for_each(tmp, &slot_list) {
-		slot = list_entry(tmp, struct slot, slot_list);
-		dbg("%s - looking at slot %s",
-		    __FUNCTION__, slot->hotplug_slot->name);
-		if(cpci_check_and_clear_ins(slot)) {
-			dbg("%s - cleared INS for slot %s",
-			    __FUNCTION__, slot->hotplug_slot->name);
-			dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0));
-			if(dev) {
-				if(update_adapter_status(slot->hotplug_slot, 1)) {
-					warn("failure to update adapter file");
-				}
-				if(update_latch_status(slot->hotplug_slot, 1)) {
-					warn("failure to update latch file");
-				}
-				slot->dev = dev;
-			} else {
-				err("%s - no driver attached to device in slot %s",
-				    __FUNCTION__, slot->hotplug_slot->name);
-			}
-		}
-	}
-	spin_unlock(&list_lock);
-	dbg("%s - exit", __FUNCTION__);
-	return 0;
-}
-
-static int
-check_slots(void)
-{
-	struct slot *slot;
-	struct list_head *tmp;
-	int extracted;
-	int inserted;
-
-	spin_lock(&list_lock);
-	if(!slots) {
-		spin_unlock(&list_lock);
-		err("no slots registered, shutting down");
-		return -1;
-	}
-	extracted = inserted = 0;
-	list_for_each(tmp, &slot_list) {
-		slot = list_entry(tmp, struct slot, slot_list);
-		dbg("%s - looking at slot %s",
-		    __FUNCTION__, slot->hotplug_slot->name);
-		if(cpci_check_and_clear_ins(slot)) {
-			u16 hs_csr;
-
-			/* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
-			if(slot->dev) {
-				warn("slot %s already inserted", slot->hotplug_slot->name);
-				inserted++;
-				continue;
-			}
-
-			/* Process insertion */
-			dbg("%s - slot %s inserted",
-			    __FUNCTION__, slot->hotplug_slot->name);
-
-			/* GSM, debug */
-			hs_csr = cpci_get_hs_csr(slot);
-			dbg("%s - slot %s HS_CSR (1) = %04x",
-			    __FUNCTION__, slot->hotplug_slot->name, hs_csr);
-
-			/* Configure device */
-			dbg("%s - configuring slot %s",
-			    __FUNCTION__, slot->hotplug_slot->name);
-			if(cpci_configure_slot(slot)) {
-				err("%s - could not configure slot %s",
-				    __FUNCTION__, slot->hotplug_slot->name);
-				continue;
-			}
-			dbg("%s - finished configuring slot %s",
-			    __FUNCTION__, slot->hotplug_slot->name);
-
-			/* GSM, debug */
-			hs_csr = cpci_get_hs_csr(slot);
-			dbg("%s - slot %s HS_CSR (2) = %04x",
-			    __FUNCTION__, slot->hotplug_slot->name, hs_csr);
-
-			if(update_latch_status(slot->hotplug_slot, 1)) {
-				warn("failure to update latch file");
-			}
-
-			if(update_adapter_status(slot->hotplug_slot, 1)) {
-				warn("failure to update adapter file");
-			}
-
-			cpci_led_off(slot);
-
-			/* GSM, debug */
-			hs_csr = cpci_get_hs_csr(slot);
-			dbg("%s - slot %s HS_CSR (3) = %04x",
-			    __FUNCTION__, slot->hotplug_slot->name, hs_csr);
-
-			inserted++;
-		} else if(cpci_check_ext(slot)) {
-			u16 hs_csr;
-
-			/* Process extraction request */
-			dbg("%s - slot %s extracted",
-			    __FUNCTION__, slot->hotplug_slot->name);
-
-			/* GSM, debug */
-			hs_csr = cpci_get_hs_csr(slot);
-			dbg("%s - slot %s HS_CSR = %04x",
-			    __FUNCTION__, slot->hotplug_slot->name, hs_csr);
-
-			if(!slot->extracting) {
-				if(update_latch_status(slot->hotplug_slot, 0)) {
-					warn("failure to update latch file");
-				}
-				slot->extracting = 1;
-			}
-			extracted++;
-		}
-	}
-	spin_unlock(&list_lock);
-	if(inserted || extracted) {
-		return extracted;
-	}
-	else {
-		err("cannot find ENUM# source, shutting down");
-		return -1;
-	}
-}
-
-/* This is the interrupt mode worker thread body */
-static int
-event_thread(void *data)
-{
-	int rc;
-	struct slot *slot;
-	struct list_head *tmp;
-
-	lock_kernel();
-	daemonize("cpci_hp_eventd");
-	unlock_kernel();
-
-	dbg("%s - event thread started", __FUNCTION__);
-	while(1) {
-		dbg("event thread sleeping");
-		down_interruptible(&event_semaphore);
-		dbg("event thread woken, thread_finished = %d",
-		    thread_finished);
-		if(thread_finished || signal_pending(current))
-			break;
-		while(controller->ops->query_enum()) {
-			rc = check_slots();
-			if(rc > 0) {
-				/* Give userspace a chance to handle extraction */
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(HZ / 2);
-			} else if(rc < 0) {
-				dbg("%s - error checking slots", __FUNCTION__);
-				thread_finished = 1;
-				break;
-			}
-		}
-		/* Check for someone yanking out a board */
-		list_for_each(tmp, &slot_list) {
-			slot = list_entry(tmp, struct slot, slot_list);
-			if(slot->extracting) {
-				/*
-				 * Hmmm, we're likely hosed at this point, should we
-				 * bother trying to tell the driver or not?
-				 */
-				err("card in slot %s was improperly removed",
-				    slot->hotplug_slot->name);
-				if(update_adapter_status(slot->hotplug_slot, 0)) {
-					warn("failure to update adapter file");
-				}
-				slot->extracting = 0;
-			}
-		}
-
-		/* Re-enable ENUM# interrupt */
-		dbg("%s - re-enabling irq", __FUNCTION__);
-		controller->ops->enable_irq();
-	}
-
-	dbg("%s - event thread signals exit", __FUNCTION__);
-	up(&thread_exit);
-	return 0;
-}
-
-/* This is the polling mode worker thread body */
-static int
-poll_thread(void *data)
-{
-	int rc;
-	struct slot *slot;
-	struct list_head *tmp;
-
-	lock_kernel();
-	daemonize("cpci_hp_polld");
-	unlock_kernel();
-
-	while(1) {
-		if(thread_finished || signal_pending(current))
-			break;
-
-		while(controller->ops->query_enum()) {
-			rc = check_slots();
-			if(rc > 0) {
-				/* Give userspace a chance to handle extraction */
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(HZ / 2);
-			} else if(rc < 0) {
-				dbg("%s - error checking slots", __FUNCTION__);
-				thread_finished = 1;
-				break;
-			}
-		}
-		/* Check for someone yanking out a board */
-		list_for_each(tmp, &slot_list) {
-			slot = list_entry(tmp, struct slot, slot_list);
-			if(slot->extracting) {
-				/*
-				 * Hmmm, we're likely hosed at this point, should we
-				 * bother trying to tell the driver or not?
-				 */
-				err("card in slot %s was improperly removed",
-				    slot->hotplug_slot->name);
-				if(update_adapter_status(slot->hotplug_slot, 0)) {
-					warn("failure to update adapter file");
-				}
-				slot->extracting = 0;
-			}
-		}
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ / 10);
-	}
-	dbg("poll thread signals exit");
-	up(&thread_exit);
-	return 0;
-}
-
-static int
-cpci_start_thread(void)
-{
-	int pid;
-
-	/* initialize our semaphores */
-	init_MUTEX_LOCKED(&event_semaphore);
-	init_MUTEX_LOCKED(&thread_exit);
-	thread_finished = 0;
-
-	if(controller->irq) {
-		pid = kernel_thread(event_thread, 0, 0);
-	} else {
-		pid = kernel_thread(poll_thread, 0, 0);
-	}
-	if(pid < 0) {
-		err("Can't start up our thread");
-		return -1;
-	}
-	dbg("Our thread pid = %d", pid);
-	return 0;
-}
-
-static void
-cpci_stop_thread(void)
-{
-	thread_finished = 1;
-	dbg("thread finish command given");
-	if(controller->irq) {
-		up(&event_semaphore);
-	}
-	dbg("wait for thread to exit");
-	down(&thread_exit);
-}
-
-int
-cpci_hp_register_controller(struct cpci_hp_controller *new_controller)
-{
-	int status = 0;
-
-	if(!controller) {
-		controller = new_controller;
-		if(controller->irq) {
-			if(request_irq(controller->irq,
-					cpci_hp_intr,
-					controller->irq_flags,
-					MY_NAME, controller->dev_id)) {
-				err("Can't get irq %d for the hotplug cPCI controller", controller->irq);
-				status = -ENODEV;
-			}
-			dbg("%s - acquired controller irq %d", __FUNCTION__,
-			    controller->irq);
-		}
-	} else {
-		err("cPCI hotplug controller already registered");
-		status = -1;
-	}
-	return status;
-}
-
-int
-cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
-{
-	int status = 0;
-
-	if(controller) {
-		if(!thread_finished) {
-			cpci_stop_thread();
-		}
-		if(controller->irq) {
-			free_irq(controller->irq, controller->dev_id);
-		}
-		controller = NULL;
-	} else {
-		status = -ENODEV;
-	}
-	return status;
-}
-
-int
-cpci_hp_start(void)
-{
-	static int first = 1;
-	int status;
-
-	dbg("%s - enter", __FUNCTION__);
-	if(!controller) {
-		return -ENODEV;
-	}
-
-	spin_lock(&list_lock);
-	if(!slots) {
-		spin_unlock(&list_lock);
-		return -ENODEV;
-	}
-	spin_unlock(&list_lock);
-
-	if(first) {
-		status = init_slots();
-		if(status) {
-			return status;
-		}
-		first = 0;
-	}
-
-	status = cpci_start_thread();
-	if(status) {
-		return status;
-	}
-	dbg("%s - thread started", __FUNCTION__);
-
-	if(controller->irq) {
-		/* Start enum interrupt processing */
-		dbg("%s - enabling irq", __FUNCTION__);
-		controller->ops->enable_irq();
-	}
-	dbg("%s - exit", __FUNCTION__);
-	return 0;
-}
-
-int
-cpci_hp_stop(void)
-{
-	if(!controller) {
-		return -ENODEV;
-	}
-
-	if(controller->irq) {
-		/* Stop enum interrupt processing */
-		dbg("%s - disabling irq", __FUNCTION__);
-		controller->ops->disable_irq();
-	}
-	cpci_stop_thread();
-	return 0;
-}
-
-static void __exit
-cleanup_slots(void)
-{
-	struct list_head *tmp;
-	struct slot *slot;
-
-	/*
-	 * Unregister all of our slots with the pci_hotplug subsystem,
-	 * and free up all memory that we had allocated.
-	 */
-	spin_lock(&list_lock);
-	if(!slots) {
-		goto null_cleanup;
-	}
-	list_for_each(tmp, &slot_list) {
-		slot = list_entry(tmp, struct slot, slot_list);
-		list_del(&slot->slot_list);
-		pci_hp_deregister(slot->hotplug_slot);
-		kfree(slot->hotplug_slot->info);
-		kfree(slot->hotplug_slot->name);
-		kfree(slot->hotplug_slot);
-		kfree(slot);
-	}
-      null_cleanup:
-	spin_unlock(&list_lock);
-	return;
-}
-
-int __init
-cpci_hotplug_init(int debug)
-{
-	spin_lock_init(&list_lock);
-	cpci_debug = debug;
-
-	info(DRIVER_DESC " version: " DRIVER_VERSION);
-	return 0;
-}
-
-void __exit
-cpci_hotplug_exit(void)
-{
-	/*
-	 * Clean everything up.
-	 */
-	cleanup_slots();
-}
-
-
-EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
-EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
-EXPORT_SYMBOL_GPL(cpci_hp_register_bus);
-EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);
-EXPORT_SYMBOL_GPL(cpci_find_slot);
-EXPORT_SYMBOL_GPL(cpci_hp_start);
-EXPORT_SYMBOL_GPL(cpci_hp_stop);
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpci_hotplug_pci.c linux-2.5.70-bk10/drivers/hotplug/cpci_hotplug_pci.c
--- linux-2.5.70-bk9/drivers/hotplug/cpci_hotplug_pci.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpci_hotplug_pci.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,647 +0,0 @@
-/*
- * CompactPCI Hot Plug Driver PCI functions
- *
- * Copyright (c) 2002 by SOMA Networks, Inc.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <scottm@somanetworks.com>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include "pci_hotplug.h"
-#include "cpci_hotplug.h"
-
-#if !defined(CONFIG_HOTPLUG_CPCI_MODULE)
-#define MY_NAME	"cpci_hotplug"
-#else
-#define MY_NAME	THIS_MODULE->name
-#endif
-
-extern int cpci_debug;
-
-#define dbg(format, arg...)					\
-	do {							\
-		if(cpci_debug)					\
-			printk (KERN_DEBUG "%s: " format "\n",	\
-				MY_NAME , ## arg); 		\
-	} while(0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
-
-#define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
-
-
-u8 cpci_get_attention_status(struct slot* slot)
-{
-	int hs_cap;
-	u16 hs_csr;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return 0;
-	}
-
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &hs_csr)) {
-		return 0;
-	}
-	return hs_csr & 0x0008 ? 1 : 0;
-}
-
-int cpci_set_attention_status(struct slot* slot, int status)
-{
-	int hs_cap;
-	u16 hs_csr;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return 0;
-	}
-
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &hs_csr)) {
-		return 0;
-	}
-	if(status) {
-		hs_csr |= HS_CSR_LOO;
-	} else {
-		hs_csr &= ~HS_CSR_LOO;
-	}
-	if(pci_bus_write_config_word(slot->bus,
-				      slot->devfn,
-				      hs_cap + 2,
-				      hs_csr)) {
-		return 0;
-	}
-	return 1;
-}
-
-u16 cpci_get_hs_csr(struct slot* slot)
-{
-	int hs_cap;
-	u16 hs_csr;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return 0xFFFF;
-	}
-
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &hs_csr)) {
-		return 0xFFFF;
-	}
-	return hs_csr;
-}
-
-u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
-{
-	int hs_cap;
-	u16 new_hs_csr;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return 0xFFFF;
-	}
-
-	/* Write out the new value */
-	if(pci_bus_write_config_word(slot->bus,
-				      slot->devfn,
-				      hs_cap + 2,
-				      hs_csr)) {
-		return 0xFFFF;
-	}
-
-	/* Read back what we just wrote out */
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &new_hs_csr)) {
-		return 0xFFFF;
-	}
-	return new_hs_csr;
-}
-
-int cpci_check_and_clear_ins(struct slot* slot)
-{
-	int hs_cap;
-	u16 hs_csr;
-	int ins = 0;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return 0;
-	}
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &hs_csr)) {
-		return 0;
-	}
-	if(hs_csr & HS_CSR_INS) {
-		/* Clear INS (by setting it) */
-		if(pci_bus_write_config_word(slot->bus,
-					      slot->devfn,
-					      hs_cap + 2,
-					      hs_csr)) {
-			ins = 0;
-		}
-		ins = 1;
-	}
-	return ins;
-}
-
-int cpci_check_ext(struct slot* slot)
-{
-	int hs_cap;
-	u16 hs_csr;
-	int ext = 0;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return 0;
-	}
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &hs_csr)) {
-		return 0;
-	}
-	if(hs_csr & HS_CSR_EXT) {
-		ext = 1;
-	}
-	return ext;
-}
-
-int cpci_clear_ext(struct slot* slot)
-{
-	int hs_cap;
-	u16 hs_csr;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return -ENODEV;
-	}
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &hs_csr)) {
-		return -ENODEV;
-	}
-	if(hs_csr & HS_CSR_EXT) {
-		/* Clear EXT (by setting it) */
-		if(pci_bus_write_config_word(slot->bus,
-					      slot->devfn,
-					      hs_cap + 2,
-					      hs_csr)) {
-			return -ENODEV;
-		}
-	}
-	return 0;
-}
-
-int cpci_led_on(struct slot* slot)
-{
-	int hs_cap;
-	u16 hs_csr;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return -ENODEV;
-	}
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &hs_csr)) {
-		return -ENODEV;
-	}
-	if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
-		/* Set LOO */
-		hs_csr |= HS_CSR_LOO;
-		if(pci_bus_write_config_word(slot->bus,
-					      slot->devfn,
-					      hs_cap + 2,
-					      hs_csr)) {
-			err("Could not set LOO for slot %s",
-			    slot->hotplug_slot->name);
-			return -ENODEV;
-		}
-	}
-	return 0;
-}
-
-int cpci_led_off(struct slot* slot)
-{
-	int hs_cap;
-	u16 hs_csr;
-
-	hs_cap = pci_bus_find_capability(slot->bus,
-					 slot->devfn,
-					 PCI_CAP_ID_CHSWP);
-	if(!hs_cap) {
-		return -ENODEV;
-	}
-	if(pci_bus_read_config_word(slot->bus,
-				     slot->devfn,
-				     hs_cap + 2,
-				     &hs_csr)) {
-		return -ENODEV;
-	}
-	if(hs_csr & HS_CSR_LOO) {
-		/* Clear LOO */
-		hs_csr &= ~HS_CSR_LOO;
-		if(pci_bus_write_config_word(slot->bus,
-					      slot->devfn,
-					      hs_cap + 2,
-					      hs_csr)) {
-			err("Could not clear LOO for slot %s",
-			    slot->hotplug_slot->name);
-			return -ENODEV;
-		}
-	}
-	return 0;
-}
-
-
-/*
- * Device configuration functions
- */
-
-static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
-{
-	u8 irq_pin;
-	int r;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	/* NOTE: device already setup from prior scan */
-
-	/* FIXME: How would we know if we need to enable the expansion ROM? */
-	pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
-
-	/* Assign resources */
-	dbg("assigning resources for %02x:%02x.%x",
-	    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	for (r = 0; r < 6; r++) {
-		struct resource *res = dev->resource + r;
-		if(res->flags)
-			pci_assign_resource(dev, r);
-	}
-	dbg("finished assigning resources for %02x:%02x.%x",
-	    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-
-	/* Does this function have an interrupt at all? */
-	dbg("checking for function interrupt");
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
-	if(irq_pin) {
-		dbg("function uses interrupt pin %d", irq_pin);
-	}
-
-	/*
-	 * Need to explicitly set irq field to 0 so that it'll get assigned
-	 * by the pcibios platform dependent code called by pci_enable_device.
-	 */
-	dev->irq = 0;
-
-	dbg("enabling device");
-	pci_enable_device(dev);	/* XXX check return */
-	dbg("now dev->irq = %d", dev->irq);
-	if(irq_pin && dev->irq) {
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-	}
-
-	/* Can't use pci_insert_device at the moment, do it manually for now */
-	pci_proc_attach_device(dev);
-	dbg("notifying drivers");
-	//pci_announce_device_to_drivers(dev);
-	dbg("%s - exit", __FUNCTION__);
-	return 0;
-}
-
-static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
-{
-	int rc;
-	struct pci_bus* child;
-	struct resource* r;
-	u8 max, n;
-	u16 command;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	/* Do basic bridge initialization */
-	rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
-	if(rc) {
-		printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
-	}
-	rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
-	if(rc) {
-		printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
-	}
-	rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
-	if(rc) {
-		printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
-	}
-
-	/*
-	 * Set parent bridge's subordinate field so that configuration space
-	 * access will work in pci_scan_bridge and friends.
-	 */
-	max = pci_max_busnr();
-	bus->subordinate = max + 1;
-	pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
-
-	/* Scan behind bridge */
-	n = pci_scan_bridge(bus, dev, max, 2);
-	child = pci_find_bus(max + 1);
-	if (!child)
-		return -ENODEV;
-#ifdef CONFIG_PROC_FS
-	pci_proc_attach_bus(child);
-#endif
-	/*
-	 * Update parent bridge's subordinate field if there were more bridges
-	 * behind the bridge that was scanned.
-	 */
-	if(n > max) {
-		bus->subordinate = n;
-		pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
-	}
-
-	/*
-	 * Update the bridge resources of the bridge to accommodate devices
-	 * behind it.
-	 */
-	pci_bus_size_bridges(child);
-	pci_bus_assign_resources(child);
-
-	/* Enable resource mapping via command register */
-	command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
-	r = child->resource[0];
-	if(r && r->start) {
-		command |= PCI_COMMAND_IO;
-	}
-	r = child->resource[1];
-	if(r && r->start) {
-		command |= PCI_COMMAND_MEMORY;
-	}
-	r = child->resource[2];
-	if(r && r->start) {
-		command |= PCI_COMMAND_MEMORY;
-	}
-	rc = pci_write_config_word(dev, PCI_COMMAND, command);
-	if(rc) {
-		err("Error setting command register");
-		return rc;
-	}
-
-	/* Set bridge control register */
-	command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
-	rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
-	if(rc) {
-		err("Error setting bridge control register");
-		return rc;
-	}
-	dbg("%s - exit", __FUNCTION__);
-	return 0;
-}
-
-static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
-			struct pci_bus_wrapped *wrapped_bus)
-{
-	int rc;
-	struct pci_dev *dev = wrapped_dev->dev;
-	struct pci_bus *bus = wrapped_bus->bus;
-	struct slot* slot;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	/*
-	 * We need to fix up the hotplug representation with the Linux
-	 * representation.
-	 */
-	slot = cpci_find_slot(dev->bus, dev->devfn);
-	if(slot) {
-		slot->dev = dev;
-	}
-
-	/* If it's a bridge, scan behind it for devices */
-	if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-		rc = cpci_configure_bridge(bus, dev);
-		if(rc)
-			return rc;
-	}
-
-	/* Actually configure device */
-	if(dev) {
-		rc = cpci_configure_dev(bus, dev);
-		if(rc)
-			return rc;
-	}
-	dbg("%s - exit", __FUNCTION__);
-	return 0;
-}
-
-static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
-					    struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-	struct slot* slot;
-
-	dbg("%s - enter", __FUNCTION__);
-	if(!dev)
-		return -ENODEV;
-
-	/* Remove the Linux representation */
-	if(pci_remove_device_safe(dev) == 0) {
-		kfree(dev);
-	} else {
-		err("Could not remove device\n");
-		return -1;
-	}
-
-	/*
-	 * Now remove the hotplug representation.
-	 */
-	slot = cpci_find_slot(dev->bus, dev->devfn);
-	if(slot) {
-		slot->dev = NULL;
-	} else {
-		dbg("No hotplug representation for %02x:%02x.%x",
-		    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	}
-	dbg("%s - exit", __FUNCTION__);
-	return 0;
-}
-
-static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
-					    struct pci_dev_wrapped *wrapped_dev)
-{
-	struct pci_bus *bus = wrapped_bus->bus;
-	struct pci_bus *parent = bus->self->bus;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	/* The cleanup code for proc entries regarding buses should be in the kernel... */
-	if(bus->procdir)
-		dbg("detach_pci_bus %s", bus->procdir->name);
-	pci_proc_detach_bus(bus);
-
-	/* The cleanup code should live in the kernel... */
-	bus->self->subordinate = NULL;
-
-	/* unlink from parent bus */
-	list_del(&bus->node);
-
-	/* Now, remove */
-	if(bus)
-		kfree(bus);
-
-	/* Update parent's subordinate field */
-	if(parent) {
-		u8 n = pci_bus_max_busnr(parent);
-		if(n < parent->subordinate) {
-			parent->subordinate = n;
-			pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
-		}
-	}
-	dbg("%s - exit", __FUNCTION__);
-	return 0;
-}
-
-static struct pci_visit configure_functions = {
-	.visit_pci_dev = configure_visit_pci_dev,
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-	.post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
-	.post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
-};
-
-
-int cpci_configure_slot(struct slot* slot)
-{
-	int rc = 0;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	if(slot->dev == NULL) {
-		dbg("pci_dev null, finding %02x:%02x:%x",
-		    slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
-		slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
-	}
-
-	/* Still NULL? Well then scan for it! */
-	if(slot->dev == NULL) {
-		dbg("pci_dev still null");
-
-		/*
-		 * This will generate pci_dev structures for all functions, but
-		 * we will only call this case when lookup fails.
-		 */
-		slot->dev = pci_scan_slot(slot->bus, slot->devfn);
-		if(slot->dev == NULL) {
-			err("Could not find PCI device for slot %02x", slot->number);
-			return 0;
-		}
-	}
-	dbg("slot->dev = %p", slot->dev);
-	if(slot->dev) {
-		struct pci_dev *dev;
-		struct pci_dev_wrapped wrapped_dev;
-		struct pci_bus_wrapped wrapped_bus;
-		int i;
-
-		memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-		memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
-		for (i = 0; i < 8; i++) {
-			dev = pci_find_slot(slot->bus->number,
-					    PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
-			if(!dev)
-				continue;
-			wrapped_dev.dev = dev;
-			wrapped_bus.bus = slot->dev->bus;
-			rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-		}
-	}
-
-	dbg("%s - exit, rc = %d", __FUNCTION__, rc);
-	return rc;
-}
-
-int cpci_unconfigure_slot(struct slot* slot)
-{
-	int rc = 0;
-	int i;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-	struct pci_dev *dev;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	if(!slot->dev) {
-		err("No device for slot %02x\n", slot->number);
-		return -ENODEV;
-	}
-
-	memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
-	for (i = 0; i < 8; i++) {
-		dev = pci_find_slot(slot->bus->number,
-				    PCI_DEVFN(PCI_SLOT(slot->devfn), i));
-		if(dev) {
-			wrapped_dev.dev = dev;
-			wrapped_bus.bus = dev->bus;
-			dbg("%s - unconfigure phase 2", __FUNCTION__);
-			rc = pci_visit_dev(&unconfigure_functions_phase2,
-					   &wrapped_dev, &wrapped_bus);
-			if(rc)
-				break;
-		}
-	}
-	dbg("%s - exit, rc = %d", __FUNCTION__, rc);
-	return rc;
-}
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpcihp_generic.c linux-2.5.70-bk10/drivers/hotplug/cpcihp_generic.c
--- linux-2.5.70-bk9/drivers/hotplug/cpcihp_generic.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpcihp_generic.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,290 +0,0 @@
-/*
- * cpcihp_generic.c
- *
- * Generic port I/O CompactPCI driver
- *
- * Copyright 2002 SOMA Networks, Inc.
- * Copyright 2001 Intel San Luis Obispo
- * Copyright 2000,2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This generic CompactPCI hotplug driver should allow using the PCI hotplug
- * mechanism on any CompactPCI board that exposes the #ENUM signal as a bit
- * in a system register that can be read through standard port I/O.
- *
- * Send feedback to <scottm@somanetworks.com>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include "cpci_hotplug.h"
-
-#define DRIVER_VERSION	"0.1"
-#define DRIVER_AUTHOR	"Scott Murray <scottm@somanetworks.com>"
-#define DRIVER_DESC	"Generic port I/O CompactPCI Hot Plug Driver"
-
-#if !defined(CONFIG_HOTPLUG_CPCI_GENERIC_MODULE)
-#define MY_NAME	"cpcihp_generic"
-#else
-#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...)					\
-	do {							\
-		if(debug)					\
-			printk (KERN_DEBUG "%s: " format "\n",	\
-				MY_NAME , ## arg); 		\
-	} while(0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
-
-/* local variables */
-static int debug;
-static char* bridge;
-static u8 bridge_busnr;
-static u8 bridge_slot;
-static struct pci_bus *bus;
-static u8 first_slot;
-static u8 last_slot;
-static u16 port;
-static unsigned int enum_bit;
-static u8 enum_mask;
-
-static struct cpci_hp_controller_ops generic_hpc_ops;
-static struct cpci_hp_controller generic_hpc;
-
-/* The following allows configuring the driver when it's compiled into the kernel */
-#ifndef MODULE
-static int __init cpcihp_generic_setup(char* str)
-{
-	char* p;
-	unsigned long tmp;
-
-	if(!str)
-		return -EINVAL;
-	bridge = str;
-
-	p = strchr(str, ',');
-	str = p + 1;
-	if(!(p && *str && *p == ','))
-		goto setup_error;
-	tmp = simple_strtoul(str, &p, 0);
-	if(p == str || tmp > 0xff) {
-		err("hotplug bus first slot number out of range");
-		goto setup_error;
-	}
-	first_slot = (u8) tmp;
-
-	str = p + 1;		
-	if(!(*str && *p == ','))
-		return -EINVAL;
-	tmp = simple_strtoul(str, &p, 0);
-	if(p == str || tmp > 0xff) {
-		err("hotplug bus last slot number out of range");
-		goto setup_error;
-	}
-	last_slot = (u8) tmp;
-
-	str = p + 1;
-	if(!(*str && *p == ','))
-		goto setup_error;
-	tmp = simple_strtoul(str, &p, 0);
-	if(p == str || tmp > 0xffff) {
-		err("port number out of range");
-		goto setup_error;
-	}
-	port = (u16) tmp;
-
-	str = p + 1;
-	if(!(*str && *p == ','))
-		goto setup_error;
-	tmp = simple_strtoul(str, &p, 0);
-	if(p == str) {
-		err("invalid #ENUM bit number");
-		goto setup_error;
-	}
-	enum_bit = (u8) tmp;
-
-	str = p + 1;
-	if(*str && *p == ',') {
-		tmp = simple_strtoul(str, &p, 0);
-		if(p != str)
-			debug = (int) tmp;
-	}
-	return 0;
-setup_error:
-	bridge = NULL;
-	return -EINVAL;
-}
-
-__setup("cpcihp_generic=", cpcihp_generic_setup);
-#endif
-
-static int __init validate_parameters(void)
-{
-	char* str;
-	char* p;
-	unsigned long tmp;
-
-	if(!bridge) {
-		info("not configured, disabling.");
-		return 1;
-	}
-	str = bridge;
-	if(!*str)
-		return -EINVAL;
-
-	tmp = simple_strtoul(str, &p, 16);
-	if(p == str || tmp > 0xff) {
-		err("Invalid hotplug bus bridge device bus number");
-		return -EINVAL;
-	}
-	bridge_busnr = (u8) tmp;
-	dbg("bridge_busnr = 0x%02x", bridge_busnr);
-	if(*p != ':') {
-		err("Invalid hotplug bus bridge device");
-		return -EINVAL;
-	}
-	str = p + 1;
-	tmp = simple_strtoul(str, &p, 16);
-	if(p == str || tmp > 0x1f) {
-		err("Invalid hotplug bus bridge device slot number");
-		return -EINVAL;
-	}
-	bridge_slot = (u8) tmp;
-	dbg("bridge_slot = 0x%02x", bridge_slot);
-
-	dbg("first_slot = 0x%02x", first_slot);
-	dbg("last_slot = 0x%02x", last_slot);
-	if(!(first_slot && last_slot)) {
-		err("Need to specify first_slot and last_slot");
-		return -EINVAL;
-	}
-	if(last_slot < first_slot) {
-		err("first_slot must be less than last_slot");
-		return -EINVAL;
-	}
-
-	dbg("port = 0x%04x", port);
-	dbg("enum_bit = 0x%02x", enum_bit);
-	if(enum_bit > 7) {
-		err("Invalid #ENUM bit");
-		return -EINVAL;
-	}
-	enum_mask = 1 << enum_bit;
-	return 0;
-}
-
-static int query_enum(void)
-{
-	u8 value;
-
-	value = inb_p(port);
-	return ((value & enum_mask) == enum_mask);
-}
-
-static int __init cpcihp_generic_init(void)
-{
-	int status;
-	struct resource* r;
-	struct pci_dev* dev;
-
-	info(DRIVER_DESC " version: " DRIVER_VERSION);
-	status = validate_parameters();
-	if(status != 0)
-		return status;
-
-	r = request_region(port, 1, "#ENUM hotswap signal register");
-	if(!r)
-		return -EBUSY;
-
-	dev = pci_find_slot(bridge_busnr, PCI_DEVFN(bridge_slot, 0));
-	if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-		err("Invalid bridge device %s", bridge);
-		return -EINVAL;
-	}
-	bus = dev->subordinate;
-
-	memset(&generic_hpc, 0, sizeof (struct cpci_hp_controller));
-	generic_hpc_ops.query_enum = query_enum;
-	generic_hpc.ops = &generic_hpc_ops;
-
-	status = cpci_hp_register_controller(&generic_hpc);
-	if(status != 0) {
-		err("Could not register cPCI hotplug controller");
-		return -ENODEV;
-	}
-	dbg("registered controller");
-
-	status = cpci_hp_register_bus(bus, first_slot, last_slot);
-	if(status != 0) {
-		err("Could not register cPCI hotplug bus");
-		goto init_bus_register_error;
-	}
-	dbg("registered bus");
-
-	status = cpci_hp_start();
-	if(status != 0) {
-		err("Could not started cPCI hotplug system");
-		goto init_start_error;
-	}
-	dbg("started cpci hp system");
-	return 0;
-init_start_error:
-	cpci_hp_unregister_bus(bus);
-init_bus_register_error:
-	cpci_hp_unregister_controller(&generic_hpc);
-	err("status = %d", status);
-	return status;
-
-}
-
-static void __exit cpcihp_generic_exit(void)
-{
-	cpci_hp_stop();
-	cpci_hp_unregister_bus(bus);
-	cpci_hp_unregister_controller(&generic_hpc);
-	release_region(port, 1);
-}
-
-module_init(cpcihp_generic_init);
-module_exit(cpcihp_generic_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-MODULE_PARM(bridge, "s");
-MODULE_PARM_DESC(bridge, "Hotswap bus bridge device, <bus>:<slot> (bus and slot are in hexadecimal)");
-MODULE_PARM(first_slot, "b");
-MODULE_PARM_DESC(first_slot, "Hotswap bus first slot number");
-MODULE_PARM(last_slot, "b");
-MODULE_PARM_DESC(last_slot, "Hotswap bus last slot number");
-MODULE_PARM(port, "h");
-MODULE_PARM_DESC(port, "#ENUM signal I/O port");
-MODULE_PARM(enum_bit, "i");
-MODULE_PARM_DESC(enum_bit, "#ENUM signal bit (0-7)");
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpcihp_zt5550.c linux-2.5.70-bk10/drivers/hotplug/cpcihp_zt5550.c
--- linux-2.5.70-bk9/drivers/hotplug/cpcihp_zt5550.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpcihp_zt5550.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,306 +0,0 @@
-/*
- * cpcihp_zt5550.c
- *
- * Intel/Ziatech ZT5550 CompactPCI Host Controller driver
- *
- * Copyright 2002 SOMA Networks, Inc.
- * Copyright 2001 Intel San Luis Obispo
- * Copyright 2000,2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <scottm@somanetworks.com>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include "cpci_hotplug.h"
-#include "cpcihp_zt5550.h"
-
-#define DRIVER_VERSION	"0.2"
-#define DRIVER_AUTHOR	"Scott Murray <scottm@somanetworks.com>"
-#define DRIVER_DESC	"ZT5550 CompactPCI Hot Plug Driver"
-
-#if !defined(CONFIG_HOTPLUG_PCI_CPCI_ZT5550_MODULE)
-#define MY_NAME	"cpcihp_zt5550"
-#else
-#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...)					\
-	do {							\
-		if(debug)					\
-			printk (KERN_DEBUG "%s: " format "\n",	\
-				MY_NAME , ## arg); 		\
-	} while(0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
-
-/* local variables */
-static int debug;
-static int poll;
-static struct cpci_hp_controller_ops zt5550_hpc_ops;
-static struct cpci_hp_controller zt5550_hpc;
-
-/* Primary cPCI bus bridge device */
-static struct pci_dev *bus0_dev;
-static struct pci_bus *bus0;
-
-/* Host controller device */
-static struct pci_dev *hc_dev;
-
-/* Host controller register addresses */
-static void *hc_registers;
-static void *csr_hc_index;
-static void *csr_hc_data;
-static void *csr_int_status;
-static void *csr_int_mask;
-
-
-static int zt5550_hc_config(struct pci_dev *pdev)
-{
-	/* Since we know that no boards exist with two HC chips, treat it as an error */
-	if(hc_dev) {
-		err("too many host controller devices?");
-		return -EBUSY;
-	}
-	hc_dev = pdev;
-	dbg("hc_dev = %p", hc_dev);
-	dbg("pci resource start %lx", pci_resource_start(hc_dev, 1));
-	dbg("pci resource len %lx", pci_resource_len(hc_dev, 1));
-
-	if(!request_mem_region(pci_resource_start(hc_dev, 1),
-				pci_resource_len(hc_dev, 1), MY_NAME)) {
-		err("cannot reserve MMIO region");
-		return -ENOMEM;
-	}
-
-	hc_registers =
-	    ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1));
-	if(!hc_registers) {
-		err("cannot remap MMIO region %lx @ %lx",
-		    pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1));
-		release_mem_region(pci_resource_start(hc_dev, 1),
-				   pci_resource_len(hc_dev, 1));
-		return -ENODEV;
-	}
-
-	csr_hc_index = hc_registers + CSR_HCINDEX;
-	csr_hc_data = hc_registers + CSR_HCDATA;
-	csr_int_status = hc_registers + CSR_INTSTAT;
-	csr_int_mask = hc_registers + CSR_INTMASK;
-
-	/*
-	 * Disable host control, fault and serial interrupts
-	 */
-	dbg("disabling host control, fault and serial interrupts");
-	writeb((u8) HC_INT_MASK_REG, csr_hc_index);
-	writeb((u8) ALL_INDEXED_INTS_MASK, csr_hc_data);
-	dbg("disabled host control, fault and serial interrupts");
-
-	/*
-	 * Disable timer0, timer1 and ENUM interrupts
-	 */
-	dbg("disabling timer0, timer1 and ENUM interrupts");
-	writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask);
-	dbg("disabled timer0, timer1 and ENUM interrupts");
-	return 0;
-}
-
-static int zt5550_hc_cleanup(void)
-{
-	if(!hc_dev)
-		return -ENODEV;
-	release_mem_region(pci_resource_start(hc_dev, 1),
-			   pci_resource_len(hc_dev, 1));
-	return 0;
-}
-
-static int zt5550_hc_query_enum(void)
-{
-	u8 value;
-
-	value = inb_p(ENUM_PORT);
-	return ((value & ENUM_MASK) == ENUM_MASK);
-}
-
-static int zt5550_hc_check_irq(void *dev_id)
-{
-	int ret;
-	u8 reg;
-
-	ret = 0;
-	if(dev_id == zt5550_hpc.dev_id) {
-		reg = readb(csr_int_status);
-		if(reg)
-			ret = 1;
-	}
-	return ret;
-}
-
-static int zt5550_hc_enable_irq(void)
-{
-	u8 reg;
-
-	if(hc_dev == NULL) {
-		return -ENODEV;
-	}
-	reg = readb(csr_int_mask);
-	reg = reg & ~ENUM_INT_MASK;
-	writeb(reg, csr_int_mask);
-	return 0;
-}
-
-int zt5550_hc_disable_irq(void)
-{
-	u8 reg;
-
-	if(hc_dev == NULL) {
-		return -ENODEV;
-	}
-
-	reg = readb(csr_int_mask);
-	reg = reg | ENUM_INT_MASK;
-	writeb(reg, csr_int_mask);
-	return 0;
-}
-
-static int __devinit zt5550_hc_init_one (struct pci_dev *pdev,
-					 const struct pci_device_id *ent)
-{
-	int status;
-
-	status = zt5550_hc_config(pdev);
-	if(status != 0) {
-		return status;
-	}
-	dbg("returned from zt5550_hc_config");
-
-	memset(&zt5550_hpc, 0, sizeof (struct cpci_hp_controller));
-	zt5550_hpc_ops.query_enum = zt5550_hc_query_enum;
-	zt5550_hpc.ops = &zt5550_hpc_ops;
-	if(!poll) {
-		zt5550_hpc.irq = hc_dev->irq;
-		zt5550_hpc.irq_flags = SA_SHIRQ;
-		zt5550_hpc.dev_id = hc_dev;
-
-		zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq;
-		zt5550_hpc_ops.disable_irq = zt5550_hc_disable_irq;
-		zt5550_hpc_ops.check_irq = zt5550_hc_check_irq;
-	} else {
-		info("using ENUM# polling mode");
-	}
-
-	status = cpci_hp_register_controller(&zt5550_hpc);
-	if(status != 0) {
-		err("could not register cPCI hotplug controller");
-		goto init_hc_error;
-	}
-	dbg("registered controller");
-
-	/* Look for first device matching cPCI bus's bridge vendor and device IDs */
-	if(!(bus0_dev = pci_find_device(PCI_VENDOR_ID_DEC,
-					 PCI_DEVICE_ID_DEC_21154, NULL))) {
-		status = -ENODEV;
-		goto init_register_error;
-	}
-	bus0 = bus0_dev->subordinate;
-
-	status = cpci_hp_register_bus(bus0, 0x0a, 0x0f);
-	if(status != 0) {
-		err("could not register cPCI hotplug bus");
-		goto init_register_error;
-	}
-	dbg("registered bus");
-
-	status = cpci_hp_start();
-	if(status != 0) {
-		err("could not started cPCI hotplug system");
-		cpci_hp_unregister_bus(bus0);
-		goto init_register_error;
-	}
-	dbg("started cpci hp system");
-
-	return 0;
-init_register_error:
-	cpci_hp_unregister_controller(&zt5550_hpc);
-init_hc_error:
-	err("status = %d", status);
-	zt5550_hc_cleanup();
-	return status;
-
-}
-
-static void __devexit zt5550_hc_remove_one(struct pci_dev *pdev)
-{
-	cpci_hp_stop();
-	cpci_hp_unregister_bus(bus0);
-	cpci_hp_unregister_controller(&zt5550_hpc);
-	zt5550_hc_cleanup();
-}
-
-
-static struct pci_device_id zt5550_hc_pci_tbl[] __devinitdata = {
-	{ PCI_VENDOR_ID_ZIATECH, PCI_DEVICE_ID_ZIATECH_5550_HC, PCI_ANY_ID, PCI_ANY_ID, },
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci, zt5550_hc_pci_tbl);
-	
-static struct pci_driver zt5550_hc_driver = {
-	.name		= "zt5550_hc",
-	.id_table	= zt5550_hc_pci_tbl,
-	.probe		= zt5550_hc_init_one,
-	.remove		= __devexit_p(zt5550_hc_remove_one),
-};
-
-static int __init zt5550_init(void)
-{
-	struct resource* r;
-
-	info(DRIVER_DESC " version: " DRIVER_VERSION);
-	r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register");
-	if(!r)
-		return -EBUSY;
-
-	return pci_module_init(&zt5550_hc_driver);
-}
-
-static void __exit
-zt5550_exit(void)
-{
-	pci_unregister_driver(&zt5550_hc_driver);
-	release_region(ENUM_PORT, 1);
-}
-
-module_init(zt5550_init);
-module_exit(zt5550_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-MODULE_PARM(poll, "i");
-MODULE_PARM_DESC(poll, "#ENUM polling mode enabled or not");
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpcihp_zt5550.h linux-2.5.70-bk10/drivers/hotplug/cpcihp_zt5550.h
--- linux-2.5.70-bk9/drivers/hotplug/cpcihp_zt5550.h	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpcihp_zt5550.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,79 +0,0 @@
-/*
- * cpcihp_zt5550.h
- *
- * Intel/Ziatech ZT5550 CompactPCI Host Controller driver definitions
- *
- * Copyright 2002 SOMA Networks, Inc.
- * Copyright 2001 Intel San Luis Obispo
- * Copyright 2000,2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <scottm@somanetworks.com>
- */
-
-#ifndef _CPCIHP_ZT5550_H
-#define _CPCIHP_ZT5550_H
-
-/* Direct registers */
-#define CSR_HCINDEX		0x00
-#define CSR_HCDATA		0x04
-#define CSR_INTSTAT		0x08
-#define CSR_INTMASK		0x09
-#define CSR_CNT0CMD		0x0C
-#define CSR_CNT1CMD		0x0E
-#define CSR_CNT0		0x10
-#define CSR_CNT1		0x14
-
-/* Masks for interrupt bits in CSR_INTMASK direct register */
-#define CNT0_INT_MASK		0x01
-#define CNT1_INT_MASK		0x02
-#define ENUM_INT_MASK		0x04
-#define ALL_DIRECT_INTS_MASK	0x07
-
-/* Indexed registers (through CSR_INDEX, CSR_DATA) */
-#define HC_INT_MASK_REG		0x04
-#define HC_STATUS_REG		0x08
-#define HC_CMD_REG		0x0C
-#define ARB_CONFIG_GNT_REG	0x10
-#define ARB_CONFIG_CFG_REG	0x12
-#define ARB_CONFIG_REG	 	0x10
-#define ISOL_CONFIG_REG		0x18
-#define FAULT_STATUS_REG	0x20
-#define FAULT_CONFIG_REG	0x24
-#define WD_CONFIG_REG		0x2C
-#define HC_DIAG_REG		0x30
-#define SERIAL_COMM_REG		0x34
-#define SERIAL_OUT_REG		0x38
-#define SERIAL_IN_REG		0x3C
-
-/* Masks for interrupt bits in HC_INT_MASK_REG indexed register */
-#define SERIAL_INT_MASK		0x01
-#define FAULT_INT_MASK		0x02
-#define HCF_INT_MASK		0x04
-#define ALL_INDEXED_INTS_MASK	0x07
-
-/* Digital I/O port storing ENUM# */
-#define ENUM_PORT	0xE1
-/* Mask to get to the ENUM# bit on the bus */
-#define ENUM_MASK	0x40
-
-#endif				/* _CPCIHP_ZT5550_H */
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpqphp.h linux-2.5.70-bk10/drivers/hotplug/cpqphp.h
--- linux-2.5.70-bk9/drivers/hotplug/cpqphp.h	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpqphp.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,912 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-#ifndef _CPQPHP_H
-#define _CPQPHP_H
-
-#include "pci_hotplug.h"
-#include <linux/interrupt.h>
-#include <asm/io.h>		/* for read? and write? functions */
-#include <linux/delay.h>	/* for delays */
-
-#if !defined(CONFIG_HOTPLUG_PCI_COMPAQ_MODULE)
-	#define MY_NAME	"cpqphp.o"
-#else
-	#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
-
-
-
-struct smbios_system_slot {
-	u8 type;
-	u8 length;
-	u16 handle;
-	u8 name_string_num;
-	u8 slot_type;
-	u8 slot_width;
-	u8 slot_current_usage;
-	u8 slot_length;
-	u16 slot_number;
-	u8 properties1;
-	u8 properties2;
-} __attribute__ ((packed));
-
-/* offsets to the smbios generic type based on the above structure layout */
-enum smbios_system_slot_offsets {
-	SMBIOS_SLOT_GENERIC_TYPE =	offsetof(struct smbios_system_slot, type),
-	SMBIOS_SLOT_GENERIC_LENGTH =	offsetof(struct smbios_system_slot, length),
-	SMBIOS_SLOT_GENERIC_HANDLE =	offsetof(struct smbios_system_slot, handle),
-	SMBIOS_SLOT_NAME_STRING_NUM =	offsetof(struct smbios_system_slot, name_string_num),
-	SMBIOS_SLOT_TYPE =		offsetof(struct smbios_system_slot, slot_type),
-	SMBIOS_SLOT_WIDTH =		offsetof(struct smbios_system_slot, slot_width),
-	SMBIOS_SLOT_CURRENT_USAGE =	offsetof(struct smbios_system_slot, slot_current_usage),
-	SMBIOS_SLOT_LENGTH =		offsetof(struct smbios_system_slot, slot_length),
-	SMBIOS_SLOT_NUMBER =		offsetof(struct smbios_system_slot, slot_number),
-	SMBIOS_SLOT_PROPERTIES1 =	offsetof(struct smbios_system_slot, properties1),
-	SMBIOS_SLOT_PROPERTIES2 =	offsetof(struct smbios_system_slot, properties2),
-};
-
-struct smbios_generic {
-	u8 type;
-	u8 length;
-	u16 handle;
-} __attribute__ ((packed));
-
-/* offsets to the smbios generic type based on the above structure layout */
-enum smbios_generic_offsets {
-	SMBIOS_GENERIC_TYPE =	offsetof(struct smbios_generic, type),
-	SMBIOS_GENERIC_LENGTH =	offsetof(struct smbios_generic, length),
-	SMBIOS_GENERIC_HANDLE =	offsetof(struct smbios_generic, handle),
-};
-
-struct smbios_entry_point {
-	char anchor[4];
-	u8 ep_checksum;
-	u8 ep_length;
-	u8 major_version;
-	u8 minor_version;
-	u16 max_size_entry;
-	u8 ep_rev;
-	u8 reserved[5];
-	char int_anchor[5];
-	u8 int_checksum;
-	u16 st_length;
-	u32 st_address;
-	u16 number_of_entrys;
-	u8 bcd_rev;
-} __attribute__ ((packed));
-
-/* offsets to the smbios entry point based on the above structure layout */
-enum smbios_entry_point_offsets {
-	ANCHOR =		offsetof(struct smbios_entry_point, anchor[0]),
-	EP_CHECKSUM =		offsetof(struct smbios_entry_point, ep_checksum),
-	EP_LENGTH =		offsetof(struct smbios_entry_point, ep_length),
-	MAJOR_VERSION =		offsetof(struct smbios_entry_point, major_version),
-	MINOR_VERSION =		offsetof(struct smbios_entry_point, minor_version),
-	MAX_SIZE_ENTRY =	offsetof(struct smbios_entry_point, max_size_entry),
-	EP_REV =		offsetof(struct smbios_entry_point, ep_rev),
-	INT_ANCHOR =		offsetof(struct smbios_entry_point, int_anchor[0]),
-	INT_CHECKSUM =		offsetof(struct smbios_entry_point, int_checksum),
-	ST_LENGTH =		offsetof(struct smbios_entry_point, st_length),
-	ST_ADDRESS =		offsetof(struct smbios_entry_point, st_address),
-	NUMBER_OF_ENTRYS =	offsetof(struct smbios_entry_point, number_of_entrys),
-	BCD_REV =		offsetof(struct smbios_entry_point, bcd_rev),
-};
-
-struct ctrl_reg {			/* offset */
-	u8	slot_RST;		/* 0x00 */
-	u8	slot_enable;		/* 0x01 */
-	u16	misc;			/* 0x02 */
-	u32	led_control;		/* 0x04 */
-	u32	int_input_clear;	/* 0x08 */
-	u32	int_mask;		/* 0x0a */
-	u8	reserved0;		/* 0x10 */
-	u8	reserved1;		/* 0x11 */
-	u8	reserved2;		/* 0x12 */
-	u8	gen_output_AB;		/* 0x13 */
-	u32	non_int_input;		/* 0x14 */
-	u32	reserved3;		/* 0x18 */
-	u32	reserved4;		/* 0x1a */
-	u32	reserved5;		/* 0x20 */
-	u8	reserved6;		/* 0x24 */
-	u8	reserved7;		/* 0x25 */
-	u16	reserved8;		/* 0x26 */
-	u8	slot_mask;		/* 0x28 */
-	u8	reserved9;		/* 0x29 */
-	u8	reserved10;		/* 0x2a */
-	u8	reserved11;		/* 0x2b */
-	u8	slot_SERR;		/* 0x2c */
-	u8	slot_power;		/* 0x2d */
-	u8	reserved12;		/* 0x2e */
-	u8	reserved13;		/* 0x2f */
-	u8	next_curr_freq;		/* 0x30 */
-	u8	reset_freq_mode;	/* 0x31 */
-} __attribute__ ((packed));
-
-/* offsets to the controller registers based on the above structure layout */
-enum ctrl_offsets {
-	SLOT_RST = 		offsetof(struct ctrl_reg, slot_RST),
-	SLOT_ENABLE =		offsetof(struct ctrl_reg, slot_enable),
-	MISC =			offsetof(struct ctrl_reg, misc),
-	LED_CONTROL =		offsetof(struct ctrl_reg, led_control),
-	INT_INPUT_CLEAR =	offsetof(struct ctrl_reg, int_input_clear),
-	INT_MASK = 		offsetof(struct ctrl_reg, int_mask),
-	CTRL_RESERVED0 = 	offsetof(struct ctrl_reg, reserved0),
-	CTRL_RESERVED1 =	offsetof(struct ctrl_reg, reserved1),
-	CTRL_RESERVED2 =	offsetof(struct ctrl_reg, reserved1),
-	GEN_OUTPUT_AB = 	offsetof(struct ctrl_reg, gen_output_AB),
-	NON_INT_INPUT = 	offsetof(struct ctrl_reg, non_int_input),
-	CTRL_RESERVED3 =	offsetof(struct ctrl_reg, reserved3),
-	CTRL_RESERVED4 =	offsetof(struct ctrl_reg, reserved4),
-	CTRL_RESERVED5 =	offsetof(struct ctrl_reg, reserved5),
-	CTRL_RESERVED6 =	offsetof(struct ctrl_reg, reserved6),
-	CTRL_RESERVED7 =	offsetof(struct ctrl_reg, reserved7),
-	CTRL_RESERVED8 =	offsetof(struct ctrl_reg, reserved8),
-	SLOT_MASK = 		offsetof(struct ctrl_reg, slot_mask),
-	CTRL_RESERVED9 = 	offsetof(struct ctrl_reg, reserved9),
-	CTRL_RESERVED10 =	offsetof(struct ctrl_reg, reserved10),
-	CTRL_RESERVED11 =	offsetof(struct ctrl_reg, reserved11),
-	SLOT_SERR =		offsetof(struct ctrl_reg, slot_SERR),
-	SLOT_POWER =		offsetof(struct ctrl_reg, slot_power),
-	NEXT_CURR_FREQ =	offsetof(struct ctrl_reg, next_curr_freq),
-	RESET_FREQ_MODE =	offsetof(struct ctrl_reg, reset_freq_mode),
-};
-
-struct hrt {
-	char sig0;
-	char sig1;
-	char sig2;
-	char sig3;
-	u16 unused_IRQ;
-	u16 PCIIRQ;
-	u8 number_of_entries;
-	u8 revision;
-	u16 reserved1;
-	u32 reserved2;
-} __attribute__ ((packed));
-
-/* offsets to the hotplug resource table registers based on the above structure layout */
-enum hrt_offsets {
-	SIG0 =			offsetof(struct hrt, sig0),
-	SIG1 =			offsetof(struct hrt, sig1),
-	SIG2 =			offsetof(struct hrt, sig2),
-	SIG3 =			offsetof(struct hrt, sig3),
-	UNUSED_IRQ =		offsetof(struct hrt, unused_IRQ),
-	PCIIRQ =		offsetof(struct hrt, PCIIRQ),
-	NUMBER_OF_ENTRIES =	offsetof(struct hrt, number_of_entries),
-	REVISION =		offsetof(struct hrt, revision),
-	HRT_RESERVED1 =		offsetof(struct hrt, reserved1),
-	HRT_RESERVED2 =		offsetof(struct hrt, reserved2),
-};
-
-struct slot_rt {
-	u8 dev_func;
-	u8 primary_bus;
-	u8 secondary_bus;
-	u8 max_bus;
-	u16 io_base;
-	u16 io_length;
-	u16 mem_base;
-	u16 mem_length;
-	u16 pre_mem_base;
-	u16 pre_mem_length;
-} __attribute__ ((packed));
-
-/* offsets to the hotplug slot resource table registers based on the above structure layout */
-enum slot_rt_offsets {
-	DEV_FUNC =		offsetof(struct slot_rt, dev_func),
-	PRIMARY_BUS = 		offsetof(struct slot_rt, primary_bus),
-	SECONDARY_BUS = 	offsetof(struct slot_rt, secondary_bus),
-	MAX_BUS = 		offsetof(struct slot_rt, max_bus),
-	IO_BASE = 		offsetof(struct slot_rt, io_base),
-	IO_LENGTH = 		offsetof(struct slot_rt, io_length),
-	MEM_BASE = 		offsetof(struct slot_rt, mem_base),
-	MEM_LENGTH = 		offsetof(struct slot_rt, mem_length),
-	PRE_MEM_BASE = 		offsetof(struct slot_rt, pre_mem_base),
-	PRE_MEM_LENGTH = 	offsetof(struct slot_rt, pre_mem_length),
-};
-
-struct pci_func {
-	struct pci_func *next;
-	u8 bus;
-	u8 device;
-	u8 function;
-	u8 is_a_board;
-	u16 status;
-	u8 configured;
-	u8 switch_save;
-	u8 presence_save;
-	u32 base_length[0x06];
-	u8 base_type[0x06];
-	u16 reserved2;
-	u32 config_space[0x20];
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
-	struct timer_list *p_task_event;
-	struct pci_dev* pci_dev;
-};
-
-#define SLOT_MAGIC	0x67267321
-struct slot {
-	u32 magic;
-	struct slot *next;
-	u8 bus;
-	u8 device;
-	u8 number;
-	u8 is_a_board;
-	u8 configured;
-	u8 state;
-	u8 switch_save;
-	u8 presence_save;
-	u32 capabilities;
-	u16 reserved2;
-	struct timer_list task_event;
-	u8 hp_slot;
-	struct controller *ctrl;
-	void *p_sm_slot;
-	struct hotplug_slot *hotplug_slot;
-};
-
-struct pci_resource {
-	struct pci_resource * next;
-	u32 base;
-	u32 length;
-};
-
-struct event_info {
-	u32 event_type;
-	u8 hp_slot;
-};
-
-struct controller {
-	struct controller *next;
-	u32 ctrl_int_comp;
-	struct semaphore crit_sect;	/* critical section semaphore */
-	void *hpc_reg;			/* cookie for our pci controller location */
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
-	struct pci_dev *pci_dev;
-	struct pci_bus *pci_bus;
-	struct event_info event_queue[10];
-	struct slot *slot;
-	u8 next_event;
-	u8 interrupt;
-	u8 cfgspc_irq;
-	u8 bus;				/* bus number for the pci hotplug controller */
-	u8 rev;
-	u8 slot_device_offset;
-	u8 first_slot;
-	u8 add_support;
-	u8 push_flag;
-	enum pci_bus_speed speed;
-	enum pci_bus_speed speed_capability;
-	u8 push_button;			/* 0 = no pushbutton, 1 = pushbutton present */
-	u8 slot_switch_type;		/* 0 = no switch, 1 = switch present */
-	u8 defeature_PHP;		/* 0 = PHP not supported, 1 = PHP supported */
-	u8 alternate_base_address;	/* 0 = not supported, 1 = supported */
-	u8 pci_config_space;		/* Index/data access to working registers 0 = not supported, 1 = supported */
-	u8 pcix_speed_capability;	/* PCI-X */
-	u8 pcix_support;		/* PCI-X */
-	u16 vendor_id;
-	struct work_struct int_task_event;
-	wait_queue_head_t queue;	/* sleep & wake process */
-};
-
-struct irq_mapping {
-	u8 barber_pole;
-	u8 valid_INT;
-	u8 interrupt[4];
-};
-
-struct resource_lists {
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
-	struct irq_mapping *irqs;
-};
-
-#define ROM_PHY_ADDR			0x0F0000
-#define ROM_PHY_LEN			0x00ffff
-
-#define PCI_HPC_ID			0xA0F7
-#define PCI_SUB_HPC_ID			0xA2F7
-#define PCI_SUB_HPC_ID2			0xA2F8
-#define PCI_SUB_HPC_ID3			0xA2F9
-#define PCI_SUB_HPC_ID_INTC		0xA2FA
-#define PCI_SUB_HPC_ID4			0xA2FD
-
-#define INT_BUTTON_IGNORE		0
-#define INT_PRESENCE_ON			1
-#define INT_PRESENCE_OFF		2
-#define INT_SWITCH_CLOSE		3
-#define INT_SWITCH_OPEN			4
-#define INT_POWER_FAULT			5
-#define INT_POWER_FAULT_CLEAR		6
-#define INT_BUTTON_PRESS		7
-#define INT_BUTTON_RELEASE		8
-#define INT_BUTTON_CANCEL		9
-
-#define STATIC_STATE			0
-#define BLINKINGON_STATE		1
-#define BLINKINGOFF_STATE		2
-#define POWERON_STATE			3
-#define POWEROFF_STATE			4
-
-#define PCISLOT_INTERLOCK_CLOSED	0x00000001
-#define PCISLOT_ADAPTER_PRESENT		0x00000002
-#define PCISLOT_POWERED			0x00000004
-#define PCISLOT_66_MHZ_OPERATION	0x00000008
-#define PCISLOT_64_BIT_OPERATION	0x00000010
-#define PCISLOT_REPLACE_SUPPORTED	0x00000020
-#define PCISLOT_ADD_SUPPORTED		0x00000040
-#define PCISLOT_INTERLOCK_SUPPORTED	0x00000080
-#define PCISLOT_66_MHZ_SUPPORTED	0x00000100
-#define PCISLOT_64_BIT_SUPPORTED	0x00000200
-
-
-
-#define PCI_TO_PCI_BRIDGE_CLASS		0x00060400
-
-
-#define INTERLOCK_OPEN			0x00000002
-#define ADD_NOT_SUPPORTED		0x00000003
-#define CARD_FUNCTIONING		0x00000005
-#define ADAPTER_NOT_SAME		0x00000006
-#define NO_ADAPTER_PRESENT		0x00000009
-#define NOT_ENOUGH_RESOURCES		0x0000000B
-#define DEVICE_TYPE_NOT_SUPPORTED	0x0000000C
-#define POWER_FAILURE			0x0000000E
-
-#define REMOVE_NOT_SUPPORTED		0x00000003
-
-
-/*
- * error Messages
- */
-#define msg_initialization_err	"Initialization failure, error=%d\n"
-#define msg_HPC_rev_error	"Unsupported revision of the PCI hot plug controller found.\n"
-#define msg_HPC_non_compaq_or_intel	"The PCI hot plug controller is not supported by this driver.\n"
-#define msg_HPC_not_supported	"this system is not supported by this version of cpqphpd. Upgrade to a newer version of cpqphpd\n"
-#define msg_unable_to_save	"unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
-#define msg_button_on		"PCI slot #%d - powering on due to button press.\n"
-#define msg_button_off		"PCI slot #%d - powering off due to button press.\n"
-#define msg_button_cancel	"PCI slot #%d - action canceled due to button press.\n"
-#define msg_button_ignore	"PCI slot #%d - button press ignored.  (action in progress...)\n"
-
-
-/* sysfs functions for the hotplug controller info */
-extern void cpqhp_create_ctrl_files		(struct controller *ctrl);
-
-/* controller functions */
-extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
-extern irqreturn_t cpqhp_ctrl_intr		(int IRQ, void *data, struct pt_regs *regs);
-extern int	cpqhp_find_available_resources	(struct controller *ctrl, void *rom_start);
-extern int	cpqhp_event_start_thread	(void);
-extern void	cpqhp_event_stop_thread		(void);
-extern struct pci_func *cpqhp_slot_create	(unsigned char busnumber);
-extern struct pci_func *cpqhp_slot_find		(unsigned char bus, unsigned char device, unsigned char index);
-extern int	cpqhp_process_SI		(struct controller *ctrl, struct pci_func *func);
-extern int	cpqhp_process_SS		(struct controller *ctrl, struct pci_func *func);
-extern int	cpqhp_hardware_test		(struct controller *ctrl, int test_num);
-
-/* resource functions */
-extern int	cpqhp_resource_sort_and_combine	(struct pci_resource **head);
-
-/* pci functions */
-extern int	cpqhp_set_irq			(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
-extern int	cpqhp_get_bus_dev		(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot);
-extern int	cpqhp_save_config		(struct controller *ctrl, int busnumber, int is_hot_plug);
-extern int	cpqhp_save_base_addr_length	(struct controller *ctrl, struct pci_func * func);
-extern int	cpqhp_save_used_resources	(struct controller *ctrl, struct pci_func * func);
-extern int	cpqhp_configure_board		(struct controller *ctrl, struct pci_func * func);
-extern int	cpqhp_save_slot_config		(struct controller *ctrl, struct pci_func * new_slot);
-extern int	cpqhp_valid_replace		(struct controller *ctrl, struct pci_func * func);
-extern void	cpqhp_destroy_board_resources	(struct pci_func * func);
-extern int	cpqhp_return_board_resources	(struct pci_func * func, struct resource_lists * resources);
-extern void	cpqhp_destroy_resource_list	(struct resource_lists * resources);
-extern int	cpqhp_configure_device		(struct controller* ctrl, struct pci_func* func);
-extern int	cpqhp_unconfigure_device	(struct pci_func* func);
-extern struct slot *cpqhp_find_slot		(struct controller *ctrl, u8 device);
-
-/* Global variables */
-extern int cpqhp_debug;
-extern struct controller *cpqhp_ctrl_list;
-extern struct pci_func *cpqhp_slot_list[256];
-
-/* these can be gotten rid of, but for debugging they are purty */
-extern u8 cpqhp_nic_irq;
-extern u8 cpqhp_disk_irq;
-
-
-
-/* inline functions */
-
-
-/* Inline functions to check the sanity of a pointer that is passed to us */
-static inline int slot_paranoia_check (struct slot *slot, const char *function)
-{
-	if (!slot) {
-		dbg("%s - slot == NULL", function);
-		return -1;
-	}
-	if (slot->magic != SLOT_MAGIC) {
-		dbg("%s - bad magic number for slot", function);
-		return -1;
-	}
-	if (!slot->hotplug_slot) {
-		dbg("%s - slot->hotplug_slot == NULL!", function);
-		return -1;
-	}
-	return 0;
-}
-
-static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
-{ 
-	struct slot *slot;
-
-	if (!hotplug_slot) {
-		dbg("%s - hotplug_slot == NULL\n", function);
-		return NULL;
-	}
-
-	slot = (struct slot *)hotplug_slot->private;
-	if (slot_paranoia_check (slot, function))
-                return NULL;
-	return slot;
-}               
-
-/*
- * return_resource
- *
- * Puts node back in the resource list pointed to by head
- *
- */
-static inline void return_resource (struct pci_resource **head, struct pci_resource *node)
-{
-	if (!node || !head)
-		return;
-	node->next = *head;
-	*head = node;
-}
-
-static inline void set_SOGO (struct controller *ctrl)
-{
-	u16 misc;
-	
-	misc = readw(ctrl->hpc_reg + MISC);
-	misc = (misc | 0x0001) & 0xFFFB;
-	writew(misc, ctrl->hpc_reg + MISC);
-}
-
-
-static inline void amber_LED_on (struct controller *ctrl, u8 slot)
-{
-	u32 led_control;
-	
-	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
-	led_control |= (0x01010000L << slot);
-	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
-}
-
-
-static inline void amber_LED_off (struct controller *ctrl, u8 slot)
-{
-	u32 led_control;
-	
-	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
-	led_control &= ~(0x01010000L << slot);
-	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
-}
-
-
-static inline int read_amber_LED (struct controller *ctrl, u8 slot)
-{
-	u32 led_control;
-
-	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
-	led_control &= (0x01010000L << slot);
-	
-	return led_control ? 1 : 0;
-}
-
-
-static inline void green_LED_on (struct controller *ctrl, u8 slot)
-{
-	u32 led_control;
-	
-	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
-	led_control |= 0x0101L << slot;
-	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
-}
-
-static inline void green_LED_off (struct controller *ctrl, u8 slot)
-{
-	u32 led_control;
-	
-	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
-	led_control &= ~(0x0101L << slot);
-	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
-}
-
-
-static inline void green_LED_blink (struct controller *ctrl, u8 slot)
-{
-	u32 led_control;
-	
-	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
-	led_control &= ~(0x0101L << slot);
-	led_control |= (0x0001L << slot);
-	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
-}
-
-
-static inline void slot_disable (struct controller *ctrl, u8 slot)
-{
-	u8 slot_enable;
-
-	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
-	slot_enable &= ~(0x01 << slot);
-	writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
-}
-
-
-static inline void slot_enable (struct controller *ctrl, u8 slot)
-{
-	u8 slot_enable;
-
-	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
-	slot_enable |= (0x01 << slot);
-	writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
-}
-
-
-static inline u8 is_slot_enabled (struct controller *ctrl, u8 slot)
-{
-	u8 slot_enable;
-
-	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
-	slot_enable &= (0x01 << slot);
-	return slot_enable ? 1 : 0;
-}
-
-
-static inline u8 read_slot_enable (struct controller *ctrl)
-{
-	return readb(ctrl->hpc_reg + SLOT_ENABLE);
-}
-
-
-/*
- * get_controller_speed - find the current frequency/mode of controller.
- *
- * @ctrl: controller to get frequency/mode for.
- *
- * Returns controller speed.
- *
- */
-static inline u8 get_controller_speed (struct controller *ctrl)
-{
-	u8 curr_freq;
- 	u16 misc;
- 	
-	if (ctrl->pcix_support) {
-		curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
-		if ((curr_freq & 0xB0) == 0xB0) 
-			return PCI_SPEED_133MHz_PCIX;
-		if ((curr_freq & 0xA0) == 0xA0)
-			return PCI_SPEED_100MHz_PCIX;
-		if ((curr_freq & 0x90) == 0x90)
-			return PCI_SPEED_66MHz_PCIX;
-		if (curr_freq & 0x10)
-			return PCI_SPEED_66MHz;
-
-		return PCI_SPEED_33MHz;
-	}
-
- 	misc = readw(ctrl->hpc_reg + MISC);
- 	return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
-}
- 
-
-/*
- * get_adapter_speed - find the max supported frequency/mode of adapter.
- *
- * @ctrl: hotplug controller.
- * @hp_slot: hotplug slot where adapter is installed.
- *
- * Returns adapter speed.
- *
- */
-static inline u8 get_adapter_speed (struct controller *ctrl, u8 hp_slot)
-{
-	u32 temp_dword = readl(ctrl->hpc_reg + NON_INT_INPUT);
-	dbg("slot: %d, PCIXCAP: %8x\n", hp_slot, temp_dword);
-	if (ctrl->pcix_support) {
-		if (temp_dword & (0x10000 << hp_slot))
-			return PCI_SPEED_133MHz_PCIX;
-		if (temp_dword & (0x100 << hp_slot))
-			return PCI_SPEED_66MHz_PCIX;
-	}
-
-	if (temp_dword & (0x01 << hp_slot))
-		return PCI_SPEED_66MHz;
-
-	return PCI_SPEED_33MHz;
-}
-
-static inline void enable_slot_power (struct controller *ctrl, u8 slot)
-{
-	u8 slot_power;
-
-	slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
-	slot_power |= (0x01 << slot);
-	writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
-}
-
-static inline void disable_slot_power (struct controller *ctrl, u8 slot)
-{
-	u8 slot_power;
-
-	slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
-	slot_power &= ~(0x01 << slot);
-	writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
-}
-
-
-static inline int cpq_get_attention_status (struct controller *ctrl, struct slot *slot)
-{
-	u8 hp_slot;
-
-	if (slot == NULL)
-		return 1;
-
-	hp_slot = slot->device - ctrl->slot_device_offset;
-
-	return read_amber_LED (ctrl, hp_slot);
-}
-
-
-static inline int get_slot_enabled (struct controller *ctrl, struct slot *slot)
-{
-	u8 hp_slot;
-
-	if (slot == NULL)
-		return 1;
-
-	hp_slot = slot->device - ctrl->slot_device_offset;
-
-	return is_slot_enabled (ctrl, hp_slot);
-}
-
-
-static inline int cpq_get_latch_status (struct controller *ctrl, struct slot *slot)
-{
-	u32 status;
-	u8 hp_slot;
-
-	if (slot == NULL)
-		return 1;
-
-	hp_slot = slot->device - ctrl->slot_device_offset;
-	dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n",
-	    __FUNCTION__, slot->device, ctrl->slot_device_offset);
-
-	status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
-
-	return(status == 0) ? 1 : 0;
-}
-
-
-static inline int get_presence_status (struct controller *ctrl, struct slot *slot)
-{
-	int presence_save = 0;
-	u8 hp_slot;
-	u32 tempdword;
-
-	if (slot == NULL)
-		return 0;
-
-	hp_slot = slot->device - ctrl->slot_device_offset;
-
-	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-	presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> hp_slot) & 0x02;
-
-	return presence_save;
-}
-
-#define SLOT_NAME_SIZE 10
-
-static inline void make_slot_name (char *buffer, int buffer_size, struct slot *slot)
-{
-	snprintf (buffer, buffer_size, "%d", slot->number);
-}
-
-
-static inline int wait_for_ctrl_irq (struct controller *ctrl)
-{
-        DECLARE_WAITQUEUE(wait, current);
-	int retval = 0;
-
-	dbg("%s - start\n", __FUNCTION__);
-	add_wait_queue(&ctrl->queue, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	/* Sleep for up to 1 second to wait for the LED to change. */
-	schedule_timeout(1*HZ);
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&ctrl->queue, &wait);
-	if (signal_pending(current))
-		retval =  -EINTR;
-
-	dbg("%s - end\n", __FUNCTION__);
-	return retval;
-}
-
-
-/**
- * set_controller_speed - set the frequency and/or mode of a specific
- * controller segment.
- *
- * @ctrl: controller to change frequency/mode for.
- * @adapter_speed: the speed of the adapter we want to match.
- * @hp_slot: the slot number where the adapter is installed.
- *
- * Returns 0 if we successfully change frequency and/or mode to match the
- * adapter speed.
- * 
- */
-static inline u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)
-{
-	struct slot *slot;
-	u8 reg;
-	u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
-	u16 reg16;
-	u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
-	
-	if (ctrl->speed == adapter_speed)
-		return 0;
-	
-	/* We don't allow freq/mode changes if we find another adapter running
-	 * in another slot on this controller */
-	for(slot = ctrl->slot; slot; slot = slot->next) {
-		if (slot->device == (hp_slot + ctrl->slot_device_offset)) 
-			continue;
-		if (!slot->hotplug_slot && !slot->hotplug_slot->info) 
-			continue;
-		if (slot->hotplug_slot->info->adapter_status == 0) 
-			continue;
-		/* If another adapter is running on the same segment but at a
-		 * lower speed/mode, we allow the new adapter to function at
-		 * this rate if supported */
-		if (ctrl->speed < adapter_speed) 
-			return 0;
-
-		return 1;
-	}
-	
-	/* If the controller doesn't support freq/mode changes and the
-	 * controller is running at a higher mode, we bail */
-	if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
-		return 1;
-	
-	/* But we allow the adapter to run at a lower rate if possible */
-	if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
-		return 0;
-
-	/* We try to set the max speed supported by both the adapter and
-	 * controller */
-	if (ctrl->speed_capability < adapter_speed) {
-		if (ctrl->speed == ctrl->speed_capability)
-			return 0;
-		adapter_speed = ctrl->speed_capability;
-	}
-
-	writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
-	writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);
-	
-	set_SOGO(ctrl); 
-	wait_for_ctrl_irq(ctrl);
-	
-	if (adapter_speed != PCI_SPEED_133MHz_PCIX)
-		reg = 0xF5;
-	else
-		reg = 0xF4;	
-	pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
-	
-	reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);
-	reg16 &= ~0x000F;
-	switch(adapter_speed) {
-		case(PCI_SPEED_133MHz_PCIX): 
-			reg = 0x75;
-			reg16 |= 0xB; 
-			break;
-		case(PCI_SPEED_100MHz_PCIX):
-			reg = 0x74;
-			reg16 |= 0xA;
-			break;
-		case(PCI_SPEED_66MHz_PCIX):
-			reg = 0x73;
-			reg16 |= 0x9;
-			break;
-		case(PCI_SPEED_66MHz):
-			reg = 0x73;
-			reg16 |= 0x1;
-			break;
-		default: /* 33MHz PCI 2.2 */
-			reg = 0x71;
-			break;
-			
-	}
-	reg16 |= 0xB << 12;
-	writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);
-	
-	mdelay(5); 
-	
-	/* Reenable interrupts */
-	writel(0, ctrl->hpc_reg + INT_MASK);
-
-	pci_write_config_byte(ctrl->pci_dev, 0x41, reg); 
-	
-	/* Restart state machine */
-	reg = ~0xF;
-	pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);
-	pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
-	
-	/* Only if mode change...*/
-	if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
-		((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) 
-			set_SOGO(ctrl);
-	
-	wait_for_ctrl_irq(ctrl);
-	mdelay(1100);
-	
-	/* Restore LED/Slot state */
-	writel(leds, ctrl->hpc_reg + LED_CONTROL);
-	writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);
-	
-	set_SOGO(ctrl);
-	wait_for_ctrl_irq(ctrl);
-
-	ctrl->speed = adapter_speed;
-	slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
-
-	info("Successfully changed frequency/mode for adapter in slot %d\n", 
-			slot->number);
-	return 0;
-}
-
-#endif
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpqphp_core.c linux-2.5.70-bk10/drivers/hotplug/cpqphp_core.c
--- linux-2.5.70-bk9/drivers/hotplug/cpqphp_core.c	2003-05-26 18:00:19.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpqphp_core.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1541 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- * Jan 12, 2003 -	Added 66/100/133MHz PCI-X support,
- * 			Torben Mathiasen <torben.mathiasen@hp.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/uaccess.h>
-
-#include "cpqphp.h"
-#include "cpqphp_nvram.h"
-#include "../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
-
-
-/* Global variables */
-int cpqhp_debug;
-struct controller *cpqhp_ctrl_list;	/* = NULL */
-struct pci_func *cpqhp_slot_list[256];
-
-/* local variables */
-static void *smbios_table;
-static void *smbios_start;
-static void *cpqhp_rom_start;
-static u8 power_mode;
-static int debug;
-
-#define DRIVER_VERSION	"0.9.7"
-#define DRIVER_AUTHOR	"Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
-#define DRIVER_DESC	"Compaq Hot Plug PCI Controller Driver"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(power_mode, "b");
-MODULE_PARM_DESC(power_mode, "Power mode enabled or not");
-
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-
-#define CPQHPC_MODULE_MINOR 208
-
-static int one_time_init (void);
-static int set_attention_status (struct hotplug_slot *slot, u8 value);
-static int process_SI		(struct hotplug_slot *slot);
-static int process_SS		(struct hotplug_slot *slot);
-static int hardware_test	(struct hotplug_slot *slot, u32 value);
-static int get_power_status	(struct hotplug_slot *slot, u8 *value);
-static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
-static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
-static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
-static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
-static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
-
-static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
-	.owner =		THIS_MODULE,
-	.set_attention_status =	set_attention_status,
-	.enable_slot =		process_SI,
-	.disable_slot =		process_SS,
-	.hardware_test =	hardware_test,
-	.get_power_status =	get_power_status,
-	.get_attention_status =	get_attention_status,
-	.get_latch_status =	get_latch_status,
-	.get_adapter_status =	get_adapter_status,
-  	.get_max_bus_speed =	get_max_bus_speed,
-  	.get_cur_bus_speed =	get_cur_bus_speed,
-};
-
-
-static inline int is_slot64bit (struct slot *slot)
-{
-	if (!slot || !slot->p_sm_slot)
-		return 0;
-
-	if (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06)
-		return 1;
-
-	return 0;
-}
-
-static inline int is_slot66mhz (struct slot *slot)
-{
-	if (!slot || !slot->p_sm_slot)
-		return 0;
-
-	if (readb(slot->p_sm_slot + SMBIOS_SLOT_TYPE) == 0x0E)
-		return 1;
-
-	return 0;
-}
-
-/**
- * detect_SMBIOS_pointer - find the system Management BIOS Table in the specified region of memory.
- *
- * @begin: begin pointer for region to be scanned.
- * @end: end pointer for region to be scanned.
- *
- * Returns pointer to the head of the SMBIOS tables (or NULL)
- *
- */
-static void * detect_SMBIOS_pointer(void *begin, void *end)
-{
-	void *fp;
-	void *endp;
-	u8 temp1, temp2, temp3, temp4;
-	int status = 0;
-
-	endp = (end - sizeof(u32) + 1);
-
-	for (fp = begin; fp <= endp; fp += 16) {
-		temp1 = readb(fp);
-		temp2 = readb(fp+1);
-		temp3 = readb(fp+2);
-		temp4 = readb(fp+3);
-		if (temp1 == '_' &&
-		    temp2 == 'S' &&
-		    temp3 == 'M' &&
-		    temp4 == '_') {
-			status = 1;
-			break;
-		}
-	}
-	
-	if (!status)
-		fp = NULL;
-
-	dbg("Discovered SMBIOS Entry point at %p\n", fp);
-
-	return fp;
-}
-
-/**
- * init_SERR - Initializes the per slot SERR generation.
- *
- * For unexpected switch opens
- *
- */
-static int init_SERR(struct controller * ctrl)
-{
-	u32 tempdword;
-	u32 number_of_slots;
-	u8 physical_slot;
-
-	if (!ctrl)
-		return 1;
-
-	tempdword = ctrl->first_slot;
-
-	number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
-	// Loop through slots
-	while (number_of_slots) {
-		physical_slot = tempdword;
-		writeb(0, ctrl->hpc_reg + SLOT_SERR);
-		tempdword++;
-		number_of_slots--;
-	}
-
-	return 0;
-}
-
-
-/* nice debugging output */
-static int pci_print_IRQ_route (void)
-{
-	struct irq_routing_table *routing_table;
-	int len;
-	int loop;
-
-	u8 tbus, tdevice, tslot;
-
-	routing_table = pcibios_get_irq_routing_table();
-	if (routing_table == NULL) {
-		err("No BIOS Routing Table??? Not good\n");
-		return -ENOMEM;
-	}
-
-	len = (routing_table->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
-	// Make sure I got at least one entry
-	if (len == 0) {
-		kfree(routing_table);
-		return -1;
-	}
-
-	dbg("bus dev func slot\n");
-
-	for (loop = 0; loop < len; ++loop) {
-		tbus = routing_table->slots[loop].bus;
-		tdevice = routing_table->slots[loop].devfn;
-		tslot = routing_table->slots[loop].slot;
-		dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
-
-	}
-	kfree(routing_table);
-	return 0;
-}
-
-
-/*
- * get_subsequent_smbios_entry
- *
- * Gets the first entry if previous == NULL
- * Otherwise, returns the next entry
- * Uses global SMBIOS Table pointer
- *
- * @curr: %NULL or pointer to previously returned structure
- *
- * returns a pointer to an SMBIOS structure or NULL if none found
- */
-static void * get_subsequent_smbios_entry(void *smbios_start, void *smbios_table, void *curr)
-{
-	u8 bail = 0;
-	u8 previous_byte = 1;
-	void *p_temp;
-	void *p_max;
-
-	if (!smbios_table || !curr)
-		return(NULL);
-
-	// set p_max to the end of the table
-	p_max = smbios_start + readw(smbios_table + ST_LENGTH);
-
-	p_temp = curr;
-	p_temp += readb(curr + SMBIOS_GENERIC_LENGTH);
-
-	while ((p_temp < p_max) && !bail) {
-		// Look for the double NULL terminator
-		// The first condition is the previous byte and the second is the curr
-		if (!previous_byte && !(readb(p_temp))) {
-			bail = 1;
-		}
-
-		previous_byte = readb(p_temp);
-		p_temp++;
-	}
-
-	if (p_temp < p_max) {
-		return p_temp;
-	} else {
-		return NULL;
-	}
-}
-
-
-/**
- * get_SMBIOS_entry
- *
- * @type:SMBIOS structure type to be returned
- * @previous: %NULL or pointer to previously returned structure
- *
- * Gets the first entry of the specified type if previous == NULL
- * Otherwise, returns the next entry of the given type.
- * Uses global SMBIOS Table pointer
- * Uses get_subsequent_smbios_entry
- *
- * returns a pointer to an SMBIOS structure or %NULL if none found
- */
-static void *get_SMBIOS_entry (void *smbios_start, void *smbios_table, u8 type, void * previous)
-{
-	if (!smbios_table)
-		return NULL;
-
-	if (!previous) {		  
-		previous = smbios_start;
-	} else {
-		previous = get_subsequent_smbios_entry(smbios_start, smbios_table, previous);
-	}
-
-	while (previous) {
-	       	if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
-			previous = get_subsequent_smbios_entry(smbios_start, smbios_table, previous);
-		} else {
-			break;
-		}
-	}
-
-	return previous;
-}
-
-
-static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void *smbios_table)
-{
-	struct slot *new_slot;
-	u8 number_of_slots;
-	u8 slot_device;
-	u8 slot_number;
-	u8 ctrl_slot;
-	u32 tempdword;
-	void *slot_entry= NULL;
-	int result;
-
-	dbg("%s\n", __FUNCTION__);
-
-	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-	number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
-	slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
-	slot_number = ctrl->first_slot;
-
-	while (number_of_slots) {
-		new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL);
-		if (!new_slot)
-			return -ENOMEM;
-
-		memset(new_slot, 0, sizeof(struct slot));
-		new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
-		if (!new_slot->hotplug_slot) {
-			kfree (new_slot);
-			return -ENOMEM;
-		}
-		memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
-
-		new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
-		if (!new_slot->hotplug_slot->info) {
-			kfree (new_slot->hotplug_slot);
-			kfree (new_slot);
-			return -ENOMEM;
-		}
-		memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
-		new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
-		if (!new_slot->hotplug_slot->name) {
-			kfree (new_slot->hotplug_slot->info);
-			kfree (new_slot->hotplug_slot);
-			kfree (new_slot);
-			return -ENOMEM;
-		}
-
-		new_slot->magic = SLOT_MAGIC;
-		new_slot->ctrl = ctrl;
-		new_slot->bus = ctrl->bus;
-		new_slot->device = slot_device;
-		new_slot->number = slot_number;
-		dbg("slot->number = %d\n",new_slot->number);
-
-		slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry);
-
-		while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) {
-			slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry);
-		}
-
-		new_slot->p_sm_slot = slot_entry;
-
-		init_timer(&new_slot->task_event);
-		new_slot->task_event.expires = jiffies + 5 * HZ;
-		new_slot->task_event.function = cpqhp_pushbutton_thread;
-
-		//FIXME: these capabilities aren't used but if they are
-		//       they need to be correctly implemented
-		new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
-		new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
-
-		if (is_slot64bit(new_slot))
-			new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
-		if (is_slot66mhz(new_slot))
-			new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
-		if (ctrl->speed == PCI_SPEED_66MHz)
-			new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
-
-		ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
-
-		// Check presence
-		new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
-		// Check the switch state
-		new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
-		// Check the slot enable
-		new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
-
-		/* register this slot with the hotplug pci core */
-		new_slot->hotplug_slot->private = new_slot;
-		make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
-		new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
-		
-		new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot);
-		new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot);
-		new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot);
-		new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot);
-		
-		dbg ("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n", 
-		     new_slot->bus, new_slot->device, new_slot->number, ctrl->slot_device_offset, slot_number);
-		result = pci_hp_register (new_slot->hotplug_slot);
-		if (result) {
-			err ("pci_hp_register failed with error %d\n", result);
-			kfree (new_slot->hotplug_slot->info);
-			kfree (new_slot->hotplug_slot->name);
-			kfree (new_slot->hotplug_slot);
-			kfree (new_slot);
-			return result;
-		}
-		
-		new_slot->next = ctrl->slot;
-		ctrl->slot = new_slot;
-
-		number_of_slots--;
-		slot_device++;
-		slot_number++;
-	}
-
-	return(0);
-}
-
-
-static int ctrl_slot_cleanup (struct controller * ctrl)
-{
-	struct slot *old_slot, *next_slot;
-
-	old_slot = ctrl->slot;
-	ctrl->slot = NULL;
-
-	while (old_slot) {
-		next_slot = old_slot->next;
-		pci_hp_deregister (old_slot->hotplug_slot);
-		kfree(old_slot->hotplug_slot->info);
-		kfree(old_slot->hotplug_slot->name);
-		kfree(old_slot->hotplug_slot);
-		kfree(old_slot);
-		old_slot = next_slot;
-	}
-
-	//Free IRQ associated with hot plug device
-	free_irq(ctrl->interrupt, ctrl);
-	//Unmap the memory
-	iounmap(ctrl->hpc_reg);
-	//Finally reclaim PCI mem
-	release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
-			   pci_resource_len(ctrl->pci_dev, 0));
-
-	return(0);
-}
-
-
-//============================================================================
-// function:	get_slot_mapping
-//
-// Description: Attempts to determine a logical slot mapping for a PCI
-//		device.  Won't work for more than one PCI-PCI bridge
-//		in a slot.
-//
-// Input:	u8 bus_num - bus number of PCI device
-//		u8 dev_num - device number of PCI device
-//		u8 *slot - Pointer to u8 where slot number will
-//			be returned
-//
-// Output:	SUCCESS or FAILURE
-//=============================================================================
-static int get_slot_mapping (struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
-{
-	struct irq_routing_table *PCIIRQRoutingInfoLength;
-	u32 work;
-	long len;
-	long loop;
-
-	u8 tbus, tdevice, tslot, bridgeSlot;
-
-	dbg("%s: %p, %d, %d, %p\n", __FUNCTION__, bus, bus_num, dev_num, slot);
-
-	bridgeSlot = 0xFF;
-
-	PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
-	if (!PCIIRQRoutingInfoLength)
-		return -1;
-
-	len = (PCIIRQRoutingInfoLength->size -
-	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
-	// Make sure I got at least one entry
-	if (len == 0) {
-		if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
-		return -1;
-	}
-
-	for (loop = 0; loop < len; ++loop) {
-		tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
-		tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
-		tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
-
-		if ((tbus == bus_num) && (tdevice == dev_num)) {
-			*slot = tslot;
-
-			if (PCIIRQRoutingInfoLength != NULL)
-				kfree(PCIIRQRoutingInfoLength);
-			return 0;
-		} else {
-			// Didn't get a match on the target PCI device. Check if the
-			// current IRQ table entry is a PCI-to-PCI bridge device.  If so,
-			// and it's secondary bus matches the bus number for the target 
-			// device, I need to save the bridge's slot number.  If I can't 
-			// find an entry for the target device, I will have to assume it's 
-			// on the other side of the bridge, and assign it the bridge's slot.
-			bus->number = tbus;
-			pci_bus_read_config_dword (bus, PCI_DEVFN(tdevice, 0), PCI_REVISION_ID, &work);
-
-			if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
-				pci_bus_read_config_dword (bus, PCI_DEVFN(tdevice, 0), PCI_PRIMARY_BUS, &work);
-				// See if bridge's secondary bus matches target bus.
-				if (((work >> 8) & 0x000000FF) == (long) bus_num) {
-					bridgeSlot = tslot;
-				}
-			}
-		}
-
-	}
-
-	// If we got here, we didn't find an entry in the IRQ mapping table 
-	// for the target PCI device.  If we did determine that the target 
-	// device is on the other side of a PCI-to-PCI bridge, return the 
-	// slot number for the bridge.
-	if (bridgeSlot != 0xFF) {
-		*slot = bridgeSlot;
-		if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
-		return 0;
-	}
-	if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
-	// Couldn't find an entry in the routing table for this PCI device
-	return -1;
-}
-
-
-/**
- * cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
- *
- */
-static int cpqhp_set_attention_status (struct controller *ctrl, struct pci_func *func, u32 status)
-{
-	u8 hp_slot;
-
-	hp_slot = func->device - ctrl->slot_device_offset;
-
-	if (func == NULL)
-		return(1);
-
-	// Wait for exclusive access to hardware
-	down(&ctrl->crit_sect);
-
-	if (status == 1) {
-		amber_LED_on (ctrl, hp_slot);
-	} else if (status == 0) {
-		amber_LED_off (ctrl, hp_slot);
-	} else {
-		// Done with exclusive hardware access
-		up(&ctrl->crit_sect);
-		return(1);
-	}
-
-	set_SOGO(ctrl);
-
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
-
-	// Done with exclusive hardware access
-	up(&ctrl->crit_sect);
-
-	return(0);
-}
-
-
-/**
- * set_attention_status - Turns the Amber LED for a slot on or off
- *
- */
-static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
-{
-	struct pci_func *slot_func;
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	u8 bus;
-	u8 devfn;
-	u8 device;
-	u8 function;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
-		return -ENODEV;
-
-	device = devfn >> 3;
-	function = devfn & 0x7;
-	dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
-
-	slot_func = cpqhp_slot_find(bus, device, function);
-	if (!slot_func) {
-		return -ENODEV;
-	}
-
-	return cpqhp_set_attention_status(ctrl, slot_func, status);
-}
-
-
-static int process_SI (struct hotplug_slot *hotplug_slot)
-{
-	struct pci_func *slot_func;
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	u8 bus;
-	u8 devfn;
-	u8 device;
-	u8 function;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
-		return -ENODEV;
-
-	device = devfn >> 3;
-	function = devfn & 0x7;
-	dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
-
-	slot_func = cpqhp_slot_find(bus, device, function);
-	if (!slot_func) {
-		return -ENODEV;
-	}
-
-	slot_func->bus = bus;
-	slot_func->device = device;
-	slot_func->function = function;
-	slot_func->configured = 0;
-	dbg("board_added(%p, %p)\n", slot_func, ctrl);
-	return cpqhp_process_SI(ctrl, slot_func);
-}
-
-
-static int process_SS (struct hotplug_slot *hotplug_slot)
-{
-	struct pci_func *slot_func;
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	u8 bus;
-	u8 devfn;
-	u8 device;
-	u8 function;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
-		return -ENODEV;
-
-	device = devfn >> 3;
-	function = devfn & 0x7;
-	dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
-
-	slot_func = cpqhp_slot_find(bus, device, function);
-	if (!slot_func) {
-		return -ENODEV;
-	}
-	
-	dbg("In power_down_board, slot_func = %p, ctrl = %p\n", slot_func, ctrl);
-	return cpqhp_process_SS(ctrl, slot_func);
-}
-
-
-static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-
-	return cpqhp_hardware_test (ctrl, value);	
-}
-
-
-static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	*value = get_slot_enabled(ctrl, slot);
-	return 0;
-}
-
-static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	*value = cpq_get_attention_status(ctrl, slot);
-	return 0;
-}
-
-static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	*value = cpq_get_latch_status (ctrl, slot);
-
-	return 0;
-}
-
-static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	*value = get_presence_status (ctrl, slot);
-
-	return 0;
-}
-
-static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	*value = ctrl->speed_capability;
-
-	return 0;
-}
-
-static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	struct controller *ctrl;
-	
-	if (slot == NULL)
-		return -ENODEV;
-
-	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	ctrl = slot->ctrl;
-	if (ctrl == NULL)
-		return -ENODEV;
-	
-	*value = ctrl->speed;
-
-	return 0;
-}
-
-static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	u8 num_of_slots = 0;
-	u8 hp_slot = 0;
-	u8 device;
-	u8 rev;
-	u8 bus_cap;
-	u16 temp_word;
-	u16 vendor_id;
-	u16 subsystem_vid;
-	u16 subsystem_deviceid;
-	u32 rc;
-	struct controller *ctrl;
-	struct pci_func *func;
-
-	// Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
-	rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
-	if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
-		err(msg_HPC_non_compaq_or_intel);
-		return -ENODEV;
-	}
-	dbg("Vendor ID: %x\n", vendor_id);
-
-	rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-	dbg("revision: %d\n", rev);
-	if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
-		err(msg_HPC_rev_error);
-		return -ENODEV;
-	}
-
-	/* Check for the proper subsytem ID's
-	 * Intel uses a different SSID programming model than Compaq.  
-	 * For Intel, each SSID bit identifies a PHP capability.
-	 * Also Intel HPC's may have RID=0.
-	 */
-	if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
-		// TODO: This code can be made to support non-Compaq or Intel subsystem IDs
-		rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
-		if (rc) {
-			err("%s : pci_read_config_word failed\n", __FUNCTION__);
-			return rc;
-		}
-		dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
-		if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
-			err(msg_HPC_non_compaq_or_intel);
-			return -ENODEV;
-		}
-
-		ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
-		if (!ctrl) {
-			err("%s : out of memory\n", __FUNCTION__);
-			return -ENOMEM;
-		}
-		memset(ctrl, 0, sizeof(struct controller));
-
-		rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
-		if (rc) {
-			err("%s : pci_read_config_word failed\n", __FUNCTION__);
-			goto err_free_ctrl;
-		}
-
-		info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
-
-		/* Set Vendor ID, so it can be accessed later from other functions */
-		ctrl->vendor_id = vendor_id;
-
-		switch (subsystem_vid) {
-			case PCI_VENDOR_ID_COMPAQ:
-				if (rev >= 0x13) { /* CIOBX */
-					ctrl->push_flag = 1;
-					ctrl->slot_switch_type = 1;		// Switch is present
-					ctrl->push_button = 1;			// Pushbutton is present
-					ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
-					ctrl->defeature_PHP = 1;		// PHP is supported
-					ctrl->pcix_support = 1;			// PCI-X supported
-					ctrl->pcix_speed_capability = 1;
-					pci_read_config_byte(pdev, 0x41, &bus_cap);
-					if (bus_cap & 0x80) {
-						dbg("bus max supports 133MHz PCI-X\n");
-						ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
-						break;
-					}
-					if (bus_cap & 0x40) {
-						dbg("bus max supports 100MHz PCI-X\n");
-						ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
-						break;
-					}
-					if (bus_cap & 20) {
-						dbg("bus max supports 66MHz PCI-X\n");
-						ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
-						break;
-					}
-					if (bus_cap & 10) {
-						dbg("bus max supports 66MHz PCI\n");
-						ctrl->speed_capability = PCI_SPEED_66MHz;
-						break;
-					}
-
-					break;
-				}
-
-				switch (subsystem_deviceid) {
-					case PCI_SUB_HPC_ID:
-						/* Original 6500/7000 implementation */
-						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = PCI_SPEED_33MHz;
-						ctrl->push_button = 0;			// No pushbutton
-						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
-						ctrl->defeature_PHP = 1;		// PHP is supported
-						ctrl->pcix_support = 0;			// PCI-X not supported
-						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
-						break;
-					case PCI_SUB_HPC_ID2:
-						/* First Pushbutton implementation */
-						ctrl->push_flag = 1;
-						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = PCI_SPEED_33MHz;
-						ctrl->push_button = 1;			// Pushbutton is present
-						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
-						ctrl->defeature_PHP = 1;		// PHP is supported
-						ctrl->pcix_support = 0;			// PCI-X not supported
-						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
-						break;
-					case PCI_SUB_HPC_ID_INTC:
-						/* Third party (6500/7000) */
-						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = PCI_SPEED_33MHz;
-						ctrl->push_button = 0;			// No pushbutton
-						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
-						ctrl->defeature_PHP = 1;			// PHP is supported
-						ctrl->pcix_support = 0;			// PCI-X not supported
-						ctrl->pcix_speed_capability = 0;		// N/A since PCI-X not supported
-						break;
-					case PCI_SUB_HPC_ID3:
-						/* First 66 Mhz implementation */
-						ctrl->push_flag = 1;
-						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = PCI_SPEED_66MHz;
-						ctrl->push_button = 1;			// Pushbutton is present
-						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
-						ctrl->defeature_PHP = 1;		// PHP is supported
-						ctrl->pcix_support = 0;			// PCI-X not supported
-						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
-						break;
-					case PCI_SUB_HPC_ID4:
-						/* First PCI-X implementation, 100MHz */
-						ctrl->push_flag = 1;
-						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
-						ctrl->push_button = 1;			// Pushbutton is present
-						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
-						ctrl->defeature_PHP = 1;		// PHP is supported
-						ctrl->pcix_support = 1;			// PCI-X supported
-						ctrl->pcix_speed_capability = 0;	
-						break;
-					default:
-						err(msg_HPC_not_supported);
-						rc = -ENODEV;
-						goto err_free_ctrl;
-				}
-				break;
-
-			case PCI_VENDOR_ID_INTEL:
-				/* Check for speed capability (0=33, 1=66) */
-				if (subsystem_deviceid & 0x0001) {
-					ctrl->speed_capability = PCI_SPEED_66MHz;
-				} else {
-					ctrl->speed_capability = PCI_SPEED_33MHz;
-				}
-
-				/* Check for push button */
-				if (subsystem_deviceid & 0x0002) {
-					/* no push button */
-					ctrl->push_button = 0;
-				} else {
-					/* push button supported */
-					ctrl->push_button = 1;
-				}
-
-				/* Check for slot switch type (0=mechanical, 1=not mechanical) */
-				if (subsystem_deviceid & 0x0004) {
-					/* no switch */
-					ctrl->slot_switch_type = 0;
-				} else {
-					/* switch */
-					ctrl->slot_switch_type = 1;
-				}
-
-				/* PHP Status (0=De-feature PHP, 1=Normal operation) */
-				if (subsystem_deviceid & 0x0008) {
-					ctrl->defeature_PHP = 1;	// PHP supported
-				} else {
-					ctrl->defeature_PHP = 0;	// PHP not supported
-				}
-
-				/* Alternate Base Address Register Interface (0=not supported, 1=supported) */
-				if (subsystem_deviceid & 0x0010) {
-					ctrl->alternate_base_address = 1;	// supported
-				} else {
-					ctrl->alternate_base_address = 0;	// not supported
-				}
-
-				/* PCI Config Space Index (0=not supported, 1=supported) */
-				if (subsystem_deviceid & 0x0020) {
-					ctrl->pci_config_space = 1;		// supported
-				} else {
-					ctrl->pci_config_space = 0;		// not supported
-				}
-
-				/* PCI-X support */
-				if (subsystem_deviceid & 0x0080) {
-					/* PCI-X capable */
-					ctrl->pcix_support = 1;
-					/* Frequency of operation in PCI-X mode */
-					if (subsystem_deviceid & 0x0040) {
-						/* 133MHz PCI-X if bit 7 is 1 */
-						ctrl->pcix_speed_capability = 1;
-					} else {
-						/* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
-						/* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
-						ctrl->pcix_speed_capability = 0;
-					}
-				} else {
-					/* Conventional PCI */
-					ctrl->pcix_support = 0;
-					ctrl->pcix_speed_capability = 0;
-				}
-				break;
-
-			default:
-				err(msg_HPC_not_supported);
-				rc = -ENODEV;
-				goto err_free_ctrl;
-		}
-
-	} else {
-		err(msg_HPC_not_supported);
-		return -ENODEV;
-	}
-
-	// Tell the user that we found one.
-	info("Initializing the PCI hot plug controller residing on PCI bus %d\n", pdev->bus->number);
-
-	dbg ("Hotplug controller capabilities:\n");
-	dbg ("    speed_capability       %d\n", ctrl->speed_capability);
-	dbg ("    slot_switch_type       %s\n", ctrl->slot_switch_type == 0 ? "no switch" : "switch present");
-	dbg ("    defeature_PHP          %s\n", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported");
-	dbg ("    alternate_base_address %s\n", ctrl->alternate_base_address == 0 ? "not supported" : "supported");
-	dbg ("    pci_config_space       %s\n", ctrl->pci_config_space == 0 ? "not supported" : "supported");
-	dbg ("    pcix_speed_capability  %s\n", ctrl->pcix_speed_capability == 0 ? "not supported" : "supported");
-	dbg ("    pcix_support           %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported");
-
-	ctrl->pci_dev = pdev;
-	pci_set_drvdata(pdev, ctrl);
-
-	/* make our own copy of the pci bus structure, as we like tweaking it a lot */
-	ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
-	if (!ctrl->pci_bus) {
-		err("out of memory\n");
-		rc = -ENOMEM;
-		goto err_free_ctrl;
-	}
-	memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
-
-	ctrl->bus = pdev->bus->number;
-	ctrl->rev = rev;
-	dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
-	     PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
-
-	init_MUTEX(&ctrl->crit_sect);
-	init_waitqueue_head(&ctrl->queue);
-
-	/* initialize our threads if they haven't already been started up */
-	rc = one_time_init();
-	if (rc) {
-		goto err_free_bus;
-	}
-	
-	dbg("pdev = %p\n", pdev);
-	dbg("pci resource start %lx\n", pci_resource_start(pdev, 0));
-	dbg("pci resource len %lx\n", pci_resource_len(pdev, 0));
-
-	if (!request_mem_region(pci_resource_start(pdev, 0),
-				pci_resource_len(pdev, 0), MY_NAME)) {
-		err("cannot reserve MMIO region\n");
-		rc = -ENOMEM;
-		goto err_free_bus;
-	}
-
-	ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-	if (!ctrl->hpc_reg) {
-		err("cannot remap MMIO region %lx @ %lx\n", pci_resource_len(pdev, 0), pci_resource_start(pdev, 0));
-		rc = -ENODEV;
-		goto err_free_mem_region;
-	}
-
-	// Check for 66Mhz operation
-	ctrl->speed = get_controller_speed(ctrl);
-
-
-	//**************************************************
-	//
-	//              Save configuration headers for this and
-	//              subordinate PCI buses
-	//
-	//**************************************************
-
-	// find the physical slot number of the first hot plug slot
-
-	// Get slot won't work for devices behind bridges, but
-	// in this case it will always be called for the "base"
-	// bus/dev/func of a slot.
-	// CS: this is leveraging the PCIIRQ routing code from the kernel (pci-pc.c: get_irq_routing_table)
-	rc = get_slot_mapping(ctrl->pci_bus, pdev->bus->number, (readb(ctrl->hpc_reg + SLOT_MASK) >> 4), &(ctrl->first_slot));
-	dbg("get_slot_mapping: first_slot = %d, returned = %d\n", ctrl->first_slot, rc);
-	if (rc) {
-		err(msg_initialization_err, rc);
-		goto err_iounmap;
-	}
-
-	// Store PCI Config Space for all devices on this bus
-	rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
-	if (rc) {
-		err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
-		goto err_iounmap;
-	}
-
-	/*
-	 * Get IO, memory, and IRQ resources for new devices
-	 */
-	// The next line is required for cpqhp_find_available_resources
-	ctrl->interrupt = pdev->irq;
-
-	ctrl->cfgspc_irq = 0;
-	pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ctrl->cfgspc_irq);
-
-	rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
-	ctrl->add_support = !rc;
-	if (rc) {
-		dbg("cpqhp_find_available_resources = 0x%x\n", rc);
-		err("unable to locate PCI configuration resources for hot plug add.\n");
-		goto err_iounmap;
-	}
-
-	/*
-	 * Finish setting up the hot plug ctrl device
-	 */
-	ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
-	dbg("NumSlots %d \n", ctrl->slot_device_offset);
-
-	ctrl->next_event = 0;
-
-	/* Setup the slot information structures */
-	rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
-	if (rc) {
-		err(msg_initialization_err, 6);
-		err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
-		goto err_iounmap;
-	}
-	
-	/* Mask all general input interrupts */
-	writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
-
-	/* set up the interrupt */
-	dbg("HPC interrupt = %d \n", ctrl->interrupt);
-	if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr,
-			SA_SHIRQ, MY_NAME, ctrl)) {
-		err("Can't get irq %d for the hotplug pci controller\n", ctrl->interrupt);
-		rc = -ENODEV;
-		goto err_iounmap;
-	}
-
-	/* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
-	temp_word = readw(ctrl->hpc_reg + MISC);
-	temp_word |= 0x4006;
-	writew(temp_word, ctrl->hpc_reg + MISC);
-
-	// Changed 05/05/97 to clear all interrupts at start
-	writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-	ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-	writel(0x0L, ctrl->hpc_reg + INT_MASK);
-
-	if (!cpqhp_ctrl_list) {
-		cpqhp_ctrl_list = ctrl;
-		ctrl->next = NULL;
-	} else {
-		ctrl->next = cpqhp_ctrl_list;
-		cpqhp_ctrl_list = ctrl;
-	}
-
-	// turn off empty slots here unless command line option "ON" set
-	// Wait for exclusive access to hardware
-	down(&ctrl->crit_sect);
-
-	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
-
-	// find first device number for the ctrl
-	device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
-
-	while (num_of_slots) {
-		dbg("num_of_slots: %d\n", num_of_slots);
-		func = cpqhp_slot_find(ctrl->bus, device, 0);
-		if (!func)
-			break;
-
-		hp_slot = func->device - ctrl->slot_device_offset;
-		dbg("hp_slot: %d\n", hp_slot);
-
-		// We have to save the presence info for these slots
-		temp_word = ctrl->ctrl_int_comp >> 16;
-		func->presence_save = (temp_word >> hp_slot) & 0x01;
-		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
-
-		if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
-			func->switch_save = 0;
-		} else {
-			func->switch_save = 0x10;
-		}
-
-		if (!power_mode) {
-			if (!func->is_a_board) {
-				green_LED_off (ctrl, hp_slot);
-				slot_disable (ctrl, hp_slot);
-			}
-		}
-
-		device++;
-		num_of_slots--;
-	}
-
-	if (!power_mode) {
-		set_SOGO(ctrl);
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-	}
-
-	rc = init_SERR(ctrl);
-	if (rc) {
-		err("init_SERR failed\n");
-		up(&ctrl->crit_sect);
-		goto err_free_irq;
-	}
-
-	// Done with exclusive hardware access
-	up(&ctrl->crit_sect);
-
-	cpqhp_create_ctrl_files (ctrl);
-
-	return 0;
-
-err_free_irq:
-	free_irq(ctrl->interrupt, ctrl);
-err_iounmap:
-	iounmap(ctrl->hpc_reg);
-err_free_mem_region:
-	release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-err_free_bus:
-	kfree(ctrl->pci_bus);
-err_free_ctrl:
-	kfree(ctrl);
-	return rc;
-}
-
-
-static int one_time_init(void)
-{
-	int loop;
-	int retval = 0;
-	static int initialized = 0;
-
-	if (initialized)
-		return 0;
-
-	power_mode = 0;
-
-	retval = pci_print_IRQ_route();
-	if (retval)
-		goto error;
-
-	dbg("Initialize + Start the notification mechanism \n");
-
-	retval = cpqhp_event_start_thread();
-	if (retval)
-		goto error;
-
-	dbg("Initialize slot lists\n");
-	for (loop = 0; loop < 256; loop++) {
-		cpqhp_slot_list[loop] = NULL;
-	}
-
-	// FIXME: We also need to hook the NMI handler eventually.
-	// this also needs to be worked with Christoph
-	// register_NMI_handler();
-
-	// Map rom address
-	cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
-	if (!cpqhp_rom_start) {
-		err ("Could not ioremap memory region for ROM\n");
-		retval = -EIO;;
-		goto error;
-	}
-	
-	/* Now, map the int15 entry point if we are on compaq specific hardware */
-	compaq_nvram_init(cpqhp_rom_start);
-	
-	/* Map smbios table entry point structure */
-	smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start, cpqhp_rom_start + ROM_PHY_LEN);
-	if (!smbios_table) {
-		err ("Could not find the SMBIOS pointer in memory\n");
-		retval = -EIO;;
-		goto error;
-	}
-
-	smbios_start = ioremap(readl(smbios_table + ST_ADDRESS), readw(smbios_table + ST_LENGTH));
-	if (!smbios_start) {
-		err ("Could not ioremap memory region taken from SMBIOS values\n");
-		retval = -EIO;;
-		goto error;
-	}
-
-	initialized = 1;
-
-	return retval;
-
-error:
-	if (cpqhp_rom_start)
-		iounmap(cpqhp_rom_start);
-	if (smbios_start)
-		iounmap(smbios_start);
-	
-	return retval;
-}
-
-
-static void unload_cpqphpd(void)
-{
-	struct pci_func *next;
-	struct pci_func *TempSlot;
-	int loop;
-	u32 rc;
-	struct controller *ctrl;
-	struct controller *tctrl;
-	struct pci_resource *res;
-	struct pci_resource *tres;
-
-	rc = compaq_nvram_store(cpqhp_rom_start);
-
-	ctrl = cpqhp_ctrl_list;
-
-	while (ctrl) {
-		if (ctrl->hpc_reg) {
-			u16 misc;
-			rc = read_slot_enable (ctrl);
-			
-			writeb(0, ctrl->hpc_reg + SLOT_SERR);
-			writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
-			
-			misc = readw(ctrl->hpc_reg + MISC);
-			misc &= 0xFFFD;
-			writew(misc, ctrl->hpc_reg + MISC);
-		}
-
-		ctrl_slot_cleanup(ctrl);
-
-		res = ctrl->io_head;
-		while (res) {
-			tres = res;
-			res = res->next;
-			kfree(tres);
-		}
-
-		res = ctrl->mem_head;
-		while (res) {
-			tres = res;
-			res = res->next;
-			kfree(tres);
-		}
-
-		res = ctrl->p_mem_head;
-		while (res) {
-			tres = res;
-			res = res->next;
-			kfree(tres);
-		}
-
-		res = ctrl->bus_head;
-		while (res) {
-			tres = res;
-			res = res->next;
-			kfree(tres);
-		}
-
-		kfree (ctrl->pci_bus);
-
-		tctrl = ctrl;
-		ctrl = ctrl->next;
-		kfree(tctrl);
-	}
-
-	for (loop = 0; loop < 256; loop++) {
-		next = cpqhp_slot_list[loop];
-		while (next != NULL) {
-			res = next->io_head;
-			while (res) {
-				tres = res;
-				res = res->next;
-				kfree(tres);
-			}
-
-			res = next->mem_head;
-			while (res) {
-				tres = res;
-				res = res->next;
-				kfree(tres);
-			}
-
-			res = next->p_mem_head;
-			while (res) {
-				tres = res;
-				res = res->next;
-				kfree(tres);
-			}
-
-			res = next->bus_head;
-			while (res) {
-				tres = res;
-				res = res->next;
-				kfree(tres);
-			}
-
-			TempSlot = next;
-			next = next->next;
-			kfree(TempSlot);
-		}
-	}
-
-	// Stop the notification mechanism
-	cpqhp_event_stop_thread();
-
-	//unmap the rom address
-	if (cpqhp_rom_start)
-		iounmap(cpqhp_rom_start);
-	if (smbios_start)
-		iounmap(smbios_start);
-}
-
-
-
-static struct pci_device_id hpcd_pci_tbl[] __devinitdata = {
-	{
-	/* handle any PCI Hotplug controller */
-	.class =        ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
-	.class_mask =   ~0,
-	
-	/* no matter who makes it */
-	.vendor =       PCI_ANY_ID,
-	.device =       PCI_ANY_ID,
-	.subvendor =    PCI_ANY_ID,
-	.subdevice =    PCI_ANY_ID,
-	
-	}, { /* end: all zeroes */ }
-};
-
-MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
-
-
-
-static struct pci_driver cpqhpc_driver = {
-	.name =		"pci_hotplug",
-	.id_table =	hpcd_pci_tbl,
-	.probe =	cpqhpc_probe,
-	/* remove:	cpqhpc_remove_one, */
-};
-
-
-
-static int __init cpqhpc_init(void)
-{
-	int result;
-
-	cpqhp_debug = debug;
-
-	result = pci_module_init(&cpqhpc_driver);
-	dbg("pci_module_init = %d\n", result);
-	if (result)
-		return result;
-	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
-	return 0;
-}
-
-
-static void __exit cpqhpc_cleanup(void)
-{
-	dbg("unload_cpqphpd()\n");
-	unload_cpqphpd();
-
-	dbg("pci_unregister_driver\n");
-	pci_unregister_driver(&cpqhpc_driver);
-}
-
-
-module_init(cpqhpc_init);
-module_exit(cpqhpc_cleanup);
-
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpqphp_ctrl.c linux-2.5.70-bk10/drivers/hotplug/cpqphp_ctrl.c
--- linux-2.5.70-bk9/drivers/hotplug/cpqphp_ctrl.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpqphp_ctrl.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,3084 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/smp_lock.h>
-#include <linux/pci.h>
-#include "cpqphp.h"
-
-static u32 configure_new_device(struct controller* ctrl, struct pci_func *func,u8 behind_bridge, struct resource_lists *resources);
-static int configure_new_function(struct controller* ctrl, struct pci_func *func,u8 behind_bridge, struct resource_lists *resources);
-static void interrupt_event_handler(struct controller *ctrl);
-
-static struct semaphore event_semaphore;	/* mutex for process loop (up if something to process) */
-static struct semaphore event_exit;		/* guard ensure thread has exited before calling it quits */
-static int event_finished;
-static unsigned long pushbutton_pending;	/* = 0 */
-
-/* things needed for the long_delay function */
-static struct semaphore		delay_sem;
-static wait_queue_head_t	delay_wait;
-
-/* delay is in jiffies to wait for */
-static void long_delay (int delay)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	
-	/* only allow 1 customer into the delay queue at once
-	 * yes this makes some people wait even longer, but who really cares?
-	 * this is for _huge_ delays to make the hardware happy as the 
-	 * signals bounce around
-	 */
-	down (&delay_sem);
-
-	init_waitqueue_head (&delay_wait);
-
-	add_wait_queue(&delay_wait, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(delay);
-	remove_wait_queue(&delay_wait, &wait);
-	set_current_state(TASK_RUNNING);
-	
-	up (&delay_sem);
-}
-
-
-//FIXME: The following line needs to be somewhere else...
-#define WRONG_BUS_FREQUENCY 0x07
-static u8 handle_switch_change(u8 change, struct controller * ctrl)
-{
-	int hp_slot;
-	u8 rc = 0;
-	u16 temp_word;
-	struct pci_func *func;
-	struct event_info *taskInfo;
-
-	if (!change)
-		return 0;
-
-	// Switch Change
-	dbg("cpqsbd:  Switch interrupt received.\n");
-
-	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
-		if (change & (0x1L << hp_slot)) {
-			//*********************************
-			// this one changed.
-			//*********************************
-			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
-
-			//this is the structure that tells the worker thread
-			//what to do
-			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
-			ctrl->next_event = (ctrl->next_event + 1) % 10;
-			taskInfo->hp_slot = hp_slot;
-
-			rc++;
-
-			temp_word = ctrl->ctrl_int_comp >> 16;
-			func->presence_save = (temp_word >> hp_slot) & 0x01;
-			func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
-
-			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
-				//*********************************
-				// Switch opened
-				//*********************************
-
-				func->switch_save = 0;
-
-				taskInfo->event_type = INT_SWITCH_OPEN;
-			} else {
-				//*********************************
-				// Switch closed
-				//*********************************
-
-				func->switch_save = 0x10;
-
-				taskInfo->event_type = INT_SWITCH_CLOSE;
-			}
-		}
-	}
-
-	return rc;
-}
-
-
-/*
- * cpqhp_find_slot
- */
-struct slot *cpqhp_find_slot (struct controller * ctrl, u8 device)
-{
-	struct slot *slot;
-
-	if (!ctrl)
-		return NULL;
-
-	slot = ctrl->slot;
-
-	while (slot && (slot->device != device)) {
-		slot = slot->next;
-	}
-
-	return slot;
-}
-
-
-static u8 handle_presence_change(u16 change, struct controller * ctrl)
-{
-	int hp_slot;
-	u8 rc = 0;
-	u8 temp_byte;
-	u16 temp_word;
-	struct pci_func *func;
-	struct event_info *taskInfo;
-	struct slot *p_slot;
-
-	if (!change)
-		return 0;
-
-	//*********************************
-	// Presence Change
-	//*********************************
-	dbg("cpqsbd:  Presence/Notify input change.\n");
-	dbg("         Changed bits are 0x%4.4x\n", change );
-
-	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
-		if (change & (0x0101 << hp_slot)) {
-			//*********************************
-			// this one changed.
-			//*********************************
-			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
-
-			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
-			ctrl->next_event = (ctrl->next_event + 1) % 10;
-			taskInfo->hp_slot = hp_slot;
-
-			rc++;
-
-			p_slot = cpqhp_find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));
-			if (!p_slot)
-				return 0;
-
-			// If the switch closed, must be a button
-			// If not in button mode, nevermind
-			if (func->switch_save && (ctrl->push_button == 1)) {
-				temp_word = ctrl->ctrl_int_comp >> 16;
-				temp_byte = (temp_word >> hp_slot) & 0x01;
-				temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
-
-				if (temp_byte != func->presence_save) {
-					//*********************************
-					// button Pressed (doesn't do anything)
-					//*********************************
-					dbg("hp_slot %d button pressed\n", hp_slot);
-					taskInfo->event_type = INT_BUTTON_PRESS;
-				} else {
-					//*********************************
-					// button Released - TAKE ACTION!!!!
-					//*********************************
-					dbg("hp_slot %d button released\n", hp_slot);
-					taskInfo->event_type = INT_BUTTON_RELEASE;
-
-					// Cancel if we are still blinking
-					if ((p_slot->state == BLINKINGON_STATE)
-					    || (p_slot->state == BLINKINGOFF_STATE)) {
-						taskInfo->event_type = INT_BUTTON_CANCEL;
-						dbg("hp_slot %d button cancel\n", hp_slot);
-					} else if ((p_slot->state == POWERON_STATE)
-						   || (p_slot->state == POWEROFF_STATE)) {
-						//info(msg_button_ignore, p_slot->number);
-						taskInfo->event_type = INT_BUTTON_IGNORE;
-						dbg("hp_slot %d button ignore\n", hp_slot);
-					}
-				}
-			} else {
-				// Switch is open, assume a presence change
-				// Save the presence state
-				temp_word = ctrl->ctrl_int_comp >> 16;
-				func->presence_save = (temp_word >> hp_slot) & 0x01;
-				func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
-
-				if ((!(ctrl->ctrl_int_comp & (0x010000 << hp_slot))) ||
-				    (!(ctrl->ctrl_int_comp & (0x01000000 << hp_slot)))) {
-					//*********************************
-					// Present
-					//*********************************
-					taskInfo->event_type = INT_PRESENCE_ON;
-				} else {
-					//*********************************
-					// Not Present
-					//*********************************
-					taskInfo->event_type = INT_PRESENCE_OFF;
-				}
-			}
-		}
-	}
-
-	return rc;
-}
-
-
-static u8 handle_power_fault(u8 change, struct controller * ctrl)
-{
-	int hp_slot;
-	u8 rc = 0;
-	struct pci_func *func;
-	struct event_info *taskInfo;
-
-	if (!change)
-		return 0;
-
-	//*********************************
-	// power fault
-	//*********************************
-
-	info("power fault interrupt\n");
-
-	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
-		if (change & (0x01 << hp_slot)) {
-			//*********************************
-			// this one changed.
-			//*********************************
-			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
-
-			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
-			ctrl->next_event = (ctrl->next_event + 1) % 10;
-			taskInfo->hp_slot = hp_slot;
-
-			rc++;
-
-			if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
-				//*********************************
-				// power fault Cleared
-				//*********************************
-				func->status = 0x00;
-
-				taskInfo->event_type = INT_POWER_FAULT_CLEAR;
-			} else {
-				//*********************************
-				// power fault
-				//*********************************
-				taskInfo->event_type = INT_POWER_FAULT;
-
-				if (ctrl->rev < 4) {
-					amber_LED_on (ctrl, hp_slot);
-					green_LED_off (ctrl, hp_slot);
-					set_SOGO (ctrl);
-
-					// this is a fatal condition, we want to crash the
-					// machine to protect from data corruption
-					// simulated_NMI shouldn't ever return
-					//FIXME
-					//simulated_NMI(hp_slot, ctrl);
-
-					//The following code causes a software crash just in
-					//case simulated_NMI did return
-					//FIXME
-					//panic(msg_power_fault);
-				} else {
-					// set power fault status for this board
-					func->status = 0xFF;
-					info("power fault bit %x set\n", hp_slot);
-				}
-			}
-		}
-	}
-
-	return rc;
-}
-
-
-/*
- * sort_by_size
- *
- * Sorts nodes on the list by their length.
- * Smallest first.
- *
- */
-static int sort_by_size(struct pci_resource **head)
-{
-	struct pci_resource *current_res;
-	struct pci_resource *next_res;
-	int out_of_order = 1;
-
-	if (!(*head))
-		return(1);
-
-	if (!((*head)->next))
-		return(0);
-
-	while (out_of_order) {
-		out_of_order = 0;
-
-		// Special case for swapping list head
-		if (((*head)->next) &&
-		    ((*head)->length > (*head)->next->length)) {
-			out_of_order++;
-			current_res = *head;
-			*head = (*head)->next;
-			current_res->next = (*head)->next;
-			(*head)->next = current_res;
-		}
-
-		current_res = *head;
-
-		while (current_res->next && current_res->next->next) {
-			if (current_res->next->length > current_res->next->next->length) {
-				out_of_order++;
-				next_res = current_res->next;
-				current_res->next = current_res->next->next;
-				current_res = current_res->next;
-				next_res->next = current_res->next;
-				current_res->next = next_res;
-			} else
-				current_res = current_res->next;
-		}
-	}  // End of out_of_order loop
-
-	return(0);
-}
-
-
-/*
- * sort_by_max_size
- *
- * Sorts nodes on the list by their length.
- * Largest first.
- *
- */
-static int sort_by_max_size(struct pci_resource **head)
-{
-	struct pci_resource *current_res;
-	struct pci_resource *next_res;
-	int out_of_order = 1;
-
-	if (!(*head))
-		return(1);
-
-	if (!((*head)->next))
-		return(0);
-
-	while (out_of_order) {
-		out_of_order = 0;
-
-		// Special case for swapping list head
-		if (((*head)->next) &&
-		    ((*head)->length < (*head)->next->length)) {
-			out_of_order++;
-			current_res = *head;
-			*head = (*head)->next;
-			current_res->next = (*head)->next;
-			(*head)->next = current_res;
-		}
-
-		current_res = *head;
-
-		while (current_res->next && current_res->next->next) {
-			if (current_res->next->length < current_res->next->next->length) {
-				out_of_order++;
-				next_res = current_res->next;
-				current_res->next = current_res->next->next;
-				current_res = current_res->next;
-				next_res->next = current_res->next;
-				current_res->next = next_res;
-			} else
-				current_res = current_res->next;
-		}
-	}  // End of out_of_order loop
-
-	return(0);
-}
-
-
-/*
- * do_pre_bridge_resource_split
- *
- *	Returns zero or one node of resources that aren't in use
- *
- */
-static struct pci_resource *do_pre_bridge_resource_split (struct pci_resource **head, struct pci_resource **orig_head, u32 alignment)
-{
-	struct pci_resource *prevnode = NULL;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u32 rc;
-	u32 temp_dword;
-	dbg("do_pre_bridge_resource_split\n");
-
-	if (!(*head) || !(*orig_head))
-		return(NULL);
-
-	rc = cpqhp_resource_sort_and_combine(head);
-
-	if (rc)
-		return(NULL);
-
-	if ((*head)->base != (*orig_head)->base)
-		return(NULL);
-
-	if ((*head)->length == (*orig_head)->length)
-		return(NULL);
-
-
-	// If we got here, there the bridge requires some of the resource, but
-	// we may be able to split some off of the front
-
-	node = *head;
-
-	if (node->length & (alignment -1)) {
-		// this one isn't an aligned length, so we'll make a new entry
-		// and split it up.
-		split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-		if (!split_node)
-			return(NULL);
-
-		temp_dword = (node->length | (alignment-1)) + 1 - alignment;
-
-		split_node->base = node->base;
-		split_node->length = temp_dword;
-
-		node->length -= temp_dword;
-		node->base += split_node->length;
-
-		// Put it in the list
-		*head = split_node;
-		split_node->next = node;
-	}
-
-	if (node->length < alignment) {
-		return(NULL);
-	}
-
-	// Now unlink it
-	if (*head == node) {
-		*head = node->next;
-		node->next = NULL;
-	} else {
-		prevnode = *head;
-		while (prevnode->next != node)
-			prevnode = prevnode->next;
-
-		prevnode->next = node->next;
-		node->next = NULL;
-	}
-
-	return(node);
-}
-
-
-/*
- * do_bridge_resource_split
- *
- *	Returns zero or one node of resources that aren't in use
- *
- */
-static struct pci_resource *do_bridge_resource_split (struct pci_resource **head, u32 alignment)
-{
-	struct pci_resource *prevnode = NULL;
-	struct pci_resource *node;
-	u32 rc;
-	u32 temp_dword;
-
-	if (!(*head))
-		return(NULL);
-
-	rc = cpqhp_resource_sort_and_combine(head);
-
-	if (rc)
-		return(NULL);
-
-	node = *head;
-
-	while (node->next) {
-		prevnode = node;
-		node = node->next;
-		kfree(prevnode);
-	}
-
-	if (node->length < alignment) {
-		kfree(node);
-		return(NULL);
-	}
-
-	if (node->base & (alignment - 1)) {
-		// Short circuit if adjusted size is too small
-		temp_dword = (node->base | (alignment-1)) + 1;
-		if ((node->length - (temp_dword - node->base)) < alignment) {
-			kfree(node);
-			return(NULL);
-		}
-
-		node->length -= (temp_dword - node->base);
-		node->base = temp_dword;
-	}
-
-	if (node->length & (alignment - 1)) {
-		// There's stuff in use after this node
-		kfree(node);
-		return(NULL);
-	}
-
-	return(node);
-}
-
-
-/*
- * get_io_resource
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length that is not in the
- * ISA aliasing window.  If it finds a node larger than "size"
- * it will split it up.
- *
- * size must be a power of two.
- */
-static struct pci_resource *get_io_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u32 temp_dword;
-
-	if (!(*head))
-		return(NULL);
-
-	if ( cpqhp_resource_sort_and_combine(head) )
-		return(NULL);
-
-	if ( sort_by_size(head) )
-		return(NULL);
-
-	for (node = *head; node; node = node->next) {
-		if (node->length < size)
-			continue;
-
-		if (node->base & (size - 1)) {
-			// this one isn't base aligned properly
-			// so we'll make a new entry and split it up
-			temp_dword = (node->base | (size-1)) + 1;
-
-			// Short circuit if adjusted size is too small
-			if ((node->length - (temp_dword - node->base)) < size)
-				continue;
-
-			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!split_node)
-				return(NULL);
-
-			split_node->base = node->base;
-			split_node->length = temp_dword - node->base;
-			node->base = temp_dword;
-			node->length -= split_node->length;
-
-			// Put it in the list
-			split_node->next = node->next;
-			node->next = split_node;
-		} // End of non-aligned base
-
-		// Don't need to check if too small since we already did
-		if (node->length > size) {
-			// this one is longer than we need
-			// so we'll make a new entry and split it up
-			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!split_node)
-				return(NULL);
-
-			split_node->base = node->base + size;
-			split_node->length = node->length - size;
-			node->length = size;
-
-			// Put it in the list
-			split_node->next = node->next;
-			node->next = split_node;
-		}  // End of too big on top end
-
-		// For IO make sure it's not in the ISA aliasing space
-		if (node->base & 0x300L)
-			continue;
-
-		// If we got here, then it is the right size
-		// Now take it out of the list
-		if (*head == node) {
-			*head = node->next;
-		} else {
-			prevnode = *head;
-			while (prevnode->next != node)
-				prevnode = prevnode->next;
-
-			prevnode->next = node->next;
-		}
-		node->next = NULL;
-		// Stop looping
-		break;
-	}
-
-	return(node);
-}
-
-
-/*
- * get_max_resource
- *
- * Gets the largest node that is at least "size" big from the
- * list pointed to by head.  It aligns the node on top and bottom
- * to "size" alignment before returning it.
- */
-static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *max;
-	struct pci_resource *temp;
-	struct pci_resource *split_node;
-	u32 temp_dword;
-
-	if (!(*head))
-		return(NULL);
-
-	if (cpqhp_resource_sort_and_combine(head))
-		return(NULL);
-
-	if (sort_by_max_size(head))
-		return(NULL);
-
-	for (max = *head;max; max = max->next) {
-
-		// If not big enough we could probably just bail, 
-		// instead we'll continue to the next.
-		if (max->length < size)
-			continue;
-
-		if (max->base & (size - 1)) {
-			// this one isn't base aligned properly
-			// so we'll make a new entry and split it up
-			temp_dword = (max->base | (size-1)) + 1;
-
-			// Short circuit if adjusted size is too small
-			if ((max->length - (temp_dword - max->base)) < size)
-				continue;
-
-			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!split_node)
-				return(NULL);
-
-			split_node->base = max->base;
-			split_node->length = temp_dword - max->base;
-			max->base = temp_dword;
-			max->length -= split_node->length;
-
-			// Put it next in the list
-			split_node->next = max->next;
-			max->next = split_node;
-		}
-
-		if ((max->base + max->length) & (size - 1)) {
-			// this one isn't end aligned properly at the top
-			// so we'll make a new entry and split it up
-			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!split_node)
-				return(NULL);
-			temp_dword = ((max->base + max->length) & ~(size - 1));
-			split_node->base = temp_dword;
-			split_node->length = max->length + max->base
-					     - split_node->base;
-			max->length -= split_node->length;
-
-			// Put it in the list
-			split_node->next = max->next;
-			max->next = split_node;
-		}
-
-		// Make sure it didn't shrink too much when we aligned it
-		if (max->length < size)
-			continue;
-
-		// Now take it out of the list
-		temp = (struct pci_resource*) *head;
-		if (temp == max) {
-			*head = max->next;
-		} else {
-			while (temp && temp->next != max) {
-				temp = temp->next;
-			}
-
-			temp->next = max->next;
-		}
-
-		max->next = NULL;
-		return(max);
-	}
-
-	// If we get here, we couldn't find one
-	return(NULL);
-}
-
-
-/*
- * get_resource
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length.  If it finds a node
- * larger than "size" it will split it up.
- *
- * size must be a power of two.
- */
-static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u32 temp_dword;
-
-	if (!(*head))
-		return(NULL);
-
-	if ( cpqhp_resource_sort_and_combine(head) )
-		return(NULL);
-
-	if ( sort_by_size(head) )
-		return(NULL);
-
-	for (node = *head; node; node = node->next) {
-		dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
-		    __FUNCTION__, size, node, node->base, node->length);
-		if (node->length < size)
-			continue;
-
-		if (node->base & (size - 1)) {
-			dbg("%s: not aligned\n", __FUNCTION__);
-			// this one isn't base aligned properly
-			// so we'll make a new entry and split it up
-			temp_dword = (node->base | (size-1)) + 1;
-
-			// Short circuit if adjusted size is too small
-			if ((node->length - (temp_dword - node->base)) < size)
-				continue;
-
-			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!split_node)
-				return(NULL);
-
-			split_node->base = node->base;
-			split_node->length = temp_dword - node->base;
-			node->base = temp_dword;
-			node->length -= split_node->length;
-
-			// Put it in the list
-			split_node->next = node->next;
-			node->next = split_node;
-		} // End of non-aligned base
-
-		// Don't need to check if too small since we already did
-		if (node->length > size) {
-			dbg("%s: too big\n", __FUNCTION__);
-			// this one is longer than we need
-			// so we'll make a new entry and split it up
-			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!split_node)
-				return(NULL);
-
-			split_node->base = node->base + size;
-			split_node->length = node->length - size;
-			node->length = size;
-
-			// Put it in the list
-			split_node->next = node->next;
-			node->next = split_node;
-		}  // End of too big on top end
-
-		dbg("%s: got one!!!\n", __FUNCTION__);
-		// If we got here, then it is the right size
-		// Now take it out of the list
-		if (*head == node) {
-			*head = node->next;
-		} else {
-			prevnode = *head;
-			while (prevnode->next != node)
-				prevnode = prevnode->next;
-
-			prevnode->next = node->next;
-		}
-		node->next = NULL;
-		// Stop looping
-		break;
-	}
-	return(node);
-}
-
-
-/*
- * cpqhp_resource_sort_and_combine
- *
- * Sorts all of the nodes in the list in ascending order by
- * their base addresses.  Also does garbage collection by
- * combining adjacent nodes.
- *
- * returns 0 if success
- */
-int cpqhp_resource_sort_and_combine(struct pci_resource **head)
-{
-	struct pci_resource *node1;
-	struct pci_resource *node2;
-	int out_of_order = 1;
-
-	dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
-
-	if (!(*head))
-		return(1);
-
-	dbg("*head->next = %p\n",(*head)->next);
-
-	if (!(*head)->next)
-		return(0);	/* only one item on the list, already sorted! */
-
-	dbg("*head->base = 0x%x\n",(*head)->base);
-	dbg("*head->next->base = 0x%x\n",(*head)->next->base);
-	while (out_of_order) {
-		out_of_order = 0;
-
-		// Special case for swapping list head
-		if (((*head)->next) &&
-		    ((*head)->base > (*head)->next->base)) {
-			node1 = *head;
-			(*head) = (*head)->next;
-			node1->next = (*head)->next;
-			(*head)->next = node1;
-			out_of_order++;
-		}
-
-		node1 = (*head);
-
-		while (node1->next && node1->next->next) {
-			if (node1->next->base > node1->next->next->base) {
-				out_of_order++;
-				node2 = node1->next;
-				node1->next = node1->next->next;
-				node1 = node1->next;
-				node2->next = node1->next;
-				node1->next = node2;
-			} else
-				node1 = node1->next;
-		}
-	}  // End of out_of_order loop
-
-	node1 = *head;
-
-	while (node1 && node1->next) {
-		if ((node1->base + node1->length) == node1->next->base) {
-			// Combine
-			dbg("8..\n");
-			node1->length += node1->next->length;
-			node2 = node1->next;
-			node1->next = node1->next->next;
-			kfree(node2);
-		} else
-			node1 = node1->next;
-	}
-
-	return(0);
-}
-
-
-irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs)
-{
-	struct controller *ctrl = data;
-	u8 schedule_flag = 0;
-	u8 reset;
-	u16 misc;
-	u32 Diff;
-	u32 temp_dword;
-
-	
-	misc = readw(ctrl->hpc_reg + MISC);
-	//*********************************
-	// Check to see if it was our interrupt
-	//*********************************
-	if (!(misc & 0x000C)) {
-		return IRQ_NONE;
-	}
-
-	if (misc & 0x0004) {
-		//*********************************
-		// Serial Output interrupt Pending
-		//*********************************
-
-		// Clear the interrupt
-		misc |= 0x0004;
-		writew(misc, ctrl->hpc_reg + MISC);
-
-		// Read to clear posted writes
-		misc = readw(ctrl->hpc_reg + MISC);
-
-		dbg ("%s - waking up\n", __FUNCTION__);
-		wake_up_interruptible(&ctrl->queue);
-	}
-
-	if (misc & 0x0008) {
-		// General-interrupt-input interrupt Pending
-		Diff = readl(ctrl->hpc_reg + INT_INPUT_CLEAR) ^ ctrl->ctrl_int_comp;
-
-		ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-		// Clear the interrupt
-		writel(Diff, ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-		// Read it back to clear any posted writes
-		temp_dword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-		if (!Diff) {
-			// Clear all interrupts
-			writel(0xFFFFFFFF, ctrl->hpc_reg + INT_INPUT_CLEAR);
-		}
-
-		schedule_flag += handle_switch_change((u8)(Diff & 0xFFL), ctrl);
-		schedule_flag += handle_presence_change((u16)((Diff & 0xFFFF0000L) >> 16), ctrl);
-		schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);
-	}
-
-	reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
-	if (reset & 0x40) {
-		/* Bus reset has completed */
-		reset &= 0xCF;
-		writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);
-		reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
-		wake_up_interruptible(&ctrl->queue);
-	}
-
-	if (schedule_flag) {
-		up(&event_semaphore);
-		dbg("Signal event_semaphore\n");
-	}
-	return IRQ_HANDLED;
-}
-
-
-/**
- * cpqhp_slot_create - Creates a node and adds it to the proper bus.
- * @busnumber - bus where new node is to be located
- *
- * Returns pointer to the new node or NULL if unsuccessful
- */
-struct pci_func *cpqhp_slot_create(u8 busnumber)
-{
-	struct pci_func *new_slot;
-	struct pci_func *next;
-
-	new_slot = (struct pci_func *) kmalloc(sizeof(struct pci_func), GFP_KERNEL);
-
-	if (new_slot == NULL) {
-		// I'm not dead yet!
-		// You will be.
-		return(new_slot);
-	}
-
-	memset(new_slot, 0, sizeof(struct pci_func));
-
-	new_slot->next = NULL;
-	new_slot->configured = 1;
-
-	if (cpqhp_slot_list[busnumber] == NULL) {
-		cpqhp_slot_list[busnumber] = new_slot;
-	} else {
-		next = cpqhp_slot_list[busnumber];
-		while (next->next != NULL)
-			next = next->next;
-		next->next = new_slot;
-	}
-	return(new_slot);
-}
-
-
-/*
- * slot_remove - Removes a node from the linked list of slots.
- * @old_slot: slot to remove
- *
- * Returns 0 if successful, !0 otherwise.
- */
-static int slot_remove(struct pci_func * old_slot)
-{
-	struct pci_func *next;
-
-	if (old_slot == NULL)
-		return(1);
-
-	next = cpqhp_slot_list[old_slot->bus];
-
-	if (next == NULL) {
-		return(1);
-	}
-
-	if (next == old_slot) {
-		cpqhp_slot_list[old_slot->bus] = old_slot->next;
-		cpqhp_destroy_board_resources(old_slot);
-		kfree(old_slot);
-		return(0);
-	}
-
-	while ((next->next != old_slot) && (next->next != NULL)) {
-		next = next->next;
-	}
-
-	if (next->next == old_slot) {
-		next->next = old_slot->next;
-		cpqhp_destroy_board_resources(old_slot);
-		kfree(old_slot);
-		return(0);
-	} else
-		return(2);
-}
-
-
-/**
- * bridge_slot_remove - Removes a node from the linked list of slots.
- * @bridge: bridge to remove
- *
- * Returns 0 if successful, !0 otherwise.
- */
-static int bridge_slot_remove(struct pci_func *bridge)
-{
-	u8 subordinateBus, secondaryBus;
-	u8 tempBus;
-	struct pci_func *next;
-
-	if (bridge == NULL)
-		return(1);
-
-	secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
-	subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
-
-	for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
-		next = cpqhp_slot_list[tempBus];
-
-		while (!slot_remove(next)) {
-			next = cpqhp_slot_list[tempBus];
-		}
-	}
-
-	next = cpqhp_slot_list[bridge->bus];
-
-	if (next == NULL) {
-		return(1);
-	}
-
-	if (next == bridge) {
-		cpqhp_slot_list[bridge->bus] = bridge->next;
-		kfree(bridge);
-		return(0);
-	}
-
-	while ((next->next != bridge) && (next->next != NULL)) {
-		next = next->next;
-	}
-
-	if (next->next == bridge) {
-		next->next = bridge->next;
-		kfree(bridge);
-		return(0);
-	} else
-		return(2);
-}
-
-
-/**
- * cpqhp_slot_find - Looks for a node by bus, and device, multiple functions accessed
- * @bus: bus to find
- * @device: device to find
- * @index: is 0 for first function found, 1 for the second...
- *
- * Returns pointer to the node if successful, %NULL otherwise.
- */
-struct pci_func *cpqhp_slot_find(u8 bus, u8 device, u8 index)
-{
-	int found = -1;
-	struct pci_func *func;
-
-	func = cpqhp_slot_list[bus];
-
-	if ((func == NULL) || ((func->device == device) && (index == 0)))
-		return(func);
-
-	if (func->device == device)
-		found++;
-
-	while (func->next != NULL) {
-		func = func->next;
-
-		if (func->device == device)
-			found++;
-
-		if (found == index)
-			return(func);
-	}
-
-	return(NULL);
-}
-
-
-// DJZ: I don't think is_bridge will work as is.
-//FIXME
-static int is_bridge(struct pci_func * func)
-{
-	// Check the header type
-	if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
-		return 1;
-	else
-		return 0;
-}
-
-
-/* the following routines constitute the bulk of the 
-   hotplug controller logic
- */
-
-
-/**
- * board_replaced - Called after a board has been replaced in the system.
- *
- * This is only used if we don't have resources for hot add
- * Turns power on for the board
- * Checks to see if board is the same
- * If board is same, reconfigures it
- * If board isn't same, turns it back off.
- *
- */
-static u32 board_replaced(struct pci_func * func, struct controller * ctrl)
-{
-	u8 hp_slot;
-	u8 temp_byte;
-	u8 adapter_speed;
-	u32 index;
-	u32 rc = 0;
-	u32 src = 8;
-
-	hp_slot = func->device - ctrl->slot_device_offset;
-
-	if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {
-		//*********************************
-		// The switch is open.
-		//*********************************
-		rc = INTERLOCK_OPEN;
-	} else if (is_slot_enabled (ctrl, hp_slot)) {
-		//*********************************
-		// The board is already on
-		//*********************************
-		rc = CARD_FUNCTIONING;
-	} else {
-		// Wait for exclusive access to hardware
-		down(&ctrl->crit_sect);
-
-		// turn on board without attaching to the bus
-		enable_slot_power (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		// Change bits in slot power register to force another shift out
-		// NOTE: this is to work around the timer bug
-		temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
-		writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
-		writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-		
-		adapter_speed = get_adapter_speed(ctrl, hp_slot);
-		if (ctrl->speed != adapter_speed)
-			if (set_controller_speed(ctrl, adapter_speed, hp_slot))
-				rc = WRONG_BUS_FREQUENCY;
-
-		// turn off board without attaching to the bus
-		disable_slot_power (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		// Done with exclusive hardware access
-		up(&ctrl->crit_sect);
-
-		if (rc)
-			return(rc);
-
-		// Wait for exclusive access to hardware
-		down(&ctrl->crit_sect);
-
-		slot_enable (ctrl, hp_slot);
-		green_LED_blink (ctrl, hp_slot);
-
-		amber_LED_off (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		// Done with exclusive hardware access
-		up(&ctrl->crit_sect);
-
-		// Wait for ~1 second because of hot plug spec
-		long_delay(1*HZ);
-
-		// Check for a power fault
-		if (func->status == 0xFF) {
-			// power fault occurred, but it was benign
-			rc = POWER_FAILURE;
-			func->status = 0;
-		} else
-			rc = cpqhp_valid_replace(ctrl, func);
-
-		if (!rc) {
-			// It must be the same board
-
-			rc = cpqhp_configure_board(ctrl, func);
-
-			if (rc || src) {
-				// If configuration fails, turn it off
-				// Get slot won't work for devices behind bridges, but
-				// in this case it will always be called for the "base"
-				// bus/dev/func of an adapter.
-
-				// Wait for exclusive access to hardware
-				down(&ctrl->crit_sect);
-
-				amber_LED_on (ctrl, hp_slot);
-				green_LED_off (ctrl, hp_slot);
-				slot_disable (ctrl, hp_slot);
-
-				set_SOGO(ctrl);
-
-				// Wait for SOBS to be unset
-				wait_for_ctrl_irq (ctrl);
-
-				// Done with exclusive hardware access
-				up(&ctrl->crit_sect);
-
-				if (rc)
-					return(rc);
-				else
-					return(1);
-			}
-
-			func->status = 0;
-			func->switch_save = 0x10;
-
-			index = 1;
-			while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
-				rc |= cpqhp_configure_board(ctrl, func);
-				index++;
-			}
-
-			if (rc) {
-				// If configuration fails, turn it off
-				// Get slot won't work for devices behind bridges, but
-				// in this case it will always be called for the "base"
-				// bus/dev/func of an adapter.
-
-				// Wait for exclusive access to hardware
-				down(&ctrl->crit_sect);
-
-				amber_LED_on (ctrl, hp_slot);
-				green_LED_off (ctrl, hp_slot);
-				slot_disable (ctrl, hp_slot);
-
-				set_SOGO(ctrl);
-
-				// Wait for SOBS to be unset
-				wait_for_ctrl_irq (ctrl);
-
-				// Done with exclusive hardware access
-				up(&ctrl->crit_sect);
-
-				return(rc);
-			}
-			// Done configuring so turn LED on full time
-
-			// Wait for exclusive access to hardware
-			down(&ctrl->crit_sect);
-
-			green_LED_on (ctrl, hp_slot);
-
-			set_SOGO(ctrl);
-
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
-
-			// Done with exclusive hardware access
-			up(&ctrl->crit_sect);
-			rc = 0;
-		} else {
-			// Something is wrong
-
-			// Get slot won't work for devices behind bridges, but
-			// in this case it will always be called for the "base"
-			// bus/dev/func of an adapter.
-
-			// Wait for exclusive access to hardware
-			down(&ctrl->crit_sect);
-
-			amber_LED_on (ctrl, hp_slot);
-			green_LED_off (ctrl, hp_slot);
-			slot_disable (ctrl, hp_slot);
-
-			set_SOGO(ctrl);
-
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
-
-			// Done with exclusive hardware access
-			up(&ctrl->crit_sect);
-		}
-
-	}
-	return(rc);
-
-}
-
-
-/**
- * board_added - Called after a board has been added to the system.
- *
- * Turns power on for the board
- * Configures board
- *
- */
-static u32 board_added(struct pci_func * func, struct controller * ctrl)
-{
-	u8 hp_slot;
-	u8 temp_byte;
-	u8 adapter_speed;
-	int index;
-	u32 temp_register = 0xFFFFFFFF;
-	u32 rc = 0;
-	struct pci_func *new_slot = NULL;
-	struct slot *p_slot;
-	struct resource_lists res_lists;
-
-	hp_slot = func->device - ctrl->slot_device_offset;
-	dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
-	    __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
-
-	// Wait for exclusive access to hardware
-	down(&ctrl->crit_sect);
-
-	// turn on board without attaching to the bus
-	enable_slot_power (ctrl, hp_slot);
-
-	set_SOGO(ctrl);
-
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
-
-	// Change bits in slot power register to force another shift out
-	// NOTE: this is to work around the timer bug
-	temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
-	writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
-	writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
-
-	set_SOGO(ctrl);
-
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
-	
-	adapter_speed = get_adapter_speed(ctrl, hp_slot);
-	if (ctrl->speed != adapter_speed)
-		if (set_controller_speed(ctrl, adapter_speed, hp_slot))
-			rc = WRONG_BUS_FREQUENCY;
-	
-	// turn off board without attaching to the bus
-	disable_slot_power (ctrl, hp_slot);
-
-	set_SOGO(ctrl);
-
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
-
-	// Done with exclusive hardware access
-	up(&ctrl->crit_sect);
-
-	if (rc)
-		return(rc);
-	
-	p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
-
-	// turn on board and blink green LED
-
-	// Wait for exclusive access to hardware
-	dbg("%s: before down\n", __FUNCTION__);
-	down(&ctrl->crit_sect);
-	dbg("%s: after down\n", __FUNCTION__);
-
-	dbg("%s: before slot_enable\n", __FUNCTION__);
-	slot_enable (ctrl, hp_slot);
-
-	dbg("%s: before green_LED_blink\n", __FUNCTION__);
-	green_LED_blink (ctrl, hp_slot);
-
-	dbg("%s: before amber_LED_blink\n", __FUNCTION__);
-	amber_LED_off (ctrl, hp_slot);
-
-	dbg("%s: before set_SOGO\n", __FUNCTION__);
-	set_SOGO(ctrl);
-
-	// Wait for SOBS to be unset
-	dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__);
-	wait_for_ctrl_irq (ctrl);
-	dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
-
-	// Done with exclusive hardware access
-	dbg("%s: before up\n", __FUNCTION__);
-	up(&ctrl->crit_sect);
-	dbg("%s: after up\n", __FUNCTION__);
-
-	// Wait for ~1 second because of hot plug spec
-	dbg("%s: before long_delay\n", __FUNCTION__);
-	long_delay(1*HZ);
-	dbg("%s: after long_delay\n", __FUNCTION__);
-
-	dbg("%s: func status = %x\n", __FUNCTION__, func->status);
-	// Check for a power fault
-	if (func->status == 0xFF) {
-		// power fault occurred, but it was benign
-		temp_register = 0xFFFFFFFF;
-		dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
-		rc = POWER_FAILURE;
-		func->status = 0;
-	} else {
-		// Get vendor/device ID u32
-		ctrl->pci_bus->number = func->bus;
-		rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
-		dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc);
-		dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
-
-		if (rc != 0) {
-			// Something's wrong here
-			temp_register = 0xFFFFFFFF;
-			dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
-		}
-		// Preset return code.  It will be changed later if things go okay.
-		rc = NO_ADAPTER_PRESENT;
-	}
-
-	// All F's is an empty slot or an invalid board
-	if (temp_register != 0xFFFFFFFF) {	  // Check for a board in the slot
-		res_lists.io_head = ctrl->io_head;
-		res_lists.mem_head = ctrl->mem_head;
-		res_lists.p_mem_head = ctrl->p_mem_head;
-		res_lists.bus_head = ctrl->bus_head;
-		res_lists.irqs = NULL;
-
-		rc = configure_new_device(ctrl, func, 0, &res_lists);
-
-		dbg("%s: back from configure_new_device\n", __FUNCTION__);
-		ctrl->io_head = res_lists.io_head;
-		ctrl->mem_head = res_lists.mem_head;
-		ctrl->p_mem_head = res_lists.p_mem_head;
-		ctrl->bus_head = res_lists.bus_head;
-
-		cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
-		cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
-		cpqhp_resource_sort_and_combine(&(ctrl->io_head));
-		cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
-
-		if (rc) {
-			// Wait for exclusive access to hardware
-			down(&ctrl->crit_sect);
-
-			amber_LED_on (ctrl, hp_slot);
-			green_LED_off (ctrl, hp_slot);
-			slot_disable (ctrl, hp_slot);
-
-			set_SOGO(ctrl);
-
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
-
-			// Done with exclusive hardware access
-			up(&ctrl->crit_sect);
-			return(rc);
-		} else {
-			cpqhp_save_slot_config(ctrl, func);
-		}
-
-
-		func->status = 0;
-		func->switch_save = 0x10;
-		func->is_a_board = 0x01;
-
-		//next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present)
-		dbg("%s: configure linux pci_dev structure\n", __FUNCTION__);
-		index = 0;
-		do {
-			new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
-			if (new_slot && !new_slot->pci_dev) {
-				cpqhp_configure_device(ctrl, new_slot);
-			}
-		} while (new_slot);
-
-		// Wait for exclusive access to hardware
-		down(&ctrl->crit_sect);
-
-		green_LED_on (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		// Done with exclusive hardware access
-		up(&ctrl->crit_sect);
-	} else {
-		// Wait for exclusive access to hardware
-		down(&ctrl->crit_sect);
-
-		amber_LED_on (ctrl, hp_slot);
-		green_LED_off (ctrl, hp_slot);
-		slot_disable (ctrl, hp_slot);
-
-		set_SOGO(ctrl);
-
-		// Wait for SOBS to be unset
-		wait_for_ctrl_irq (ctrl);
-
-		// Done with exclusive hardware access
-		up(&ctrl->crit_sect);
-
-		return(rc);
-	}
-	return 0;
-}
-
-
-/**
- * remove_board - Turns off slot and LED's
- *
- */
-static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl)
-{
-	int index;
-	u8 skip = 0;
-	u8 device;
-	u8 hp_slot;
-	u8 temp_byte;
-	u32 rc;
-	struct resource_lists res_lists;
-	struct pci_func *temp_func;
-
-	if (func == NULL)
-		return(1);
-
-	if (cpqhp_unconfigure_device(func))
-		return(1);
-
-	device = func->device;
-
-	hp_slot = func->device - ctrl->slot_device_offset;
-	dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
-
-	// When we get here, it is safe to change base Address Registers.
-	// We will attempt to save the base Address Register Lengths
-	if (replace_flag || !ctrl->add_support)
-		rc = cpqhp_save_base_addr_length(ctrl, func);
-	else if (!func->bus_head && !func->mem_head &&
-		 !func->p_mem_head && !func->io_head) {
-		// Here we check to see if we've saved any of the board's
-		// resources already.  If so, we'll skip the attempt to
-		// determine what's being used.
-		index = 0;
-		temp_func = cpqhp_slot_find(func->bus, func->device, index++);
-		while (temp_func) {
-			if (temp_func->bus_head || temp_func->mem_head
-			    || temp_func->p_mem_head || temp_func->io_head) {
-				skip = 1;
-				break;
-			}
-			temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++);
-		}
-
-		if (!skip)
-			rc = cpqhp_save_used_resources(ctrl, func);
-	}
-	// Change status to shutdown
-	if (func->is_a_board)
-		func->status = 0x01;
-	func->configured = 0;
-
-	// Wait for exclusive access to hardware
-	down(&ctrl->crit_sect);
-
-	green_LED_off (ctrl, hp_slot);
-	slot_disable (ctrl, hp_slot);
-
-	set_SOGO(ctrl);
-
-	// turn off SERR for slot
-	temp_byte = readb(ctrl->hpc_reg + SLOT_SERR);
-	temp_byte &= ~(0x01 << hp_slot);
-	writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);
-
-	// Wait for SOBS to be unset
-	wait_for_ctrl_irq (ctrl);
-
-	// Done with exclusive hardware access
-	up(&ctrl->crit_sect);
-
-	if (!replace_flag && ctrl->add_support) {
-		while (func) {
-			res_lists.io_head = ctrl->io_head;
-			res_lists.mem_head = ctrl->mem_head;
-			res_lists.p_mem_head = ctrl->p_mem_head;
-			res_lists.bus_head = ctrl->bus_head;
-
-			cpqhp_return_board_resources(func, &res_lists);
-
-			ctrl->io_head = res_lists.io_head;
-			ctrl->mem_head = res_lists.mem_head;
-			ctrl->p_mem_head = res_lists.p_mem_head;
-			ctrl->bus_head = res_lists.bus_head;
-
-			cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
-			cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
-			cpqhp_resource_sort_and_combine(&(ctrl->io_head));
-			cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
-
-			if (is_bridge(func)) {
-				bridge_slot_remove(func);
-			} else
-				slot_remove(func);
-
-			func = cpqhp_slot_find(ctrl->bus, device, 0);
-		}
-
-		// Setup slot structure with entry for empty slot
-		func = cpqhp_slot_create(ctrl->bus);
-
-		if (func == NULL) {
-			// Out of memory
-			return(1);
-		}
-
-		func->bus = ctrl->bus;
-		func->device = device;
-		func->function = 0;
-		func->configured = 0;
-		func->switch_save = 0x10;
-		func->is_a_board = 0;
-		func->p_task_event = NULL;
-	}
-
-	return 0;
-}
-
-
-static void pushbutton_helper_thread (unsigned long data)
-{
-	pushbutton_pending = data;
-	up(&event_semaphore);
-}
-
-
-// this is the main worker thread
-static int event_thread(void* data)
-{
-	struct controller *ctrl;
-	lock_kernel();
-	daemonize("phpd_event");
-	
-	unlock_kernel();
-
-	while (1) {
-		dbg("!!!!event_thread sleeping\n");
-		down_interruptible (&event_semaphore);
-		dbg("event_thread woken finished = %d\n", event_finished);
-		if (event_finished) break;
-		/* Do stuff here */
-		if (pushbutton_pending)
-			cpqhp_pushbutton_thread(pushbutton_pending);
-		else
-			for (ctrl = cpqhp_ctrl_list; ctrl; ctrl=ctrl->next)
-				interrupt_event_handler(ctrl);
-	}
-	dbg("event_thread signals exit\n");
-	up(&event_exit);
-	return 0;
-}
-
-
-int cpqhp_event_start_thread (void)
-{
-	int pid;
-
-	/* initialize our semaphores */
-	init_MUTEX(&delay_sem);
-	init_MUTEX_LOCKED(&event_semaphore);
-	init_MUTEX_LOCKED(&event_exit);
-	event_finished=0;
-
-	pid = kernel_thread(event_thread, 0, 0);
-	if (pid < 0) {
-		err ("Can't start up our event thread\n");
-		return -1;
-	}
-	dbg("Our event thread pid = %d\n", pid);
-	return 0;
-}
-
-
-void cpqhp_event_stop_thread (void)
-{
-	event_finished = 1;
-	dbg("event_thread finish command given\n");
-	up(&event_semaphore);
-	dbg("wait for event_thread to exit\n");
-	down(&event_exit);
-}
-
-
-static int update_slot_info (struct controller *ctrl, struct slot *slot)
-{
-	struct hotplug_slot_info *info;
-	int result;
-
-	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-
-	info->power_status = get_slot_enabled(ctrl, slot);
-	info->attention_status = cpq_get_attention_status(ctrl, slot);
-	info->latch_status = cpq_get_latch_status(ctrl, slot);
-	info->adapter_status = get_presence_status(ctrl, slot);
-	result = pci_hp_change_slot_info(slot->hotplug_slot, info);
-	kfree (info);
-	return result;
-}
-
-static void interrupt_event_handler(struct controller *ctrl)
-{
-	int loop = 0;
-	int change = 1;
-	struct pci_func *func;
-	u8 hp_slot;
-	struct slot *p_slot;
-
-	while (change) {
-		change = 0;
-
-		for (loop = 0; loop < 10; loop++) {
-			//dbg("loop %d\n", loop);
-			if (ctrl->event_queue[loop].event_type != 0) {
-				hp_slot = ctrl->event_queue[loop].hp_slot;
-
-				func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
-				if (!func)
-					return;
-
-				p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
-				if (!p_slot)
-					return;
-
-				dbg("hp_slot %d, func %p, p_slot %p\n",
-				    hp_slot, func, p_slot);
-
-				if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
-					dbg("button pressed\n");
-				} else if (ctrl->event_queue[loop].event_type == 
-					   INT_BUTTON_CANCEL) {
-					dbg("button cancel\n");
-					del_timer(&p_slot->task_event);
-
-					// Wait for exclusive access to hardware
-					down(&ctrl->crit_sect);
-
-					if (p_slot->state == BLINKINGOFF_STATE) {
-						// slot is on
-						// turn on green LED
-						dbg("turn on green LED\n");
-						green_LED_on (ctrl, hp_slot);
-					} else if (p_slot->state == BLINKINGON_STATE) {
-						// slot is off
-						// turn off green LED
-						dbg("turn off green LED\n");
-						green_LED_off (ctrl, hp_slot);
-					}
-
-					info(msg_button_cancel, p_slot->number);
-
-					p_slot->state = STATIC_STATE;
-
-					amber_LED_off (ctrl, hp_slot);
-
-					set_SOGO(ctrl);
-
-					// Wait for SOBS to be unset
-					wait_for_ctrl_irq (ctrl);
-
-					// Done with exclusive hardware access
-					up(&ctrl->crit_sect);
-				}
-				// ***********button Released (No action on press...)
-				else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
-					dbg("button release\n");
-
-					if (is_slot_enabled (ctrl, hp_slot)) {
-						// slot is on
-						dbg("slot is on\n");
-						p_slot->state = BLINKINGOFF_STATE;
-						info(msg_button_off, p_slot->number);
-					} else {
-						// slot is off
-						dbg("slot is off\n");
-						p_slot->state = BLINKINGON_STATE;
-						info(msg_button_on, p_slot->number);
-					}
-					// Wait for exclusive access to hardware
-					down(&ctrl->crit_sect);
-					
-					dbg("blink green LED and turn off amber\n");
-					
-					amber_LED_off (ctrl, hp_slot);
-					green_LED_blink (ctrl, hp_slot);
-					
-					set_SOGO(ctrl);
-
-					// Wait for SOBS to be unset
-					wait_for_ctrl_irq (ctrl);
-
-					// Done with exclusive hardware access
-					up(&ctrl->crit_sect);
-					init_timer(&p_slot->task_event);
-					p_slot->hp_slot = hp_slot;
-					p_slot->ctrl = ctrl;
-//					p_slot->physical_slot = physical_slot;
-					p_slot->task_event.expires = jiffies + 5 * HZ;   // 5 second delay
-					p_slot->task_event.function = pushbutton_helper_thread;
-					p_slot->task_event.data = (u32) p_slot;
-
-					dbg("add_timer p_slot = %p\n", p_slot);
-					add_timer(&p_slot->task_event);
-				}
-				// ***********POWER FAULT
-				else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
-					dbg("power fault\n");
-				} else {
-					/* refresh notification */
-					if (p_slot)
-						update_slot_info(ctrl, p_slot);
-				}
-
-				ctrl->event_queue[loop].event_type = 0;
-
-				change = 1;
-			}
-		}		// End of FOR loop
-	}
-
-	return;
-}
-
-
-/**
- * cpqhp_pushbutton_thread
- *
- * Scheduled procedure to handle blocking stuff for the pushbuttons
- * Handles all pending events and exits.
- *
- */
-void cpqhp_pushbutton_thread (unsigned long slot)
-{
-	u8 hp_slot;
-	u8 device;
-	struct pci_func *func;
-	struct slot *p_slot = (struct slot *) slot;
-	struct controller *ctrl = (struct controller *) p_slot->ctrl;
-
-	pushbutton_pending = 0;
-	hp_slot = p_slot->hp_slot;
-
-	device = p_slot->device;
-
-	if (is_slot_enabled (ctrl, hp_slot)) {
-		p_slot->state = POWEROFF_STATE;
-		// power Down board
-		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
-		dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
-		if (!func) {
-			dbg("Error! func NULL in %s\n", __FUNCTION__);
-			return ;
-		}
-
-		if (func != NULL && ctrl != NULL) {
-			if (cpqhp_process_SS(ctrl, func) != 0) {
-				amber_LED_on (ctrl, hp_slot);
-				green_LED_on (ctrl, hp_slot);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOBS to be unset
-				wait_for_ctrl_irq (ctrl);
-			}
-		}
-
-		p_slot->state = STATIC_STATE;
-	} else {
-		p_slot->state = POWERON_STATE;
-		// slot is off
-
-		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
-		dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
-		if (!func) {
-			dbg("Error! func NULL in %s\n", __FUNCTION__);
-			return ;
-		}
-
-		if (func != NULL && ctrl != NULL) {
-			if (cpqhp_process_SI(ctrl, func) != 0) {
-				amber_LED_on (ctrl, hp_slot);
-				green_LED_off (ctrl, hp_slot);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOBS to be unset
-				wait_for_ctrl_irq (ctrl);
-			}
-		}
-
-		p_slot->state = STATIC_STATE;
-	}
-
-	return;
-}
-
-
-int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
-{
-	u8 device, hp_slot;
-	u16 temp_word;
-	u32 tempdword;
-	int rc;
-	struct slot* p_slot;
-	int physical_slot = 0;
-
-	if (!ctrl)
-		return(1);
-
-	tempdword = 0;
-
-	device = func->device;
-	hp_slot = device - ctrl->slot_device_offset;
-	p_slot = cpqhp_find_slot(ctrl, device);
-	if (p_slot) {
-		physical_slot = p_slot->number;
-	}
-
-	// Check to see if the interlock is closed
-	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-	if (tempdword & (0x01 << hp_slot)) {
-		return(1);
-	}
-
-	if (func->is_a_board) {
-		rc = board_replaced(func, ctrl);
-	} else {
-		// add board
-		slot_remove(func);
-
-		func = cpqhp_slot_create(ctrl->bus);
-		if (func == NULL) {
-			return(1);
-		}
-
-		func->bus = ctrl->bus;
-		func->device = device;
-		func->function = 0;
-		func->configured = 0;
-		func->is_a_board = 1;
-
-		// We have to save the presence info for these slots
-		temp_word = ctrl->ctrl_int_comp >> 16;
-		func->presence_save = (temp_word >> hp_slot) & 0x01;
-		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
-
-		if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
-			func->switch_save = 0;
-		} else {
-			func->switch_save = 0x10;
-		}
-
-		rc = board_added(func, ctrl);
-		if (rc) {
-			if (is_bridge(func)) {
-				bridge_slot_remove(func);
-			} else
-				slot_remove(func);
-
-			// Setup slot structure with entry for empty slot
-			func = cpqhp_slot_create(ctrl->bus);
-
-			if (func == NULL) {
-				// Out of memory
-				return(1);
-			}
-
-			func->bus = ctrl->bus;
-			func->device = device;
-			func->function = 0;
-			func->configured = 0;
-			func->is_a_board = 0;
-
-			// We have to save the presence info for these slots
-			temp_word = ctrl->ctrl_int_comp >> 16;
-			func->presence_save = (temp_word >> hp_slot) & 0x01;
-			func->presence_save |=
-			(temp_word >> (hp_slot + 7)) & 0x02;
-
-			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
-				func->switch_save = 0;
-			} else {
-				func->switch_save = 0x10;
-			}
-		}
-	}
-
-	if (rc) {
-		dbg("%s: rc = %d\n", __FUNCTION__, rc);
-	}
-
-	if (p_slot)
-		update_slot_info(ctrl, p_slot);
-
-	return rc;
-}
-
-
-int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
-{
-	u8 device, class_code, header_type, BCR;
-	u8 index = 0;
-	u8 replace_flag;
-	u32 rc = 0;
-	unsigned int devfn;
-	struct slot* p_slot;
-	struct pci_bus *pci_bus = ctrl->pci_bus;
-	int physical_slot=0;
-
-	device = func->device; 
-	func = cpqhp_slot_find(ctrl->bus, device, index++);
-	p_slot = cpqhp_find_slot(ctrl, device);
-	if (p_slot) {
-		physical_slot = p_slot->number;
-	}
-
-	// Make sure there are no video controllers here
-	while (func && !rc) {
-		pci_bus->number = func->bus;
-		devfn = PCI_DEVFN(func->device, func->function);
-
-		// Check the Class Code
-		rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
-		if (rc)
-			return rc;
-
-		if (class_code == PCI_BASE_CLASS_DISPLAY) {
-			/* Display/Video adapter (not supported) */
-			rc = REMOVE_NOT_SUPPORTED;
-		} else {
-			// See if it's a bridge
-			rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
-			if (rc)
-				return rc;
-
-			// If it's a bridge, check the VGA Enable bit
-			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
-				rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
-				if (rc)
-					return rc;
-
-				// If the VGA Enable bit is set, remove isn't supported
-				if (BCR & PCI_BRIDGE_CTL_VGA) {
-					rc = REMOVE_NOT_SUPPORTED;
-				}
-			}
-		}
-
-		func = cpqhp_slot_find(ctrl->bus, device, index++);
-	}
-
-	func = cpqhp_slot_find(ctrl->bus, device, 0);
-	if ((func != NULL) && !rc) {
-		//FIXME: Replace flag should be passed into process_SS
-		replace_flag = !(ctrl->add_support);
-		rc = remove_board(func, replace_flag, ctrl);
-	} else if (!rc) {
-		rc = 1;
-	}
-
-	if (p_slot)
-		update_slot_info(ctrl, p_slot);
-
-	return(rc);
-}
-
-
-
-/**
- * hardware_test - runs hardware tests
- *
- * For hot plug ctrl folks to play with.
- * test_num is the number entered in the GUI
- *
- */
-int cpqhp_hardware_test(struct controller *ctrl, int test_num)
-{
-	u32 save_LED;
-	u32 work_LED;
-	int loop;
-	int num_of_slots;
-
-	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
-
-	switch (test_num) {
-		case 1:
-			// Do stuff here!
-
-			// Do that funky LED thing
-			save_LED = readl(ctrl->hpc_reg + LED_CONTROL);	// so we can restore them later
-			work_LED = 0x01010101;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED >> 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED >> 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-
-			work_LED = 0x01010000;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED >> 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-			work_LED = 0x00000101;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-			for (loop = 0; loop < num_of_slots; loop++) {
-				work_LED = work_LED >> 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((2*HZ)/10);
-			}
-
-
-			work_LED = 0x01010000;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((3*HZ)/10);
-				work_LED = work_LED >> 16;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
-
-				// Wait for SOGO interrupt
-				wait_for_ctrl_irq (ctrl);
-
-				// Get ready for next iteration
-				long_delay((3*HZ)/10);
-				work_LED = work_LED << 16;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			}
-
-			writel (save_LED, ctrl->hpc_reg + LED_CONTROL);	// put it back the way it was
-
-			set_SOGO(ctrl);
-
-			// Wait for SOBS to be unset
-			wait_for_ctrl_irq (ctrl);
-			break;
-		case 2:
-			// Do other stuff here!
-			break;
-		case 3:
-			// and more...
-			break;
-	}
-	return 0;
-}
-
-
-/**
- * configure_new_device - Configures the PCI header information of one board.
- *
- * @ctrl: pointer to controller structure
- * @func: pointer to function structure
- * @behind_bridge: 1 if this is a recursive call, 0 if not
- * @resources: pointer to set of resource lists
- *
- * Returns 0 if success
- *
- */
-static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
-				 u8 behind_bridge, struct resource_lists * resources)
-{
-	u8 temp_byte, function, max_functions, stop_it;
-	int rc;
-	u32 ID;
-	struct pci_func *new_slot;
-	int index;
-
-	new_slot = func;
-
-	dbg("%s\n", __FUNCTION__);
-	// Check for Multi-function device
-	ctrl->pci_bus->number = func->bus;
-	rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
-	if (rc) {
-		dbg("%s: rc = %d\n", __FUNCTION__, rc);
-		return rc;
-	}
-
-	if (temp_byte & 0x80)	// Multi-function device
-		max_functions = 8;
-	else
-		max_functions = 1;
-
-	function = 0;
-
-	do {
-		rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);
-
-		if (rc) {
-			dbg("configure_new_function failed %d\n",rc);
-			index = 0;
-
-			while (new_slot) {
-				new_slot = cpqhp_slot_find(new_slot->bus, new_slot->device, index++);
-
-				if (new_slot)
-					cpqhp_return_board_resources(new_slot, resources);
-			}
-
-			return(rc);
-		}
-
-		function++;
-
-		stop_it = 0;
-
-		//  The following loop skips to the next present function
-		//  and creates a board structure
-
-		while ((function < max_functions) && (!stop_it)) {
-			pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
-
-			if (ID == 0xFFFFFFFF) {	  // There's nothing there. 
-				function++;
-			} else {  // There's something there
-				// Setup slot structure.
-				new_slot = cpqhp_slot_create(func->bus);
-
-				if (new_slot == NULL) {
-					// Out of memory
-					return(1);
-				}
-
-				new_slot->bus = func->bus;
-				new_slot->device = func->device;
-				new_slot->function = function;
-				new_slot->is_a_board = 1;
-				new_slot->status = 0;
-
-				stop_it++;
-			}
-		}
-
-	} while (function < max_functions);
-	dbg("returning from configure_new_device\n");
-
-	return 0;
-}
-
-
-/*
-  Configuration logic that involves the hotplug data structures and 
-  their bookkeeping
- */
-
-
-/**
- * configure_new_function - Configures the PCI header information of one device
- *
- * @ctrl: pointer to controller structure
- * @func: pointer to function structure
- * @behind_bridge: 1 if this is a recursive call, 0 if not
- * @resources: pointer to set of resource lists
- *
- * Calls itself recursively for bridged devices.
- * Returns 0 if success
- *
- */
-static int configure_new_function (struct controller * ctrl, struct pci_func * func,
-				   u8 behind_bridge, struct resource_lists * resources)
-{
-	int cloop;
-	u8 IRQ;
-	u8 temp_byte;
-	u8 device;
-	u8 class_code;
-	u16 command;
-	u16 temp_word;
-	u32 temp_dword;
-	u32 rc;
-	u32 temp_register;
-	u32 base;
-	u32 ID;
-	unsigned int devfn;
-	struct pci_resource *mem_node;
-	struct pci_resource *p_mem_node;
-	struct pci_resource *io_node;
-	struct pci_resource *bus_node;
-	struct pci_resource *hold_mem_node;
-	struct pci_resource *hold_p_mem_node;
-	struct pci_resource *hold_IO_node;
-	struct pci_resource *hold_bus_node;
-	struct irq_mapping irqs;
-	struct pci_func *new_slot;
-	struct pci_bus *pci_bus;
-	struct resource_lists temp_resources;
-
-	pci_bus = ctrl->pci_bus;
-	pci_bus->number = func->bus;
-	devfn = PCI_DEVFN(func->device, func->function);
-
-	// Check for Bridge
-	rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
-	if (rc)
-		return rc;
-
-	if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
-		// set Primary bus
-		dbg("set Primary bus = %d\n", func->bus);
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
-		if (rc)
-			return rc;
-
-		// find range of busses to use
-		dbg("find ranges of buses to use\n");
-		bus_node = get_max_resource(&resources->bus_head, 1);
-
-		// If we don't have any busses to allocate, we can't continue
-		if (!bus_node)
-			return -ENOMEM;
-
-		// set Secondary bus
-		temp_byte = bus_node->base;
-		dbg("set Secondary bus = %d\n", bus_node->base);
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
-		if (rc)
-			return rc;
-
-		// set subordinate bus
-		temp_byte = bus_node->base + bus_node->length - 1;
-		dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
-		if (rc)
-			return rc;
-
-		// set subordinate Latency Timer and base Latency Timer
-		temp_byte = 0x40;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
-		if (rc)
-			return rc;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
-		if (rc)
-			return rc;
-
-		// set Cache Line size
-		temp_byte = 0x08;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
-		if (rc)
-			return rc;
-
-		// Setup the IO, memory, and prefetchable windows
-
-		io_node = get_max_resource(&(resources->io_head), 0x1000);
-		if (!io_node)
-			return -ENOMEM;
-		mem_node = get_max_resource(&(resources->mem_head), 0x100000);
-		if (!mem_node)
-			return -ENOMEM;
-		p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);
-		if (!p_mem_node)
-			return -ENOMEM;
-		dbg("Setup the IO, memory, and prefetchable windows\n");
-		dbg("io_node\n");
-		dbg("(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
-		dbg("mem_node\n");
-		dbg("(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
-		dbg("p_mem_node\n");
-		dbg("(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
-
-		// set up the IRQ info
-		if (!resources->irqs) {
-			irqs.barber_pole = 0;
-			irqs.interrupt[0] = 0;
-			irqs.interrupt[1] = 0;
-			irqs.interrupt[2] = 0;
-			irqs.interrupt[3] = 0;
-			irqs.valid_INT = 0;
-		} else {
-			irqs.barber_pole = resources->irqs->barber_pole;
-			irqs.interrupt[0] = resources->irqs->interrupt[0];
-			irqs.interrupt[1] = resources->irqs->interrupt[1];
-			irqs.interrupt[2] = resources->irqs->interrupt[2];
-			irqs.interrupt[3] = resources->irqs->interrupt[3];
-			irqs.valid_INT = resources->irqs->valid_INT;
-		}
-
-		// set up resource lists that are now aligned on top and bottom
-		// for anything behind the bridge.
-		temp_resources.bus_head = bus_node;
-		temp_resources.io_head = io_node;
-		temp_resources.mem_head = mem_node;
-		temp_resources.p_mem_head = p_mem_node;
-		temp_resources.irqs = &irqs;
-
-		// Make copies of the nodes we are going to pass down so that
-		// if there is a problem,we can just use these to free resources
-		hold_bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-		hold_IO_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-		hold_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-		hold_p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-		if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
-			if (hold_bus_node)
-				kfree(hold_bus_node);
-			if (hold_IO_node)
-				kfree(hold_IO_node);
-			if (hold_mem_node)
-				kfree(hold_mem_node);
-			if (hold_p_mem_node)
-				kfree(hold_p_mem_node);
-
-			return(1);
-		}
-
-		memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
-
-		bus_node->base += 1;
-		bus_node->length -= 1;
-		bus_node->next = NULL;
-
-		// If we have IO resources copy them and fill in the bridge's
-		// IO range registers
-		if (io_node) {
-			memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
-			io_node->next = NULL;
-
-			// set IO base and Limit registers
-			temp_byte = io_node->base >> 8;
-			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
-			temp_byte = (io_node->base + io_node->length - 1) >> 8;
-			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
-		} else {
-			kfree(hold_IO_node);
-			hold_IO_node = NULL;
-		}
-
-		// If we have memory resources copy them and fill in the bridge's
-		// memory range registers.  Otherwise, fill in the range
-		// registers with values that disable them.
-		if (mem_node) {
-			memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
-			mem_node->next = NULL;
-
-			// set Mem base and Limit registers
-			temp_word = mem_node->base >> 16;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
-
-			temp_word = (mem_node->base + mem_node->length - 1) >> 16;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-		} else {
-			temp_word = 0xFFFF;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
-
-			temp_word = 0x0000;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
-			kfree(hold_mem_node);
-			hold_mem_node = NULL;
-		}
-
-		// If we have prefetchable memory resources copy them and 
-		// fill in the bridge's memory range registers.  Otherwise,
-		// fill in the range registers with values that disable them.
-		if (p_mem_node) {
-			memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
-			p_mem_node->next = NULL;
-
-			// set Pre Mem base and Limit registers
-			temp_word = p_mem_node->base >> 16;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
-			temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-		} else {
-			temp_word = 0xFFFF;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
-			temp_word = 0x0000;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
-			kfree(hold_p_mem_node);
-			hold_p_mem_node = NULL;
-		}
-
-		// Adjust this to compensate for extra adjustment in first loop
-		irqs.barber_pole--;
-
-		rc = 0;
-
-		// Here we actually find the devices and configure them
-		for (device = 0; (device <= 0x1F) && !rc; device++) {
-			irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
-
-			ID = 0xFFFFFFFF;
-			pci_bus->number = hold_bus_node->base;
-			pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
-			pci_bus->number = func->bus;
-
-			if (ID != 0xFFFFFFFF) {	  //  device Present
-				// Setup slot structure.
-				new_slot = cpqhp_slot_create(hold_bus_node->base);
-
-				if (new_slot == NULL) {
-					// Out of memory
-					rc = -ENOMEM;
-					continue;
-				}
-
-				new_slot->bus = hold_bus_node->base;
-				new_slot->device = device;
-				new_slot->function = 0;
-				new_slot->is_a_board = 1;
-				new_slot->status = 0;
-
-				rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);
-				dbg("configure_new_device rc=0x%x\n",rc);
-			}	// End of IF (device in slot?)
-		}		// End of FOR loop
-
-		if (rc) {
-			cpqhp_destroy_resource_list(&temp_resources);
-
-			return_resource(&(resources->bus_head), hold_bus_node);
-			return_resource(&(resources->io_head), hold_IO_node);
-			return_resource(&(resources->mem_head), hold_mem_node);
-			return_resource(&(resources->p_mem_head), hold_p_mem_node);
-			return(rc);
-		}
-		// save the interrupt routing information
-		if (resources->irqs) {
-			resources->irqs->interrupt[0] = irqs.interrupt[0];
-			resources->irqs->interrupt[1] = irqs.interrupt[1];
-			resources->irqs->interrupt[2] = irqs.interrupt[2];
-			resources->irqs->interrupt[3] = irqs.interrupt[3];
-			resources->irqs->valid_INT = irqs.valid_INT;
-		} else if (!behind_bridge) {
-			// We need to hook up the interrupts here
-			for (cloop = 0; cloop < 4; cloop++) {
-				if (irqs.valid_INT & (0x01 << cloop)) {
-					rc = cpqhp_set_irq(func->bus, func->device,
-							   0x0A + cloop, irqs.interrupt[cloop]);
-					if (rc) {
-						cpqhp_destroy_resource_list (&temp_resources);
-
-						return_resource(&(resources-> bus_head), hold_bus_node);
-						return_resource(&(resources-> io_head), hold_IO_node);
-						return_resource(&(resources-> mem_head), hold_mem_node);
-						return_resource(&(resources-> p_mem_head), hold_p_mem_node);
-						return rc;
-					}
-				}
-			}	// end of for loop
-		}
-		// Return unused bus resources
-		// First use the temporary node to store information for the board
-		if (hold_bus_node && bus_node && temp_resources.bus_head) {
-			hold_bus_node->length = bus_node->base - hold_bus_node->base;
-
-			hold_bus_node->next = func->bus_head;
-			func->bus_head = hold_bus_node;
-
-			temp_byte = temp_resources.bus_head->base - 1;
-
-			// set subordinate bus
-			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
-
-			if (temp_resources.bus_head->length == 0) {
-				kfree(temp_resources.bus_head);
-				temp_resources.bus_head = NULL;
-			} else {
-				return_resource(&(resources->bus_head), temp_resources.bus_head);
-			}
-		}
-
-		// If we have IO space available and there is some left,
-		// return the unused portion
-		if (hold_IO_node && temp_resources.io_head) {
-			io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
-							       &hold_IO_node, 0x1000);
-
-			// Check if we were able to split something off
-			if (io_node) {
-				hold_IO_node->base = io_node->base + io_node->length;
-
-				temp_byte = (hold_IO_node->base) >> 8;
-				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_BASE, temp_byte);
-
-				return_resource(&(resources->io_head), io_node);
-			}
-
-			io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
-
-			// Check if we were able to split something off
-			if (io_node) {
-				// First use the temporary node to store information for the board
-				hold_IO_node->length = io_node->base - hold_IO_node->base;
-
-				// If we used any, add it to the board's list
-				if (hold_IO_node->length) {
-					hold_IO_node->next = func->io_head;
-					func->io_head = hold_IO_node;
-
-					temp_byte = (io_node->base - 1) >> 8;
-					rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
-
-					return_resource(&(resources->io_head), io_node);
-				} else {
-					// it doesn't need any IO
-					temp_word = 0x0000;
-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_LIMIT, temp_word);
-
-					return_resource(&(resources->io_head), io_node);
-					kfree(hold_IO_node);
-				}
-			} else {
-				// it used most of the range
-				hold_IO_node->next = func->io_head;
-				func->io_head = hold_IO_node;
-			}
-		} else if (hold_IO_node) {
-			// it used the whole range
-			hold_IO_node->next = func->io_head;
-			func->io_head = hold_IO_node;
-		}
-		// If we have memory space available and there is some left,
-		// return the unused portion
-		if (hold_mem_node && temp_resources.mem_head) {
-			mem_node = do_pre_bridge_resource_split(&(temp_resources.  mem_head),
-								&hold_mem_node, 0x100000);
-
-			// Check if we were able to split something off
-			if (mem_node) {
-				hold_mem_node->base = mem_node->base + mem_node->length;
-
-				temp_word = (hold_mem_node->base) >> 16;
-				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
-
-				return_resource(&(resources->mem_head), mem_node);
-			}
-
-			mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000);
-
-			// Check if we were able to split something off
-			if (mem_node) {
-				// First use the temporary node to store information for the board
-				hold_mem_node->length = mem_node->base - hold_mem_node->base;
-
-				if (hold_mem_node->length) {
-					hold_mem_node->next = func->mem_head;
-					func->mem_head = hold_mem_node;
-
-					// configure end address
-					temp_word = (mem_node->base - 1) >> 16;
-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
-					// Return unused resources to the pool
-					return_resource(&(resources->mem_head), mem_node);
-				} else {
-					// it doesn't need any Mem
-					temp_word = 0x0000;
-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
-
-					return_resource(&(resources->mem_head), mem_node);
-					kfree(hold_mem_node);
-				}
-			} else {
-				// it used most of the range
-				hold_mem_node->next = func->mem_head;
-				func->mem_head = hold_mem_node;
-			}
-		} else if (hold_mem_node) {
-			// it used the whole range
-			hold_mem_node->next = func->mem_head;
-			func->mem_head = hold_mem_node;
-		}
-		// If we have prefetchable memory space available and there is some 
-		// left at the end, return the unused portion
-		if (hold_p_mem_node && temp_resources.p_mem_head) {
-			p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
-								  &hold_p_mem_node, 0x100000);
-
-			// Check if we were able to split something off
-			if (p_mem_node) {
-				hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
-
-				temp_word = (hold_p_mem_node->base) >> 16;
-				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
-				return_resource(&(resources->p_mem_head), p_mem_node);
-			}
-
-			p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000);
-
-			// Check if we were able to split something off
-			if (p_mem_node) {
-				// First use the temporary node to store information for the board
-				hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
-
-				// If we used any, add it to the board's list
-				if (hold_p_mem_node->length) {
-					hold_p_mem_node->next = func->p_mem_head;
-					func->p_mem_head = hold_p_mem_node;
-
-					temp_word = (p_mem_node->base - 1) >> 16;
-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
-					return_resource(&(resources->p_mem_head), p_mem_node);
-				} else {
-					// it doesn't need any PMem
-					temp_word = 0x0000;
-					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
-					return_resource(&(resources->p_mem_head), p_mem_node);
-					kfree(hold_p_mem_node);
-				}
-			} else {
-				// it used the most of the range
-				hold_p_mem_node->next = func->p_mem_head;
-				func->p_mem_head = hold_p_mem_node;
-			}
-		} else if (hold_p_mem_node) {
-			// it used the whole range
-			hold_p_mem_node->next = func->p_mem_head;
-			func->p_mem_head = hold_p_mem_node;
-		}
-		// We should be configuring an IRQ and the bridge's base address
-		// registers if it needs them.  Although we have never seen such
-		// a device
-
-		// enable card
-		command = 0x0157;	// = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
-		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
-
-		// set Bridge Control Register
-		command = 0x07;		// = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA
-		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
-	} else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
-		// Standard device
-		rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
-
-		if (class_code == PCI_BASE_CLASS_DISPLAY) {
-			// Display (video) adapter (not supported)
-			return(DEVICE_TYPE_NOT_SUPPORTED);
-		}
-		// Figure out IO and memory needs
-		for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
-			temp_register = 0xFFFFFFFF;
-
-			dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
-			rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-
-			rc = pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
-			dbg("CND: base = 0x%x\n", temp_register);
-
-			if (temp_register) {	  // If this register is implemented
-				if ((temp_register & 0x03L) == 0x01) {
-					// Map IO
-
-					// set base = amount of IO space
-					base = temp_register & 0xFFFFFFFC;
-					base = ~base + 1;
-
-					dbg("CND:      length = 0x%x\n", base);
-					io_node = get_io_resource(&(resources->io_head), base);
-					dbg("Got io_node start = %8.8x, length = %8.8x next (%p)\n",
-					    io_node->base, io_node->length, io_node->next);
-					dbg("func (%p) io_head (%p)\n", func, func->io_head);
-
-					// allocate the resource to the board
-					if (io_node) {
-						base = io_node->base;
-
-						io_node->next = func->io_head;
-						func->io_head = io_node;
-					} else
-						return -ENOMEM;
-				} else if ((temp_register & 0x0BL) == 0x08) {
-					// Map prefetchable memory
-					base = temp_register & 0xFFFFFFF0;
-					base = ~base + 1;
-
-					dbg("CND:      length = 0x%x\n", base);
-					p_mem_node = get_resource(&(resources->p_mem_head), base);
-
-					// allocate the resource to the board
-					if (p_mem_node) {
-						base = p_mem_node->base;
-
-						p_mem_node->next = func->p_mem_head;
-						func->p_mem_head = p_mem_node;
-					} else
-						return -ENOMEM;
-				} else if ((temp_register & 0x0BL) == 0x00) {
-					// Map memory
-					base = temp_register & 0xFFFFFFF0;
-					base = ~base + 1;
-
-					dbg("CND:      length = 0x%x\n", base);
-					mem_node = get_resource(&(resources->mem_head), base);
-
-					// allocate the resource to the board
-					if (mem_node) {
-						base = mem_node->base;
-
-						mem_node->next = func->mem_head;
-						func->mem_head = mem_node;
-					} else
-						return -ENOMEM;
-				} else if ((temp_register & 0x0BL) == 0x04) {
-					// Map memory
-					base = temp_register & 0xFFFFFFF0;
-					base = ~base + 1;
-
-					dbg("CND:      length = 0x%x\n", base);
-					mem_node = get_resource(&(resources->mem_head), base);
-
-					// allocate the resource to the board
-					if (mem_node) {
-						base = mem_node->base;
-
-						mem_node->next = func->mem_head;
-						func->mem_head = mem_node;
-					} else
-						return -ENOMEM;
-				} else if ((temp_register & 0x0BL) == 0x06) {
-					// Those bits are reserved, we can't handle this
-					return(1);
-				} else {
-					// Requesting space below 1M
-					return(NOT_ENOUGH_RESOURCES);
-				}
-
-				rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
-
-				// Check for 64-bit base
-				if ((temp_register & 0x07L) == 0x04) {
-					cloop += 4;
-
-					// Upper 32 bits of address always zero on today's systems
-					// FIXME this is probably not true on Alpha and ia64???
-					base = 0;
-					rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
-				}
-			}
-		}		// End of base register loop
-
-		// Figure out which interrupt pin this function uses
-		rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
-
-		// If this function needs an interrupt and we are behind a bridge
-		// and the pin is tied to something that's alread mapped,
-		// set this one the same
-		if (temp_byte && resources->irqs && 
-		    (resources->irqs->valid_INT & 
-		     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
-			// We have to share with something already set up
-			IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
-		} else {
-			// Program IRQ based on card type
-			rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
-
-			if (class_code == PCI_BASE_CLASS_STORAGE) {
-				IRQ = cpqhp_disk_irq;
-			} else {
-				IRQ = cpqhp_nic_irq;
-			}
-		}
-
-		// IRQ Line
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
-
-		if (!behind_bridge) {
-			rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
-			if (rc)
-				return(1);
-		} else {
-			//TBD - this code may also belong in the other clause of this If statement
-			resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
-			resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
-		}
-
-		// Latency Timer
-		temp_byte = 0x40;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
-
-		// Cache Line size
-		temp_byte = 0x08;
-		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
-
-		// disable ROM base Address
-		temp_dword = 0x00L;
-		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_dword);
-
-		// enable card
-		temp_word = 0x0157;	// = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
-		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, temp_word);
-	}			// End of Not-A-Bridge else
-	else {
-		// It's some strange type of PCI adapter (Cardbus?)
-		return(DEVICE_TYPE_NOT_SUPPORTED);
-	}
-
-	func->configured = 1;
-
-	return 0;
-}
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpqphp_nvram.c linux-2.5.70-bk10/drivers/hotplug/cpqphp_nvram.c
--- linux-2.5.70-bk9/drivers/hotplug/cpqphp_nvram.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpqphp_nvram.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,667 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include "cpqphp.h"
-#include "cpqphp_nvram.h"
-
-
-#define ROM_INT15_PHY_ADDR		0x0FF859
-#define READ_EV				0xD8A4
-#define WRITE_EV			0xD8A5
-
-struct register_foo {
-	union {
-		unsigned long lword;		/* eax */
-		unsigned short word;		/* ax */
-
-		struct {
-			unsigned char low;	/* al */
-			unsigned char high;	/* ah */
-		} byte;
-	} data;
-
-	unsigned char opcode;	/* see below */
-	unsigned long length;	/* if the reg. is a pointer, how much data */
-} __attribute__ ((packed));
-
-struct all_reg {
-	struct register_foo eax_reg;
-	struct register_foo ebx_reg;
-	struct register_foo ecx_reg;
-	struct register_foo edx_reg;
-	struct register_foo edi_reg;
-	struct register_foo esi_reg;
-	struct register_foo eflags_reg;
-} __attribute__ ((packed));
-
-
-struct ev_hrt_header {
-	u8 Version;
-	u8 num_of_ctrl;
-	u8 next;
-};
-
-struct ev_hrt_ctrl {
-	u8 bus;
-	u8 device;
-	u8 function;
-	u8 mem_avail;
-	u8 p_mem_avail;
-	u8 io_avail;
-	u8 bus_avail;
-	u8 next;
-};
-
-
-static u8 evbuffer_init;
-static u8 evbuffer_length;
-static u8 evbuffer[1024];
-
-static void *compaq_int15_entry_point;
-
-static spinlock_t int15_lock;		/* lock for ordering int15_bios_call() */
-
-
-/* This is a series of function that deals with
-   setting & getting the hotplug resource table in some environment variable.
-*/
-
-/*
- * We really shouldn't be doing this unless there is a _very_ good reason to!!!
- * greg k-h
- */
-
-
-static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail)
-{
-	u8 **tByte;
-
-	if ((*used + 1) > *avail)
-		return(1);
-	
-	*((u8*)*p_buffer) = value;
-	tByte = (u8**)p_buffer;
-	(*tByte)++;
-	*used+=1;
-	return(0);
-}
-
-
-static u32 add_dword( u32 **p_buffer, u32 value, u32 *used, u32 *avail)
-{
-	if ((*used + 4) > *avail)
-		return(1);
-
-	**p_buffer = value;
-	(*p_buffer)++;
-	*used+=4;
-	return(0);
-}
-
-
-/*
- * check_for_compaq_ROM
- *
- * this routine verifies that the ROM OEM string is 'COMPAQ'
- *
- * returns 0 for non-Compaq ROM, 1 for Compaq ROM
- */
-static int check_for_compaq_ROM (void *rom_start)
-{
-	u8 temp1, temp2, temp3, temp4, temp5, temp6;
-	int result = 0;
-
-	temp1 = readb(rom_start + 0xffea + 0);
-	temp2 = readb(rom_start + 0xffea + 1);
-	temp3 = readb(rom_start + 0xffea + 2);
-	temp4 = readb(rom_start + 0xffea + 3);
-	temp5 = readb(rom_start + 0xffea + 4);
-	temp6 = readb(rom_start + 0xffea + 5);
-	if ((temp1 == 'C') &&
-	    (temp2 == 'O') &&
-	    (temp3 == 'M') &&
-	    (temp4 == 'P') &&
-	    (temp5 == 'A') &&
-	    (temp6 == 'Q')) {
-		result = 1;
-	}
-	dbg ("%s - returned %d\n", __FUNCTION__, result);
-	return result;
-}
-
-
-static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
-{
-	unsigned long flags;
-	int op = operation;
-	int ret_val;
-	
-	if (!compaq_int15_entry_point)
-		return -ENODEV;
-	
-	spin_lock_irqsave(&int15_lock, flags);
-	__asm__ (
-		"xorl   %%ebx,%%ebx\n" \
-		"xorl    %%edx,%%edx\n" \
-		"pushf\n" \
-		"push %%cs\n" \
-		"cli\n" \
-		"call *%6\n"
-		: "=c" (*buf_size), "=a" (ret_val)
-		: "a" (op), "c" (*buf_size), "S" (ev_name),
-		"D" (buffer), "m" (compaq_int15_entry_point)
-		: "%ebx", "%edx");
-	spin_unlock_irqrestore(&int15_lock, flags);
-	
-	return((ret_val & 0xFF00) >> 8);
-}
-
-
-/*
- * load_HRT
- *
- * Read the hot plug Resource Table from NVRAM
- */
-static int load_HRT (void *rom_start)
-{
-	u32 available;
-	u32 temp_dword;
-	u8 temp_byte = 0xFF;
-	u32 rc;
-
-	if (!check_for_compaq_ROM(rom_start)) {
-		return -ENODEV;
-	}
-
-	available = 1024;
-
-	// Now load the EV
-	temp_dword = available;
-
-	rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);
-
-	evbuffer_length = temp_dword;
-
-	// We're maintaining the resource lists so write FF to invalidate old info
-	temp_dword = 1;
-
-	rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);
-
-	return rc;
-}
-
-
-/*
- * store_HRT
- *
- * Save the hot plug Resource Table in NVRAM
- */
-static u32 store_HRT (void *rom_start)
-{
-	u32 *buffer;
-	u32 *pFill;
-	u32 usedbytes;
-	u32 available;
-	u32 temp_dword;
-	u32 rc;
-	u8 loop;
-	u8 numCtrl = 0;
-	struct controller *ctrl;
-	struct pci_resource *resNode;
-	struct ev_hrt_header *p_EV_header;
-	struct ev_hrt_ctrl *p_ev_ctrl;
-
-	available = 1024;
-
-	if (!check_for_compaq_ROM(rom_start)) {
-		return(1);
-	}
-
-	buffer = (u32*) evbuffer;
-
-	if (!buffer)
-		return(1);
-
-	pFill = buffer;
-	usedbytes = 0;
-
-	p_EV_header = (struct ev_hrt_header *) pFill;
-
-	ctrl = cpqhp_ctrl_list;
-	
-	// The revision of this structure
-	rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available);
-	if (rc)
-		return(rc);
-
-	// The number of controllers
-	rc = add_byte( &pFill, 1, &usedbytes, &available);
-	if (rc)
-		return(rc);
-
-	while (ctrl) {
-		p_ev_ctrl = (struct ev_hrt_ctrl *) pFill;
-
-		numCtrl++;
-
-		// The bus number
-		rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available);
-		if (rc)
-			return(rc);
-
-		// The device Number
-		rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
-		if (rc)
-			return(rc);
-
-		// The function Number
-		rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
-		if (rc)
-			return(rc);
-
-		// Skip the number of available entries
-		rc = add_dword( &pFill, 0, &usedbytes, &available);
-		if (rc)
-			return(rc);
-
-		// Figure out memory Available
-
-		resNode = ctrl->mem_head;
-
-		loop = 0;
-
-		while (resNode) {
-			loop ++;
-
-			// base
-			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
-			if (rc)
-				return(rc);
-
-			// length
-			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
-			if (rc)
-				return(rc);
-
-			resNode = resNode->next;
-		}
-
-		// Fill in the number of entries
-		p_ev_ctrl->mem_avail = loop;
-
-		// Figure out prefetchable memory Available
-
-		resNode = ctrl->p_mem_head;
-
-		loop = 0;
-
-		while (resNode) {
-			loop ++;
-
-			// base
-			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
-			if (rc)
-				return(rc);
-
-			// length
-			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
-			if (rc)
-				return(rc);
-
-			resNode = resNode->next;
-		}
-
-		// Fill in the number of entries
-		p_ev_ctrl->p_mem_avail = loop;
-
-		// Figure out IO Available
-
-		resNode = ctrl->io_head;
-
-		loop = 0;
-
-		while (resNode) {
-			loop ++;
-
-			// base
-			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
-			if (rc)
-				return(rc);
-
-			// length
-			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
-			if (rc)
-				return(rc);
-
-			resNode = resNode->next;
-		}
-
-		// Fill in the number of entries
-		p_ev_ctrl->io_avail = loop;
-
-		// Figure out bus Available
-
-		resNode = ctrl->bus_head;
-
-		loop = 0;
-
-		while (resNode) {
-			loop ++;
-
-			// base
-			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
-			if (rc)
-				return(rc);
-
-			// length
-			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
-			if (rc)
-				return(rc);
-
-			resNode = resNode->next;
-		}
-
-		// Fill in the number of entries
-		p_ev_ctrl->bus_avail = loop;
-
-		ctrl = ctrl->next;
-	}
-	
-	p_EV_header->num_of_ctrl = numCtrl;
-
-	// Now store the EV
-
-	temp_dword = usedbytes;
-
-	rc = access_EV(WRITE_EV, "CQTHPS", (u8*) buffer, &temp_dword);
-
-	dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword);
-
-	evbuffer_length = temp_dword;
-
-	if (rc) {
-		err(msg_unable_to_save);
-		return(1);
-	}
-
-	return(0);
-}
-
-
-void compaq_nvram_init (void *rom_start)
-{
-	if (rom_start) {
-		compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
-	}
-	dbg("int15 entry  = %p\n", compaq_int15_entry_point);
-
-	/* initialize our int15 lock */
-	spin_lock_init(&int15_lock);
-}
-
-
-int compaq_nvram_load (void *rom_start, struct controller *ctrl)
-{
-	u8 bus, device, function;
-	u8 nummem, numpmem, numio, numbus;
-	u32 rc;
-	u8 *p_byte;
-	struct pci_resource *mem_node;
-	struct pci_resource *p_mem_node;
-	struct pci_resource *io_node;
-	struct pci_resource *bus_node;
-	struct ev_hrt_ctrl *p_ev_ctrl;
-	struct ev_hrt_header *p_EV_header;
-
-	if (!evbuffer_init) {
-		// Read the resource list information in from NVRAM
-		if (load_HRT(rom_start))
-			memset (evbuffer, 0, 1024);
-
-		evbuffer_init = 1;
-	}
-
-	// If we saved information in NVRAM, use it now
-	p_EV_header = (struct ev_hrt_header *) evbuffer;
-
-	// The following code is for systems where version 1.0 of this
-	// driver has been loaded, but doesn't support the hardware.
-	// In that case, the driver would incorrectly store something
-	// in NVRAM.
-	if ((p_EV_header->Version == 2) ||
-	    ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
-		p_byte = &(p_EV_header->next);
-
-		p_ev_ctrl = (struct ev_hrt_ctrl *) &(p_EV_header->next);
-
-		p_byte += 3;
-
-		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-			return 2;
-
-		bus = p_ev_ctrl->bus;
-		device = p_ev_ctrl->device;
-		function = p_ev_ctrl->function;
-
-		while ((bus != ctrl->bus) ||
-		       (device != PCI_SLOT(ctrl->pci_dev->devfn)) || 
-		       (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
-			nummem = p_ev_ctrl->mem_avail;
-			numpmem = p_ev_ctrl->p_mem_avail;
-			numio = p_ev_ctrl->io_avail;
-			numbus = p_ev_ctrl->bus_avail;
-
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return 2;
-
-			// Skip forward to the next entry
-			p_byte += (nummem + numpmem + numio + numbus) * 8;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return 2;
-
-			p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;
-
-			p_byte += 3;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return 2;
-
-			bus = p_ev_ctrl->bus;
-			device = p_ev_ctrl->device;
-			function = p_ev_ctrl->function;
-		}
-
-		nummem = p_ev_ctrl->mem_avail;
-		numpmem = p_ev_ctrl->p_mem_avail;
-		numio = p_ev_ctrl->io_avail;
-		numbus = p_ev_ctrl->bus_avail;
-
-		p_byte += 4;
-
-		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-			return 2;
-
-		while (nummem--) {
-			mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!mem_node)
-				break;
-
-			mem_node->base = *(u32*)p_byte;
-			dbg("mem base = %8.8x\n",mem_node->base);
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
-				kfree(mem_node);
-				return 2;
-			}
-
-			mem_node->length = *(u32*)p_byte;
-			dbg("mem length = %8.8x\n",mem_node->length);
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
-				kfree(mem_node);
-				return 2;
-			}
-
-			mem_node->next = ctrl->mem_head;
-			ctrl->mem_head = mem_node;
-		}
-
-		while (numpmem--) {
-			p_mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!p_mem_node)
-				break;
-
-			p_mem_node->base = *(u32*)p_byte;
-			dbg("pre-mem base = %8.8x\n",p_mem_node->base);
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
-				kfree(p_mem_node);
-				return 2;
-			}
-
-			p_mem_node->length = *(u32*)p_byte;
-			dbg("pre-mem length = %8.8x\n",p_mem_node->length);
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
-				kfree(p_mem_node);
-				return 2;
-			}
-
-			p_mem_node->next = ctrl->p_mem_head;
-			ctrl->p_mem_head = p_mem_node;
-		}
-
-		while (numio--) {
-			io_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!io_node)
-				break;
-
-			io_node->base = *(u32*)p_byte;
-			dbg("io base = %8.8x\n",io_node->base);
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
-				kfree(io_node);
-				return 2;
-			}
-
-			io_node->length = *(u32*)p_byte;
-			dbg("io length = %8.8x\n",io_node->length);
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
-				kfree(io_node);
-				return 2;
-			}
-
-			io_node->next = ctrl->io_head;
-			ctrl->io_head = io_node;
-		}
-
-		while (numbus--) {
-			bus_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-
-			if (!bus_node)
-				break;
-
-			bus_node->base = *(u32*)p_byte;
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
-				kfree(bus_node);
-				return 2;
-			}
-
-			bus_node->length = *(u32*)p_byte;
-			p_byte += 4;
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
-				kfree(bus_node);
-				return 2;
-			}
-
-			bus_node->next = ctrl->bus_head;
-			ctrl->bus_head = bus_node;
-		}
-
-		// If all of the following fail, we don't have any resources for
-		// hot plug add
-		rc = 1;
-		rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
-		rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
-		rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
-		rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
-
-		if (rc)
-			return(rc);
-	} else {
-		if ((evbuffer[0] != 0) && (!ctrl->push_flag)) 
-			return 1;
-	}
-
-	return 0;
-}
-
-	
-int compaq_nvram_store (void *rom_start)
-{
-	int rc = 1;
-
-	if (rom_start == NULL)
-		return -ENODEV;
-
-	if (evbuffer_init) {
-		rc = store_HRT(rom_start);
-		if (rc) {
-			err(msg_unable_to_save);
-		}
-	}
-	return rc;
-}
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpqphp_nvram.h linux-2.5.70-bk10/drivers/hotplug/cpqphp_nvram.h
--- linux-2.5.70-bk9/drivers/hotplug/cpqphp_nvram.h	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpqphp_nvram.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,57 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#ifndef _CPQPHP_NVRAM_H
-#define _CPQPHP_NVRAM_H
-
-#ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
-
-static inline void compaq_nvram_init (void *rom_start)
-{
-	return;
-}
-
-static inline int compaq_nvram_load (void *rom_start, struct controller *ctrl)
-{
-	return 0;
-}
-
-static inline int compaq_nvram_store (void *rom_start)
-{
-	return 0;
-}
-
-#else
-
-extern void compaq_nvram_init	(void *rom_start);
-extern int compaq_nvram_load	(void *rom_start, struct controller *ctrl);
-extern int compaq_nvram_store	(void *rom_start);
-
-#endif
-
-#endif
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpqphp_pci.c linux-2.5.70-bk10/drivers/hotplug/cpqphp_pci.c
--- linux-2.5.70-bk9/drivers/hotplug/cpqphp_pci.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpqphp_pci.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1548 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/proc_fs.h>
-#include <linux/pci.h>
-#include "cpqphp.h"
-#include "cpqphp_nvram.h"
-#include "../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
-
-
-u8 cpqhp_nic_irq;
-u8 cpqhp_disk_irq;
-
-static u16 unused_IRQ;
-
-/*
- * detect_HRT_floating_pointer
- *
- * find the Hot Plug Resource Table in the specified region of memory.
- *
- */
-static void *detect_HRT_floating_pointer(void *begin, void *end)
-{
-	void *fp;
-	void *endp;
-	u8 temp1, temp2, temp3, temp4;
-	int status = 0;
-
-	endp = (end - sizeof(struct hrt) + 1);
-
-	for (fp = begin; fp <= endp; fp += 16) {
-		temp1 = readb(fp + SIG0);
-		temp2 = readb(fp + SIG1);
-		temp3 = readb(fp + SIG2);
-		temp4 = readb(fp + SIG3);
-		if (temp1 == '$' &&
-		    temp2 == 'H' &&
-		    temp3 == 'R' &&
-		    temp4 == 'T') {
-			status = 1;
-			break;
-		}
-	}
-
-	if (!status)
-		fp = NULL;
-
-	dbg("Discovered Hotplug Resource Table at %p\n", fp);
-	return fp;
-}
-
-
-int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  
-{
-	unsigned char bus;
-	struct pci_bus *child;
-	int num;
-
-	if (func->pci_dev == NULL)
-		func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
-
-	/* No pci device, we need to create it then */
-	if (func->pci_dev == NULL) {
-		dbg("INFO: pci_dev still null\n");
-
-		num = pci_scan_slot(ctrl->pci_dev->bus, PCI_DEVFN(func->device, func->function));
-		if (num)
-			pci_bus_add_devices(ctrl->pci_dev->bus);
-
-		func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
-		if (func->pci_dev == NULL) {
-			dbg("ERROR: pci_dev still null\n");
-			return 0;
-		}
-	}
-
-	if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-		pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
-		child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
-		pci_do_scan_bus(child);
-	}
-
-	return 0;
-}
-
-
-int cpqhp_unconfigure_device(struct pci_func* func) 
-{
-	int j;
-	
-	dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
-
-	for (j=0; j<8 ; j++) {
-		struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
-		if (temp)
-			pci_remove_bus_device(temp);
-	}
-	return 0;
-}
-
-static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
-{
-	u32 vendID = 0;
-
-	if (pci_bus_read_config_dword (bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
-		return -1;
-	if (vendID == 0xffffffff)
-		return -1;
-	return pci_bus_read_config_dword (bus, devfn, offset, value);
-}
-
-
-/*
- * cpqhp_set_irq
- *
- * @bus_num: bus number of PCI device
- * @dev_num: device number of PCI device
- * @slot: pointer to u8 where slot number will be returned
- */
-int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
-{
-	int rc;
-	u16 temp_word;
-	struct pci_dev fakedev;
-	struct pci_bus fakebus;
-
-	fakedev.devfn = dev_num << 3;
-	fakedev.bus = &fakebus;
-	fakebus.number = bus_num;
-	dbg("%s: dev %d, bus %d, pin %d, num %d\n",
-	    __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
-	rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
-	dbg("%s: rc %d\n", __FUNCTION__, rc);
-	if (!rc)
-		return !rc;
-
-	// set the Edge Level Control Register (ELCR)
-	temp_word = inb(0x4d0);
-	temp_word |= inb(0x4d1) << 8;
-
-	temp_word |= 0x01 << irq_num;
-
-	// This should only be for x86 as it sets the Edge Level Control Register
-	outb((u8) (temp_word & 0xFF), 0x4d0);
-	outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
-
-	return 0;
-}
-
-
-/*
- * WTF??? This function isn't in the code, yet a function calls it, but the 
- * compiler optimizes it away?  strange.  Here as a placeholder to keep the 
- * compiler happy.
- */
-static int PCI_ScanBusNonBridge (u8 bus, u8 device)
-{
-	return 0;
-}
-
-static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
-{
-	u8 tdevice;
-	u32 work;
-	u8 tbus;
-
-	ctrl->pci_bus->number = bus_num;
-
-	for (tdevice = 0; tdevice < 0x100; tdevice++) {
-		//Scan for access first
-		if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
-			continue;
-		dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
-		//Yep we got one. Not a bridge ?
-		if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
-			*dev_num = tdevice;
-			dbg("found it !\n");
-			return 0;
-		}
-	}
-	for (tdevice = 0; tdevice < 0x100; tdevice++) {
-		//Scan for access first
-		if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
-			continue;
-		dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
-		//Yep we got one. bridge ?
-		if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
-			pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
-			dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
-			if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
-				return 0;
-		}
-	}
-
-	return -1;
-}
-
-
-static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
-{
-	struct irq_routing_table *PCIIRQRoutingInfoLength;
-	long len;
-	long loop;
-	u32 work;
-
-	u8 tbus, tdevice, tslot;
-
-	PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
-	if (!PCIIRQRoutingInfoLength)
-		return -1;
-
-	len = (PCIIRQRoutingInfoLength->size -
-	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
-	// Make sure I got at least one entry
-	if (len == 0) {
-		if (PCIIRQRoutingInfoLength != NULL)
-			kfree(PCIIRQRoutingInfoLength );
-		return -1;
-	}
-
-	for (loop = 0; loop < len; ++loop) {
-		tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
-		tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn;
-		tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
-
-		if (tslot == slot) {
-			*bus_num = tbus;
-			*dev_num = tdevice;
-			ctrl->pci_bus->number = tbus;
-			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
-			if (!nobridge || (work == 0xffffffff)) {
-				if (PCIIRQRoutingInfoLength != NULL)
-					kfree(PCIIRQRoutingInfoLength );
-				return 0;
-			}
-
-			dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
-			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
-			dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);
-
-			if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
-				pci_bus_read_config_byte (ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
-				dbg("Scan bus for Non Bridge: bus %d\n", tbus);
-				if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
-					*bus_num = tbus;
-					if (PCIIRQRoutingInfoLength != NULL)
-						kfree(PCIIRQRoutingInfoLength );
-					return 0;
-				}
-			} else {
-				if (PCIIRQRoutingInfoLength != NULL)
-					kfree(PCIIRQRoutingInfoLength );
-				return 0;
-			}
-
-		}
-	}
-	if (PCIIRQRoutingInfoLength != NULL)
-		kfree(PCIIRQRoutingInfoLength );
-	return -1;
-}
-
-
-int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot)
-{
-	return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0);	//plain (bridges allowed)
-}
-
-
-/* More PCI configuration routines; this time centered around hotplug controller */
-
-
-/*
- * cpqhp_save_config
- *
- * Reads configuration for all slots in a PCI bus and saves info.
- *
- * Note:  For non-hot plug busses, the slot # saved is the device #
- *
- * returns 0 if success
- */
-int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
-{
-	long rc;
-	u8 class_code;
-	u8 header_type;
-	u32 ID;
-	u8 secondary_bus;
-	struct pci_func *new_slot;
-	int sub_bus;
-	int FirstSupported;
-	int LastSupported;
-	int max_functions;
-	int function;
-	u8 DevError;
-	int device = 0;
-	int cloop = 0;
-	int stop_it;
-	int index;
-
-	//              Decide which slots are supported
-
-	if (is_hot_plug) {
-		//*********************************
-		// is_hot_plug is the slot mask
-		//*********************************
-		FirstSupported = is_hot_plug >> 4;
-		LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
-	} else {
-		FirstSupported = 0;
-		LastSupported = 0x1F;
-	}
-
-	//     Save PCI configuration space for all devices in supported slots
-	ctrl->pci_bus->number = busnumber;
-	for (device = FirstSupported; device <= LastSupported; device++) {
-		ID = 0xFFFFFFFF;
-		rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
-
-		if (ID != 0xFFFFFFFF) {	  //  device in slot
-			rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
-			if (rc)
-				return rc;
-
-			rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
-			if (rc)
-				return rc;
-
-			// If multi-function device, set max_functions to 8
-			if (header_type & 0x80)
-				max_functions = 8;
-			else
-				max_functions = 1;
-
-			function = 0;
-
-			do {
-				DevError = 0;
-
-				if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {   // P-P Bridge
-					//  Recurse the subordinate bus
-					//  get the subordinate bus number
-					rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
-					if (rc) {
-						return rc;
-					} else {
-						sub_bus = (int) secondary_bus;
-
-						// Save secondary bus cfg spc
-						// with this recursive call.
-						rc = cpqhp_save_config(ctrl, sub_bus, 0);
-						if (rc)
-							return rc;
-						ctrl->pci_bus->number = busnumber;
-					}
-				}
-
-				index = 0;
-				new_slot = cpqhp_slot_find(busnumber, device, index++);
-				while (new_slot && 
-				       (new_slot->function != (u8) function))
-					new_slot = cpqhp_slot_find(busnumber, device, index++);
-
-				if (!new_slot) {
-					// Setup slot structure.
-					new_slot = cpqhp_slot_create(busnumber);
-
-					if (new_slot == NULL)
-						return(1);
-				}
-
-				new_slot->bus = (u8) busnumber;
-				new_slot->device = (u8) device;
-				new_slot->function = (u8) function;
-				new_slot->is_a_board = 1;
-				new_slot->switch_save = 0x10;
-				// In case of unsupported board
-				new_slot->status = DevError;
-				new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
-
-				for (cloop = 0; cloop < 0x20; cloop++) {
-					rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
-					if (rc)
-						return rc;
-				}
-
-				function++;
-
-				stop_it = 0;
-
-				//  this loop skips to the next present function
-				//  reading in Class Code and Header type.
-
-				while ((function < max_functions)&&(!stop_it)) {
-					rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
-					if (ID == 0xFFFFFFFF) {	 // nothing there.
-						function++;
-					} else {  // Something there
-						rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
-						if (rc)
-							return rc;
-
-						rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
-						if (rc)
-							return rc;
-
-						stop_it++;
-					}
-				}
-
-			} while (function < max_functions);
-		}		// End of IF (device in slot?)
-		else if (is_hot_plug) {
-			// Setup slot structure with entry for empty slot
-			new_slot = cpqhp_slot_create(busnumber);
-
-			if (new_slot == NULL) {
-				return(1);
-			}
-
-			new_slot->bus = (u8) busnumber;
-			new_slot->device = (u8) device;
-			new_slot->function = 0;
-			new_slot->is_a_board = 0;
-			new_slot->presence_save = 0;
-			new_slot->switch_save = 0;
-		}
-	}			// End of FOR loop
-
-	return(0);
-}
-
-
-/*
- * cpqhp_save_slot_config
- *
- * Saves configuration info for all PCI devices in a given slot
- * including subordinate busses.
- *
- * returns 0 if success
- */
-int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
-{
-	long rc;
-	u8 class_code;
-	u8 header_type;
-	u32 ID;
-	u8 secondary_bus;
-	int sub_bus;
-	int max_functions;
-	int function;
-	int cloop = 0;
-	int stop_it;
-
-	ID = 0xFFFFFFFF;
-
-	ctrl->pci_bus->number = new_slot->bus;
-	pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
-
-	if (ID != 0xFFFFFFFF) {	  //  device in slot
-		pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
-		pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
-
-		if (header_type & 0x80)	// Multi-function device
-			max_functions = 8;
-		else
-			max_functions = 1;
-
-		function = 0;
-
-		do {
-			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
-				//  Recurse the subordinate bus
-				pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
-
-				sub_bus = (int) secondary_bus;
-
-				// Save the config headers for the secondary bus.
-				rc = cpqhp_save_config(ctrl, sub_bus, 0);
-				if (rc)
-					return(rc);
-				ctrl->pci_bus->number = new_slot->bus;
-
-			}	// End of IF
-
-			new_slot->status = 0;
-
-			for (cloop = 0; cloop < 0x20; cloop++) {
-				pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
-			}
-
-			function++;
-
-			stop_it = 0;
-
-			//  this loop skips to the next present function
-			//  reading in the Class Code and the Header type.
-
-			while ((function < max_functions) && (!stop_it)) {
-				pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
-
-				if (ID == 0xFFFFFFFF) {	 // nothing there.
-					function++;
-				} else {  // Something there
-					pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
-
-					pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
-
-					stop_it++;
-				}
-			}
-
-		} while (function < max_functions);
-	}			// End of IF (device in slot?)
-	else {
-		return(2);
-	}
-
-	return(0);
-}
-
-
-/*
- * cpqhp_save_base_addr_length
- *
- * Saves the length of all base address registers for the
- * specified slot.  this is for hot plug REPLACE
- *
- * returns 0 if success
- */
-int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
-{
-	u8 cloop;
-	u8 header_type;
-	u8 secondary_bus;
-	u8 type;
-	int sub_bus;
-	u32 temp_register;
-	u32 base;
-	u32 rc;
-	struct pci_func *next;
-	int index = 0;
-	struct pci_bus *pci_bus = ctrl->pci_bus;
-	unsigned int devfn;
-
-	func = cpqhp_slot_find(func->bus, func->device, index++);
-
-	while (func != NULL) {
-		pci_bus->number = func->bus;
-		devfn = PCI_DEVFN(func->device, func->function);
-
-		// Check for Bridge
-		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
-
-		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
-			// PCI-PCI Bridge
-			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
-
-			sub_bus = (int) secondary_bus;
-
-			next = cpqhp_slot_list[sub_bus];
-
-			while (next != NULL) {
-				rc = cpqhp_save_base_addr_length(ctrl, next);
-
-				if (rc)
-					return(rc);
-
-				next = next->next;
-			}
-			pci_bus->number = func->bus;
-
-			//FIXME: this loop is duplicated in the non-bridge case.  The two could be rolled together
-			// Figure out IO and memory base lengths
-			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
-				temp_register = 0xFFFFFFFF;
-				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
-
-				if (base) {  // If this register is implemented
-					if (base & 0x01L) {
-						// IO base
-						// set base = amount of IO space requested
-						base = base & 0xFFFFFFFE;
-						base = (~base) + 1;
-
-						type = 1;
-					} else {
-						// memory base
-						base = base & 0xFFFFFFF0;
-						base = (~base) + 1;
-
-						type = 0;
-					}
-				} else {
-					base = 0x0L;
-					type = 0;
-				}
-
-				// Save information in slot structure
-				func->base_length[(cloop - 0x10) >> 2] =
-				base;
-				func->base_type[(cloop - 0x10) >> 2] = type;
-
-			}	// End of base register loop
-
-
-		} else if ((header_type & 0x7F) == 0x00) {	  // PCI-PCI Bridge
-			// Figure out IO and memory base lengths
-			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
-				temp_register = 0xFFFFFFFF;
-				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
-
-				if (base) {  // If this register is implemented
-					if (base & 0x01L) {
-						// IO base
-						// base = amount of IO space requested
-						base = base & 0xFFFFFFFE;
-						base = (~base) + 1;
-
-						type = 1;
-					} else {
-						// memory base
-						// base = amount of memory space requested
-						base = base & 0xFFFFFFF0;
-						base = (~base) + 1;
-
-						type = 0;
-					}
-				} else {
-					base = 0x0L;
-					type = 0;
-				}
-
-				// Save information in slot structure
-				func->base_length[(cloop - 0x10) >> 2] = base;
-				func->base_type[(cloop - 0x10) >> 2] = type;
-
-			}	// End of base register loop
-
-		} else {	  // Some other unknown header type
-		}
-
-		// find the next device in this slot
-		func = cpqhp_slot_find(func->bus, func->device, index++);
-	}
-
-	return(0);
-}
-
-
-/*
- * cpqhp_save_used_resources
- *
- * Stores used resource information for existing boards.  this is
- * for boards that were in the system when this driver was loaded.
- * this function is for hot plug ADD
- *
- * returns 0 if success
- */
-int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
-{
-	u8 cloop;
-	u8 header_type;
-	u8 secondary_bus;
-	u8 temp_byte;
-	u8 b_base;
-	u8 b_length;
-	u16 command;
-	u16 save_command;
-	u16 w_base;
-	u16 w_length;
-	u32 temp_register;
-	u32 save_base;
-	u32 base;
-	int index = 0;
-	struct pci_resource *mem_node;
-	struct pci_resource *p_mem_node;
-	struct pci_resource *io_node;
-	struct pci_resource *bus_node;
-	struct pci_bus *pci_bus = ctrl->pci_bus;
-	unsigned int devfn;
-
-	func = cpqhp_slot_find(func->bus, func->device, index++);
-
-	while ((func != NULL) && func->is_a_board) {
-		pci_bus->number = func->bus;
-		devfn = PCI_DEVFN(func->device, func->function);
-
-		// Save the command register
-		pci_bus_read_config_word (pci_bus, devfn, PCI_COMMAND, &save_command);
-
-		// disable card
-		command = 0x00;
-		pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
-
-		// Check for Bridge
-		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
-
-		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
-			// Clear Bridge Control Register
-			command = 0x00;
-			pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
-			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
-			pci_bus_read_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
-
-			bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-			if (!bus_node)
-				return -ENOMEM;
-
-			bus_node->base = secondary_bus;
-			bus_node->length = temp_byte - secondary_bus + 1;
-
-			bus_node->next = func->bus_head;
-			func->bus_head = bus_node;
-
-			// Save IO base and Limit registers
-			pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_BASE, &b_base);
-			pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_LIMIT, &b_length);
-
-			if ((b_base <= b_length) && (save_command & 0x01)) {
-				io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-				if (!io_node)
-					return -ENOMEM;
-
-				io_node->base = (b_base & 0xF0) << 8;
-				io_node->length = (b_length - b_base + 0x10) << 8;
-
-				io_node->next = func->io_head;
-				func->io_head = io_node;
-			}
-
-			// Save memory base and Limit registers
-			pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
-			pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
-
-			if ((w_base <= w_length) && (save_command & 0x02)) {
-				mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-				if (!mem_node)
-					return -ENOMEM;
-
-				mem_node->base = w_base << 16;
-				mem_node->length = (w_length - w_base + 0x10) << 16;
-
-				mem_node->next = func->mem_head;
-				func->mem_head = mem_node;
-			}
-
-			// Save prefetchable memory base and Limit registers
-			pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
-			pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
-
-			if ((w_base <= w_length) && (save_command & 0x02)) {
-				p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-				if (!p_mem_node)
-					return -ENOMEM;
-
-				p_mem_node->base = w_base << 16;
-				p_mem_node->length = (w_length - w_base + 0x10) << 16;
-
-				p_mem_node->next = func->p_mem_head;
-				func->p_mem_head = p_mem_node;
-			}
-			// Figure out IO and memory base lengths
-			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
-				pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
-
-				temp_register = 0xFFFFFFFF;
-				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
-
-				temp_register = base;
-
-				if (base) {  // If this register is implemented
-					if (((base & 0x03L) == 0x01)
-					    && (save_command & 0x01)) {
-						// IO base
-						// set temp_register = amount of IO space requested
-						temp_register = base & 0xFFFFFFFE;
-						temp_register = (~temp_register) + 1;
-
-						io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-						if (!io_node)
-							return -ENOMEM;
-
-						io_node->base =
-						save_base & (~0x03L);
-						io_node->length = temp_register;
-
-						io_node->next = func->io_head;
-						func->io_head = io_node;
-					} else
-						if (((base & 0x0BL) == 0x08)
-						    && (save_command & 0x02)) {
-						// prefetchable memory base
-						temp_register = base & 0xFFFFFFF0;
-						temp_register = (~temp_register) + 1;
-
-						p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-						if (!p_mem_node)
-							return -ENOMEM;
-
-						p_mem_node->base = save_base & (~0x0FL);
-						p_mem_node->length = temp_register;
-
-						p_mem_node->next = func->p_mem_head;
-						func->p_mem_head = p_mem_node;
-					} else
-						if (((base & 0x0BL) == 0x00)
-						    && (save_command & 0x02)) {
-						// prefetchable memory base
-						temp_register = base & 0xFFFFFFF0;
-						temp_register = (~temp_register) + 1;
-
-						mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-						if (!mem_node)
-							return -ENOMEM;
-
-						mem_node->base = save_base & (~0x0FL);
-						mem_node->length = temp_register;
-
-						mem_node->next = func->mem_head;
-						func->mem_head = mem_node;
-					} else
-						return(1);
-				}
-			}	// End of base register loop
-		} else if ((header_type & 0x7F) == 0x00) {	  // Standard header
-			// Figure out IO and memory base lengths
-			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
-				pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
-
-				temp_register = 0xFFFFFFFF;
-				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
-
-				temp_register = base;
-
-				if (base) {	  // If this register is implemented
-					if (((base & 0x03L) == 0x01)
-					    && (save_command & 0x01)) {
-						// IO base
-						// set temp_register = amount of IO space requested
-						temp_register = base & 0xFFFFFFFE;
-						temp_register = (~temp_register) + 1;
-
-						io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-						if (!io_node)
-							return -ENOMEM;
-
-						io_node->base = save_base & (~0x01L);
-						io_node->length = temp_register;
-
-						io_node->next = func->io_head;
-						func->io_head = io_node;
-					} else
-						if (((base & 0x0BL) == 0x08)
-						    && (save_command & 0x02)) {
-						// prefetchable memory base
-						temp_register = base & 0xFFFFFFF0;
-						temp_register = (~temp_register) + 1;
-
-						p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-						if (!p_mem_node)
-							return -ENOMEM;
-
-						p_mem_node->base = save_base & (~0x0FL);
-						p_mem_node->length = temp_register;
-
-						p_mem_node->next = func->p_mem_head;
-						func->p_mem_head = p_mem_node;
-					} else
-						if (((base & 0x0BL) == 0x00)
-						    && (save_command & 0x02)) {
-						// prefetchable memory base
-						temp_register = base & 0xFFFFFFF0;
-						temp_register = (~temp_register) + 1;
-
-						mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-						if (!mem_node)
-							return -ENOMEM;
-
-						mem_node->base = save_base & (~0x0FL);
-						mem_node->length = temp_register;
-
-						mem_node->next = func->mem_head;
-						func->mem_head = mem_node;
-					} else
-						return(1);
-				}
-			}	// End of base register loop
-		} else {	  // Some other unknown header type
-		}
-
-		// find the next device in this slot
-		func = cpqhp_slot_find(func->bus, func->device, index++);
-	}
-
-	return(0);
-}
-
-
-/*
- * cpqhp_configure_board
- *
- * Copies saved configuration information to one slot.
- * this is called recursively for bridge devices.
- * this is for hot plug REPLACE!
- *
- * returns 0 if success
- */
-int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
-{
-	int cloop;
-	u8 header_type;
-	u8 secondary_bus;
-	int sub_bus;
-	struct pci_func *next;
-	u32 temp;
-	u32 rc;
-	int index = 0;
-	struct pci_bus *pci_bus = ctrl->pci_bus;
-	unsigned int devfn;
-
-	func = cpqhp_slot_find(func->bus, func->device, index++);
-
-	while (func != NULL) {
-		pci_bus->number = func->bus;
-		devfn = PCI_DEVFN(func->device, func->function);
-
-		// Start at the top of config space so that the control
-		// registers are programmed last
-		for (cloop = 0x3C; cloop > 0; cloop -= 4) {
-			pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
-		}
-
-		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
-
-		// If this is a bridge device, restore subordinate devices
-		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
-			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
-
-			sub_bus = (int) secondary_bus;
-
-			next = cpqhp_slot_list[sub_bus];
-
-			while (next != NULL) {
-				rc = cpqhp_configure_board(ctrl, next);
-
-				if (rc)
-					return rc;
-
-				next = next->next;
-			}
-		} else {
-
-			// Check all the base Address Registers to make sure
-			// they are the same.  If not, the board is different.
-
-			for (cloop = 16; cloop < 40; cloop += 4) {
-				pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
-
-				if (temp != func->config_space[cloop >> 2]) {
-					dbg("Config space compare failure!!! offset = %x\n", cloop);
-					dbg("bus = %x, device = %x, function = %x\n", func->bus, func->device, func->function);
-					dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop >> 2]);
-					return 1;
-				}
-			}
-		}
-
-		func->configured = 1;
-
-		func = cpqhp_slot_find(func->bus, func->device, index++);
-	}
-
-	return 0;
-}
-
-
-/*
- * cpqhp_valid_replace
- *
- * this function checks to see if a board is the same as the
- * one it is replacing.  this check will detect if the device's
- * vendor or device id's are the same
- *
- * returns 0 if the board is the same nonzero otherwise
- */
-int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
-{
-	u8 cloop;
-	u8 header_type;
-	u8 secondary_bus;
-	u8 type;
-	u32 temp_register = 0;
-	u32 base;
-	u32 rc;
-	struct pci_func *next;
-	int index = 0;
-	struct pci_bus *pci_bus = ctrl->pci_bus;
-	unsigned int devfn;
-
-	if (!func->is_a_board)
-		return(ADD_NOT_SUPPORTED);
-
-	func = cpqhp_slot_find(func->bus, func->device, index++);
-
-	while (func != NULL) {
-		pci_bus->number = func->bus;
-		devfn = PCI_DEVFN(func->device, func->function);
-
-		pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
-
-		// No adapter present
-		if (temp_register == 0xFFFFFFFF)
-			return(NO_ADAPTER_PRESENT);
-
-		if (temp_register != func->config_space[0])
-			return(ADAPTER_NOT_SAME);
-
-		// Check for same revision number and class code
-		pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
-
-		// Adapter not the same
-		if (temp_register != func->config_space[0x08 >> 2])
-			return(ADAPTER_NOT_SAME);
-
-		// Check for Bridge
-		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
-
-		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
-			// In order to continue checking, we must program the
-			// bus registers in the bridge to respond to accesses
-			// for it's subordinate bus(es)
-
-			temp_register = func->config_space[0x18 >> 2];
-			pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
-
-			secondary_bus = (temp_register >> 8) & 0xFF;
-
-			next = cpqhp_slot_list[secondary_bus];
-
-			while (next != NULL) {
-				rc = cpqhp_valid_replace(ctrl, next);
-
-				if (rc)
-					return(rc);
-
-				next = next->next;
-			}
-
-		}
-		// Check to see if it is a standard config header
-		else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
-			// Check subsystem vendor and ID
-			pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
-
-			if (temp_register != func->config_space[0x2C >> 2]) {
-				// If it's a SMART-2 and the register isn't filled
-				// in, ignore the difference because
-				// they just have an old rev of the firmware
-
-				if (!((func->config_space[0] == 0xAE100E11)
-				      && (temp_register == 0x00L)))
-					return(ADAPTER_NOT_SAME);
-			}
-			// Figure out IO and memory base lengths
-			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
-				temp_register = 0xFFFFFFFF;
-				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
-				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
-				if (base) {	  // If this register is implemented
-					if (base & 0x01L) {
-						// IO base
-						// set base = amount of IO space requested
-						base = base & 0xFFFFFFFE;
-						base = (~base) + 1;
-
-						type = 1;
-					} else {
-						// memory base
-						base = base & 0xFFFFFFF0;
-						base = (~base) + 1;
-
-						type = 0;
-					}
-				} else {
-					base = 0x0L;
-					type = 0;
-				}
-
-				// Check information in slot structure
-				if (func->base_length[(cloop - 0x10) >> 2] != base)
-					return(ADAPTER_NOT_SAME);
-
-				if (func->base_type[(cloop - 0x10) >> 2] != type)
-					return(ADAPTER_NOT_SAME);
-
-			}	// End of base register loop
-
-		}		// End of (type 0 config space) else
-		else {
-			// this is not a type 0 or 1 config space header so
-			// we don't know how to do it
-			return(DEVICE_TYPE_NOT_SUPPORTED);
-		}
-
-		// Get the next function
-		func = cpqhp_slot_find(func->bus, func->device, index++);
-	}
-
-
-	return(0);
-}
-
-
-/*
- * cpqhp_find_available_resources
- *
- * Finds available memory, IO, and IRQ resources for programming
- * devices which may be added to the system
- * this function is for hot plug ADD!
- *
- * returns 0 if success
- */  
-int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
-{
-	u8 temp;
-	u8 populated_slot;
-	u8 bridged_slot;
-	void *one_slot;
-	struct pci_func *func = NULL;
-	int i = 10, index;
-	u32 temp_dword, rc;
-	struct pci_resource *mem_node;
-	struct pci_resource *p_mem_node;
-	struct pci_resource *io_node;
-	struct pci_resource *bus_node;
-	void *rom_resource_table;
-
-	rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
-	dbg("rom_resource_table = %p\n", rom_resource_table);
-
-	if (rom_resource_table == NULL) {
-		return -ENODEV;
-	}
-	// Sum all resources and setup resource maps
-	unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
-	dbg("unused_IRQ = %x\n", unused_IRQ);
-
-	temp = 0;
-	while (unused_IRQ) {
-		if (unused_IRQ & 1) {
-			cpqhp_disk_irq = temp;
-			break;
-		}
-		unused_IRQ = unused_IRQ >> 1;
-		temp++;
-	}
-
-	dbg("cpqhp_disk_irq= %d\n", cpqhp_disk_irq);
-	unused_IRQ = unused_IRQ >> 1;
-	temp++;
-
-	while (unused_IRQ) {
-		if (unused_IRQ & 1) {
-			cpqhp_nic_irq = temp;
-			break;
-		}
-		unused_IRQ = unused_IRQ >> 1;
-		temp++;
-	}
-
-	dbg("cpqhp_nic_irq= %d\n", cpqhp_nic_irq);
-	unused_IRQ = readl(rom_resource_table + PCIIRQ);
-
-	temp = 0;
-
-	if (!cpqhp_nic_irq) {
-		cpqhp_nic_irq = ctrl->cfgspc_irq;
-	}
-
-	if (!cpqhp_disk_irq) {
-		cpqhp_disk_irq = ctrl->cfgspc_irq;
-	}
-
-	dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
-
-	rc = compaq_nvram_load(rom_start, ctrl);
-	if (rc)
-		return rc;
-
-	one_slot = rom_resource_table + sizeof (struct hrt);
-
-	i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
-	dbg("number_of_entries = %d\n", i);
-
-	if (!readb(one_slot + SECONDARY_BUS)) {
-		return(1);
-	}
-
-	dbg("dev|IO base|length|Mem base|length|Pre base|length|PB SB MB\n");
-
-	while (i && readb(one_slot + SECONDARY_BUS)) {
-		u8 dev_func = readb(one_slot + DEV_FUNC);
-		u8 primary_bus = readb(one_slot + PRIMARY_BUS);
-		u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
-		u8 max_bus = readb(one_slot + MAX_BUS);
-		u16 io_base = readw(one_slot + IO_BASE);
-		u16 io_length = readw(one_slot + IO_LENGTH);
-		u16 mem_base = readw(one_slot + MEM_BASE);
-		u16 mem_length = readw(one_slot + MEM_LENGTH);
-		u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
-		u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
-
-		dbg("%2.2x | %4.4x  | %4.4x | %4.4x   | %4.4x | %4.4x   | %4.4x |%2.2x %2.2x %2.2x\n",
-		    dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
-		    primary_bus, secondary_bus, max_bus);
-
-		// If this entry isn't for our controller's bus, ignore it
-		if (primary_bus != ctrl->bus) {
-			i--;
-			one_slot += sizeof (struct slot_rt);
-			continue;
-		}
-		// find out if this entry is for an occupied slot
-		ctrl->pci_bus->number = primary_bus;
-		pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
-		dbg("temp_D_word = %x\n", temp_dword);
-
-		if (temp_dword != 0xFFFFFFFF) {
-			index = 0;
-			func = cpqhp_slot_find(primary_bus, dev_func >> 3, 0);
-
-			while (func && (func->function != (dev_func & 0x07))) {
-				dbg("func = %p (bus, dev, fun) = (%d, %d, %d)\n", func, primary_bus, dev_func >> 3, index);
-				func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
-			}
-
-			// If we can't find a match, skip this table entry
-			if (!func) {
-				i--;
-				one_slot += sizeof (struct slot_rt);
-				continue;
-			}
-			// this may not work and shouldn't be used
-			if (secondary_bus != primary_bus)
-				bridged_slot = 1;
-			else
-				bridged_slot = 0;
-
-			populated_slot = 1;
-		} else {
-			populated_slot = 0;
-			bridged_slot = 0;
-		}
-
-
-		// If we've got a valid IO base, use it
-
-		temp_dword = io_base + io_length;
-
-		if ((io_base) && (temp_dword < 0x10000)) {
-			io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-			if (!io_node)
-				return -ENOMEM;
-
-			io_node->base = io_base;
-			io_node->length = io_length;
-
-			dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length);
-			dbg("populated slot =%d \n", populated_slot);
-			if (!populated_slot) {
-				io_node->next = ctrl->io_head;
-				ctrl->io_head = io_node;
-			} else {
-				io_node->next = func->io_head;
-				func->io_head = io_node;
-			}
-		}
-
-		// If we've got a valid memory base, use it
-		temp_dword = mem_base + mem_length;
-		if ((mem_base) && (temp_dword < 0x10000)) {
-			mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-			if (!mem_node)
-				return -ENOMEM;
-
-			mem_node->base = mem_base << 16;
-
-			mem_node->length = mem_length << 16;
-
-			dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length);
-			dbg("populated slot =%d \n", populated_slot);
-			if (!populated_slot) {
-				mem_node->next = ctrl->mem_head;
-				ctrl->mem_head = mem_node;
-			} else {
-				mem_node->next = func->mem_head;
-				func->mem_head = mem_node;
-			}
-		}
-
-		// If we've got a valid prefetchable memory base, and
-		// the base + length isn't greater than 0xFFFF
-		temp_dword = pre_mem_base + pre_mem_length;
-		if ((pre_mem_base) && (temp_dword < 0x10000)) {
-			p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-			if (!p_mem_node)
-				return -ENOMEM;
-
-			p_mem_node->base = pre_mem_base << 16;
-
-			p_mem_node->length = pre_mem_length << 16;
-			dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length);
-			dbg("populated slot =%d \n", populated_slot);
-
-			if (!populated_slot) {
-				p_mem_node->next = ctrl->p_mem_head;
-				ctrl->p_mem_head = p_mem_node;
-			} else {
-				p_mem_node->next = func->p_mem_head;
-				func->p_mem_head = p_mem_node;
-			}
-		}
-
-		// If we've got a valid bus number, use it
-		// The second condition is to ignore bus numbers on
-		// populated slots that don't have PCI-PCI bridges
-		if (secondary_bus && (secondary_bus != primary_bus)) {
-			bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-			if (!bus_node)
-				return -ENOMEM;
-
-			bus_node->base = secondary_bus;
-			bus_node->length = max_bus - secondary_bus + 1;
-			dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length);
-			dbg("populated slot =%d \n", populated_slot);
-			if (!populated_slot) {
-				bus_node->next = ctrl->bus_head;
-				ctrl->bus_head = bus_node;
-			} else {
-				bus_node->next = func->bus_head;
-				func->bus_head = bus_node;
-			}
-		}
-
-		i--;
-		one_slot += sizeof (struct slot_rt);
-	}
-
-	// If all of the following fail, we don't have any resources for
-	// hot plug add
-	rc = 1;
-	rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
-	rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
-	rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
-	rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
-
-	return(rc);
-}
-
-
-/*
- * cpqhp_return_board_resources
- *
- * this routine returns all resources allocated to a board to
- * the available pool.
- *
- * returns 0 if success
- */
-int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * resources)
-{
-	int rc = 0;
-	struct pci_resource *node;
-	struct pci_resource *t_node;
-	dbg("%s\n", __FUNCTION__);
-
-	if (!func)
-		return(1);
-
-	node = func->io_head;
-	func->io_head = NULL;
-	while (node) {
-		t_node = node->next;
-		return_resource(&(resources->io_head), node);
-		node = t_node;
-	}
-
-	node = func->mem_head;
-	func->mem_head = NULL;
-	while (node) {
-		t_node = node->next;
-		return_resource(&(resources->mem_head), node);
-		node = t_node;
-	}
-
-	node = func->p_mem_head;
-	func->p_mem_head = NULL;
-	while (node) {
-		t_node = node->next;
-		return_resource(&(resources->p_mem_head), node);
-		node = t_node;
-	}
-
-	node = func->bus_head;
-	func->bus_head = NULL;
-	while (node) {
-		t_node = node->next;
-		return_resource(&(resources->bus_head), node);
-		node = t_node;
-	}
-
-	rc |= cpqhp_resource_sort_and_combine(&(resources->mem_head));
-	rc |= cpqhp_resource_sort_and_combine(&(resources->p_mem_head));
-	rc |= cpqhp_resource_sort_and_combine(&(resources->io_head));
-	rc |= cpqhp_resource_sort_and_combine(&(resources->bus_head));
-
-	return(rc);
-}
-
-
-/*
- * cpqhp_destroy_resource_list
- *
- * Puts node back in the resource list pointed to by head
- */
-void cpqhp_destroy_resource_list (struct resource_lists * resources)
-{
-	struct pci_resource *res, *tres;
-
-	res = resources->io_head;
-	resources->io_head = NULL;
-
-	while (res) {
-		tres = res;
-		res = res->next;
-		kfree(tres);
-	}
-
-	res = resources->mem_head;
-	resources->mem_head = NULL;
-
-	while (res) {
-		tres = res;
-		res = res->next;
-		kfree(tres);
-	}
-
-	res = resources->p_mem_head;
-	resources->p_mem_head = NULL;
-
-	while (res) {
-		tres = res;
-		res = res->next;
-		kfree(tres);
-	}
-
-	res = resources->bus_head;
-	resources->bus_head = NULL;
-
-	while (res) {
-		tres = res;
-		res = res->next;
-		kfree(tres);
-	}
-}
-
-
-/*
- * cpqhp_destroy_board_resources
- *
- * Puts node back in the resource list pointed to by head
- */
-void cpqhp_destroy_board_resources (struct pci_func * func)
-{
-	struct pci_resource *res, *tres;
-
-	res = func->io_head;
-	func->io_head = NULL;
-
-	while (res) {
-		tres = res;
-		res = res->next;
-		kfree(tres);
-	}
-
-	res = func->mem_head;
-	func->mem_head = NULL;
-
-	while (res) {
-		tres = res;
-		res = res->next;
-		kfree(tres);
-	}
-
-	res = func->p_mem_head;
-	func->p_mem_head = NULL;
-
-	while (res) {
-		tres = res;
-		res = res->next;
-		kfree(tres);
-	}
-
-	res = func->bus_head;
-	func->bus_head = NULL;
-
-	while (res) {
-		tres = res;
-		res = res->next;
-		kfree(tres);
-	}
-}
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/cpqphp_sysfs.c linux-2.5.70-bk10/drivers/hotplug/cpqphp_sysfs.c
--- linux-2.5.70-bk9/drivers/hotplug/cpqphp_sysfs.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/cpqphp_sysfs.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,143 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/workqueue.h>
-#include <linux/pci.h>
-#include "cpqphp.h"
-
-
-/* A few routines that create sysfs entries for the hot plug controller */
-
-static int show_ctrl (struct device *dev, char *buf)
-{
-	struct pci_dev *pci_dev;
-	struct controller *ctrl;
-	char * out = buf;
-	int index;
-	struct pci_resource *res;
-
-	pci_dev = container_of (dev, struct pci_dev, dev);
-	ctrl = pci_get_drvdata(pci_dev);
-
-	out += sprintf(buf, "Free resources: memory\n");
-	index = 11;
-	res = ctrl->mem_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: prefetchable memory\n");
-	index = 11;
-	res = ctrl->p_mem_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: IO\n");
-	index = 11;
-	res = ctrl->io_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: bus numbers\n");
-	index = 11;
-	res = ctrl->bus_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-
-	return out - buf;
-}
-static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
-
-static int show_dev (struct device *dev, char *buf)
-{
-	struct pci_dev *pci_dev;
-	struct controller *ctrl;
-	char * out = buf;
-	int index;
-	struct pci_resource *res;
-	struct pci_func *new_slot;
-	struct slot *slot;
-
-	pci_dev = container_of (dev, struct pci_dev, dev);
-	ctrl = pci_get_drvdata(pci_dev);
-
-	slot=ctrl->slot;
-
-	while (slot) {
-		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
-		if (!new_slot)
-			break;
-		out += sprintf(out, "assigned resources: memory\n");
-		index = 11;
-		res = new_slot->mem_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: prefetchable memory\n");
-		index = 11;
-		res = new_slot->p_mem_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: IO\n");
-		index = 11;
-		res = new_slot->io_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: bus numbers\n");
-		index = 11;
-		res = new_slot->bus_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		slot=slot->next;
-	}
-
-	return out - buf;
-}
-static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
-
-void cpqhp_create_ctrl_files (struct controller *ctrl)
-{
-	device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
-	device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
-}
diff -urN linux-2.5.70-bk9/drivers/hotplug/ibmphp.h linux-2.5.70-bk10/drivers/hotplug/ibmphp.h
--- linux-2.5.70-bk9/drivers/hotplug/ibmphp.h	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/ibmphp.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,772 +0,0 @@
-#ifndef __IBMPHP_H
-#define __IBMPHP_H
-
-/*
- * IBM Hot Plug Controller Driver
- *
- * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
- *
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001,2002 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>
- *
- */
-
-#include "pci_hotplug.h"
-
-extern int ibmphp_debug;
-
-#if !defined(CONFIG_HOTPLUG_PCI_IBM_MODULE)
-	#define MY_NAME "ibmphpd"
-#else
-	#define MY_NAME THIS_MODULE->name
-#endif
-#define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
-#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
-
-
-/* EBDA stuff */
-
-/***********************************************************
-* SLOT CAPABILITY                                          *
-***********************************************************/
-
-#define EBDA_SLOT_133_MAX		0x20
-#define EBDA_SLOT_100_MAX		0x10
-#define EBDA_SLOT_66_MAX		0x02
-#define EBDA_SLOT_PCIX_CAP		0x08
-
-
-/************************************************************
-*  RESOURE TYPE                                             *
-************************************************************/
-
-#define EBDA_RSRC_TYPE_MASK		0x03
-#define EBDA_IO_RSRC_TYPE		0x00
-#define EBDA_MEM_RSRC_TYPE		0x01
-#define EBDA_PFM_RSRC_TYPE		0x03
-#define EBDA_RES_RSRC_TYPE		0x02
-
-
-/*************************************************************
-*  IO RESTRICTION TYPE                                       *
-*************************************************************/
-
-#define EBDA_IO_RESTRI_MASK		0x0c
-#define EBDA_NO_RESTRI			0x00
-#define EBDA_AVO_VGA_ADDR		0x04
-#define EBDA_AVO_VGA_ADDR_AND_ALIA	0x08
-#define EBDA_AVO_ISA_ADDR		0x0c
-
-
-/**************************************************************
-*  DEVICE TYPE DEF                                            *
-**************************************************************/
-
-#define EBDA_DEV_TYPE_MASK		0x10
-#define EBDA_PCI_DEV			0x10
-#define EBDA_NON_PCI_DEV		0x00
-
-
-/***************************************************************
-*  PRIMARY DEF DEFINITION                                      *
-***************************************************************/
-
-#define EBDA_PRI_DEF_MASK		0x20
-#define EBDA_PRI_PCI_BUS_INFO		0x20
-#define EBDA_NORM_DEV_RSRC_INFO		0x00
-
-
-//--------------------------------------------------------------
-// RIO TABLE DATA STRUCTURE
-//--------------------------------------------------------------
-
-struct rio_table_hdr {
-	u8 ver_num; 
-	u8 scal_count;
-	u8 riodev_count;
-	u16 offset;
-};
-
-//-------------------------------------------------------------
-// SCALABILITY DETAIL
-//-------------------------------------------------------------
-
-struct scal_detail {
-	u8 node_id;
-	u32 cbar;
-	u8 port0_node_connect;
-	u8 port0_port_connect;
-	u8 port1_node_connect;
-	u8 port1_port_connect;
-	u8 port2_node_connect;
-	u8 port2_port_connect;
-	u8 chassis_num;
-//	struct list_head scal_detail_list;
-};
-
-//--------------------------------------------------------------
-// RIO DETAIL 
-//--------------------------------------------------------------
-
-struct rio_detail {
-	u8 rio_node_id;
-	u32 bbar;
-	u8 rio_type;
-	u8 owner_id;
-	u8 port0_node_connect;
-	u8 port0_port_connect;
-	u8 port1_node_connect;
-	u8 port1_port_connect;
-	u8 first_slot_num;
-	u8 status;
-	u8 wpindex;
-	u8 chassis_num;
-	struct list_head rio_detail_list;
-};
-
-struct opt_rio {
-	u8 rio_type;
-	u8 chassis_num;
-	u8 first_slot_num;
-	u8 middle_num;
-	struct list_head opt_rio_list;
-};	
-
-struct opt_rio_lo {
-	u8 rio_type;
-	u8 chassis_num;
-	u8 first_slot_num;
-	u8 middle_num;
-	u8 pack_count;
-	struct list_head opt_rio_lo_list;
-};	
-
-/****************************************************************
-*  HPC DESCRIPTOR NODE                                          *
-****************************************************************/
-
-struct ebda_hpc_list {
-	u8 format;
-	u16 num_ctlrs;
-	short phys_addr;
-//      struct list_head ebda_hpc_list;
-};
-/*****************************************************************
-*   IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS           *
-*   STRUCTURE                                                    *
-*****************************************************************/
-
-struct ebda_hpc_slot {
-	u8 slot_num;
-	u32 slot_bus_num;
-	u8 ctl_index;
-	u8 slot_cap;
-};
-
-struct ebda_hpc_bus {
-	u32 bus_num;
-	u8 slots_at_33_conv;
-	u8 slots_at_66_conv;
-	u8 slots_at_66_pcix;
-	u8 slots_at_100_pcix;
-	u8 slots_at_133_pcix;
-};
-
-
-/********************************************************************
-*   THREE TYPE OF HOT PLUG CONTROLER                                *
-********************************************************************/
-
-struct isa_ctlr_access {
-	u16 io_start;
-	u16 io_end;
-};
-
-struct pci_ctlr_access {
-	u8 bus;
-	u8 dev_fun;
-};
-
-struct wpeg_i2c_ctlr_access {
-	ulong wpegbbar;
-	u8 i2c_addr;
-};
-
-#define HPC_DEVICE_ID		0x0246
-#define HPC_SUBSYSTEM_ID	0x0247
-#define HPC_PCI_OFFSET		0x40
-/*************************************************************************
-*   RSTC DESCRIPTOR NODE                                                 *
-*************************************************************************/
-
-struct ebda_rsrc_list {
-	u8 format;
-	u16 num_entries;
-	u16 phys_addr;
-	struct ebda_rsrc_list *next;
-};
-
-
-/***************************************************************************
-*   PCI RSRC NODE                                                          *
-***************************************************************************/
-
-struct ebda_pci_rsrc {
-	u8 rsrc_type;
-	u8 bus_num;
-	u8 dev_fun;
-	u32 start_addr;
-	u32 end_addr;
-	u8 marked;	/* for NVRAM */
-	struct list_head ebda_pci_rsrc_list;
-};
-
-
-/***********************************************************
-* BUS_INFO DATE STRUCTURE                                  *
-***********************************************************/
-
-struct bus_info {
-	u8 slot_min;
-	u8 slot_max;
-	u8 slot_count;
-	u8 busno;
-	u8 controller_id;
-	u8 current_speed;
-	u8 current_bus_mode;
-	u8 index;
-	u8 slots_at_33_conv;
-	u8 slots_at_66_conv;
-	u8 slots_at_66_pcix;
-	u8 slots_at_100_pcix;
-	u8 slots_at_133_pcix;
-	struct list_head bus_info_list;
-};
-
-
-/***********************************************************
-* GLOBAL VARIABLES                                         *
-***********************************************************/
-extern struct list_head ibmphp_ebda_pci_rsrc_head;
-extern struct list_head ibmphp_slot_head;
-extern struct list_head ibmphp_res_head;
-/***********************************************************
-* FUNCTION PROTOTYPES                                      *
-***********************************************************/
-
-extern void ibmphp_free_ebda_hpc_queue (void);
-extern int ibmphp_access_ebda (void);
-extern struct slot *ibmphp_get_slot_from_physical_num (u8);
-extern int ibmphp_get_total_hp_slots (void);
-extern void ibmphp_free_ibm_slot (struct slot *);
-extern void ibmphp_free_bus_info_queue (void);
-extern void ibmphp_free_ebda_pci_rsrc_queue (void);
-extern struct bus_info *ibmphp_find_same_bus_num (u32);
-extern int ibmphp_get_bus_index (u8);
-extern u16 ibmphp_get_total_controllers (void);
-extern int ibmphp_register_pci (void);
-
-/* passed parameters */
-#define MEM		0
-#define IO		1
-#define PFMEM		2
-
-/* bit masks */
-#define RESTYPE		0x03
-#define IOMASK		0x00	/* will need to take its complement */
-#define MMASK		0x01
-#define PFMASK		0x03
-#define PCIDEVMASK	0x10	/* we should always have PCI devices */
-#define PRIMARYBUSMASK	0x20
-
-/* pci specific defines */
-#define PCI_VENDOR_ID_NOTVALID		0xFFFF
-#define PCI_HEADER_TYPE_MULTIDEVICE	0x80
-#define PCI_HEADER_TYPE_MULTIBRIDGE	0x81
-
-#define LATENCY		0x64
-#define CACHE		64
-#define DEVICEENABLE	0x015F		/* CPQ has 0x0157 */
-
-#define IOBRIDGE	0x1000		/* 4k */
-#define MEMBRIDGE	0x100000	/* 1M */
-
-/* irqs */
-#define SCSI_IRQ	0x09
-#define LAN_IRQ		0x0A
-#define OTHER_IRQ	0x0B
-
-/* Data Structures */
-
-/* type is of the form x x xx xx
- *                     | |  |  |_ 00 - I/O, 01 - Memory, 11 - PFMemory
- *                     | |  - 00 - No Restrictions, 01 - Avoid VGA, 10 - Avoid
- *                     | |    VGA and their aliases, 11 - Avoid ISA
- *                     | - 1 - PCI device, 0 - non pci device
- *                     - 1 - Primary PCI Bus Information (0 if Normal device)
- * the IO restrictions [2:3] are only for primary buses
- */
-
-
-/* we need this struct because there could be several resource blocks
- * allocated per primary bus in the EBDA
- */
-struct range_node {
-	int rangeno;
-	u32 start;
-	u32 end;
-	struct range_node *next;
-};
-
-struct bus_node {
-	u8 busno;
-	int noIORanges;
-	struct range_node *rangeIO;
-	int noMemRanges;
-	struct range_node *rangeMem;
-	int noPFMemRanges;
-	struct range_node *rangePFMem;
-	int needIOUpdate;
-	int needMemUpdate;
-	int needPFMemUpdate;
-	struct resource_node *firstIO;	/* first IO resource on the Bus */
-	struct resource_node *firstMem;	/* first memory resource on the Bus */
-	struct resource_node *firstPFMem;	/* first prefetchable memory resource on the Bus */
-	struct resource_node *firstPFMemFromMem;	/* when run out of pfmem available, taking from Mem */
-	struct list_head bus_list;
-};
-
-struct resource_node {
-	int rangeno;
-	u8 busno;
-	u8 devfunc;
-	u32 start;
-	u32 end;
-	u32 len;
-	int type;		/* MEM, IO, PFMEM */
-	u8 fromMem;		/* this is to indicate that the range is from
-				 * from the Memory bucket rather than from PFMem */
-	struct resource_node *next;
-	struct resource_node *nextRange;	/* for the other mem range on bus */
-};
-
-struct res_needed {
-	u32 mem;
-	u32 pfmem;
-	u32 io;
-	u8 not_correct;		/* needed for return */
-	int devices[32];	/* for device numbers behind this bridge */
-};
-
-/* functions */
-
-extern int ibmphp_rsrc_init (void);
-extern int ibmphp_add_resource (struct resource_node *);
-extern int ibmphp_remove_resource (struct resource_node *);
-extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int);
-extern int ibmphp_check_resource (struct resource_node *, u8);
-extern int ibmphp_remove_bus (struct bus_node *, u8);
-extern void ibmphp_free_resources (void);
-extern int ibmphp_add_pfmem_from_mem (struct resource_node *);
-extern struct bus_node *ibmphp_find_res_bus (u8);
-extern void ibmphp_print_test (void);	/* for debugging purposes */
-
-extern void ibmphp_hpc_initvars (void);
-extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *);
-extern int ibmphp_hpc_writeslot (struct slot *, u8);
-extern void ibmphp_lock_operations (void);
-extern void ibmphp_unlock_operations (void);
-extern int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *);
-extern int ibmphp_hpc_start_poll_thread (void);
-extern void ibmphp_hpc_stop_poll_thread (void);
-
-//----------------------------------------------------------------------------
-
-
-//----------------------------------------------------------------------------
-// HPC return codes
-//----------------------------------------------------------------------------
-#define FALSE				0x00
-#define TRUE				0x01
-#define HPC_ERROR			0xFF
-
-//-----------------------------------------------------------------------------
-// BUS INFO
-//-----------------------------------------------------------------------------
-#define BUS_SPEED			0x30
-#define BUS_MODE			0x40
-#define BUS_MODE_PCIX			0x01
-#define BUS_MODE_PCI			0x00
-#define BUS_SPEED_2			0x20
-#define BUS_SPEED_1			0x10
-#define BUS_SPEED_33			0x00
-#define BUS_SPEED_66			0x01
-#define BUS_SPEED_100			0x02
-#define BUS_SPEED_133			0x03
-#define BUS_SPEED_66PCIX		0x04
-#define BUS_SPEED_66UNKNOWN		0x05
-#define BUS_STATUS_AVAILABLE		0x01
-#define BUS_CONTROL_AVAILABLE		0x02
-#define SLOT_LATCH_REGS_SUPPORTED	0x10
-
-#define PRGM_MODEL_REV_LEVEL		0xF0
-#define MAX_ADAPTER_NONE		0x09
-
-//----------------------------------------------------------------------------
-// HPC 'write' operations/commands
-//----------------------------------------------------------------------------
-//	Command			Code	State	Write to reg
-//					Machine	at index
-//-------------------------	----	-------	------------
-#define HPC_CTLR_ENABLEIRQ	0x00	// N	15
-#define HPC_CTLR_DISABLEIRQ	0x01	// N	15
-#define HPC_SLOT_OFF		0x02	// Y	0-14
-#define HPC_SLOT_ON		0x03	// Y	0-14
-#define HPC_SLOT_ATTNOFF	0x04	// N	0-14
-#define HPC_SLOT_ATTNON		0x05	// N	0-14
-#define HPC_CTLR_CLEARIRQ	0x06	// N	15
-#define HPC_CTLR_RESET		0x07	// Y	15
-#define HPC_CTLR_IRQSTEER	0x08	// N	15
-#define HPC_BUS_33CONVMODE	0x09	// Y	31-34
-#define HPC_BUS_66CONVMODE	0x0A	// Y	31-34
-#define HPC_BUS_66PCIXMODE	0x0B	// Y	31-34
-#define HPC_BUS_100PCIXMODE	0x0C	// Y	31-34
-#define HPC_BUS_133PCIXMODE	0x0D	// Y	31-34
-#define HPC_ALLSLOT_OFF		0x11	// Y	15
-#define HPC_ALLSLOT_ON		0x12	// Y	15
-#define HPC_SLOT_BLINKLED	0x13	// N	0-14
-
-//----------------------------------------------------------------------------
-// read commands
-//----------------------------------------------------------------------------
-#define READ_SLOTSTATUS		0x01
-#define READ_EXTSLOTSTATUS	0x02
-#define READ_BUSSTATUS		0x03
-#define READ_CTLRSTATUS		0x04
-#define READ_ALLSTAT		0x05
-#define READ_ALLSLOT		0x06
-#define READ_SLOTLATCHLOWREG	0x07
-#define READ_REVLEVEL		0x08
-#define READ_HPCOPTIONS		0x09
-//----------------------------------------------------------------------------
-// slot status
-//----------------------------------------------------------------------------
-#define HPC_SLOT_POWER		0x01
-#define HPC_SLOT_CONNECT	0x02
-#define HPC_SLOT_ATTN		0x04
-#define HPC_SLOT_PRSNT2		0x08
-#define HPC_SLOT_PRSNT1		0x10
-#define HPC_SLOT_PWRGD		0x20
-#define HPC_SLOT_BUS_SPEED	0x40
-#define HPC_SLOT_LATCH		0x80
-
-//----------------------------------------------------------------------------
-// HPC_SLOT_POWER status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_POWER_OFF	0x00
-#define HPC_SLOT_POWER_ON	0x01
-
-//----------------------------------------------------------------------------
-// HPC_SLOT_CONNECT status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_CONNECTED	0x00
-#define HPC_SLOT_DISCONNECTED	0x01
-
-//----------------------------------------------------------------------------
-// HPC_SLOT_ATTN status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_ATTN_OFF	0x00
-#define HPC_SLOT_ATTN_ON	0x01
-#define HPC_SLOT_ATTN_BLINK	0x02
-
-//----------------------------------------------------------------------------
-// HPC_SLOT_PRSNT status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_EMPTY		0x00
-#define HPC_SLOT_PRSNT_7	0x01
-#define HPC_SLOT_PRSNT_15	0x02
-#define HPC_SLOT_PRSNT_25	0x03
-
-//----------------------------------------------------------------------------
-// HPC_SLOT_PWRGD status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_PWRGD_FAULT_NONE	0x00
-#define HPC_SLOT_PWRGD_GOOD		0x01
-
-//----------------------------------------------------------------------------
-// HPC_SLOT_BUS_SPEED status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_BUS_SPEED_OK	0x00
-#define HPC_SLOT_BUS_SPEED_MISM	0x01
-
-//----------------------------------------------------------------------------
-// HPC_SLOT_LATCH status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_LATCH_OPEN	0x01	// NOTE : in PCI spec bit off = open
-#define HPC_SLOT_LATCH_CLOSED	0x00	// NOTE : in PCI spec bit on  = closed
-
-
-//----------------------------------------------------------------------------
-// extended slot status
-//----------------------------------------------------------------------------
-#define HPC_SLOT_PCIX		0x01
-#define HPC_SLOT_SPEED1		0x02
-#define HPC_SLOT_SPEED2		0x04
-#define HPC_SLOT_BLINK_ATTN	0x08
-#define HPC_SLOT_RSRVD1		0x10
-#define HPC_SLOT_RSRVD2		0x20
-#define HPC_SLOT_BUS_MODE	0x40
-#define HPC_SLOT_RSRVD3		0x80
-
-//----------------------------------------------------------------------------
-// HPC_XSLOT_PCIX_CAP status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_PCIX_NO	0x00
-#define HPC_SLOT_PCIX_YES	0x01
-
-//----------------------------------------------------------------------------
-// HPC_XSLOT_SPEED status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_SPEED_33	0x00
-#define HPC_SLOT_SPEED_66	0x01
-#define HPC_SLOT_SPEED_133	0x02
-
-//----------------------------------------------------------------------------
-// HPC_XSLOT_ATTN_BLINK status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_ATTN_BLINK_OFF	0x00
-#define HPC_SLOT_ATTN_BLINK_ON	0x01
-
-//----------------------------------------------------------------------------
-// HPC_XSLOT_BUS_MODE status return codes
-//----------------------------------------------------------------------------
-#define HPC_SLOT_BUS_MODE_OK	0x00
-#define HPC_SLOT_BUS_MODE_MISM	0x01
-
-//----------------------------------------------------------------------------
-// Controller status
-//----------------------------------------------------------------------------
-#define HPC_CTLR_WORKING	0x01
-#define HPC_CTLR_FINISHED	0x02
-#define HPC_CTLR_RESULT0	0x04
-#define HPC_CTLR_RESULT1	0x08
-#define HPC_CTLR_RESULE2	0x10
-#define HPC_CTLR_RESULT3	0x20
-#define HPC_CTLR_IRQ_ROUTG	0x40
-#define HPC_CTLR_IRQ_PENDG	0x80
-
-//----------------------------------------------------------------------------
-// HPC_CTLR_WROKING status return codes
-//----------------------------------------------------------------------------
-#define HPC_CTLR_WORKING_NO	0x00
-#define HPC_CTLR_WORKING_YES	0x01
-
-//----------------------------------------------------------------------------
-// HPC_CTLR_FINISHED status return codes
-//----------------------------------------------------------------------------
-#define HPC_CTLR_FINISHED_NO	0x00
-#define HPC_CTLR_FINISHED_YES	0x01
-
-//----------------------------------------------------------------------------
-// HPC_CTLR_RESULT status return codes
-//----------------------------------------------------------------------------
-#define HPC_CTLR_RESULT_SUCCESS	0x00
-#define HPC_CTLR_RESULT_FAILED	0x01
-#define HPC_CTLR_RESULT_RSVD	0x02
-#define HPC_CTLR_RESULT_NORESP	0x03
-
-
-//----------------------------------------------------------------------------
-// macro for slot info
-//----------------------------------------------------------------------------
-#define SLOT_POWER(s)	((u8) ((s & HPC_SLOT_POWER) \
-	? HPC_SLOT_POWER_ON : HPC_SLOT_POWER_OFF))
-
-#define SLOT_CONNECT(s)	((u8) ((s & HPC_SLOT_CONNECT) \
-	? HPC_SLOT_DISCONNECTED : HPC_SLOT_CONNECTED))
-
-#define SLOT_ATTN(s,es)	((u8) ((es & HPC_SLOT_BLINK_ATTN) \
-	? HPC_SLOT_ATTN_BLINK \
-	: ((s & HPC_SLOT_ATTN) ? HPC_SLOT_ATTN_ON : HPC_SLOT_ATTN_OFF)))
-
-#define SLOT_PRESENT(s)	((u8) ((s & HPC_SLOT_PRSNT1) \
-	? ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_EMPTY : HPC_SLOT_PRSNT_15) \
-	: ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_PRSNT_25 : HPC_SLOT_PRSNT_7)))
-
-#define SLOT_PWRGD(s)	((u8) ((s & HPC_SLOT_PWRGD) \
-	? HPC_SLOT_PWRGD_GOOD : HPC_SLOT_PWRGD_FAULT_NONE))
-
-#define SLOT_BUS_SPEED(s)	((u8) ((s & HPC_SLOT_BUS_SPEED) \
-	? HPC_SLOT_BUS_SPEED_MISM : HPC_SLOT_BUS_SPEED_OK))
-
-#define SLOT_LATCH(s)	((u8) ((s & HPC_SLOT_LATCH) \
-	? HPC_SLOT_LATCH_CLOSED : HPC_SLOT_LATCH_OPEN))
-
-#define SLOT_PCIX(es)	((u8) ((es & HPC_SLOT_PCIX) \
-	? HPC_SLOT_PCIX_YES : HPC_SLOT_PCIX_NO))
-
-#define SLOT_SPEED(es)	((u8) ((es & HPC_SLOT_SPEED2) \
-	? ((es & HPC_SLOT_SPEED1) ? HPC_SLOT_SPEED_133   \
-				: HPC_SLOT_SPEED_66)   \
-	: HPC_SLOT_SPEED_33))
-
-#define SLOT_BUS_MODE(es)	((u8) ((es & HPC_SLOT_BUS_MODE) \
-	? HPC_SLOT_BUS_MODE_MISM : HPC_SLOT_BUS_MODE_OK))
-
-//--------------------------------------------------------------------------
-// macro for bus info
-//---------------------------------------------------------------------------
-#define CURRENT_BUS_SPEED(s)	((u8) (s & BUS_SPEED_2) \
-	? ((s & BUS_SPEED_1) ? BUS_SPEED_133 : BUS_SPEED_100) \
-	: ((s & BUS_SPEED_1) ? BUS_SPEED_66 : BUS_SPEED_33))
-
-#define CURRENT_BUS_MODE(s)	((u8) (s & BUS_MODE) ? BUS_MODE_PCIX : BUS_MODE_PCI)
-
-#define READ_BUS_STATUS(s)	((u8) (s->options & BUS_STATUS_AVAILABLE))
-
-#define READ_BUS_MODE(s)	((s->revision & PRGM_MODEL_REV_LEVEL) >= 0x20)
-
-#define SET_BUS_STATUS(s)	((u8) (s->options & BUS_CONTROL_AVAILABLE))
-
-#define READ_SLOT_LATCH(s)	((u8) (s->options & SLOT_LATCH_REGS_SUPPORTED))
-
-//----------------------------------------------------------------------------
-// macro for controller info
-//----------------------------------------------------------------------------
-#define CTLR_WORKING(c) ((u8) ((c & HPC_CTLR_WORKING) \
-	? HPC_CTLR_WORKING_YES : HPC_CTLR_WORKING_NO))
-#define CTLR_FINISHED(c) ((u8) ((c & HPC_CTLR_FINISHED) \
-	? HPC_CTLR_FINISHED_YES : HPC_CTLR_FINISHED_NO))
-#define CTLR_RESULT(c) ((u8) ((c & HPC_CTLR_RESULT1)  \
-	? ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_NORESP \
-				: HPC_CTLR_RESULT_RSVD)  \
-	: ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_FAILED \
-				: HPC_CTLR_RESULT_SUCCESS)))
-
-// command that affect the state machine of HPC
-#define NEEDTOCHECK_CMDSTATUS(c) ((c == HPC_SLOT_OFF)        || \
-				  (c == HPC_SLOT_ON)         || \
-				  (c == HPC_CTLR_RESET)      || \
-				  (c == HPC_BUS_33CONVMODE)  || \
-				  (c == HPC_BUS_66CONVMODE)  || \
-				  (c == HPC_BUS_66PCIXMODE)  || \
-				  (c == HPC_BUS_100PCIXMODE) || \
-				  (c == HPC_BUS_133PCIXMODE) || \
-				  (c == HPC_ALLSLOT_OFF)     || \
-				  (c == HPC_ALLSLOT_ON))
-
-
-/* Core part of the driver */
-
-#define ENABLE		1
-#define DISABLE		0
-
-#define CARD_INFO	0x07
-#define PCIX133		0x07
-#define PCIX66		0x05
-#define PCI66		0x04
-
-extern struct pci_bus *ibmphp_pci_bus;
-
-/* Variables */
-
-struct pci_func {
-	struct pci_dev *dev;	/* from the OS */
-	u8 busno;
-	u8 device;
-	u8 function;
-	struct resource_node *io[6];
-	struct resource_node *mem[6];
-	struct resource_node *pfmem[6];
-	struct pci_func *next;
-	int devices[32];	/* for bridge config */
-	u8 irq[4];		/* for interrupt config */
-	u8 bus;			/* flag for unconfiguring, to say if PPB */
-};
-
-struct slot {
-	u8 bus;
-	u8 device;
-	u8 number;
-	u8 real_physical_slot_num;
-	char name[100];
-	u32 capabilities;
-	u8 supported_speed;
-	u8 supported_bus_mode;
-	struct hotplug_slot *hotplug_slot;
-	struct controller *ctrl;
-	struct pci_func *func;
-	u8 irq[4];
-	u8 flag;		/* this is for disable slot and polling */
-	int bit_mode;		/* 0 = 32, 1 = 64 */
-	u8 ctlr_index;
-	struct bus_info *bus_on;
-	struct list_head ibm_slot_list;
-	u8 status;
-	u8 ext_status;
-	u8 busstatus;
-};
-
-struct controller {
-	struct ebda_hpc_slot *slots;
-	struct ebda_hpc_bus *buses;
-	struct pci_dev *ctrl_dev; /* in case where controller is PCI */
-	u8 starting_slot_num;	/* starting and ending slot #'s this ctrl controls*/
-	u8 ending_slot_num;
-	u8 revision;
-	u8 options;		/* which options HPC supports */
-	u8 status;
-	u8 ctlr_id;
-	u8 slot_count;
-	u8 bus_count;
-	u8 ctlr_relative_id;
-	u32 irq;
-	union {
-		struct isa_ctlr_access isa_ctlr;
-		struct pci_ctlr_access pci_ctlr;
-		struct wpeg_i2c_ctlr_access wpeg_ctlr;
-	} u;
-	u8 ctlr_type;
-	struct list_head ebda_hpc_list;
-};
-
-/* Functions */
-
-extern int ibmphp_init_devno (struct slot **);	/* This function is called from EBDA, so we need it not be static */
-extern int ibmphp_disable_slot (struct hotplug_slot *);	/* This function is called from HPC, so we need it to not be static */
-extern int ibmphp_do_disable_slot (struct slot *slot_cur);
-extern int ibmphp_update_slot_info (struct slot *);	/* This function is called from HPC, so we need it to not be be static */
-extern int ibmphp_configure_card (struct pci_func *, u8);
-extern int ibmphp_unconfigure_card (struct slot **, int);
-extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops;
-
-static inline void long_delay (int delay)
-{
-	set_current_state (TASK_INTERRUPTIBLE);
-	schedule_timeout (delay);
-}
-
-#endif				//__IBMPHP_H
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/ibmphp_core.c linux-2.5.70-bk10/drivers/hotplug/ibmphp_core.c
--- linux-2.5.70-bk9/drivers/hotplug/ibmphp_core.c	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/ibmphp_core.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1439 +0,0 @@
-/*
- * IBM Hot Plug Controller Driver
- *
- * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
- *
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001,2002 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/smp_lock.h>
-#include "../../arch/i386/pci/pci.h"	/* for struct irq_routing_table */
-#include "ibmphp.h"
-
-#define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
-#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
-#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
-#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
-#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
-
-#define DRIVER_VERSION	"0.6"
-#define DRIVER_DESC	"IBM Hot Plug PCI Controller Driver"
-
-int ibmphp_debug;
-
-static int debug;
-MODULE_PARM (debug, "i");
-MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
-MODULE_LICENSE ("GPL");
-MODULE_DESCRIPTION (DRIVER_DESC);
-
-struct pci_bus *ibmphp_pci_bus;
-static int max_slots;
-
-static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */
-
-static int init_flag;
-
-/*
-static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
-
-static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
-{
-	return get_max_adapter_speed_1 (hs, value, 1);
-}
-*/
-static inline int get_cur_bus_info (struct slot **sl) 
-{
-	int rc = 1;
-	struct slot * slot_cur = *sl;
-
-	debug ("options = %x\n", slot_cur->ctrl->options);
-	debug ("revision = %x\n", slot_cur->ctrl->revision);	
-
-	if (READ_BUS_STATUS (slot_cur->ctrl)) 
-		rc = ibmphp_hpc_readslot (slot_cur, READ_BUSSTATUS, NULL);
-	
-	if (rc) 
-		return rc;
-	  
-	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus);
-	if (READ_BUS_MODE (slot_cur->ctrl))
-		slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus);
-	else
-		slot_cur->bus_on->current_bus_mode = 0xFF;
-
-	debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode);
-	
-	*sl = slot_cur;
-	return 0;
-}
-
-static inline int slot_update (struct slot **sl)
-{
-	int rc;
- 	rc = ibmphp_hpc_readslot (*sl, READ_ALLSTAT, NULL);
-	if (rc) 
-		return rc;
-	if (!init_flag)
-		return get_cur_bus_info (sl);
-	return rc;
-}
-
-static int __init get_max_slots (void)
-{
-	struct slot * slot_cur;
-	struct list_head * tmp;
-	u8 slot_count = 0;
-
-	list_for_each (tmp, &ibmphp_slot_head) {
-		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
-		/* sometimes the hot-pluggable slots start with 4 (not always from 1 */
-		slot_count = max (slot_count, slot_cur->number);
-	}
-	return slot_count;
-}
-
-/* This routine will put the correct slot->device information per slot.  It's
- * called from initialization of the slot structures. It will also assign
- * interrupt numbers per each slot.
- * Parameters: struct slot
- * Returns 0 or errors
- */
-int ibmphp_init_devno (struct slot **cur_slot)
-{
-	struct irq_routing_table *rtable;
-	int len;
-	int loop;
-	int i;
-
-	rtable = pcibios_get_irq_routing_table ();
-	if (!rtable) {
-		err ("no BIOS routing table...\n");
-		return -ENOMEM;
-	}
-
-	len = (rtable->size - sizeof (struct irq_routing_table)) / sizeof (struct irq_info);
-
-	if (!len)
-		return -1;
-	for (loop = 0; loop < len; loop++) {
-		if ((*cur_slot)->number == rtable->slots[loop].slot) {
-		if ((*cur_slot)->bus == rtable->slots[loop].bus) {
-			(*cur_slot)->device = PCI_SLOT (rtable->slots[loop].devfn);
-			for (i = 0; i < 4; i++)
-				(*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector ((int) (*cur_slot)->bus, (int) (*cur_slot)->device, i);
-
-				debug ("(*cur_slot)->irq[0] = %x\n", (*cur_slot)->irq[0]);
-				debug ("(*cur_slot)->irq[1] = %x\n", (*cur_slot)->irq[1]);
-				debug ("(*cur_slot)->irq[2] = %x\n", (*cur_slot)->irq[2]);
-				debug ("(*cur_slot)->irq[3] = %x\n", (*cur_slot)->irq[3]);
-
-				debug ("rtable->exlusive_irqs = %x\n", rtable->exclusive_irqs);
-				debug ("rtable->slots[loop].irq[0].bitmap = %x\n", rtable->slots[loop].irq[0].bitmap);
-				debug ("rtable->slots[loop].irq[1].bitmap = %x\n", rtable->slots[loop].irq[1].bitmap);
-				debug ("rtable->slots[loop].irq[2].bitmap = %x\n", rtable->slots[loop].irq[2].bitmap);
-				debug ("rtable->slots[loop].irq[3].bitmap = %x\n", rtable->slots[loop].irq[3].bitmap);
-
-				debug ("rtable->slots[loop].irq[0].link= %x\n", rtable->slots[loop].irq[0].link);
-				debug ("rtable->slots[loop].irq[1].link = %x\n", rtable->slots[loop].irq[1].link);
-				debug ("rtable->slots[loop].irq[2].link = %x\n", rtable->slots[loop].irq[2].link);
-				debug ("rtable->slots[loop].irq[3].link = %x\n", rtable->slots[loop].irq[3].link);
-				debug ("end of init_devno\n");
-				return 0;
-			}
-		}
-	}
-
-	return -1;
-}
-
-static inline int power_on (struct slot *slot_cur)
-{
-	u8 cmd = HPC_SLOT_ON;
-	int retval;
-
-	retval = ibmphp_hpc_writeslot (slot_cur, cmd);
-	if (retval) {
-		err ("power on failed\n");
-		return retval;
-	}
-	if (CTLR_RESULT (slot_cur->ctrl->status)) {
-		err ("command not completed successfully in power_on \n");
-		return -EIO;
-	}
-	long_delay (3 * HZ); /* For ServeRAID cards, and some 66 PCI */
-	return 0;
-}
-
-static inline int power_off (struct slot *slot_cur)
-{
-	u8 cmd = HPC_SLOT_OFF;
-	int retval;
-
-	retval = ibmphp_hpc_writeslot (slot_cur, cmd);
-	if (retval) {
-		err ("power off failed \n");
-		return retval;
-	}
-	if (CTLR_RESULT (slot_cur->ctrl->status)) {
-		err ("command not completed successfully in power_off \n");
-		return -EIO;
-	}
-	return 0;
-}
-
-static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 value)
-{
-	int rc = 0;
-	struct slot *pslot;
-	u8 cmd;
-	int hpcrc = 0;
-
-	debug ("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n", (ulong) hotplug_slot, value);
-	ibmphp_lock_operations ();
-	cmd = 0x00;     // avoid compiler warning
-
-	if (hotplug_slot) {
-		switch (value) {
-		case HPC_SLOT_ATTN_OFF:
-			cmd = HPC_SLOT_ATTNOFF;
-			break;
-		case HPC_SLOT_ATTN_ON:
-			cmd = HPC_SLOT_ATTNON;
-			break;
-		case HPC_SLOT_ATTN_BLINK:
-			cmd = HPC_SLOT_BLINKLED;
-			break;
-		default:
-			rc = -ENODEV;
-			err ("set_attention_status - Error : invalid input [%x]\n", value);
-			break;
-		}
-		if (rc == 0) {
-			pslot = (struct slot *) hotplug_slot->private;
-			if (pslot)
-				hpcrc = ibmphp_hpc_writeslot (pslot, cmd);
-			else
-				rc = -ENODEV;
-		}
-	} else	
-		rc = -ENODEV;
-
-	if (hpcrc)
-		rc = hpcrc;
-
-	ibmphp_unlock_operations ();
-
-	debug ("set_attention_status - Exit rc[%d]\n", rc);
-	return rc;
-}
-
-static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 * value)
-{
-	int rc = -ENODEV;
-	struct slot *pslot;
-	int hpcrc = 0;
-	struct slot myslot;
-
-	debug ("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
-        
-	ibmphp_lock_operations ();
-	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
-		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
-			if (!hpcrc)
-				hpcrc = ibmphp_hpc_readslot (pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
-			if (!hpcrc) {
-				*value = SLOT_ATTN (myslot.status, myslot.ext_status);
-				rc = 0;
-			}
-		}
-	} else
-		rc = -ENODEV;
-
-	if (hpcrc)
-		rc = hpcrc;
-
-	ibmphp_unlock_operations ();
-	debug ("get_attention_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
-	return rc;
-}
-
-static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 * value)
-{
-	int rc = -ENODEV;
-	struct slot *pslot;
-	int hpcrc = 0;
-	struct slot myslot;
-
-	debug ("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
-	ibmphp_lock_operations ();
-	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
-		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
-			if (!hpcrc) {
-				*value = SLOT_LATCH (myslot.status);
-				rc = 0;
-			}
-		}
-	} else
-		rc = -ENODEV;
-
-	if (hpcrc)
-		rc = hpcrc;
-
-	ibmphp_unlock_operations ();
-	debug ("get_latch_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
-	return rc;
-}
-
-
-static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value)
-{
-	int rc = -ENODEV;
-	struct slot *pslot;
-	int hpcrc = 0;
-	struct slot myslot;
-
-	debug ("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
-	ibmphp_lock_operations ();
-	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
-		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
-			if (!hpcrc) {
-				*value = SLOT_PWRGD (myslot.status);
-				rc = 0;
-			}
-		}
-	} else
-		rc = -ENODEV;
-
-	if (hpcrc)
-		rc = hpcrc;
-
-	ibmphp_unlock_operations ();
-	debug ("get_power_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
-	return rc;
-}
-
-static int get_adapter_present (struct hotplug_slot *hotplug_slot, u8 * value)
-{
-	int rc = -ENODEV;
-	struct slot *pslot;
-	u8 present;
-	int hpcrc = 0;
-	struct slot myslot;
-
-	debug ("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
-	ibmphp_lock_operations ();
-	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
-		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
-			if (!hpcrc) {
-				present = SLOT_PRESENT (myslot.status);
-				if (present == HPC_SLOT_EMPTY)
-					*value = 0;
-				else
-					*value = 1;
-				rc = 0;
-			}
-		}
-	} else
-		rc = -ENODEV;
-	if (hpcrc)
-		rc = hpcrc;
-
-	ibmphp_unlock_operations ();
-	debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
-	return rc;
-}
-
-static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	int rc = -ENODEV;
-	struct slot *pslot;
-	u8 mode = 0;
-
-	debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
-		hotplug_slot, value);
-
-	ibmphp_lock_operations ();
-
-	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
-		if (pslot) {
-			rc = 0;
-			mode = pslot->supported_bus_mode;
-			*value = pslot->supported_speed; 
-			switch (*value) {
-			case BUS_SPEED_33:
-				break;
-			case BUS_SPEED_66:
-				if (mode == BUS_MODE_PCIX) 
-					*value += 0x01;
-				break;
-			case BUS_SPEED_100:
-			case BUS_SPEED_133:
-				*value = pslot->supported_speed + 0x01;
-				break;
-			default:
-				/* Note (will need to change): there would be soon 256, 512 also */
-				rc = -ENODEV;
-			}
-		}
-	} else
-		rc = -ENODEV;
-
-	ibmphp_unlock_operations ();
-	debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
-	return rc;
-}
-
-static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
-{
-	int rc = -ENODEV;
-	struct slot *pslot;
-	u8 mode = 0;
-
-	debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
-		hotplug_slot, value);
-
-	ibmphp_lock_operations ();
-
-	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
-		if (pslot) {
-			rc = get_cur_bus_info (&pslot);
-			if (!rc) {
-				mode = pslot->bus_on->current_bus_mode;
-				*value = pslot->bus_on->current_speed;
-				switch (*value) {
-				case BUS_SPEED_33:
-					break;
-				case BUS_SPEED_66:
-					if (mode == BUS_MODE_PCIX) 
-						*value += 0x01;
-					else if (mode == BUS_MODE_PCI)
-						;
-					else
-						*value = PCI_SPEED_UNKNOWN;
-					break;
-				case BUS_SPEED_100:
-				case BUS_SPEED_133:
-					*value += 0x01;
-					break;
-				default:
-					/* Note of change: there would also be 256, 512 soon */
-					rc = -ENODEV;
-				}
-			}
-		}
-	} else
-		rc = -ENODEV;
-
-	ibmphp_unlock_operations ();
-	debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
-	return rc;
-}
-/*
-static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
-{
-	int rc = -ENODEV;
-	struct slot *pslot;
-	int hpcrc = 0;
-	struct slot myslot;
-
-	debug ("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
-
-	if (flag)
-		ibmphp_lock_operations ();
-
-	if (hotplug_slot && value) {
-		pslot = (struct slot *) hotplug_slot->private;
-		if (pslot) {
-			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
-
-			if (!(SLOT_LATCH (myslot.status)) && (SLOT_PRESENT (myslot.status))) {
-				hpcrc = ibmphp_hpc_readslot (pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
-				if (!hpcrc) {
-					*value = SLOT_SPEED (myslot.ext_status);
-					rc = 0;
-				}
-			} else {
-				*value = MAX_ADAPTER_NONE;
-				rc = 0;
-			}
-                }
-        } else
-		rc = -ENODEV;
-
-	if (hpcrc)
-		rc = hpcrc;
-
-	if (flag)
-		ibmphp_unlock_operations ();
-
-	debug ("get_max_adapter_speed_1 - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
-	return rc;
-}
-
-static int get_bus_name (struct hotplug_slot *hotplug_slot, char * value)
-{
-	int rc = -ENODEV;
-	struct slot *pslot = NULL;
-
-	debug ("get_bus_name - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot);
-
-	ibmphp_lock_operations ();
-
-	if (hotplug_slot) {
-		pslot = (struct slot *) hotplug_slot->private;
-		if (pslot) {
-			rc = 0;
-			snprintf (value, 100, "Bus %x", pslot->bus);
-		}
-	} else
-		rc = -ENODEV;
-
-	ibmphp_unlock_operations ();
-	debug ("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
-	return rc;
-}
-*/
-
-/*******************************************************************************
- * This routine will initialize the ops data structure used in the validate
- * function. It will also power off empty slots that are powered on since BIOS
- * leaves those on, albeit disconnected
- ******************************************************************************/
-static int __init init_ops (void)
-{
-	struct slot *slot_cur;
-	struct list_head *tmp;
-	int retval;
-	int rc;
-
-	list_for_each (tmp, &ibmphp_slot_head) {
-		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
-
-		if (!slot_cur)
-			return -ENODEV;
-
-		debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);
-		if (slot_cur->ctrl->revision == 0xFF) 
-			if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
-				return -1;
-
-		if (slot_cur->bus_on->current_speed == 0xFF) 
-			if (get_cur_bus_info (&slot_cur)) 
-				return -1;
-
-		if (slot_cur->ctrl->options == 0xFF)
-			if (get_hpc_options (slot_cur, &slot_cur->ctrl->options))
-				return -1;
-
-		retval = slot_update (&slot_cur);
-		if (retval)
-			return retval;
-
-		debug ("status = %x\n", slot_cur->status);
-		debug ("ext_status = %x\n", slot_cur->ext_status);
-		debug ("SLOT_POWER = %x\n", SLOT_POWER (slot_cur->status));
-		debug ("SLOT_PRESENT = %x\n", SLOT_PRESENT (slot_cur->status));
-		debug ("SLOT_LATCH = %x\n", SLOT_LATCH (slot_cur->status));
-
-		if ((SLOT_PWRGD (slot_cur->status)) && 
-		    !(SLOT_PRESENT (slot_cur->status)) && 
-		    !(SLOT_LATCH (slot_cur->status))) {
-			debug ("BEFORE POWER OFF COMMAND\n");
-				rc = power_off (slot_cur);
-				if (rc)
-					return rc;
-
-	/*		retval = slot_update (&slot_cur);
-	 *		if (retval)
-	 *			return retval;
-	 *		ibmphp_update_slot_info (slot_cur);
-	 */
-		}
-	}
-	init_flag = 0;
-	return 0;
-}
-
-/* This operation will check whether the slot is within the bounds and
- * the operation is valid to perform on that slot
- * Parameters: slot, operation
- * Returns: 0 or error codes
- */
-static int validate (struct slot *slot_cur, int opn)
-{
-	int number;
-	int retval;
-
-	if (!slot_cur)
-		return -ENODEV;
-	number = slot_cur->number;
-	if ((number > max_slots) || (number < 0))
-		return -EBADSLT;
-	debug ("slot_number in validate is %d\n", slot_cur->number);
-
-	retval = slot_update (&slot_cur);
-	if (retval)
-		return retval;
-
-	switch (opn) {
-		case ENABLE:
-			if (!(SLOT_PWRGD (slot_cur->status)) && 
-			     (SLOT_PRESENT (slot_cur->status)) && 
-			     !(SLOT_LATCH (slot_cur->status)))
-				return 0;
-			break;
-		case DISABLE:
-			if ((SLOT_PWRGD (slot_cur->status)) && 
-			    (SLOT_PRESENT (slot_cur->status)) &&
-			    !(SLOT_LATCH (slot_cur->status)))
-				return 0;
-			break;
-		default:
-			break;
-	}
-	err ("validate failed....\n");
-	return -EINVAL;
-}
-
-/********************************************************************************
- * This routine is for updating the data structures in the hotplug core
- * Parameters: struct slot
- * Returns: 0 or error
- *******************************************************************************/
-int ibmphp_update_slot_info (struct slot *slot_cur)
-{
-	struct hotplug_slot_info *info;
-	int rc;
-	u8 bus_speed;
-	u8 mode;
-
-	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
-	if (!info) {
-		err ("out of system memory \n");
-		return -ENOMEM;
-	}
-        
-	info->power_status = SLOT_PWRGD (slot_cur->status);
-	info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
-	info->latch_status = SLOT_LATCH (slot_cur->status);
-        if (!SLOT_PRESENT (slot_cur->status)) {
-                info->adapter_status = 0;
-//		info->max_adapter_speed_status = MAX_ADAPTER_NONE;
-	} else {
-                info->adapter_status = 1;
-//		get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
-	}
-
-	bus_speed = slot_cur->bus_on->current_speed;
-	mode = slot_cur->bus_on->current_bus_mode;
-
-	switch (bus_speed) {
-	case BUS_SPEED_33:
-		break;
-	case BUS_SPEED_66:
-		if (mode == BUS_MODE_PCIX) 
-			bus_speed += 0x01;
-		else if (mode == BUS_MODE_PCI)
-			;
-		else
-			bus_speed = PCI_SPEED_UNKNOWN;
-		break;
-	case BUS_SPEED_100:
-	case BUS_SPEED_133:
-		bus_speed += 0x01;
-		break;
-	default:
-		bus_speed = PCI_SPEED_UNKNOWN;
-	}
-
-	info->cur_bus_speed = bus_speed;
-	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
-	// To do: bus_names 
-	
-	rc = pci_hp_change_slot_info (slot_cur->hotplug_slot, info);
-	kfree (info);
-	return rc;
-}
-
-
-/******************************************************************************
- * This function will return the pci_func, given bus and devfunc, or NULL.  It
- * is called from visit routines
- ******************************************************************************/
-
-static struct pci_func *ibm_slot_find (u8 busno, u8 device, u8 function)
-{
-	struct pci_func *func_cur;
-	struct slot *slot_cur;
-	struct list_head * tmp;
-	list_for_each (tmp, &ibmphp_slot_head) {
-		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
-		if (slot_cur->func) {
-			func_cur = slot_cur->func;
-			while (func_cur) {
-				if ((func_cur->busno == busno) && (func_cur->device == device) && (func_cur->function == function))
-					return func_cur;
-				func_cur = func_cur->next;
-			}
-		}
-	}
-	return NULL;
-}
-
-/* This routine is to find the pci_bus from kernel structures.
- * Parameters: bus number
- * Returns : pci_bus *  or NULL if not found
- */
-static struct pci_bus *ibmphp_find_bus (u8 busno)
-{
-	const struct list_head *tmp;
-	struct pci_bus *bus;
-	debug ("inside %s, busno = %x \n", __FUNCTION__, busno);
-
-	list_for_each (tmp, &pci_root_buses) {
-		bus = (struct pci_bus *) pci_bus_b (tmp);
-		if (bus)
-			if (bus->number == busno)
-				return bus;
-	}
-	return NULL;
-}
-
-/*************************************************************
- * This routine frees up memory used by struct slot, including
- * the pointers to pci_func, bus, hotplug_slot, controller,
- * and deregistering from the hotplug core
- *************************************************************/
-static void free_slots (void)
-{
-	struct slot *slot_cur;
-	struct list_head * tmp;
-	struct list_head * next;
-
-	debug ("%s -- enter\n", __FUNCTION__);
-
-	list_for_each_safe (tmp, next, &ibmphp_slot_head) {
-	
-		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
-
-		pci_hp_deregister (slot_cur->hotplug_slot);
-
-		if (slot_cur->hotplug_slot) {
-			kfree (slot_cur->hotplug_slot);
-			slot_cur->hotplug_slot = NULL;
-		}
-
-		if (slot_cur->ctrl) 
-			slot_cur->ctrl = NULL;
-		
-		if (slot_cur->bus_on) 
-			slot_cur->bus_on = NULL;
-
-		ibmphp_unconfigure_card (&slot_cur, -1);  /* we don't want to actually remove the resources, since free_resources will do just that */
-
-		kfree (slot_cur);
-		slot_cur = NULL;
-	}
-	debug ("%s -- exit\n", __FUNCTION__);
-}
-
-static int ibm_unconfigure_device (struct pci_func *func)
-{
-	struct pci_dev *temp;
-	u8 j;
-
-	debug ("inside %s\n", __FUNCTION__);
-	debug ("func->device = %x, func->function = %x\n", func->device, func->function);
-	debug ("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
-
-	for (j = 0; j < 0x08; j++) {
-		temp = pci_find_slot (func->busno, (func->device << 3) | j);
-		if (temp)
-			pci_remove_bus_device(temp);
-	}
-	return 0;
-}
-
-/*
- * The following function is to fix kernel bug regarding 
- * getting bus entries, here we manually add those primary 
- * bus entries to kernel bus structure whenever apply
- */
-
-static u8 bus_structure_fixup (u8 busno)
-{
-	struct pci_bus *bus;
-	struct pci_dev *dev;
-	u16 l;
-
-	if (ibmphp_find_bus (busno) || !(ibmphp_find_same_bus_num (busno)))
-		return 1;
-
-	bus = kmalloc (sizeof (*bus), GFP_KERNEL);
-	if (!bus) {
-		err ("%s - out of memory\n", __FUNCTION__);
-		return 1;
-	}
-	dev = kmalloc (sizeof (*dev), GFP_KERNEL);
-	if (!dev) {
-		kfree (bus);
-		err ("%s - out of memory\n", __FUNCTION__);
-		return 1;
-	}
-
-	bus->number = busno;
-	bus->ops = ibmphp_pci_bus->ops;
-	dev->bus = bus;
-	for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
-		if (!pci_read_config_word (dev, PCI_VENDOR_ID, &l) &&  l != 0x0000 && l != 0xffff) {
-			debug ("%s - Inside bus_struture_fixup() \n", __FUNCTION__);
-			pci_scan_bus (busno, ibmphp_pci_bus->ops, NULL);
-			break;
-		}
-	}
-
-	kfree (dev);
-	kfree (bus);
-
-	return 0;
-}
-
-static int ibm_configure_device (struct pci_func *func)
-{
-	unsigned char bus;
-	struct pci_bus *child;
-	int num;
-	int flag = 0;	/* this is to make sure we don't double scan the bus, for bridged devices primarily */
-
-	if (!(bus_structure_fixup (func->busno)))
-		flag = 1;
-	if (func->dev == NULL)
-		func->dev = pci_find_slot (func->busno, PCI_DEVFN(func->device, func->function));
-
-	if (func->dev == NULL) {
-		struct pci_bus *bus = ibmphp_find_bus (func->busno);
-		if (!bus)
-			return 0;
-
-		num = pci_scan_slot(bus, PCI_DEVFN(func->device, func->function));
-		if (num)
-			pci_bus_add_devices(bus);
-
-		func->dev = pci_find_slot(func->busno, PCI_DEVFN(func->device, func->function));
-		if (func->dev == NULL) {
-			err ("ERROR... : pci_dev still NULL \n");
-			return 0;
-		}
-	}
-	if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
-		pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);
-		child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
-		pci_do_scan_bus (child);
-	}
-
-	return 0;
-}
-
-/*******************************************************
- * Returns whether the bus is empty or not 
- *******************************************************/
-static int is_bus_empty (struct slot * slot_cur)
-{
-	int rc;
-	struct slot * tmp_slot;
-	u8 i = slot_cur->bus_on->slot_min;
-
-	while (i <= slot_cur->bus_on->slot_max) {
-		if (i == slot_cur->number) {
-			i++;
-			continue;
-		}
-		tmp_slot = ibmphp_get_slot_from_physical_num (i);
-		if (!tmp_slot)
-			return 0;
-		rc = slot_update (&tmp_slot);
-		if (rc)
-			return 0;
-		if (SLOT_PRESENT (tmp_slot->status) && SLOT_PWRGD (tmp_slot->status))
-			return 0;
-		i++;
-	}
-	return 1;
-}
-
-/***********************************************************
- * If the HPC permits and the bus currently empty, tries to set the 
- * bus speed and mode at the maximum card and bus capability
- * Parameters: slot
- * Returns: bus is set (0) or error code
- ***********************************************************/
-static int set_bus (struct slot * slot_cur)
-{
-	int rc;
-	u8 speed;
-	u8 cmd = 0x0;
-	const struct list_head *tmp;
-	struct pci_dev * dev;
-	int retval;
-
-	debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number);
-	if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
-		rc = slot_update (&slot_cur);
-		if (rc)
-			return rc;
-		speed = SLOT_SPEED (slot_cur->ext_status);
-		debug ("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
-		switch (speed) {
-		case HPC_SLOT_SPEED_33:
-			cmd = HPC_BUS_33CONVMODE;
-			break;
-		case HPC_SLOT_SPEED_66:
-			if (SLOT_PCIX (slot_cur->ext_status)) {
-				if ((slot_cur->supported_speed >= BUS_SPEED_66) && (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
-					cmd = HPC_BUS_66PCIXMODE;
-				else if (!SLOT_BUS_MODE (slot_cur->ext_status))
-					/* if max slot/bus capability is 66 pci
-					and there's no bus mode mismatch, then
-					the adapter supports 66 pci */ 
-					cmd = HPC_BUS_66CONVMODE;
-				else
-					cmd = HPC_BUS_33CONVMODE;
-			} else {
-				if (slot_cur->supported_speed >= BUS_SPEED_66)
-					cmd = HPC_BUS_66CONVMODE;
-				else
-					cmd = HPC_BUS_33CONVMODE;
-			}
-			break;
-		case HPC_SLOT_SPEED_133:
-			switch (slot_cur->supported_speed) {
-			case BUS_SPEED_33:
-				cmd = HPC_BUS_33CONVMODE;
-				break;
-			case BUS_SPEED_66:
-				if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
-					cmd = HPC_BUS_66PCIXMODE;
-				else
-					cmd = HPC_BUS_66CONVMODE;
-				break;
-			case BUS_SPEED_100:
-				cmd = HPC_BUS_100PCIXMODE;
-				break;
-			case BUS_SPEED_133:
-				/* This is to take care of the bug in CIOBX chip*/
-				list_for_each (tmp, &pci_devices) {
-					dev = (struct pci_dev *) pci_dev_g (tmp);
-					if (dev) {
-						if ((dev->vendor == 0x1166) && (dev->device == 0x0101))
-							ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
-					}
-				}
-				cmd = HPC_BUS_133PCIXMODE;
-				break;
-			default:
-				err ("Wrong bus speed \n");
-				return -ENODEV;
-			}
-			break;
-		default:
-			err ("wrong slot speed \n");
-			return -ENODEV;
-		}
-		debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd);
-		retval = ibmphp_hpc_writeslot (slot_cur, cmd);
-		if (retval) {
-			err ("setting bus speed failed\n");
-			return retval;
-		}
-		if (CTLR_RESULT (slot_cur->ctrl->status)) {
-			err ("command not completed successfully in set_bus \n");
-			return -EIO;
-		}
-	}
-	/* This is for x440, once Brandon fixes the firmware, 
-	will not need this delay */
-	long_delay (1 * HZ);
-	debug ("%s -Exit \n", __FUNCTION__);
-	return 0;
-}
-
-/* This routine checks the bus limitations that the slot is on from the BIOS.
- * This is used in deciding whether or not to power up the slot.  
- * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
- * same bus) 
- * Parameters: slot
- * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
- */
-static int check_limitations (struct slot *slot_cur)
-{
-	u8 i;
-	struct slot * tmp_slot;
-	u8 count = 0;
-	u8 limitation = 0;
-
-	for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
-		tmp_slot = ibmphp_get_slot_from_physical_num (i);
-		if (!tmp_slot)
-			return -ENODEV;
-		if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) 
-			count++;
-	}
-	get_cur_bus_info (&slot_cur);
-	switch (slot_cur->bus_on->current_speed) {
-	case BUS_SPEED_33:
-		limitation = slot_cur->bus_on->slots_at_33_conv;
-		break;
-	case BUS_SPEED_66:
-		if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
-			limitation = slot_cur->bus_on->slots_at_66_pcix;
-		else
-			limitation = slot_cur->bus_on->slots_at_66_conv;
-		break;
-	case BUS_SPEED_100:
-		limitation = slot_cur->bus_on->slots_at_100_pcix;
-		break;
-	case BUS_SPEED_133:
-		limitation = slot_cur->bus_on->slots_at_133_pcix;
-		break;
-	}
-
-	if ((count + 1) > limitation)
-		return -EINVAL;
-	return 0;
-}
-
-static inline void print_card_capability (struct slot *slot_cur)
-{
-	info ("capability of the card is ");
-	if ((slot_cur->ext_status & CARD_INFO) == PCIX133) 
-		info ("   133 MHz PCI-X \n");
-	else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
-		info ("    66 MHz PCI-X \n");
-	else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
-		info ("    66 MHz PCI \n");
-	else
-		info ("    33 MHz PCI \n");
-
-}
-
-/* This routine will power on the slot, configure the device(s) and find the
- * drivers for them.
- * Parameters: hotplug_slot
- * Returns: 0 or failure codes
- */
-static int enable_slot (struct hotplug_slot *hs)
-{
-	int rc, i, rcpr;
-	struct slot *slot_cur;
-	u8 function;
-	struct pci_func *tmp_func;
-
-	ibmphp_lock_operations ();
-
-	debug ("ENABLING SLOT........ \n");
-	slot_cur = (struct slot *) hs->private;
-
-	if ((rc = validate (slot_cur, ENABLE))) {
-		err ("validate function failed \n");
-		goto error_nopower;
-	}
-
-	attn_LED_blink (slot_cur);
-	
-	rc = set_bus (slot_cur);
-	if (rc) {
-		err ("was not able to set the bus \n");
-		goto error_nopower;
-	}
-
-	/*-----------------debugging------------------------------*/
-	get_cur_bus_info (&slot_cur);
-	debug ("the current bus speed right after set_bus = %x \n", slot_cur->bus_on->current_speed); 
-	/*----------------------------------------------------------*/
-
-	rc = check_limitations (slot_cur);
-	if (rc) {
-		err ("Adding this card exceeds the limitations of this bus.\n");
-		err ("(i.e., >1 133MHz cards running on same bus, or "
-		     ">2 66 PCI cards running on same bus\n.");
-		err ("Try hot-adding into another bus \n");
-		rc = -EINVAL;
-		goto error_nopower;
-	}
-
-	rc = power_on (slot_cur);
-
-	if (rc) {
-		err ("something wrong when powering up... please see below for details\n");
-		/* need to turn off before on, otherwise, blinking overwrites */
-		attn_off(slot_cur);
-		attn_on (slot_cur);
-		if (slot_update (&slot_cur)) {
-			attn_off (slot_cur);
-			attn_on (slot_cur);
-			rc = -ENODEV;
-			goto exit;
-		}
-		/* Check to see the error of why it failed */
-		if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PWRGD (slot_cur->status)))
-			err ("power fault occurred trying to power up \n");
-		else if (SLOT_BUS_SPEED (slot_cur->status)) {
-			err ("bus speed mismatch occurred.  please check current bus speed and card capability \n");
-			print_card_capability (slot_cur);
-		} else if (SLOT_BUS_MODE (slot_cur->ext_status)) {
-			err ("bus mode mismatch occurred.  please check current bus mode and card capability \n");
-			print_card_capability (slot_cur);
-		}
-		ibmphp_update_slot_info (slot_cur);
-		goto exit;
-	}
-	debug ("after power_on\n");
-	/*-----------------------debugging---------------------------*/
-	get_cur_bus_info (&slot_cur);
-	debug ("the current bus speed right after power_on = %x \n", slot_cur->bus_on->current_speed);
-	/*----------------------------------------------------------*/
-
-	rc = slot_update (&slot_cur);
-	if (rc)
-		goto error_power;
-	
-	rc = -EINVAL;
-	if (SLOT_POWER (slot_cur->status) && !(SLOT_PWRGD (slot_cur->status))) {
-		err ("power fault occurred trying to power up... \n");
-		goto error_power;
-	}
-	if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
-		err ("bus speed mismatch occurred.  please check current bus speed and card capability \n");
-		print_card_capability (slot_cur);
-		goto error_power;
-	} 
-	/* Don't think this case will happen after above checks... but just in case, for paranoia sake */
-	if (!(SLOT_POWER (slot_cur->status))) {
-		err ("power on failed... \n");
-		goto error_power;
-	}
-
-	slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
-	if (!slot_cur->func) {
-		/* We cannot do update_slot_info here, since no memory for
-		 * kmalloc n.e.ways, and update_slot_info allocates some */
-		err ("out of system memory \n");
-		rc = -ENOMEM;
-		goto error_power;
-	}
-	memset (slot_cur->func, 0, sizeof (struct pci_func));
-	slot_cur->func->busno = slot_cur->bus;
-	slot_cur->func->device = slot_cur->device;
-	for (i = 0; i < 4; i++)
-		slot_cur->func->irq[i] = slot_cur->irq[i];
-
-	debug ("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n", slot_cur->bus, slot_cur->device);
-
-	if (ibmphp_configure_card (slot_cur->func, slot_cur->number)) {
-		err ("configure_card was unsuccessful... \n");
-		ibmphp_unconfigure_card (&slot_cur, 1); /* true because don't need to actually deallocate resources, just remove references */
-		debug ("after unconfigure_card\n");
-		slot_cur->func = NULL;
-		rc = -ENOMEM;
-		goto error_power;
-	}
-
-	function = 0x00;
-	do {
-		tmp_func = ibm_slot_find (slot_cur->bus, slot_cur->func->device, function++);
-		if (tmp_func && !(tmp_func->dev))
-			ibm_configure_device (tmp_func);
-	} while (tmp_func);
-
-	attn_off (slot_cur);
-	if (slot_update (&slot_cur)) {
-		rc = -EFAULT;
-		goto exit;
-	}
-	ibmphp_print_test ();
-	rc = ibmphp_update_slot_info (slot_cur);
-exit:
-	ibmphp_unlock_operations(); 
-	return rc;
-
-error_nopower:
-	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
-	attn_on (slot_cur);
-error_cont:
-	rcpr = slot_update (&slot_cur);
-	if (rcpr) {
-		rc = rcpr;
-		goto exit;
-	}
-	ibmphp_update_slot_info (slot_cur);
-	goto exit;
-
-error_power:
-	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
-	attn_on (slot_cur);
-	rcpr = power_off (slot_cur);
-	if (rcpr) {
-		rc = rcpr;
-		goto exit;
-	}
-	goto error_cont;
-}
-
-/**************************************************************
-* HOT REMOVING ADAPTER CARD                                   *
-* INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
-* OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
-          DISABLE POWER ,                                    *
-**************************************************************/
-int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
-{
-	struct slot *slot = hotplug_slot->private;
-	int rc;
-	
-	ibmphp_lock_operations();
-	rc = ibmphp_do_disable_slot(slot);
-	ibmphp_unlock_operations();
-	return rc;
-}
-
-int ibmphp_do_disable_slot (struct slot *slot_cur)
-{
-	int rc;
-	u8 flag;
-	int parm = 0;
-
-	debug ("DISABLING SLOT... \n"); 
-		
-	if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
-		return -ENODEV;
-	}
-	
-	flag = slot_cur->flag;
-	slot_cur->flag = TRUE;
-
-	if (flag == TRUE) {
-		rc = validate (slot_cur, DISABLE);	/* checking if powered off already & valid slot # */
-		if (rc)
-			goto error;
-	}
-	attn_LED_blink (slot_cur);
-
-	if (slot_cur->func == NULL) {
-		/* We need this for fncs's that were there on bootup */
-		slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
-		if (!slot_cur->func) {
-			err ("out of system memory \n");
-			rc = -ENOMEM;
-			goto error;
-		}
-		memset (slot_cur->func, 0, sizeof (struct pci_func));
-		slot_cur->func->busno = slot_cur->bus;
-		slot_cur->func->device = slot_cur->device;
-	}
-
-	if ((rc = ibm_unconfigure_device (slot_cur->func))) {
-		err ("removing from kernel failed... \n");
-		err ("Please check to see if it was statically linked or is "
-		     "in use otherwise. (perhaps the driver is not 'hot-removable')\n");
-		goto error;
-	}
-        
-	/* If we got here from latch suddenly opening on operating card or 
-	a power fault, there's no power to the card, so cannot
-	read from it to determine what resources it occupied.  This operation
-	is forbidden anyhow.  The best we can do is remove it from kernel
-	lists at least */
-
-	if (!flag) {
-		attn_off (slot_cur);
-		return 0;
-	}
-
-	rc = ibmphp_unconfigure_card (&slot_cur, parm);
-	slot_cur->func = NULL;
-	debug ("in disable_slot. after unconfigure_card\n");
-	if (rc) {
-		err ("could not unconfigure card.\n");
-		goto error;
-	}
-
-	rc = ibmphp_hpc_writeslot (slot_cur, HPC_SLOT_OFF);
-	if (rc)
-		goto error;
-
-	attn_off (slot_cur);
-	rc = slot_update (&slot_cur);
-	if (rc)
-		goto exit;
-
-	rc = ibmphp_update_slot_info (slot_cur);
-	ibmphp_print_test ();
-exit:
-	return rc;
-
-error:
-	/*  Need to turn off if was blinking b4 */
-	attn_off (slot_cur);
-	attn_on (slot_cur);
-	if (slot_update (&slot_cur)) {
-		rc = -EFAULT;
-		goto exit;
-	}
-	if (flag)		
-		ibmphp_update_slot_info (slot_cur);
-	goto exit;
-}
-
-struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
-	.owner =			THIS_MODULE,
-	.set_attention_status =		set_attention_status,
-	.enable_slot =			enable_slot,
-	.disable_slot =			ibmphp_disable_slot,
-	.hardware_test =		NULL,
-	.get_power_status =		get_power_status,
-	.get_attention_status =		get_attention_status,
-	.get_latch_status =		get_latch_status,
-	.get_adapter_status =		get_adapter_present,
-	.get_max_bus_speed =		get_max_bus_speed,
-	.get_cur_bus_speed =		get_cur_bus_speed,
-/*	.get_max_adapter_speed =	get_max_adapter_speed,
-	.get_bus_name_status =		get_bus_name,
-*/
-};
-
-static void ibmphp_unload (void)
-{
-	free_slots ();
-	debug ("after slots \n");
-	ibmphp_free_resources ();
-	debug ("after resources \n");
-	ibmphp_free_bus_info_queue ();
-	debug ("after bus info \n");
-	ibmphp_free_ebda_hpc_queue ();
-	debug ("after ebda hpc \n");
-	ibmphp_free_ebda_pci_rsrc_queue ();
-	debug ("after ebda pci rsrc \n");
-	kfree (ibmphp_pci_bus);
-}
-
-static int __init ibmphp_init (void)
-{
-	struct pci_bus *bus;
-	int i = 0;
-	int rc = 0;
-
-	init_flag = 1;
-
-	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
-
-	ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL);
-	if (!ibmphp_pci_bus) {
-		err ("out of memory\n");
-		rc = -ENOMEM;
-		goto exit;
-	}
-
-	bus = ibmphp_find_bus (0);
-	if (!bus) {
-		err ("Can't find the root pci bus, can not continue\n");
-		rc = -ENODEV;
-		goto error;
-	}
-	memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
-
-	ibmphp_debug = debug;
-
-	ibmphp_hpc_initvars ();
-
-	for (i = 0; i < 16; i++)
-		irqs[i] = 0;
-
-	if ((rc = ibmphp_access_ebda ()))
-		goto error;
-	debug ("after ibmphp_access_ebda ()\n");
-
-	if ((rc = ibmphp_rsrc_init ()))
-		goto error;
-	debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
-
-	max_slots = get_max_slots ();
-	
-	if ((rc = ibmphp_register_pci ()))
-		goto error;
-
-	if (init_ops ()) {
-		rc = -ENODEV;
-		goto error;
-	}
-
-	ibmphp_print_test ();
-	if ((rc = ibmphp_hpc_start_poll_thread ())) {
-		goto error;
-	}
-
-	/* lock ourselves into memory with a module 
-	 * count of -1 so that no one can unload us. */
-	module_put(THIS_MODULE);
-
-exit:
-	return rc;
-
-error:
-	ibmphp_unload ();
-	goto exit;
-}
-
-static void __exit ibmphp_exit (void)
-{
-	ibmphp_hpc_stop_poll_thread ();
-	debug ("after polling\n");
-	ibmphp_unload ();
-	debug ("done\n");
-}
-
-module_init (ibmphp_init);
-module_exit (ibmphp_exit);
diff -urN linux-2.5.70-bk9/drivers/hotplug/ibmphp_ebda.c linux-2.5.70-bk10/drivers/hotplug/ibmphp_ebda.c
--- linux-2.5.70-bk9/drivers/hotplug/ibmphp_ebda.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/ibmphp_ebda.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1228 +0,0 @@
-/*
- * IBM Hot Plug Controller Driver
- *
- * Written By: Tong Yu, IBM Corporation
- *
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001,2002 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/list.h>
-#include <linux/init.h>
-#include "ibmphp.h"
-
-/*
- * POST builds data blocks(in this data block definition, a char-1
- * byte, short(or word)-2 byte, long(dword)-4 byte) in the Extended
- * BIOS Data Area which describe the configuration of the hot-plug
- * controllers and resources used by the PCI Hot-Plug devices.
- *
- * This file walks EBDA, maps data block from physical addr,
- * reconstruct linked lists about all system resource(MEM, PFM, IO)
- * already assigned by POST, as well as linked lists about hot plug
- * controllers (ctlr#, slot#, bus&slot features...)
- */
-
-/* Global lists */
-LIST_HEAD (ibmphp_ebda_pci_rsrc_head);
-LIST_HEAD (ibmphp_slot_head);
-
-/* Local variables */
-static struct ebda_hpc_list *hpc_list_ptr;
-static struct ebda_rsrc_list *rsrc_list_ptr;
-static struct rio_table_hdr *rio_table_ptr = NULL;
-static LIST_HEAD (ebda_hpc_head);
-static LIST_HEAD (bus_info_head);
-static LIST_HEAD (rio_vg_head);
-static LIST_HEAD (rio_lo_head);
-static LIST_HEAD (opt_vg_head);
-static LIST_HEAD (opt_lo_head);
-static void *io_mem;
-
-/* Local functions */
-static int ebda_rsrc_controller (void);
-static int ebda_rsrc_rsrc (void);
-static int ebda_rio_table (void);
-
-static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
-{
-	struct ebda_hpc_list *list;
-
-	list = kmalloc (sizeof (struct ebda_hpc_list), GFP_KERNEL);
-	if (!list)
-		return NULL;
-	memset (list, 0, sizeof (*list));
-	return list;
-}
-
-static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
-{
-	struct controller *controller;
-	struct ebda_hpc_slot *slots;
-	struct ebda_hpc_bus *buses;
-
-	controller = kmalloc (sizeof (struct controller), GFP_KERNEL);
-	if (!controller)
-		return NULL;
-	memset (controller, 0, sizeof (*controller));
-
-	slots = kmalloc (sizeof (struct ebda_hpc_slot) * slot_count, GFP_KERNEL);
-	if (!slots) {
-		kfree (controller);
-		return NULL;
-	}
-	memset (slots, 0, sizeof (*slots) * slot_count);
-	controller->slots = slots;
-
-	buses = kmalloc (sizeof (struct ebda_hpc_bus) * bus_count, GFP_KERNEL);
-	if (!buses) {
-		kfree (controller->slots);
-		kfree (controller);
-		return NULL;
-	}
-	memset (buses, 0, sizeof (*buses) * bus_count);
-	controller->buses = buses;
-
-	return controller;
-}
-
-static void free_ebda_hpc (struct controller *controller)
-{
-	kfree (controller->slots);
-	controller->slots = NULL;
-	kfree (controller->buses);
-	controller->buses = NULL;
-	controller->ctrl_dev = NULL;
-	kfree (controller);
-}
-
-static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void)
-{
-	struct ebda_rsrc_list *list;
-
-	list = kmalloc (sizeof (struct ebda_rsrc_list), GFP_KERNEL);
-	if (!list)
-		return NULL;
-	memset (list, 0, sizeof (*list));
-	return list;
-}
-
-static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
-{
-	struct ebda_pci_rsrc *resource;
-
-	resource = kmalloc (sizeof (struct ebda_pci_rsrc), GFP_KERNEL);
-	if (!resource)
-		return NULL;
-	memset (resource, 0, sizeof (*resource));
-	return resource;
-}
-
-static void __init print_bus_info (void)
-{
-	struct bus_info *ptr;
-	struct list_head *ptr1;
-	
-	list_for_each (ptr1, &bus_info_head) {
-		ptr = list_entry (ptr1, struct bus_info, bus_info_list);
-		debug ("%s - slot_min = %x\n", __FUNCTION__, ptr->slot_min);
-		debug ("%s - slot_max = %x\n", __FUNCTION__, ptr->slot_max);
-		debug ("%s - slot_count = %x\n", __FUNCTION__, ptr->slot_count);
-		debug ("%s - bus# = %x\n", __FUNCTION__, ptr->busno);
-		debug ("%s - current_speed = %x\n", __FUNCTION__, ptr->current_speed);
-		debug ("%s - controller_id = %x\n", __FUNCTION__, ptr->controller_id);
-		
-		debug ("%s - slots_at_33_conv = %x\n", __FUNCTION__, ptr->slots_at_33_conv);
-		debug ("%s - slots_at_66_conv = %x\n", __FUNCTION__, ptr->slots_at_66_conv);
-		debug ("%s - slots_at_66_pcix = %x\n", __FUNCTION__, ptr->slots_at_66_pcix);
-		debug ("%s - slots_at_100_pcix = %x\n", __FUNCTION__, ptr->slots_at_100_pcix);
-		debug ("%s - slots_at_133_pcix = %x\n", __FUNCTION__, ptr->slots_at_133_pcix);
-
-	}
-}
-
-static void print_lo_info (void)
-{
-	struct rio_detail *ptr;
-	struct list_head *ptr1;
-	debug ("print_lo_info ---- \n");	
-	list_for_each (ptr1, &rio_lo_head) {
-		ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
-		debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
-		debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
-		debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
-		debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
-		debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
-		debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
-
-	}
-}
-
-static void print_vg_info (void)
-{
-	struct rio_detail *ptr;
-	struct list_head *ptr1;
-	debug ("%s --- \n", __FUNCTION__);
-	list_for_each (ptr1, &rio_vg_head) {
-		ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
-		debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
-		debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
-		debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
-		debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
-		debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
-		debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
-
-	}
-}
-
-static void __init print_ebda_pci_rsrc (void)
-{
-	struct ebda_pci_rsrc *ptr;
-	struct list_head *ptr1;
-
-	list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
-		ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
-		debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", 
-			__FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
-	}
-}
-
-static void __init print_ibm_slot (void)
-{
-	struct slot *ptr;
-	struct list_head *ptr1;
-
-	list_for_each (ptr1, &ibmphp_slot_head) {
-		ptr = list_entry (ptr1, struct slot, ibm_slot_list);
-		debug ("%s - slot_number: %x \n", __FUNCTION__, ptr->number); 
-	}
-}
-
-static void __init print_opt_vg (void)
-{
-	struct opt_rio *ptr;
-	struct list_head *ptr1;
-	debug ("%s --- \n", __FUNCTION__);
-	list_for_each (ptr1, &opt_vg_head) {
-		ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
-		debug ("%s - rio_type %x \n", __FUNCTION__, ptr->rio_type); 
-		debug ("%s - chassis_num: %x \n", __FUNCTION__, ptr->chassis_num); 
-		debug ("%s - first_slot_num: %x \n", __FUNCTION__, ptr->first_slot_num); 
-		debug ("%s - middle_num: %x \n", __FUNCTION__, ptr->middle_num); 
-	}
-}
-
-static void __init print_ebda_hpc (void)
-{
-	struct controller *hpc_ptr;
-	struct list_head *ptr1;
-	u16 index;
-
-	list_for_each (ptr1, &ebda_hpc_head) {
-
-		hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list); 
-
-		for (index = 0; index < hpc_ptr->slot_count; index++) {
-			debug ("%s - physical slot#: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_num);
-			debug ("%s - pci bus# of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_bus_num);
-			debug ("%s - index into ctlr addr: %x\n", __FUNCTION__, hpc_ptr->slots[index].ctl_index);
-			debug ("%s - cap of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_cap);
-		}
-
-		for (index = 0; index < hpc_ptr->bus_count; index++) {
-			debug ("%s - bus# of each bus controlled by this ctlr: %x\n", __FUNCTION__, hpc_ptr->buses[index].bus_num);
-		}
-
-		debug ("%s - type of hpc: %x\n", __FUNCTION__, hpc_ptr->ctlr_type);
-		switch (hpc_ptr->ctlr_type) {
-		case 1:
-			debug ("%s - bus: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.bus);
-			debug ("%s - dev_fun: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.dev_fun);
-			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
-			break;
-
-		case 0:
-			debug ("%s - io_start: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_start);
-			debug ("%s - io_end: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_end);
-			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
-			break;
-
-		case 2:
-		case 4:
-			debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
-			debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
-			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
-			break;
-		}
-	}
-}
-
-int __init ibmphp_access_ebda (void)
-{
-	u8 format, num_ctlrs, rio_complete, hs_complete;
-	u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, rc, re, rc_id, re_id, base;
-
-
-	rio_complete = 0;
-	hs_complete = 0;
-
-	io_mem = ioremap ((0x40 << 4) + 0x0e, 2);
-	if (!io_mem )
-		return -ENOMEM;
-	ebda_seg = readw (io_mem);
-	iounmap (io_mem);
-	debug ("returned ebda segment: %x\n", ebda_seg);
-	
-	io_mem = ioremap (ebda_seg<<4, 65000);
-	if (!io_mem )
-		return -ENOMEM;
-	next_offset = 0x180;
-
-	for (;;) {
-		offset = next_offset;
-		next_offset = readw (io_mem + offset);	/* offset of next blk */
-
-		offset += 2;
-		if (next_offset == 0)	/* 0 indicate it's last blk */
-			break;
-		blk_id = readw (io_mem + offset);	/* this blk id */
-
-		offset += 2;
-		/* check if it is hot swap block or rio block */
-		if (blk_id != 0x4853 && blk_id != 0x4752)
-			continue;
-		/* found hs table */
-		if (blk_id == 0x4853) {
-			debug ("now enter hot swap block---\n");
-			debug ("hot blk id: %x\n", blk_id);
-			format = readb (io_mem + offset);
-
-			offset += 1;
-			if (format != 4) {
-				iounmap (io_mem);
-				return -ENODEV;
-			}
-			debug ("hot blk format: %x\n", format);
-			/* hot swap sub blk */
-			base = offset;
-
-			sub_addr = base;
-			re = readw (io_mem + sub_addr);	/* next sub blk */
-
-			sub_addr += 2;
-			rc_id = readw (io_mem + sub_addr); 	/* sub blk id */
-
-			sub_addr += 2;
-			if (rc_id != 0x5243) {
-				iounmap (io_mem);
-				return -ENODEV;
-			}
-			/* rc sub blk signature  */
-			num_ctlrs = readb (io_mem + sub_addr);
-
-			sub_addr += 1;
-			hpc_list_ptr = alloc_ebda_hpc_list ();
-			if (!hpc_list_ptr) {
-				iounmap (io_mem);
-				return -ENOMEM;
-			}
-			hpc_list_ptr->format = format;
-			hpc_list_ptr->num_ctlrs = num_ctlrs;
-			hpc_list_ptr->phys_addr = sub_addr;	/*  offset of RSRC_CONTROLLER blk */
-			debug ("info about hpc descriptor---\n");
-			debug ("hot blk format: %x\n", format);
-			debug ("num of controller: %x\n", num_ctlrs);
-			debug ("offset of hpc data structure enteries: %x\n ", sub_addr);
-
-			sub_addr = base + re;	/* re sub blk */
-			rc = readw (io_mem + sub_addr);	/* next sub blk */
-
-			sub_addr += 2;
-			re_id = readw (io_mem + sub_addr);	/* sub blk id */
-
-			sub_addr += 2;
-			if (re_id != 0x5245) {
-				iounmap (io_mem);
-				return -ENODEV;
-			}
-
-			/* signature of re */
-			num_entries = readw (io_mem + sub_addr);
-
-			sub_addr += 2;	/* offset of RSRC_ENTRIES blk */
-			rsrc_list_ptr = alloc_ebda_rsrc_list ();
-			if (!rsrc_list_ptr ) {
-				iounmap (io_mem);
-				return -ENOMEM;
-			}
-			rsrc_list_ptr->format = format;
-			rsrc_list_ptr->num_entries = num_entries;
-			rsrc_list_ptr->phys_addr = sub_addr;
-
-			debug ("info about rsrc descriptor---\n");
-			debug ("format: %x\n", format);
-			debug ("num of rsrc: %x\n", num_entries);
-			debug ("offset of rsrc data structure enteries: %x\n ", sub_addr);
-
-			hs_complete = 1;
-		}
-		/* found rio table */
-		else if (blk_id == 0x4752) {
-			debug ("now enter io table ---\n");
-			debug ("rio blk id: %x\n", blk_id);
-
-			rio_table_ptr = kmalloc (sizeof (struct rio_table_hdr), GFP_KERNEL);
-			if (!rio_table_ptr)
-				return -ENOMEM; 
-			memset (rio_table_ptr, 0, sizeof (struct rio_table_hdr) );
-			rio_table_ptr->ver_num = readb (io_mem + offset);
-			rio_table_ptr->scal_count = readb (io_mem + offset + 1);
-			rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
-			rio_table_ptr->offset = offset +3 ;
-			
-			debug ("info about rio table hdr ---\n");
-			debug ("ver_num: %x\nscal_count: %x\nriodev_count: %x\noffset of rio table: %x\n ", rio_table_ptr->ver_num, rio_table_ptr->scal_count, rio_table_ptr->riodev_count, rio_table_ptr->offset);
-
-			rio_complete = 1;
-		}
-	}
-
-	if (!hs_complete && !rio_complete) {
-		iounmap (io_mem);
-		return -ENODEV;
-	}
-
-	if (rio_table_ptr) {
-		if (rio_complete == 1 && rio_table_ptr->ver_num == 3) {
-			rc = ebda_rio_table ();
-			if (rc) {
-				iounmap (io_mem);
-				return rc;
-			}
-		}
-	}
-	rc = ebda_rsrc_controller ();
-	if (rc) {
-		iounmap (io_mem);
-		return rc;
-	}
-
-	rc = ebda_rsrc_rsrc ();
-	if (rc) {
-		iounmap (io_mem);
-		return rc;
-	}
-
-	iounmap (io_mem);
-	return 0;
-}
-
-/*
- * map info of scalability details and rio details from physical address
- */
-static int __init ebda_rio_table (void)
-{
-	u16 offset;
-	u8 i;
-	struct rio_detail *rio_detail_ptr;
-
-	offset = rio_table_ptr->offset;
-	offset += 12 * rio_table_ptr->scal_count;
-
-	// we do concern about rio details
-	for (i = 0; i < rio_table_ptr->riodev_count; i++) {
-		rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
-		if (!rio_detail_ptr)
-			return -ENOMEM;
-		memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
-		rio_detail_ptr->rio_node_id = readb (io_mem + offset);
-		rio_detail_ptr->bbar = readl (io_mem + offset + 1);
-		rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
-		rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
-		rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
-		rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
-		rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
-		rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
-		rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
-		rio_detail_ptr->status = readb (io_mem + offset + 12);
-		rio_detail_ptr->wpindex = readb (io_mem + offset + 13);
-		rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);
-//		debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
-		//create linked list of chassis
-		if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5) 
-			list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head);
-		//create linked list of expansion box				
-		else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7) 
-			list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head);
-		else 
-			// not in my concern
-			kfree (rio_detail_ptr);
-		offset += 15;
-	}
-	print_lo_info ();
-	print_vg_info ();
-	return 0;
-}
-
-/*
- * reorganizing linked list of chassis	 
- */
-static struct opt_rio *search_opt_vg (u8 chassis_num)
-{
-	struct opt_rio *ptr;
-	struct list_head *ptr1;
-	list_for_each (ptr1, &opt_vg_head) {
-		ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
-		if (ptr->chassis_num == chassis_num)
-			return ptr;
-	}		
-	return NULL;
-}
-
-static int __init combine_wpg_for_chassis (void)
-{
-	struct opt_rio *opt_rio_ptr = NULL;
-	struct rio_detail *rio_detail_ptr = NULL;
-	struct list_head *list_head_ptr = NULL;
-	
-	list_for_each (list_head_ptr, &rio_vg_head) {
-		rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
-		opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
-		if (!opt_rio_ptr) {
-			opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
-			if (!opt_rio_ptr)
-				return -ENOMEM;
-			memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
-			opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
-			opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
-			opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
-			opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
-			list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head);
-		} else {	
-			opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
-			opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
-		}	
-	}
-	print_opt_vg ();
-	return 0;	
-}	
-
-/*
- * reorgnizing linked list of expansion box	 
- */
-static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
-{
-	struct opt_rio_lo *ptr;
-	struct list_head *ptr1;
-	list_for_each (ptr1, &opt_lo_head) {
-		ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
-		if (ptr->chassis_num == chassis_num)
-			return ptr;
-	}		
-	return NULL;
-}
-
-static int combine_wpg_for_expansion (void)
-{
-	struct opt_rio_lo *opt_rio_lo_ptr = NULL;
-	struct rio_detail *rio_detail_ptr = NULL;
-	struct list_head *list_head_ptr = NULL;
-	
-	list_for_each (list_head_ptr, &rio_lo_head) {
-		rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
-		opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
-		if (!opt_rio_lo_ptr) {
-			opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
-			if (!opt_rio_lo_ptr)
-				return -ENOMEM;
-			memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
-			opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
-			opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
-			opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
-			opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
-			opt_rio_lo_ptr->pack_count = 1;
-			
-			list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
-		} else {	
-			opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
-			opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
-			opt_rio_lo_ptr->pack_count = 2;
-		}	
-	}
-	return 0;	
-}
-	
-
-/* Since we don't know the max slot number per each chassis, hence go
- * through the list of all chassis to find out the range
- * Arguments: slot_num, 1st slot number of the chassis we think we are on, 
- * var (0 = chassis, 1 = expansion box) 
- */
-static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
-{
-	struct opt_rio *opt_vg_ptr = NULL;
-	struct opt_rio_lo *opt_lo_ptr = NULL;
-	struct list_head *ptr = NULL;
-	int rc = 0;
-
-	if (!var) {
-		list_for_each (ptr, &opt_vg_head) {
-			opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
-			if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) { 
-				rc = -ENODEV;
-				break;
-			}
-		}
-	} else {
-		list_for_each (ptr, &opt_lo_head) {
-			opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
-			if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
-				rc = -ENODEV;
-				break;
-			}
-		}
-	}
-	return rc;
-}
-
-static struct opt_rio_lo * find_rxe_num (u8 slot_num)
-{
-	struct opt_rio_lo *opt_lo_ptr;
-	struct list_head *ptr;
-
-	list_for_each (ptr, &opt_lo_head) {
-		opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
-		//check to see if this slot_num belongs to expansion box
-		if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1))) 
-			return opt_lo_ptr;
-	}
-	return NULL;
-}
-
-static struct opt_rio * find_chassis_num (u8 slot_num)
-{
-	struct opt_rio *opt_vg_ptr;
-	struct list_head *ptr;
-
-	list_for_each (ptr, &opt_vg_head) {
-		opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
-		//check to see if this slot_num belongs to chassis 
-		if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0))) 
-			return opt_vg_ptr;
-	}
-	return NULL;
-}
-
-/* This routine will find out how many slots are in the chassis, so that
- * the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
- */
-static u8 calculate_first_slot (u8 slot_num)
-{
-	u8 first_slot = 1;
-	struct list_head * list;
-	struct slot * slot_cur;
-	
-	list_for_each (list, &ibmphp_slot_head) {
-		slot_cur = list_entry (list, struct slot, ibm_slot_list);
-		if (slot_cur->ctrl) {
-			if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num)) 
-				first_slot = slot_cur->ctrl->ending_slot_num;
-		}
-	}			
-	return first_slot + 1;
-
-}
-static char *create_file_name (struct slot * slot_cur)
-{
-	struct opt_rio *opt_vg_ptr = NULL;
-	struct opt_rio_lo *opt_lo_ptr = NULL;
-	static char str[30];
-	int which = 0; /* rxe = 1, chassis = 0 */
-	u8 number = 1; /* either chassis or rxe # */
-	u8 first_slot = 1;
-	u8 slot_num;
-	u8 flag = 0;
-
-	if (!slot_cur) {
-		err ("Structure passed is empty \n");
-		return NULL;
-	}
-	
-	slot_num = slot_cur->number;
-
-	memset (str, 0, sizeof(str));
-	
-	if (rio_table_ptr) {
-		if (rio_table_ptr->ver_num == 3) {
-			opt_vg_ptr = find_chassis_num (slot_num);
-			opt_lo_ptr = find_rxe_num (slot_num);
-		}
-	}
-	if (opt_vg_ptr) {
-		if (opt_lo_ptr) {
-			if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) {
-				number = opt_lo_ptr->chassis_num;
-				first_slot = opt_lo_ptr->first_slot_num;
-				which = 1; /* it is RXE */
-			} else {
-				first_slot = opt_vg_ptr->first_slot_num;
-				number = opt_vg_ptr->chassis_num;
-				which = 0;
-			}
-		} else {
-			first_slot = opt_vg_ptr->first_slot_num;
-			number = opt_vg_ptr->chassis_num;
-			which = 0;
-		}
-		++flag;
-	} else if (opt_lo_ptr) {
-		number = opt_lo_ptr->chassis_num;
-		first_slot = opt_lo_ptr->first_slot_num;
-		which = 1;
-		++flag;
-	} else if (rio_table_ptr) {
-		if (rio_table_ptr->ver_num == 3) {
-			/* if both NULL and we DO have correct RIO table in BIOS */
-			return NULL;
-		}
-	} 
-	if (!flag) {
-		if (slot_cur->ctrl->ctlr_type == 4) {
-			first_slot = calculate_first_slot (slot_num);
-			which = 1;
-		} else {
-			which = 0;
-		}
-	}
-
-	sprintf(str, "%s%dslot%d",
-		which == 0 ? "chassis" : "rxe",
-		number, slot_num - first_slot + 1);
-	return str;
-}
-
-static struct pci_driver ibmphp_driver;
-
-/*
- * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
- * each hpc from physical address to a list of hot plug controllers based on
- * hpc descriptors.
- */
-static int __init ebda_rsrc_controller (void)
-{
-	u16 addr, addr_slot, addr_bus;
-	u8 ctlr_id, temp, bus_index;
-	u16 ctlr, slot, bus;
-	u16 slot_num, bus_num, index;
-	struct hotplug_slot *hp_slot_ptr;
-	struct controller *hpc_ptr;
-	struct ebda_hpc_bus *bus_ptr;
-	struct ebda_hpc_slot *slot_ptr;
-	struct bus_info *bus_info_ptr1, *bus_info_ptr2;
-	int rc;
-	struct slot *tmp_slot;
-	struct list_head *list;
-
-	addr = hpc_list_ptr->phys_addr;
-	for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
-		bus_index = 1;
-		ctlr_id = readb (io_mem + addr);
-		addr += 1;
-		slot_num = readb (io_mem + addr);
-
-		addr += 1;
-		addr_slot = addr;	/* offset of slot structure */
-		addr += (slot_num * 4);
-
-		bus_num = readb (io_mem + addr);
-
-		addr += 1;
-		addr_bus = addr;	/* offset of bus */
-		addr += (bus_num * 9);	/* offset of ctlr_type */
-		temp = readb (io_mem + addr);
-
-		addr += 1;
-		/* init hpc structure */
-		hpc_ptr = alloc_ebda_hpc (slot_num, bus_num);
-		if (!hpc_ptr ) {
-			rc = -ENOMEM;
-			goto error_no_hpc;
-		}
-		hpc_ptr->ctlr_id = ctlr_id;
-		hpc_ptr->ctlr_relative_id = ctlr;
-		hpc_ptr->slot_count = slot_num;
-		hpc_ptr->bus_count = bus_num;
-		debug ("now enter ctlr data struture ---\n");
-		debug ("ctlr id: %x\n", ctlr_id);
-		debug ("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
-		debug ("count of slots controlled by this ctlr: %x\n", slot_num);
-		debug ("count of buses controlled by this ctlr: %x\n", bus_num);
-
-		/* init slot structure, fetch slot, bus, cap... */
-		slot_ptr = hpc_ptr->slots;
-		for (slot = 0; slot < slot_num; slot++) {
-			slot_ptr->slot_num = readb (io_mem + addr_slot);
-			slot_ptr->slot_bus_num = readb (io_mem + addr_slot + slot_num);
-			slot_ptr->ctl_index = readb (io_mem + addr_slot + 2*slot_num);
-			slot_ptr->slot_cap = readb (io_mem + addr_slot + 3*slot_num);
-
-			// create bus_info lined list --- if only one slot per bus: slot_min = slot_max 
-
-			bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);
-			if (!bus_info_ptr2) {
-				bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL);
-				if (!bus_info_ptr1) {
-					rc = -ENOMEM;
-					goto error_no_hp_slot;
-				}
-				memset (bus_info_ptr1, 0, sizeof (struct bus_info));
-				bus_info_ptr1->slot_min = slot_ptr->slot_num;
-				bus_info_ptr1->slot_max = slot_ptr->slot_num;
-				bus_info_ptr1->slot_count += 1;
-				bus_info_ptr1->busno = slot_ptr->slot_bus_num;
-				bus_info_ptr1->index = bus_index++;
-				bus_info_ptr1->current_speed = 0xff;
-				bus_info_ptr1->current_bus_mode = 0xff;
-				
-				bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;
-				
-				list_add_tail (&bus_info_ptr1->bus_info_list, &bus_info_head);
-
-			} else {
-				bus_info_ptr2->slot_min = min (bus_info_ptr2->slot_min, slot_ptr->slot_num);
-				bus_info_ptr2->slot_max = max (bus_info_ptr2->slot_max, slot_ptr->slot_num);
-				bus_info_ptr2->slot_count += 1;
-
-			}
-
-			// end of creating the bus_info linked list
-
-			slot_ptr++;
-			addr_slot += 1;
-		}
-
-		/* init bus structure */
-		bus_ptr = hpc_ptr->buses;
-		for (bus = 0; bus < bus_num; bus++) {
-			bus_ptr->bus_num = readb (io_mem + addr_bus + bus);
-			bus_ptr->slots_at_33_conv = readb (io_mem + addr_bus + bus_num + 8 * bus);
-			bus_ptr->slots_at_66_conv = readb (io_mem + addr_bus + bus_num + 8 * bus + 1);
-
-			bus_ptr->slots_at_66_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 2);
-
-			bus_ptr->slots_at_100_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 3);
-
-			bus_ptr->slots_at_133_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 4);
-
-			bus_info_ptr2 = ibmphp_find_same_bus_num (bus_ptr->bus_num);
-			if (bus_info_ptr2) {
-				bus_info_ptr2->slots_at_33_conv = bus_ptr->slots_at_33_conv;
-				bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv;
-				bus_info_ptr2->slots_at_66_pcix = bus_ptr->slots_at_66_pcix;
-				bus_info_ptr2->slots_at_100_pcix = bus_ptr->slots_at_100_pcix;
-				bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix; 
-			}
-			bus_ptr++;
-		}
-
-		hpc_ptr->ctlr_type = temp;
-
-		switch (hpc_ptr->ctlr_type) {
-			case 1:
-				hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
-				hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
-				hpc_ptr->irq = readb (io_mem + addr + 2);
-				addr += 3;
-				debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", 
-					hpc_ptr->u.pci_ctlr.bus,
-					hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
-				break;
-
-			case 0:
-				hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
-				hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
-				if (!request_region (hpc_ptr->u.isa_ctlr.io_start,
-						     (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
-						     "ibmphp")) {
-					rc = -ENODEV;
-					goto error_no_hp_slot;
-				}
-				hpc_ptr->irq = readb (io_mem + addr + 4);
-				addr += 5;
-				break;
-
-			case 2:
-			case 4:
-				hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
-				hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
-				hpc_ptr->irq = readb (io_mem + addr + 5);
-				addr += 6;
-				break;
-			default:
-				rc = -ENODEV;
-				goto error_no_hp_slot;
-		}
-
-		//reorganize chassis' linked list
-		combine_wpg_for_chassis ();
-		combine_wpg_for_expansion ();
-		hpc_ptr->revision = 0xff;
-		hpc_ptr->options = 0xff;
-		hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
-		hpc_ptr->ending_slot_num = hpc_ptr->slots[slot_num-1].slot_num;
-
-		// register slots with hpc core as well as create linked list of ibm slot
-		for (index = 0; index < hpc_ptr->slot_count; index++) {
-
-			hp_slot_ptr = (struct hotplug_slot *) kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
-			if (!hp_slot_ptr) {
-				rc = -ENOMEM;
-				goto error_no_hp_slot;
-			}
-			memset (hp_slot_ptr, 0, sizeof (struct hotplug_slot));
-
-			hp_slot_ptr->info = (struct hotplug_slot_info *) kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
-			if (!hp_slot_ptr->info) {
-				rc = -ENOMEM;
-				goto error_no_hp_info;
-			}
-			memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info));
-
-			hp_slot_ptr->name = (char *) kmalloc (30, GFP_KERNEL);
-			if (!hp_slot_ptr->name) {
-				rc = -ENOMEM;
-				goto error_no_hp_name;
-			}
-
-			tmp_slot = kmalloc (sizeof (struct slot), GFP_KERNEL);
-			if (!tmp_slot) {
-				rc = -ENOMEM;
-				goto error_no_slot;
-			}
-			memset (tmp_slot, 0, sizeof (*tmp_slot));
-
-			tmp_slot->flag = TRUE;
-
-			tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
-			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
-				tmp_slot->supported_speed =  3;
-			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX)
-				tmp_slot->supported_speed =  2;
-			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX)
-				tmp_slot->supported_speed =  1;
-				
-			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP)
-				tmp_slot->supported_bus_mode = 1;
-			else
-				tmp_slot->supported_bus_mode = 0;
-
-
-			tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num;
-
-			bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num);
-			if (!bus_info_ptr1) {
-				rc = -ENODEV;
-				goto error;
-			}
-			tmp_slot->bus_on = bus_info_ptr1;
-			bus_info_ptr1 = NULL;
-			tmp_slot->ctrl = hpc_ptr;
-
-			tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index;
-			tmp_slot->number = hpc_ptr->slots[index].slot_num;
-			tmp_slot->hotplug_slot = hp_slot_ptr;
-
-			hp_slot_ptr->private = tmp_slot;
-
-			rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr);
-			if (rc)
-				goto error;
-
-			rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private);
-			if (rc)
-				goto error;
-			hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
-
-			// end of registering ibm slot with hotplug core
-
-			list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
-		}
-
-		print_bus_info ();
-		list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
-
-	}			/* each hpc  */
-
-	list_for_each (list, &ibmphp_slot_head) {
-		tmp_slot = list_entry (list, struct slot, ibm_slot_list);
-
-		snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
-		pci_hp_register (tmp_slot->hotplug_slot);
-	}
-
-	print_ebda_hpc ();
-	print_ibm_slot ();
-	return 0;
-
-error:
-	kfree (hp_slot_ptr->private);
-error_no_slot:
-	kfree (hp_slot_ptr->name);
-error_no_hp_name:
-	kfree (hp_slot_ptr->info);
-error_no_hp_info:
-	kfree (hp_slot_ptr);
-error_no_hp_slot:
-	free_ebda_hpc (hpc_ptr);
-error_no_hpc:
-	iounmap (io_mem);
-	return rc;
-}
-
-/* 
- * map info (bus, devfun, start addr, end addr..) of i/o, memory,
- * pfm from the physical addr to a list of resource.
- */
-static int __init ebda_rsrc_rsrc (void)
-{
-	u16 addr;
-	short rsrc;
-	u8 type, rsrc_type;
-	struct ebda_pci_rsrc *rsrc_ptr;
-
-	addr = rsrc_list_ptr->phys_addr;
-	debug ("now entering rsrc land\n");
-	debug ("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr);
-
-	for (rsrc = 0; rsrc < rsrc_list_ptr->num_entries; rsrc++) {
-		type = readb (io_mem + addr);
-
-		addr += 1;
-		rsrc_type = type & EBDA_RSRC_TYPE_MASK;
-
-		if (rsrc_type == EBDA_IO_RSRC_TYPE) {
-			rsrc_ptr = alloc_ebda_pci_rsrc ();
-			if (!rsrc_ptr) {
-				iounmap (io_mem);
-				return -ENOMEM;
-			}
-			rsrc_ptr->rsrc_type = type;
-
-			rsrc_ptr->bus_num = readb (io_mem + addr);
-			rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
-			rsrc_ptr->start_addr = readw (io_mem + addr + 2);
-			rsrc_ptr->end_addr = readw (io_mem + addr + 4);
-			addr += 6;
-
-			debug ("rsrc from io type ----\n");
-			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
-				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
-
-			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
-		}
-
-		if (rsrc_type == EBDA_MEM_RSRC_TYPE || rsrc_type == EBDA_PFM_RSRC_TYPE) {
-			rsrc_ptr = alloc_ebda_pci_rsrc ();
-			if (!rsrc_ptr ) {
-				iounmap (io_mem);
-				return -ENOMEM;
-			}
-			rsrc_ptr->rsrc_type = type;
-
-			rsrc_ptr->bus_num = readb (io_mem + addr);
-			rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
-			rsrc_ptr->start_addr = readl (io_mem + addr + 2);
-			rsrc_ptr->end_addr = readl (io_mem + addr + 6);
-			addr += 10;
-
-			debug ("rsrc from mem or pfm ---\n");
-			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", 
-				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
-
-			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
-		}
-	}
-	kfree (rsrc_list_ptr);
-	rsrc_list_ptr = NULL;
-	print_ebda_pci_rsrc ();
-	return 0;
-}
-
-u16 ibmphp_get_total_controllers (void)
-{
-	return hpc_list_ptr->num_ctlrs;
-}
-
-struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
-{
-	struct slot *slot;
-	struct list_head *list;
-
-	list_for_each (list, &ibmphp_slot_head) {
-		slot = list_entry (list, struct slot, ibm_slot_list);
-		if (slot->number == physical_num)
-			return slot;
-	}
-	return NULL;
-}
-
-/* To find:
- *	- the smallest slot number
- *	- the largest slot number
- *	- the total number of the slots based on each bus
- *	  (if only one slot per bus slot_min = slot_max )
- */
-struct bus_info *ibmphp_find_same_bus_num (u32 num)
-{
-	struct bus_info *ptr;
-	struct list_head  *ptr1;
-
-	list_for_each (ptr1, &bus_info_head) {
-		ptr = list_entry (ptr1, struct bus_info, bus_info_list); 
-		if (ptr->busno == num) 
-			 return ptr;
-	}
-	return NULL;
-}
-
-/*  Finding relative bus number, in order to map corresponding
- *  bus register
- */
-int ibmphp_get_bus_index (u8 num)
-{
-	struct bus_info *ptr;
-	struct list_head  *ptr1;
-
-	list_for_each (ptr1, &bus_info_head) {
-		ptr = list_entry (ptr1, struct bus_info, bus_info_list);
-		if (ptr->busno == num)  
-			return ptr->index;
-	}
-	return -ENODEV;
-}
-
-void ibmphp_free_bus_info_queue (void)
-{
-	struct bus_info *bus_info;
-	struct list_head *list;
-	struct list_head *next;
-
-	list_for_each_safe (list, next, &bus_info_head ) {
-		bus_info = list_entry (list, struct bus_info, bus_info_list);
-		kfree (bus_info);
-	}
-}
-
-void ibmphp_free_ebda_hpc_queue (void)
-{
-	struct controller *controller = NULL;
-	struct list_head *list;
-	struct list_head *next;
-	int pci_flag = 0;
-
-	list_for_each_safe (list, next, &ebda_hpc_head) {
-		controller = list_entry (list, struct controller, ebda_hpc_list);
-		if (controller->ctlr_type == 0)
-			release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
-		else if ((controller->ctlr_type == 1) && (!pci_flag)) {
-			++pci_flag;
-			pci_unregister_driver (&ibmphp_driver);
-		}
-		free_ebda_hpc (controller);
-	}
-}
-
-void ibmphp_free_ebda_pci_rsrc_queue (void)
-{
-	struct ebda_pci_rsrc *resource;
-	struct list_head *list;
-	struct list_head *next;
-
-	list_for_each_safe (list, next, &ibmphp_ebda_pci_rsrc_head) {
-		resource = list_entry (list, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
-		kfree (resource);
-		resource = NULL;
-	}
-}
-
-static struct pci_device_id id_table[] __devinitdata = {
-	{
-		.vendor		= PCI_VENDOR_ID_IBM,
-		.device		= HPC_DEVICE_ID,
-		.subvendor	= PCI_VENDOR_ID_IBM,
-		.subdevice	= HPC_SUBSYSTEM_ID,
-		.class		= ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
-	}, {}
-};		
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
-static struct pci_driver ibmphp_driver = {
-	.name		= "ibmphp",
-	.id_table	= id_table,
-	.probe		= ibmphp_probe,
-};
-
-int ibmphp_register_pci (void)
-{
-	struct controller *ctrl;
-	struct list_head *tmp;
-	int rc = 0;
-
-	list_for_each (tmp, &ebda_hpc_head) {
-		ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
-		if (ctrl->ctlr_type == 1) {
-			rc = pci_module_init (&ibmphp_driver);
-			break;
-		}
-	}
-	return rc;
-}
-static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
-{
-	struct controller *ctrl;
-	struct list_head *tmp;
-
-	debug ("inside ibmphp_probe \n");
-	
-	list_for_each (tmp, &ebda_hpc_head) {
-		ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
-		if (ctrl->ctlr_type == 1) {
-			if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
-				ctrl->ctrl_dev = dev;
-				debug ("found device!!! \n");
-				debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
-				return 0;
-			}
-		}
-	}
-	return -ENODEV;
-}
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/ibmphp_hpc.c linux-2.5.70-bk10/drivers/hotplug/ibmphp_hpc.c
--- linux-2.5.70-bk9/drivers/hotplug/ibmphp_hpc.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/ibmphp_hpc.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1228 +0,0 @@
-/*
- * IBM Hot Plug Controller Driver
- *
- * Written By: Jyoti Shah, IBM Corporation
- *
- * Copyright (c) 2001-2002 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>
- *                  <jshah@us.ibm.com>
- *
- */
-
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include "ibmphp.h"
-
-static int to_debug = FALSE;
-#define debug_polling(fmt, arg...)	do { if (to_debug) debug (fmt, arg); } while (0)
-
-//----------------------------------------------------------------------------
-// timeout values
-//----------------------------------------------------------------------------
-#define CMD_COMPLETE_TOUT_SEC	60	// give HPC 60 sec to finish cmd
-#define HPC_CTLR_WORKING_TOUT	60	// give HPC 60 sec to finish cmd
-#define HPC_GETACCESS_TIMEOUT	60	// seconds
-#define POLL_INTERVAL_SEC	2	// poll HPC every 2 seconds
-#define POLL_LATCH_CNT		5	// poll latch 5 times, then poll slots
-
-//----------------------------------------------------------------------------
-// Winnipeg Architected Register Offsets
-//----------------------------------------------------------------------------
-#define WPG_I2CMBUFL_OFFSET	0x08	// I2C Message Buffer Low
-#define WPG_I2CMOSUP_OFFSET	0x10	// I2C Master Operation Setup Reg
-#define WPG_I2CMCNTL_OFFSET	0x20	// I2C Master Control Register
-#define WPG_I2CPARM_OFFSET	0x40	// I2C Parameter Register
-#define WPG_I2CSTAT_OFFSET	0x70	// I2C Status Register
-
-//----------------------------------------------------------------------------
-// Winnipeg Store Type commands (Add this commands to the register offset)
-//----------------------------------------------------------------------------
-#define WPG_I2C_AND		0x1000	// I2C AND operation
-#define WPG_I2C_OR		0x2000	// I2C OR operation
-
-//----------------------------------------------------------------------------
-// Command set for I2C Master Operation Setup Regisetr
-//----------------------------------------------------------------------------
-#define WPG_READATADDR_MASK	0x00010000	// read,bytes,I2C shifted,index
-#define WPG_WRITEATADDR_MASK	0x40010000	// write,bytes,I2C shifted,index
-#define WPG_READDIRECT_MASK	0x10010000
-#define WPG_WRITEDIRECT_MASK	0x60010000
-
-
-//----------------------------------------------------------------------------
-// bit masks for I2C Master Control Register
-//----------------------------------------------------------------------------
-#define WPG_I2CMCNTL_STARTOP_MASK	0x00000002	// Start the Operation
-
-//----------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------
-#define WPG_I2C_IOREMAP_SIZE	0x2044	// size of linear address interval
-
-//----------------------------------------------------------------------------
-// command index
-//----------------------------------------------------------------------------
-#define WPG_1ST_SLOT_INDEX	0x01	// index - 1st slot for ctlr
-#define WPG_CTLR_INDEX		0x0F	// index - ctlr
-#define WPG_1ST_EXTSLOT_INDEX	0x10	// index - 1st ext slot for ctlr
-#define WPG_1ST_BUS_INDEX	0x1F	// index - 1st bus for ctlr
-
-//----------------------------------------------------------------------------
-// macro utilities
-//----------------------------------------------------------------------------
-// if bits 20,22,25,26,27,29,30 are OFF return TRUE
-#define HPC_I2CSTATUS_CHECK(s)	((u8)((s & 0x00000A76) ? FALSE : TRUE))
-
-//----------------------------------------------------------------------------
-// global variables
-//----------------------------------------------------------------------------
-static int ibmphp_shutdown;
-static int tid_poll;
-static struct semaphore sem_hpcaccess;	// lock access to HPC
-static struct semaphore semOperations;	// lock all operations and
-					// access to data structures
-static struct semaphore sem_exit;	// make sure polling thread goes away
-//----------------------------------------------------------------------------
-// local function prototypes
-//----------------------------------------------------------------------------
-static u8 i2c_ctrl_read (struct controller *, void *, u8);
-static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
-static u8 hpc_writecmdtoindex (u8, u8);
-static u8 hpc_readcmdtoindex (u8, u8);
-static void get_hpc_access (void);
-static void free_hpc_access (void);
-static void poll_hpc (void);
-static int update_slot (struct slot *, u8);
-static int process_changeinstatus (struct slot *, struct slot *);
-static int process_changeinlatch (u8, u8, struct controller *);
-static int hpc_poll_thread (void *);
-static int hpc_wait_ctlr_notworking (int, struct controller *, void *, u8 *);
-//----------------------------------------------------------------------------
-
-
-/*----------------------------------------------------------------------
-* Name:    ibmphp_hpc_initvars
-*
-* Action:  initialize semaphores and variables
-*---------------------------------------------------------------------*/
-void __init ibmphp_hpc_initvars (void)
-{
-	debug ("%s - Entry\n", __FUNCTION__);
-
-	init_MUTEX (&sem_hpcaccess);
-	init_MUTEX (&semOperations);
-	init_MUTEX_LOCKED (&sem_exit);
-	to_debug = FALSE;
-	ibmphp_shutdown = FALSE;
-	tid_poll = 0;
-
-	debug ("%s - Exit\n", __FUNCTION__);
-}
-
-/*----------------------------------------------------------------------
-* Name:    i2c_ctrl_read
-*
-* Action:  read from HPC over I2C
-*
-*---------------------------------------------------------------------*/
-static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
-{
-	u8 status;
-	int i;
-	void *wpg_addr;		// base addr + offset
-	ulong wpg_data,		// data to/from WPG LOHI format
-	ultemp, data;		// actual data HILO format
-
-
-	debug_polling ("%s - Entry WPGBbar[%lx] index[%x] \n", __FUNCTION__, (ulong) WPGBbar, index);
-
-	//--------------------------------------------------------------------
-	// READ - step 1
-	// read at address, byte length, I2C address (shifted), index
-	// or read direct, byte length, index
-	if (ctlr_ptr->ctlr_type == 0x02) {
-		data = WPG_READATADDR_MASK;
-		// fill in I2C address
-		ultemp = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr;
-		ultemp = ultemp >> 1;
-		data |= (ultemp << 8);
-
-		// fill in index
-		data |= (ulong) index;
-	} else if (ctlr_ptr->ctlr_type == 0x04) {
-		data = WPG_READDIRECT_MASK;
-
-		// fill in index
-		ultemp = (ulong) index;
-		ultemp = ultemp << 8;
-		data |= ultemp;
-	} else {
-		err ("this controller type is not supported \n");
-		return HPC_ERROR;
-	}
-
-	wpg_data = swab32 (data);	// swap data before writing
-	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET;
-	writel (wpg_data, wpg_addr);
-
-	//--------------------------------------------------------------------
-	// READ - step 2 : clear the message buffer
-	data = 0x00000000;
-	wpg_data = swab32 (data);
-	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
-	writel (wpg_data, wpg_addr);
-
-	//--------------------------------------------------------------------
-	// READ - step 3 : issue start operation, I2C master control bit 30:ON
-	//                 2020 : [20] OR operation at [20] offset 0x20
-	data = WPG_I2CMCNTL_STARTOP_MASK;
-	wpg_data = swab32 (data);
-	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) WPG_I2C_OR;
-	writel (wpg_data, wpg_addr);
-
-	//--------------------------------------------------------------------
-	// READ - step 4 : wait until start operation bit clears
-	i = CMD_COMPLETE_TOUT_SEC;
-	while (i) {
-		long_delay (1 * HZ / 100);
-		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET;
-		wpg_data = readl (wpg_addr);
-		data = swab32 (wpg_data);
-		if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
-			break;
-		i--;
-	}
-	if (i == 0) {
-		debug ("%s - Error : WPG timeout\n", __FUNCTION__);
-		return HPC_ERROR;
-	}
-	//--------------------------------------------------------------------
-	// READ - step 5 : read I2C status register
-	i = CMD_COMPLETE_TOUT_SEC;
-	while (i) {
-		long_delay (1 * HZ / 100);
-		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CSTAT_OFFSET;
-		wpg_data = readl (wpg_addr);
-		data = swab32 (wpg_data);
-		if (HPC_I2CSTATUS_CHECK (data))
-			break;
-		i--;
-	}
-	if (i == 0) {
-		debug ("ctrl_read - Exit Error:I2C timeout\n");
-		return HPC_ERROR;
-	}
-
-	//--------------------------------------------------------------------
-	// READ - step 6 : get DATA
-	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
-	wpg_data = readl (wpg_addr);
-	data = swab32 (wpg_data);
-
-	status = (u8) data;
-
-	debug_polling ("%s - Exit index[%x] status[%x]\n", __FUNCTION__, index, status);
-
-	return (status);
-}
-
-/*----------------------------------------------------------------------
-* Name:    i2c_ctrl_write
-*
-* Action:  write to HPC over I2C
-*
-* Return   0 or error codes
-*---------------------------------------------------------------------*/
-static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
-{
-	u8 rc;
-	void *wpg_addr;		// base addr + offset
-	ulong wpg_data,		// data to/from WPG LOHI format 
-	ultemp, data;		// actual data HILO format
-	int i;
-
-
-	debug_polling ("%s - Entry WPGBbar[%lx] index[%x] cmd[%x]\n", __FUNCTION__, (ulong) WPGBbar, index, cmd);
-
-	rc = 0;
-	//--------------------------------------------------------------------
-	// WRITE - step 1
-	// write at address, byte length, I2C address (shifted), index
-	// or write direct, byte length, index
-	data = 0x00000000;
-
-	if (ctlr_ptr->ctlr_type == 0x02) {
-		data = WPG_WRITEATADDR_MASK;
-		// fill in I2C address
-		ultemp = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr;
-		ultemp = ultemp >> 1;
-		data |= (ultemp << 8);
-
-		// fill in index
-		data |= (ulong) index;
-	} else if (ctlr_ptr->ctlr_type == 0x04) {
-		data = WPG_WRITEDIRECT_MASK;
-
-		// fill in index
-		ultemp = (ulong) index;
-		ultemp = ultemp << 8;
-		data |= ultemp;
-	} else {
-		err ("this controller type is not supported \n");
-		return HPC_ERROR;
-	}
-
-	wpg_data = swab32 (data);	// swap data before writing
-	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET;
-	writel (wpg_data, wpg_addr);
-
-	//--------------------------------------------------------------------
-	// WRITE - step 2 : clear the message buffer
-	data = 0x00000000 | (ulong) cmd;
-	wpg_data = swab32 (data);
-	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
-	writel (wpg_data, wpg_addr);
-
-	//--------------------------------------------------------------------
-	// WRITE - step 3 : issue start operation,I2C master control bit 30:ON
-	//                 2020 : [20] OR operation at [20] offset 0x20
-	data = WPG_I2CMCNTL_STARTOP_MASK;
-	wpg_data = swab32 (data);
-	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) WPG_I2C_OR;
-	writel (wpg_data, wpg_addr);
-
-	//--------------------------------------------------------------------
-	// WRITE - step 4 : wait until start operation bit clears
-	i = CMD_COMPLETE_TOUT_SEC;
-	while (i) {
-		long_delay (1 * HZ / 100);
-		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET;
-		wpg_data = readl (wpg_addr);
-		data = swab32 (wpg_data);
-		if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
-			break;
-		i--;
-	}
-	if (i == 0) {
-		debug ("%s - Exit Error:WPG timeout\n", __FUNCTION__);
-		rc = HPC_ERROR;
-	}
-
-	//--------------------------------------------------------------------
-	// WRITE - step 5 : read I2C status register
-	i = CMD_COMPLETE_TOUT_SEC;
-	while (i) {
-		long_delay (1 * HZ / 100);
-		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CSTAT_OFFSET;
-		wpg_data = readl (wpg_addr);
-		data = swab32 (wpg_data);
-		if (HPC_I2CSTATUS_CHECK (data))
-			break;
-		i--;
-	}
-	if (i == 0) {
-		debug ("ctrl_read - Error : I2C timeout\n");
-		rc = HPC_ERROR;
-	}
-
-	debug_polling ("%s Exit rc[%x]\n", __FUNCTION__, rc);
-	return (rc);
-}
-
-//------------------------------------------------------------
-//  Read from ISA type HPC 
-//------------------------------------------------------------
-static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
-{
-	u16 start_address;
-	u16 end_address;
-	u8 data;
-
-	start_address = ctlr_ptr->u.isa_ctlr.io_start;
-	end_address = ctlr_ptr->u.isa_ctlr.io_end;
-	data = inb (start_address + offset);
-	return data;
-}
-
-//--------------------------------------------------------------
-// Write to ISA type HPC
-//--------------------------------------------------------------
-static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
-{
-	u16 start_address;
-	u16 port_address;
-	
-	start_address = ctlr_ptr->u.isa_ctlr.io_start;
-	port_address = start_address + (u16) offset;
-	outb (data, port_address);
-}
-
-static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
-{
-	u8 data = 0x00;
-	debug ("inside pci_ctrl_read\n");
-	if (ctrl->ctrl_dev)
-		pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
-	return data;
-}
-
-static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
-{
-	u8 rc = -ENODEV;
-	debug ("inside pci_ctrl_write\n");
-	if (ctrl->ctrl_dev) {
-		pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
-		rc = 0;
-	}
-	return rc;
-}
-
-static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset)
-{
-	u8 rc;
-	switch (ctlr->ctlr_type) {
-	case 0:
-		rc = isa_ctrl_read (ctlr, offset);
-		break;
-	case 1:
-		rc = pci_ctrl_read (ctlr, offset);
-		break;
-	case 2:
-	case 4:
-		rc = i2c_ctrl_read (ctlr, base, offset);
-		break;
-	default:
-		return -ENODEV;
-	}
-	return rc;
-}
-
-static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data)
-{
-	u8 rc = 0;
-	switch (ctlr->ctlr_type) {
-	case 0:
-		isa_ctrl_write(ctlr, offset, data);
-		break;
-	case 1:
-		rc = pci_ctrl_write (ctlr, offset, data);
-		break;
-	case 2:
-	case 4:
-		rc = i2c_ctrl_write(ctlr, base, offset, data);
-		break;
-	default:
-		return -ENODEV;
-	}
-	return rc;
-}
-/*----------------------------------------------------------------------
-* Name:    hpc_writecmdtoindex()
-*
-* Action:  convert a write command to proper index within a controller
-*
-* Return   index, HPC_ERROR
-*---------------------------------------------------------------------*/
-static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
-{
-	u8 rc;
-
-	switch (cmd) {
-	case HPC_CTLR_ENABLEIRQ:	// 0x00.N.15
-	case HPC_CTLR_CLEARIRQ:	// 0x06.N.15
-	case HPC_CTLR_RESET:	// 0x07.N.15
-	case HPC_CTLR_IRQSTEER:	// 0x08.N.15
-	case HPC_CTLR_DISABLEIRQ:	// 0x01.N.15
-	case HPC_ALLSLOT_ON:	// 0x11.N.15
-	case HPC_ALLSLOT_OFF:	// 0x12.N.15
-		rc = 0x0F;
-		break;
-
-	case HPC_SLOT_OFF:	// 0x02.Y.0-14
-	case HPC_SLOT_ON:	// 0x03.Y.0-14
-	case HPC_SLOT_ATTNOFF:	// 0x04.N.0-14
-	case HPC_SLOT_ATTNON:	// 0x05.N.0-14
-	case HPC_SLOT_BLINKLED:	// 0x13.N.0-14
-		rc = index;
-		break;
-
-	case HPC_BUS_33CONVMODE:
-	case HPC_BUS_66CONVMODE:
-	case HPC_BUS_66PCIXMODE:
-	case HPC_BUS_100PCIXMODE:
-	case HPC_BUS_133PCIXMODE:
-		rc = index + WPG_1ST_BUS_INDEX - 1;
-		break;
-
-	default:
-		err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
-		rc = HPC_ERROR;
-	}
-
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    hpc_readcmdtoindex()
-*
-* Action:  convert a read command to proper index within a controller
-*
-* Return   index, HPC_ERROR
-*---------------------------------------------------------------------*/
-static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
-{
-	u8 rc;
-
-	switch (cmd) {
-	case READ_CTLRSTATUS:
-		rc = 0x0F;
-		break;
-	case READ_SLOTSTATUS:
-	case READ_ALLSTAT:
-		rc = index;
-		break;
-	case READ_EXTSLOTSTATUS:
-		rc = index + WPG_1ST_EXTSLOT_INDEX;
-		break;
-	case READ_BUSSTATUS:
-		rc = index + WPG_1ST_BUS_INDEX - 1;
-		break;
-	case READ_SLOTLATCHLOWREG:
-		rc = 0x28;
-		break;
-	case READ_REVLEVEL:
-		rc = 0x25;
-		break;
-	case READ_HPCOPTIONS:
-		rc = 0x27;
-		break;
-	default:
-		rc = HPC_ERROR;
-	}
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    HPCreadslot()
-*
-* Action:  issue a READ command to HPC
-*
-* Input:   pslot   - can not be NULL for READ_ALLSTAT
-*          pstatus - can be NULL for READ_ALLSTAT
-*
-* Return   0 or error codes
-*---------------------------------------------------------------------*/
-int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
-{
-	void *wpg_bbar = NULL;
-	struct controller *ctlr_ptr;
-	struct list_head *pslotlist;
-	u8 index, status;
-	int rc = 0;
-	int busindex;
-
-	debug_polling ("%s - Entry pslot[%lx] cmd[%x] pstatus[%lx]\n", __FUNCTION__, (ulong) pslot, cmd, (ulong) pstatus);
-
-	if ((pslot == NULL)
-	    || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
-		rc = -EINVAL;
-		err ("%s - Error invalid pointer, rc[%d]\n", __FUNCTION__, rc);
-		return rc;
-	}
-
-	if (cmd == READ_BUSSTATUS) {
-		busindex = ibmphp_get_bus_index (pslot->bus);
-		if (busindex < 0) {
-			rc = -EINVAL;
-			err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
-			return rc;
-		} else
-			index = (u8) busindex;
-	} else
-		index = pslot->ctlr_index;
-
-	index = hpc_readcmdtoindex (cmd, index);
-
-	if (index == HPC_ERROR) {
-		rc = -EINVAL;
-		err ("%s - Exit Error:invalid index, rc[%d]\n", __FUNCTION__, rc);
-		return rc;
-	}
-
-	ctlr_ptr = pslot->ctrl;
-
-	get_hpc_access ();
-
-	//--------------------------------------------------------------------
-	// map physical address to logical address
-	//--------------------------------------------------------------------
-	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-		wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
-
-	//--------------------------------------------------------------------
-	// check controller status before reading
-	//--------------------------------------------------------------------
-	rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
-	if (!rc) {
-		switch (cmd) {
-		case READ_ALLSTAT:
-			// update the slot structure
-			pslot->ctrl->status = status;
-			pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
-			rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
-						       &status);
-			if (!rc)
-				pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
-
-			break;
-
-		case READ_SLOTSTATUS:
-			// DO NOT update the slot structure
-			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
-			break;
-
-		case READ_EXTSLOTSTATUS:
-			// DO NOT update the slot structure
-			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
-			break;
-
-		case READ_CTLRSTATUS:
-			// DO NOT update the slot structure
-			*pstatus = status;
-			break;
-
-		case READ_BUSSTATUS:
-			pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
-			break;
-		case READ_REVLEVEL:
-			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
-			break;
-		case READ_HPCOPTIONS:
-			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
-			break;
-		case READ_SLOTLATCHLOWREG:
-			// DO NOT update the slot structure
-			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
-			break;
-
-			// Not used
-		case READ_ALLSLOT:
-			list_for_each (pslotlist, &ibmphp_slot_head) {
-				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
-				index = pslot->ctlr_index;
-				rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr,
-								wpg_bbar, &status);
-				if (!rc) {
-					pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
-					rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT,
-									ctlr_ptr, wpg_bbar, &status);
-					if (!rc)
-						pslot->ext_status =
-						    ctrl_read (ctlr_ptr, wpg_bbar,
-								index + WPG_1ST_EXTSLOT_INDEX);
-				} else {
-					err ("%s - Error ctrl_read failed\n", __FUNCTION__);
-					rc = -EINVAL;
-					break;
-				}
-			}
-			break;
-		default:
-			rc = -EINVAL;
-			break;
-		}
-	}
-	//--------------------------------------------------------------------
-	// cleanup
-	//--------------------------------------------------------------------
-	
-	// remove physical to logical address mapping
-	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-		iounmap (wpg_bbar);	
-	
-	free_hpc_access ();
-
-	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    ibmphp_hpc_writeslot()
-*
-* Action: issue a WRITE command to HPC
-*---------------------------------------------------------------------*/
-int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
-{
-	void *wpg_bbar = NULL;
-	struct controller *ctlr_ptr;
-	u8 index, status;
-	int busindex;
-	u8 done;
-	int rc = 0;
-	int timeout;
-
-	debug_polling ("%s - Entry pslot[%lx] cmd[%x]\n", __FUNCTION__, (ulong) pslot, cmd);
-	if (pslot == NULL) {
-		rc = -EINVAL;
-		err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
-		return rc;
-	}
-
-	if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
-		(cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
-		(cmd == HPC_BUS_133PCIXMODE)) {
-		busindex = ibmphp_get_bus_index (pslot->bus);
-		if (busindex < 0) {
-			rc = -EINVAL;
-			err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
-			return rc;
-		} else
-			index = (u8) busindex;
-	} else
-		index = pslot->ctlr_index;
-
-	index = hpc_writecmdtoindex (cmd, index);
-
-	if (index == HPC_ERROR) {
-		rc = -EINVAL;
-		err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
-		return rc;
-	}
-
-	ctlr_ptr = pslot->ctrl;
-
-	get_hpc_access ();
-
-	//--------------------------------------------------------------------
-	// map physical address to logical address
-	//--------------------------------------------------------------------
-	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
-		wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
-
-		debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
-		ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
-		ctlr_ptr->u.wpeg_ctlr.i2c_addr);
-	}
-	//--------------------------------------------------------------------
-	// check controller status before writing
-	//--------------------------------------------------------------------
-	rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
-	if (!rc) {
-
-		ctrl_write (ctlr_ptr, wpg_bbar, index, cmd);
-
-		//--------------------------------------------------------------------
-		// check controller is still not working on the command
-		//--------------------------------------------------------------------
-		timeout = CMD_COMPLETE_TOUT_SEC;
-		done = FALSE;
-		while (!done) {
-			rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
-							&status);
-			if (!rc) {
-				if (NEEDTOCHECK_CMDSTATUS (cmd)) {
-					if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
-						done = TRUE;
-				} else
-					done = TRUE;
-			}
-			if (!done) {
-				long_delay (1 * HZ);
-				if (timeout < 1) {
-					done = TRUE;
-					err ("%s - Error command complete timeout\n", __FUNCTION__);
-					rc = -EFAULT;
-				} else
-					timeout--;
-			}
-		}
-		ctlr_ptr->status = status;
-	}
-	// cleanup
-
-	// remove physical to logical address mapping
-	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-		iounmap (wpg_bbar);	
-	free_hpc_access ();
-
-	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    get_hpc_access()
-*
-* Action: make sure only one process can access HPC at one time
-*---------------------------------------------------------------------*/
-static void get_hpc_access (void)
-{
-	down (&sem_hpcaccess);
-}
-
-/*----------------------------------------------------------------------
-* Name:    free_hpc_access()
-*---------------------------------------------------------------------*/
-void free_hpc_access (void)
-{
-	up (&sem_hpcaccess);
-}
-
-/*----------------------------------------------------------------------
-* Name:    ibmphp_lock_operations()
-*
-* Action: make sure only one process can change the data structure
-*---------------------------------------------------------------------*/
-void ibmphp_lock_operations (void)
-{
-	down (&semOperations);
-	to_debug = TRUE;
-}
-
-/*----------------------------------------------------------------------
-* Name:    ibmphp_unlock_operations()
-*---------------------------------------------------------------------*/
-void ibmphp_unlock_operations (void)
-{
-	debug ("%s - Entry\n", __FUNCTION__);
-	up (&semOperations);
-	to_debug = FALSE;
-	debug ("%s - Exit\n", __FUNCTION__);
-}
-
-/*----------------------------------------------------------------------
-* Name:    poll_hpc()
-*---------------------------------------------------------------------*/
-#define POLL_LATCH_REGISTER	0
-#define POLL_SLOTS		1
-#define POLL_SLEEP		2
-static void poll_hpc (void)
-{
-	struct slot myslot;
-	struct slot *pslot = NULL;
-	struct list_head *pslotlist;
-	int rc;
-	int poll_state = POLL_LATCH_REGISTER;
-	u8 oldlatchlow = 0x00;
-	u8 curlatchlow = 0x00;
-	int poll_count = 0;
-	u8 ctrl_count = 0x00;
-
-	debug ("%s - Entry\n", __FUNCTION__);
-
-	while (!ibmphp_shutdown) {
-		if (ibmphp_shutdown) 
-			break;
-		
-		/* try to get the lock to do some kind of harware access */
-		down (&semOperations);
-
-		switch (poll_state) {
-		case POLL_LATCH_REGISTER: 
-			oldlatchlow = curlatchlow;
-			ctrl_count = 0x00;
-			list_for_each (pslotlist, &ibmphp_slot_head) {
-				if (ctrl_count >= ibmphp_get_total_controllers())
-					break;
-				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
-				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
-					ctrl_count++;
-					if (READ_SLOT_LATCH (pslot->ctrl)) {
-						rc = ibmphp_hpc_readslot (pslot,
-									  READ_SLOTLATCHLOWREG,
-									  &curlatchlow);
-						if (oldlatchlow != curlatchlow)
-							process_changeinlatch (oldlatchlow,
-									       curlatchlow,
-									       pslot->ctrl);
-					}
-				}
-			}
-			++poll_count;
-			poll_state = POLL_SLEEP;
-			break;
-		case POLL_SLOTS:
-			list_for_each (pslotlist, &ibmphp_slot_head) {
-				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
-				// make a copy of the old status
-				memcpy ((void *) &myslot, (void *) pslot,
-					sizeof (struct slot));
-				rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
-				if ((myslot.status != pslot->status)
-				    || (myslot.ext_status != pslot->ext_status))
-					process_changeinstatus (pslot, &myslot);
-			}
-			ctrl_count = 0x00;
-			list_for_each (pslotlist, &ibmphp_slot_head) {
-				if (ctrl_count >= ibmphp_get_total_controllers())
-					break;
-				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
-				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
-					ctrl_count++;
-					if (READ_SLOT_LATCH (pslot->ctrl))
-						rc = ibmphp_hpc_readslot (pslot,
-									  READ_SLOTLATCHLOWREG,
-									  &curlatchlow);
-				}
-			}
-			++poll_count;
-			poll_state = POLL_SLEEP;
-			break;
-		case POLL_SLEEP:
-			/* don't sleep with a lock on the hardware */
-			up (&semOperations);
-			long_delay (POLL_INTERVAL_SEC * HZ);
-
-			if (ibmphp_shutdown) 
-				break;
-			
-			down (&semOperations);
-			
-			if (poll_count >= POLL_LATCH_CNT) {
-				poll_count = 0;
-				poll_state = POLL_SLOTS;
-			} else
-				poll_state = POLL_LATCH_REGISTER;
-			break;
-		}	
-		/* give up the harware semaphore */
-		up (&semOperations);
-		/* sleep for a short time just for good measure */
-		set_current_state (TASK_INTERRUPTIBLE);
-		schedule_timeout (HZ/10);
-	}
-	up (&sem_exit);
-	debug ("%s - Exit\n", __FUNCTION__);
-}
-
-
-/* ----------------------------------------------------------------------
- *  Name:    ibmphp_hpc_fillhpslotinfo(hotplug_slot * phpslot)
- *
- *  Action:  fill out the hotplug_slot info
- *
- *  Input:   pointer to hotplug_slot
- *
- *  Return
- *  Value:   0 or error codes
- *-----------------------------------------------------------------------*/
-int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *phpslot)
-{
-	int rc = 0;
-	struct slot *pslot;
-
-	if (phpslot && phpslot->private) {
-		pslot = (struct slot *) phpslot->private;
-		rc = update_slot (pslot, (u8) TRUE);
-		if (!rc) {
-
-			// power - enabled:1  not:0
-			phpslot->info->power_status = SLOT_POWER (pslot->status);
-
-			// attention - off:0, on:1, blinking:2
-			phpslot->info->attention_status = SLOT_ATTN (pslot->status, pslot->ext_status);
-
-			// latch - open:1 closed:0
-			phpslot->info->latch_status = SLOT_LATCH (pslot->status);
-
-			// pci board - present:1 not:0
-			if (SLOT_PRESENT (pslot->status))
-				phpslot->info->adapter_status = 1;
-			else
-				phpslot->info->adapter_status = 0;
-/*
-			if (pslot->bus_on->supported_bus_mode
-				&& (pslot->bus_on->supported_speed == BUS_SPEED_66))
-				phpslot->info->max_bus_speed_status = BUS_SPEED_66PCIX;
-			else
-				phpslot->info->max_bus_speed_status = pslot->bus_on->supported_speed;
-*/		} else
-			rc = -EINVAL;
-	} else
-		rc = -EINVAL;
-
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    update_slot
-*
-* Action:  fill out slot status and extended status, controller status
-*
-* Input:   pointer to slot struct
-*---------------------------------------------------------------------*/
-static int update_slot (struct slot *pslot, u8 update)
-{
-	int rc = 0;
-
-	debug ("%s - Entry pslot[%lx]\n", __FUNCTION__, (ulong) pslot);
-	rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
-	debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    process_changeinstatus
-*
-* Action:  compare old and new slot status, process the change in status
-*
-* Input:   pointer to slot struct, old slot struct
-*
-* Return   0 or error codes
-* Value:
-*
-* Side
-* Effects: None.
-*
-* Notes:
-*---------------------------------------------------------------------*/
-static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
-{
-	u8 status;
-	int rc = 0;
-	u8 disable = FALSE;
-	u8 update = FALSE;
-
-	debug ("process_changeinstatus - Entry pslot[%lx], poldslot[%lx]\n", (ulong) pslot,
-	       (ulong) poldslot);
-
-	// bit 0 - HPC_SLOT_POWER
-	if ((pslot->status & 0x01) != (poldslot->status & 0x01))
-		update = TRUE;
-
-	// bit 1 - HPC_SLOT_CONNECT
-	// ignore
-
-	// bit 2 - HPC_SLOT_ATTN
-	if ((pslot->status & 0x04) != (poldslot->status & 0x04))
-		update = TRUE;
-
-	// bit 3 - HPC_SLOT_PRSNT2
-	// bit 4 - HPC_SLOT_PRSNT1
-	if (((pslot->status & 0x08) != (poldslot->status & 0x08))
-		|| ((pslot->status & 0x10) != (poldslot->status & 0x10)))
-		update = TRUE;
-
-	// bit 5 - HPC_SLOT_PWRGD
-	if ((pslot->status & 0x20) != (poldslot->status & 0x20))
-		// OFF -> ON: ignore, ON -> OFF: disable slot
-		if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) 
-			disable = TRUE;
-
-	// bit 6 - HPC_SLOT_BUS_SPEED
-	// ignore
-
-	// bit 7 - HPC_SLOT_LATCH
-	if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
-		update = TRUE;
-		// OPEN -> CLOSE
-		if (pslot->status & 0x80) {
-			if (SLOT_PWRGD (pslot->status)) {
-				// power goes on and off after closing latch
-				// check again to make sure power is still ON
-				long_delay (1 * HZ);
-				rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
-				if (SLOT_PWRGD (status))
-					update = TRUE;
-				else	// overwrite power in pslot to OFF
-					pslot->status &= ~HPC_SLOT_POWER;
-			}
-		}
-		// CLOSE -> OPEN 
-		else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
-			&& (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
-			disable = TRUE;
-		}
-		// else - ignore
-	}
-	// bit 4 - HPC_SLOT_BLINK_ATTN
-	if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
-		update = TRUE;
-
-	if (disable) {
-		debug ("process_changeinstatus - disable slot\n");
-		pslot->flag = FALSE;
-		rc = ibmphp_do_disable_slot (pslot);
-	}
-
-	if (update || disable) {
-		ibmphp_update_slot_info (pslot);
-	}
-
-	debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __FUNCTION__, rc, disable, update);
-
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    process_changeinlatch
-*
-* Action:  compare old and new latch reg status, process the change
-*
-* Input:   old and current latch register status
-*
-* Return   0 or error codes
-* Value:
-*---------------------------------------------------------------------*/
-static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl)
-{
-	struct slot myslot, *pslot;
-	u8 i;
-	u8 mask;
-	int rc = 0;
-
-	debug ("%s - Entry old[%x], new[%x]\n", __FUNCTION__, old, new);
-	// bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
-
-	for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
-		mask = 0x01 << i;
-		if ((mask & old) != (mask & new)) {
-			pslot = ibmphp_get_slot_from_physical_num (i);
-			if (pslot) {
-				memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
-				rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
-				debug ("%s - call process_changeinstatus for slot[%d]\n", __FUNCTION__, i);
-				process_changeinstatus (pslot, &myslot);
-			} else {
-				rc = -EINVAL;
-				err ("%s - Error bad pointer for slot[%d]\n", __FUNCTION__, i);
-			}
-		}
-	}
-	debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    hpc_poll_thread
-*
-* Action:  polling
-*
-* Return   0
-* Value:
-*---------------------------------------------------------------------*/
-static int hpc_poll_thread (void *data)
-{
-	debug ("%s - Entry\n", __FUNCTION__);
-
-	daemonize("hpc_poll");
-	allow_signal(SIGKILL);
-
-	poll_hpc ();
-
-	tid_poll = 0;
-	debug ("%s - Exit\n", __FUNCTION__);
-	return 0;
-}
-
-
-/*----------------------------------------------------------------------
-* Name:    ibmphp_hpc_start_poll_thread
-*
-* Action:  start polling thread
-*---------------------------------------------------------------------*/
-int __init ibmphp_hpc_start_poll_thread (void)
-{
-	int rc = 0;
-
-	debug ("%s - Entry\n", __FUNCTION__);
-
-	tid_poll = kernel_thread (hpc_poll_thread, 0, 0);
-	if (tid_poll < 0) {
-		err ("%s - Error, thread not started\n", __FUNCTION__);
-		rc = -1;
-	}
-
-	debug ("%s - Exit tid_poll[%d] rc[%d]\n", __FUNCTION__, tid_poll, rc);
-	return rc;
-}
-
-/*----------------------------------------------------------------------
-* Name:    ibmphp_hpc_stop_poll_thread
-*
-* Action:  stop polling thread and cleanup
-*---------------------------------------------------------------------*/
-void __exit ibmphp_hpc_stop_poll_thread (void)
-{
-	debug ("%s - Entry\n", __FUNCTION__);
-
-	ibmphp_shutdown = TRUE;
-	debug ("before locking operations \n");
-	ibmphp_lock_operations ();
-	debug ("after locking operations \n");
-	
-	// wait for poll thread to exit
-	debug ("before sem_exit down \n");
-	down (&sem_exit);
-	debug ("after sem_exit down \n");
-
-	// cleanup
-	debug ("before free_hpc_access \n");
-	free_hpc_access ();
-	debug ("after free_hpc_access \n");
-	ibmphp_unlock_operations ();
-	debug ("after unlock operations \n");
-	up (&sem_exit);
-	debug ("after sem exit up\n");
-
-	debug ("%s - Exit\n", __FUNCTION__);
-}
-
-/*----------------------------------------------------------------------
-* Name:    hpc_wait_ctlr_notworking
-*
-* Action:  wait until the controller is in a not working state
-*
-* Return   0, HPC_ERROR
-* Value:
-*---------------------------------------------------------------------*/
-static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void *wpg_bbar,
-				    u8 * pstatus)
-{
-	int rc = 0;
-	u8 done = FALSE;
-
-	debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
-
-	while (!done) {
-		*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
-		if (*pstatus == HPC_ERROR) {
-			rc = HPC_ERROR;
-			done = TRUE;
-		}
-		if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
-			done = TRUE;
-		if (!done) {
-			long_delay (1 * HZ);
-			if (timeout < 1) {
-				done = TRUE;
-				err ("HPCreadslot - Error ctlr timeout\n");
-				rc = HPC_ERROR;
-			} else
-				timeout--;
-		}
-	}
-	debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
-	return rc;
-}
diff -urN linux-2.5.70-bk9/drivers/hotplug/ibmphp_pci.c linux-2.5.70-bk10/drivers/hotplug/ibmphp_pci.c
--- linux-2.5.70-bk9/drivers/hotplug/ibmphp_pci.c	2003-05-26 18:00:19.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/ibmphp_pci.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1758 +0,0 @@
-/*
- * IBM Hot Plug Controller Driver
- * 
- * Written By: Irene Zubarev, IBM Corporation
- * 
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001,2002 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/list.h>
-#include "ibmphp.h"
-
-
-static int configure_device(struct pci_func *);
-static int configure_bridge(struct pci_func **, u8);
-static struct res_needed *scan_behind_bridge(struct pci_func *, u8);
-static int add_new_bus (struct bus_node *, struct resource_node *, struct resource_node *, struct resource_node *, u8);
-static u8 find_sec_number (u8 primary_busno, u8 slotno);
-
-/*
- * NOTE..... If BIOS doesn't provide default routing, we assign:
- * 9 for SCSI, 10 for LAN adapters, and 11 for everything else. 
- * If adapter is bridged, then we assign 11 to it and devices behind it.
- * We also assign the same irq numbers for multi function devices.
- * These are PIC mode, so shouldn't matter n.e.ways (hopefully)
- */
-static void assign_alt_irq (struct pci_func * cur_func, u8 class_code)
-{
-	int j = 0;
-	for (j = 0; j < 4; j++) {
-		if (cur_func->irq[j] == 0xff) {
-			switch (class_code) {
-				case PCI_BASE_CLASS_STORAGE:
-					cur_func->irq[j] = SCSI_IRQ;
-					break;
-				case PCI_BASE_CLASS_NETWORK:
-					cur_func->irq[j] = LAN_IRQ;
-					break;
-				default:
-					cur_func->irq[j] = OTHER_IRQ;
-					break;
-			}
-		}
-	}
-}
-
-/*
- * Configures the device to be added (will allocate needed resources if it
- * can), the device can be a bridge or a regular pci device, can also be
- * multi-functional
- * 
- * Input: function to be added
- * 
- * TO DO:  The error case with Multifunction device or multi function bridge,
- * if there is an error, will need to go through all previous functions and 
- * unconfigure....or can add some code into unconfigure_card....
- */
-int ibmphp_configure_card (struct pci_func *func, u8 slotno)
-{
-	u16 vendor_id;
-	u32 class;
-	u8 class_code;
-	u8 hdr_type, device, sec_number;
-	u8 function;
-	struct pci_func *newfunc;	/* for multi devices */
-	struct pci_func *cur_func, *prev_func;
-	int rc, i, j;
-	int cleanup_count;
-	u8 flag;
-	u8 valid_device = 0x00; /* to see if we are able to read from card any device info at all */
-
-	debug ("inside configure_card, func->busno = %x \n", func->busno);
-
-	device = func->device;
-	cur_func = func;
-
-	/* We only get bus and device from IRQ routing table.  So at this point,
-	 * func->busno is correct, and func->device contains only device (at the 5 
-	 * highest bits)
-	 */
-
-	/* For every function on the card */
-	for (function = 0x00; function < 0x08; function++) {
-		unsigned int devfn = PCI_DEVFN(device, function);
-		ibmphp_pci_bus->number = cur_func->busno;
-
-		cur_func->function = function;
-
-		debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n",
-			cur_func->busno, cur_func->device, cur_func->function);
-
-		pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
-
-		debug ("vendor_id is %x\n", vendor_id);
-		if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
-			/* found correct device!!! */
-			debug ("found valid device, vendor_id = %x\n", vendor_id);
-
-			++valid_device;
-
-			/* header: x x x x x x x x
-			 *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
-			 *         |_=> 0 = single function device, 1 = multi-function device
-			 */
-
-			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
-			pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
-
-			class_code = class >> 24;
-			debug ("hrd_type = %x, class = %x, class_code %x \n", hdr_type, class, class_code);
-			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
-			if (class == PCI_CLASS_NOT_DEFINED_VGA) {
-				err ("The device %x is VGA compatible and as is not supported for hot plugging. "
-				     "Please choose another device.\n", cur_func->device);
-				return -ENODEV;
-			} else if (class == PCI_CLASS_DISPLAY_VGA) {
-				err ("The device %x is not supported for hot plugging. "
-				     "Please choose another device.\n", cur_func->device);
-				return -ENODEV;
-			}
-			switch (hdr_type) {
-				case PCI_HEADER_TYPE_NORMAL:
-					debug ("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class);
-					assign_alt_irq (cur_func, class_code);
-					if ((rc = configure_device (cur_func)) < 0) {
-						/* We need to do this in case some other BARs were properly inserted */
-						err ("was not able to configure devfunc %x on bus %x. \n",
-						     cur_func->device, cur_func->busno);
-						cleanup_count = 6;
-						goto error;
-					}	
-					cur_func->next = NULL;
-					function = 0x8;
-					break;
-				case PCI_HEADER_TYPE_MULTIDEVICE:
-					assign_alt_irq (cur_func, class_code);
-					if ((rc = configure_device (cur_func)) < 0) {
-						/* We need to do this in case some other BARs were properly inserted */
-						err ("was not able to configure devfunc %x on bus %x...bailing out\n",
-						     cur_func->device, cur_func->busno);
-						cleanup_count = 6;
-						goto error;
-					}
-					newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
-					if (!newfunc) {
-						err ("out of system memory \n");
-						return -ENOMEM;
-					}
-					memset (newfunc, 0, sizeof (struct pci_func));
-					newfunc->busno = cur_func->busno;
-					newfunc->device = device;
-					cur_func->next = newfunc;
-					cur_func = newfunc;
-					for (j = 0; j < 4; j++)
-						newfunc->irq[j] = cur_func->irq[j];
-					break;
-				case PCI_HEADER_TYPE_MULTIBRIDGE:
-					class >>= 8;
-					if (class != PCI_CLASS_BRIDGE_PCI) {
-						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
-						     "Please insert another card.\n", cur_func->device);
-						return -ENODEV;
-					}
-					assign_alt_irq (cur_func, class_code);
-					rc = configure_bridge (&cur_func, slotno);
-					if (rc == -ENODEV) {
-						err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
-						err ("Bus %x, devfunc %x \n", cur_func->busno, cur_func->device);
-						return rc;
-					}
-					if (rc) {
-						/* We need to do this in case some other BARs were properly inserted */
-						err ("was not able to hot-add PPB properly.\n");
-						func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
-						cleanup_count = 2;
-						goto error;
-					}
-
-					pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-					flag = FALSE;
-					for (i = 0; i < 32; i++) {
-						if (func->devices[i]) {
-							newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
-							if (!newfunc) {
-								err ("out of system memory \n");
-								return -ENOMEM;
-							}
-							memset (newfunc, 0, sizeof (struct pci_func));
-							newfunc->busno = sec_number;
-							newfunc->device = (u8) i;
-							for (j = 0; j < 4; j++)
-								newfunc->irq[j] = cur_func->irq[j];
-
-							if (flag) {
-								for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
-								prev_func->next = newfunc;
-							} else
-								cur_func->next = newfunc;
-
-							rc = ibmphp_configure_card (newfunc, slotno);
-							/* This could only happen if kmalloc failed */
-							if (rc) {
-								/* We need to do this in case bridge itself got configured properly, but devices behind it failed */
-								func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
-								cleanup_count = 2;
-								goto error;
-							}
-							flag = TRUE;
-						}
-					}
-
-					newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
-					if (!newfunc) {
-						err ("out of system memory \n");
-						return -ENOMEM;
-					}
-					memset (newfunc, 0, sizeof (struct pci_func));
-					newfunc->busno = cur_func->busno;
-					newfunc->device = device;
-					for (j = 0; j < 4; j++)
-						newfunc->irq[j] = cur_func->irq[j];
-					for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
-					prev_func->next = newfunc;
-					cur_func = newfunc;
-					break;
-				case PCI_HEADER_TYPE_BRIDGE:
-					class >>= 8;
-					debug ("class now is %x\n", class);
-					if (class != PCI_CLASS_BRIDGE_PCI) {
-						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
-						     "Please insert another card.\n", cur_func->device);
-						return -ENODEV;
-					}
-
-					assign_alt_irq (cur_func, class_code);
-
-					debug ("cur_func->busno b4 configure_bridge is %x\n", cur_func->busno);
-					rc = configure_bridge (&cur_func, slotno);
-					if (rc == -ENODEV) {
-						err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
-						err ("Bus %x, devfunc %x \n", cur_func->busno, cur_func->device);
-						return rc;
-					}
-					if (rc) {
-						/* We need to do this in case some other BARs were properly inserted */
-						func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
-						err ("was not able to hot-add PPB properly.\n");
-						cleanup_count = 2;
-						goto error;
-					}
-					debug ("cur_func->busno = %x, device = %x, function = %x\n",
-						cur_func->busno, device, function);
-					pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-					debug ("after configuring bridge..., sec_number = %x\n", sec_number);
-					flag = FALSE;
-					for (i = 0; i < 32; i++) {
-						if (func->devices[i]) {
-							debug ("inside for loop, device is %x\n", i);
-							newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
-							if (!newfunc) {
-								err (" out of system memory \n");
-								return -ENOMEM;
-							}
-							memset (newfunc, 0, sizeof (struct pci_func));
-							newfunc->busno = sec_number;
-							newfunc->device = (u8) i;
-							for (j = 0; j < 4; j++)
-								newfunc->irq[j] = cur_func->irq[j];
-
-							if (flag) {
-								for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
-								prev_func->next = newfunc;
-							} else
-								cur_func->next = newfunc;
-
-							rc = ibmphp_configure_card (newfunc, slotno);
-
-							/* Again, this case should not happen... For complete paranoia, will need to call remove_bus */
-							if (rc) {
-								/* We need to do this in case some other BARs were properly inserted */
-								func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
-								cleanup_count = 2;
-								goto error;
-							}
-							flag = TRUE;
-						}
-					}
-
-					function = 0x8;
-					break;
-				default:
-					err ("MAJOR PROBLEM!!!!, header type not supported? %x\n", hdr_type);
-					return -ENXIO;
-					break;
-			}	/* end of switch */
-		}	/* end of valid device */
-	}	/* end of for */
-
-	if (!valid_device) {
-		err ("Cannot find any valid devices on the card.  Or unable to read from card.\n");
-		return -ENODEV;
-	}
-
-	return 0;
-
-error:
-	for (i = 0; i < cleanup_count; i++) {
-		if (cur_func->io[i]) {
-			ibmphp_remove_resource (cur_func->io[i]);
-			cur_func->io[i] = NULL;
-		} else if (cur_func->pfmem[i]) {
-			ibmphp_remove_resource (cur_func->pfmem[i]);
-			cur_func->pfmem[i] = NULL;
-		} else if (cur_func->mem[i]) {
-			ibmphp_remove_resource (cur_func->mem[i]);
-			cur_func->mem[i] = NULL;
-		}
-	}
-	return rc;
-}
-
-/*
- * This function configures the pci BARs of a single device.  
- * Input: pointer to the pci_func
- * Output: configured PCI, 0, or error
- */
-static int configure_device (struct pci_func *func)
-{
-	u32 bar[6];
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	u8 irq;
-	int count;
-	int len[6];
-	struct resource_node *io[6];
-	struct resource_node *mem[6];
-	struct resource_node *mem_tmp;
-	struct resource_node *pfmem[6];
-	unsigned int devfn;
-
-	debug ("%s - inside\n", __FUNCTION__);
-
-	devfn = PCI_DEVFN(func->device, func->function);
-	ibmphp_pci_bus->number = func->busno;
-
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-
-		/* not sure if i need this.  per scott, said maybe need smth like this
-		   if devices don't adhere 100% to the spec, so don't want to write
-		   to the reserved bits
-
-		pcibios_read_config_byte(cur_func->busno, cur_func->device, 
-		PCI_BASE_ADDRESS_0 + 4 * count, &tmp);
-		if (tmp & 0x01) // IO
-			pcibios_write_config_dword(cur_func->busno, cur_func->device, 
-			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFD);
-		else  // Memory
-			pcibios_write_config_dword(cur_func->busno, cur_func->device, 
-			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
-		 */
-		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-
-		if (!bar[count])	/* This BAR is not implemented */
-			continue;
-
-		debug ("Device %x BAR %d wants %x\n", func->device, count, bar[count]);
-
-		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			debug ("inside IO SPACE\n");
-
-			len[count] = bar[count] & 0xFFFFFFFC;
-			len[count] = ~len[count] + 1;
-
-			debug ("len[count] in IO %x, count %d\n", len[count], count);
-
-			io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-
-			if (!io[count]) {
-				err ("out of system memory \n");
-				return -ENOMEM;
-			}
-			memset (io[count], 0, sizeof (struct resource_node));
-			io[count]->type = IO;
-			io[count]->busno = func->busno;
-			io[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
-			io[count]->len = len[count];
-			if (ibmphp_check_resource(io[count], 0) == 0) {
-				ibmphp_add_resource (io[count]);
-				func->io[count] = io[count];
-			} else {
-				err ("cannot allocate requested io for bus %x device %x function %x len %x\n",
-				     func->busno, func->device, func->function, len[count]);
-				kfree (io[count]);
-				return -EIO;
-			}
-			pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
-	
-			/* _______________This is for debugging purposes only_____________________ */ 
-			debug ("b4 writing, the IO address is %x\n", func->io[count]->start);
-			pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-			debug ("after writing.... the start address is %x\n", bar[count]);
-			/* _________________________________________________________________________*/
-
-		} else {
-			/* This is Memory */
-			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-				debug ("PFMEM SPACE\n");
-
-				len[count] = bar[count] & 0xFFFFFFF0;
-				len[count] = ~len[count] + 1;
-
-				debug ("len[count] in PFMEM %x, count %d\n", len[count], count);
-
-				pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-				if (!pfmem[count]) {
-					err ("out of system memory \n");
-					return -ENOMEM;
-				}
-				memset (pfmem[count], 0, sizeof (struct resource_node));
-				pfmem[count]->type = PFMEM;
-				pfmem[count]->busno = func->busno;
-				pfmem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
-				pfmem[count]->len = len[count];
-				pfmem[count]->fromMem = FALSE;
-				if (ibmphp_check_resource (pfmem[count], 0) == 0) {
-					ibmphp_add_resource (pfmem[count]);
-					func->pfmem[count] = pfmem[count];
-				} else {
-					mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-					if (!mem_tmp) {
-						err ("out of system memory \n");
-						kfree (pfmem[count]);
-						return -ENOMEM;
-					}
-					memset (mem_tmp, 0, sizeof (struct resource_node));
-					mem_tmp->type = MEM;
-					mem_tmp->busno = pfmem[count]->busno;
-					mem_tmp->devfunc = pfmem[count]->devfunc;
-					mem_tmp->len = pfmem[count]->len;
-					debug ("there's no pfmem... going into mem.\n");
-					if (ibmphp_check_resource (mem_tmp, 0) == 0) {
-						ibmphp_add_resource (mem_tmp);
-						pfmem[count]->fromMem = TRUE;
-						pfmem[count]->rangeno = mem_tmp->rangeno;
-						pfmem[count]->start = mem_tmp->start;
-						pfmem[count]->end = mem_tmp->end;
-						ibmphp_add_pfmem_from_mem (pfmem[count]);
-						func->pfmem[count] = pfmem[count];
-					} else {
-						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
-						     func->busno, func->device, len[count]);
-						kfree (mem_tmp);
-						kfree (pfmem[count]);
-						return -EIO;
-					}
-				}
-
-				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
-
-				/*_______________This is for debugging purposes only______________________________*/				
-				debug ("b4 writing, start address is %x\n", func->pfmem[count]->start);
-				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-				debug ("after writing, start address is %x\n", bar[count]);
-				/*_________________________________________________________________________________*/
-
-				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					debug ("inside the mem 64 case, count %d\n", count);
-					count += 1;
-					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
-					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
-				}
-			} else {
-				/* regular memory */
-				debug ("REGULAR MEM SPACE\n");
-
-				len[count] = bar[count] & 0xFFFFFFF0;
-				len[count] = ~len[count] + 1;
-
-				debug ("len[count] in Mem %x, count %d\n", len[count], count);
-
-				mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-				if (!mem[count]) {
-					err ("out of system memory \n");
-					return -ENOMEM;
-				}
-				memset (mem[count], 0, sizeof (struct resource_node));
-				mem[count]->type = MEM;
-				mem[count]->busno = func->busno;
-				mem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
-				mem[count]->len = len[count];
-				if (ibmphp_check_resource (mem[count], 0) == 0) {
-					ibmphp_add_resource (mem[count]);
-					func->mem[count] = mem[count];
-				} else {
-					err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
-					     func->busno, func->device, len[count]);
-					kfree (mem[count]);
-					return -EIO;
-				}
-				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
-				/* _______________________This is for debugging purposes only _______________________*/
-				debug ("b4 writing, start address is %x\n", func->mem[count]->start);
-				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-				debug ("after writing, the address is %x\n", bar[count]);
-				/* __________________________________________________________________________________*/
-
-				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					debug ("inside mem 64 case, reg. mem, count %d\n", count);
-					count += 1;
-					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
-					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
-				}
-			}
-		}		/* end of mem */
-	}			/* end of for */
-
-	func->bus = 0;		/* To indicate that this is not a PPB */
-	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
-	if ((irq > 0x00) && (irq < 0x05))
-		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
-
-	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
-	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
-
-	pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
-	pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
-
-	return 0;
-}
-
-/******************************************************************************
- * This routine configures a PCI-2-PCI bridge and the functions behind it
- * Parameters: pci_func
- * Returns: 
- ******************************************************************************/
-static int configure_bridge (struct pci_func **func_passed, u8 slotno)
-{
-	int count;
-	int i;
-	int rc;
-	u8 sec_number;
-	u8 io_base;
-	u16 pfmem_base;
-	u32 bar[2];
-	u32 len[2];
-	u8 flag_io = FALSE;
-	u8 flag_mem = FALSE;
-	u8 flag_pfmem = FALSE;
-	u8 need_io_upper = FALSE;
-	u8 need_pfmem_upper = FALSE;
-	struct res_needed *amount_needed = NULL;
-	struct resource_node *io = NULL;
-	struct resource_node *bus_io[2] = {NULL, NULL};
-	struct resource_node *mem = NULL;
-	struct resource_node *bus_mem[2] = {NULL, NULL};
-	struct resource_node *mem_tmp = NULL;
-	struct resource_node *pfmem = NULL;
-	struct resource_node *bus_pfmem[2] = {NULL, NULL};
-	struct bus_node *bus;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		0
-	};
-	struct pci_func *func = *func_passed;
-	unsigned int devfn;
-	u8 irq;
-	int retval;
-
-	debug ("%s - enter\n", __FUNCTION__);
-
-	devfn = PCI_DEVFN(func->function, func->device);
-	ibmphp_pci_bus->number = func->busno;
-
-	/* Configuring necessary info for the bridge so that we could see the devices
-	 * behind it
-	 */
-
-	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
-
-	/* _____________________For debugging purposes only __________________________
-	pci_bus_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
-	debug ("primary # written into the bridge is %x\n", pri_number);
-	 ___________________________________________________________________________*/
-
-	/* in EBDA, only get allocated 1 additional bus # per slot */
-	sec_number = find_sec_number (func->busno, slotno);
-	if (sec_number == 0xff) {
-		err ("cannot allocate secondary bus number for the bridged device \n");
-		return -EINVAL;
-	}
-
-	debug ("after find_sec_number, the number we got is %x\n", sec_number);
-	debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
-
-	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
-	
-	/* __________________For debugging purposes only __________________________________
-	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-	debug ("sec_number after write/read is %x\n", sec_number);
-	 ________________________________________________________________________________*/
-
-	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
-
-	/* __________________For debugging purposes only ____________________________________
-	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
-	debug ("subordinate number after write/read is %x\n", sec_number);
-	 __________________________________________________________________________________*/
-
-	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
-	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
-	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
-
-	debug ("func->busno is %x\n", func->busno);
-	debug ("sec_number after writing is %x\n", sec_number);
-
-
-	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	   !!!!!!!!!!!!!!!NEED TO ADD!!!  FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!! 
-	   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-
-
-	/* First we need to allocate mem/io for the bridge itself in case it needs it */
-	for (count = 0; address[count]; count++) {	/* for 2 BARs */
-		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-
-		if (!bar[count]) {
-			/* This BAR is not implemented */
-			debug ("so we come here then, eh?, count = %d\n", count);
-			continue;
-		}
-		//  tmp_bar = bar[count];
-
-		debug ("Bar %d wants %x\n", count, bar[count]);
-
-		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			len[count] = bar[count] & 0xFFFFFFFC;
-			len[count] = ~len[count] + 1;
-
-			debug ("len[count] in IO = %x\n", len[count]);
-
-			bus_io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-		
-			if (!bus_io[count]) {
-				err ("out of system memory \n");
-				retval = -ENOMEM;
-				goto error;
-			}
-			memset (bus_io[count], 0, sizeof (struct resource_node));
-			bus_io[count]->type = IO;
-			bus_io[count]->busno = func->busno;
-			bus_io[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
-			bus_io[count]->len = len[count];
-			if (ibmphp_check_resource (bus_io[count], 0) == 0) {
-				ibmphp_add_resource (bus_io[count]);
-				func->io[count] = bus_io[count];
-			} else {
-				err ("cannot allocate requested io for bus %x, device %x, len %x\n",
-				     func->busno, func->device, len[count]);
-				kfree (bus_io[count]);
-				return -EIO;
-			}
-
-			pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
-
-		} else {
-			/* This is Memory */
-			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-				len[count] = bar[count] & 0xFFFFFFF0;
-				len[count] = ~len[count] + 1;
-
-				debug ("len[count] in PFMEM = %x\n", len[count]);
-
-				bus_pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-				if (!bus_pfmem[count]) {
-					err ("out of system memory \n");
-					retval = -ENOMEM;
-					goto error;
-				}
-				memset (bus_pfmem[count], 0, sizeof (struct resource_node));
-				bus_pfmem[count]->type = PFMEM;
-				bus_pfmem[count]->busno = func->busno;
-				bus_pfmem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
-				bus_pfmem[count]->len = len[count];
-				bus_pfmem[count]->fromMem = FALSE;
-				if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {
-					ibmphp_add_resource (bus_pfmem[count]);
-					func->pfmem[count] = bus_pfmem[count];
-				} else {
-					mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-					if (!mem_tmp) {
-						err ("out of system memory \n");
-						retval = -ENOMEM;
-						goto error;
-					}
-					memset (mem_tmp, 0, sizeof (struct resource_node));
-					mem_tmp->type = MEM;
-					mem_tmp->busno = bus_pfmem[count]->busno;
-					mem_tmp->devfunc = bus_pfmem[count]->devfunc;
-					mem_tmp->len = bus_pfmem[count]->len;
-					if (ibmphp_check_resource (mem_tmp, 0) == 0) {
-						ibmphp_add_resource (mem_tmp);
-						bus_pfmem[count]->fromMem = TRUE;
-						bus_pfmem[count]->rangeno = mem_tmp->rangeno;
-						ibmphp_add_pfmem_from_mem (bus_pfmem[count]);
-						func->pfmem[count] = bus_pfmem[count];
-					} else {
-						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n", 
-						     func->busno, func->device, len[count]);
-						kfree (mem_tmp);
-						kfree (bus_pfmem[count]);
-						return -EIO;
-					}
-				}
-
-				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
-
-				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					count += 1;
-					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
-					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
-
-				}
-			} else {
-				/* regular memory */
-				len[count] = bar[count] & 0xFFFFFFF0;
-				len[count] = ~len[count] + 1;
-
-				debug ("len[count] in Memory is %x\n", len[count]);
-
-				bus_mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-				if (!bus_mem[count]) {
-					err ("out of system memory \n");
-					retval = -ENOMEM;
-					goto error;
-				}
-				memset (bus_mem[count], 0, sizeof (struct resource_node));
-				bus_mem[count]->type = MEM;
-				bus_mem[count]->busno = func->busno;
-				bus_mem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
-				bus_mem[count]->len = len[count];
-				if (ibmphp_check_resource (bus_mem[count], 0) == 0) {
-					ibmphp_add_resource (bus_mem[count]);
-					func->mem[count] = bus_mem[count];
-				} else {
-					err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
-					     func->busno, func->device, len[count]);
-					kfree (bus_mem[count]);
-					return -EIO;
-				}
-
-				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
-
-				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					count += 1;
-					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
-					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
-
-				}
-			}
-		}		/* end of mem */
-	}			/* end of for  */
-
-	/* Now need to see how much space the devices behind the bridge needed */
-	amount_needed = scan_behind_bridge (func, sec_number);
-	if (amount_needed == NULL)
-		return -ENOMEM;
-
-	ibmphp_pci_bus->number = func->busno;
-	debug ("after coming back from scan_behind_bridge\n");
-	debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
-	debug ("amount_needed->io = %x\n", amount_needed->io);
-	debug ("amount_needed->mem = %x\n", amount_needed->mem);
-	debug ("amount_needed->pfmem =  %x\n", amount_needed->pfmem);
-
-	if (amount_needed->not_correct) {		
-		debug ("amount_needed is not correct \n");
-		for (count = 0; address[count]; count++) {
-			/* for 2 BARs */
-			if (bus_io[count]) {
-				ibmphp_remove_resource (bus_io[count]);
-				func->io[count] = NULL;
-			} else if (bus_pfmem[count]) {
-				ibmphp_remove_resource (bus_pfmem[count]);
-				func->pfmem[count] = NULL;
-			} else if (bus_mem[count]) {
-				ibmphp_remove_resource (bus_mem[count]);
-				func->mem[count] = NULL;
-			}
-		}
-		kfree (amount_needed);
-		return -ENODEV;
-	}
-
-	if (!amount_needed->io) {
-		debug ("it doesn't want IO?\n");
-		flag_io = TRUE;
-	} else {
-		debug ("it wants %x IO behind the bridge \n", amount_needed->io);
-		io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-		
-		if (!io) {
-			err ("out of system memory \n");
-			retval = -ENOMEM;
-			goto error;
-		}
-		memset (io, 0, sizeof (struct resource_node));
-		io->type = IO;
-		io->busno = func->busno;
-		io->devfunc = ((func->device << 3) | (func->function & 0x7));
-		io->len = amount_needed->io;
-		if (ibmphp_check_resource (io, 1) == 0) {
-			debug ("were we able to add io\n");
-			ibmphp_add_resource (io);
-			flag_io = TRUE;
-		}
-	}
-
-	if (!amount_needed->mem) {
-		debug ("it doesn't want n.e.memory?\n");
-		flag_mem = TRUE;
-	} else {
-		debug ("it wants %x memory behind the bridge\n", amount_needed->mem);
-		mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-		if (!mem) {
-			err ("out of system memory \n");
-			retval = -ENOMEM;
-			goto error;
-		}
-		memset (mem, 0, sizeof (struct resource_node));
-		mem->type = MEM;
-		mem->busno = func->busno;
-		mem->devfunc = ((func->device << 3) | (func->function & 0x7));
-		mem->len = amount_needed->mem;
-		if (ibmphp_check_resource (mem, 1) == 0) {
-			ibmphp_add_resource (mem);
-			flag_mem = TRUE;
-			debug ("were we able to add mem\n");
-		}
-	}
-
-	if (!amount_needed->pfmem) {
-		debug ("it doesn't want n.e.pfmem mem?\n");
-		flag_pfmem = TRUE;
-	} else {
-		debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
-		pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-		if (!pfmem) {
-			err ("out of system memory \n");
-			retval = -ENOMEM;
-			goto error;
-		}
-		memset (pfmem, 0, sizeof (struct resource_node));
-		pfmem->type = PFMEM;
-		pfmem->busno = func->busno;
-		pfmem->devfunc = ((func->device << 3) | (func->function & 0x7));
-		pfmem->len = amount_needed->pfmem;
-		pfmem->fromMem = FALSE;
-		if (ibmphp_check_resource (pfmem, 1) == 0) {
-			ibmphp_add_resource (pfmem);
-			flag_pfmem = TRUE;
-		} else {
-			mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-			if (!mem_tmp) {
-				err ("out of system memory \n");
-				retval = -ENOMEM;
-				goto error;
-			}
-			memset (mem_tmp, 0, sizeof (struct resource_node));
-			mem_tmp->type = MEM;
-			mem_tmp->busno = pfmem->busno;
-			mem_tmp->devfunc = pfmem->devfunc;
-			mem_tmp->len = pfmem->len;
-			if (ibmphp_check_resource (mem_tmp, 1) == 0) {
-				ibmphp_add_resource (mem_tmp);
-				pfmem->fromMem = TRUE;
-				pfmem->rangeno = mem_tmp->rangeno;
-				ibmphp_add_pfmem_from_mem (pfmem);
-				flag_pfmem = TRUE;
-			}
-		}
-	}
-
-	debug ("b4 if (flag_io && flag_mem && flag_pfmem)\n");
-	debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
-
-	if (flag_io && flag_mem && flag_pfmem) {
-		/* If on bootup, there was a bridged card in this slot,
-		 * then card was removed and ibmphp got unloaded and loaded
-		 * back again, there's no way for us to remove the bus
-		 * struct, so no need to kmalloc, can use existing node
-		 */
-		bus = ibmphp_find_res_bus (sec_number);
-		if (!bus) {
-			bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
-			if (!bus) {
-				err ("out of system memory \n");
-				retval = -ENOMEM;
-				goto error;
-			}
-			memset (bus, 0, sizeof (struct bus_node));
-			bus->busno = sec_number;
-			debug ("b4 adding new bus\n");
-			rc = add_new_bus (bus, io, mem, pfmem, func->busno);
-		} else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
-			rc = add_new_bus (bus, io, mem, pfmem, 0xFF);
-		else {
-			err ("expected bus structure not empty? \n");
-			retval = -EIO;
-			goto error;
-		}
-		if (rc) {
-			if (rc == -ENOMEM) {
-				ibmphp_remove_bus (bus, func->busno);
-				kfree (amount_needed);
-				return rc;
-			}
-			retval = rc;
-			goto error;
-		}
-		pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
-		pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
-
-		if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
-			debug ("io 32\n");
-			need_io_upper = TRUE;
-		}
-		if ((io_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
-			debug ("pfmem 64\n");
-			need_pfmem_upper = TRUE;
-		}
-
-		if (bus->noIORanges) {
-			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
-			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);	
-
-			/* _______________This is for debugging purposes only ____________________
-			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
-			debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
-			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
-			debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
-			 ________________________________________________________________________*/
-
-			if (need_io_upper) {	/* since can't support n.e.ways */
-				pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
-				pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
-			}
-		} else {
-			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
-			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
-		}
-
-		if (bus->noMemRanges) {
-			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
-			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
-			
-			/* ____________________This is for debugging purposes only ________________________
-			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
-			debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
-			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
-			debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
-			 __________________________________________________________________________________*/
-
-		} else {
-			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
-			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
-		}
-		if (bus->noPFMemRanges) {
-			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
-			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
-
-			/* __________________________This is for debugging purposes only _______________________
-			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
-			debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
-			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
-			debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
-			 ______________________________________________________________________________________*/
-
-			if (need_pfmem_upper) {	/* since can't support n.e.ways */
-				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
-				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
-			}
-		} else {
-			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
-			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
-		}
-
-		debug ("b4 writing control information\n");
-
-		pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
-		if ((irq > 0x00) && (irq < 0x05))
-			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
-		/*    
-		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
-		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
-		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
-		 */
-
-		pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
-		pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
-		for (i = 0; i < 32; i++) {
-			if (amount_needed->devices[i]) {
-				debug ("device where devices[i] is 1 = %x\n", i);
-				func->devices[i] = 1;
-			}
-		}
-		func->bus = 1;	/* For unconfiguring, to indicate it's PPB */
-		func_passed = &func;
-		debug ("func->busno b4 returning is %x\n", func->busno);
-		debug ("func->busno b4 returning in the other structure is %x\n", (*func_passed)->busno);
-		kfree (amount_needed);
-		return 0;
-	} else {
-		err ("Configuring bridge was unsuccessful... \n");
-		mem_tmp = NULL;
-		retval = -EIO;
-		goto error;
-	}
-
-error:
-	if (amount_needed)
-		kfree (amount_needed);
-	if (pfmem)
-		ibmphp_remove_resource (pfmem);
-	if (io)
-		ibmphp_remove_resource (io);
-	if (mem)
-		ibmphp_remove_resource (mem);
-	for (i = 0; i < 2; i++) {	/* for 2 BARs */
-		if (bus_io[i]) {
-			ibmphp_remove_resource (bus_io[i]);
-			func->io[i] = NULL;
-		} else if (bus_pfmem[i]) {
-			ibmphp_remove_resource (bus_pfmem[i]);
-			func->pfmem[i] = NULL;
-		} else if (bus_mem[i]) {
-			ibmphp_remove_resource (bus_mem[i]);
-			func->mem[i] = NULL;
-		}
-	}
-	return retval;
-}
-
-/*****************************************************************************
- * This function adds up the amount of resources needed behind the PPB bridge
- * and passes it to the configure_bridge function
- * Input: bridge function
- * Ouput: amount of resources needed
- *****************************************************************************/
-static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
-{
-	int count, len[6];
-	u16 vendor_id;
-	u8 hdr_type;
-	u8 device, function;
-	unsigned int devfn;
-	int howmany = 0;	/*this is to see if there are any devices behind the bridge */
-
-	u32 bar[6], class;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	struct res_needed *amount;
-
-	amount = kmalloc (sizeof (struct res_needed), GFP_KERNEL);
-	if (amount == NULL)
-		return NULL;
-	memset (amount, 0, sizeof (struct res_needed));
-
-	ibmphp_pci_bus->number = busno;
-
-	debug ("the bus_no behind the bridge is %x\n", busno);
-	debug ("scanning devices behind the bridge...\n");
-	for (device = 0; device < 32; device++) {
-		amount->devices[device] = 0;
-		for (function = 0; function < 8; function++) {
-			devfn = PCI_DEVFN(device, function);
-
-			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
-
-			if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
-				/* found correct device!!! */
-				howmany++;
-
-				pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
-				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
-
-				debug ("hdr_type behind the bridge is %x\n", hdr_type);
-				if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
-					err ("embedded bridges not supported for hot-plugging.\n");
-					amount->not_correct = TRUE;
-					return amount;
-				}
-
-				class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
-				if (class == PCI_CLASS_NOT_DEFINED_VGA) {
-					err ("The device %x is VGA compatible and as is not supported for hot plugging. "
-					     "Please choose another device.\n", device);
-					amount->not_correct = TRUE;
-					return amount;
-				} else if (class == PCI_CLASS_DISPLAY_VGA) {
-					err ("The device %x is not supported for hot plugging. "
-					     "Please choose another device.\n", device);
-					amount->not_correct = TRUE;
-					return amount;
-				}
-
-				amount->devices[device] = 1;
-
-				for (count = 0; address[count]; count++) {
-					/* for 6 BARs */
-					/*
-					pci_bus_read_config_byte (ibmphp_pci_bus, devfn, address[count], &tmp);
-					if (tmp & 0x01) // IO
-						pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
-					else // MEMORY
-						pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-					*/
-					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-					pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
-
-					debug ("what is bar[count]? %x, count = %d\n", bar[count], count);
-
-					if (!bar[count])	/* This BAR is not implemented */
-						continue;
-
-					//tmp_bar = bar[count];
-
-					debug ("count %d device %x function %x wants %x resources \n", count, device, function, bar[count]);
-
-					if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
-						/* This is IO */
-						len[count] = bar[count] & 0xFFFFFFFC;
-						len[count] = ~len[count] + 1;
-						amount->io += len[count];
-					} else {
-						/* This is Memory */
-						if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-							/* pfmem */
-							len[count] = bar[count] & 0xFFFFFFF0;
-							len[count] = ~len[count] + 1;
-							amount->pfmem += len[count];
-							if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64)
-								/* takes up another dword */
-								count += 1;
-
-						} else {
-							/* regular memory */
-							len[count] = bar[count] & 0xFFFFFFF0;
-							len[count] = ~len[count] + 1;
-							amount->mem += len[count];
-							if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-								/* takes up another dword */
-								count += 1;
-							}
-						}
-					}
-				}	/* end for */
-			}	/* end if (valid) */
-		}	/* end for */
-	}	/* end for */
-
-	if (!howmany)
-		amount->not_correct = TRUE;
-	else
-		amount->not_correct = FALSE;
-	if ((amount->io) && (amount->io < IOBRIDGE))
-		amount->io = IOBRIDGE;
-	if ((amount->mem) && (amount->mem < MEMBRIDGE))
-		amount->mem = MEMBRIDGE;
-	if ((amount->pfmem) && (amount->pfmem < MEMBRIDGE))
-		amount->pfmem = MEMBRIDGE;
-	return amount;
-}
-
-/* The following 3 unconfigure_boot_ routines deal with the case when we had the card 
- * upon bootup in the system, since we don't allocate func to such case, we need to read 
- * the start addresses from pci config space and then find the corresponding entries in 
- * our resource lists.  The functions return either 0, -ENODEV, or -1 (general failure)
- * Change: we also call these functions even if we configured the card ourselves (i.e., not
- * the bootup case), since it should work same way
- */
-static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
-{
-	u32 start_address;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	int count;
-	struct resource_node *io;
-	struct resource_node *mem;
-	struct resource_node *pfmem;
-	struct bus_node *bus;
-	u32 end_address;
-	u32 temp_end;
-	u32 size;
-	u32 tmp_address;
-	unsigned int devfn;
-
-	debug ("%s - enter\n", __FUNCTION__);
-
-	bus = ibmphp_find_res_bus (busno);
-	if (!bus) {
-		debug ("cannot find corresponding bus.\n");
-		return -EINVAL;
-	}
-
-	devfn = PCI_DEVFN(device, function);
-	ibmphp_pci_bus->number = busno;
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
-
-		/* We can do this here, b/c by that time the device driver of the card has been stopped */
-
-		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
-		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &size);
-		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], start_address);
-
-		debug ("start_address is %x\n", start_address);
-		debug ("busno, device, function %x %x %x\n", busno, device, function);
-		if (!size) {
-			/* This BAR is not implemented */
-			debug ("is this bar no implemented?, count = %d\n", count);
-			continue;
-		}
-		tmp_address = start_address;
-		if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			start_address &= PCI_BASE_ADDRESS_IO_MASK;
-			size = size & 0xFFFFFFFC;
-			size = ~size + 1;
-			end_address = start_address + size - 1;
-			if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
-				err ("cannot find corresponding IO resource to remove\n");
-				return -EIO;
-			}
-			debug ("io->start = %x\n", io->start);
-			temp_end = io->end;
-			start_address = io->end + 1;
-			ibmphp_remove_resource (io);
-			/* This is needed b/c of the old I/O restrictions in the BIOS */
-			while (temp_end < end_address) {
-				if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
-					err ("cannot find corresponding IO resource to remove\n");
-					return -EIO;
-				}
-				debug ("io->start = %x\n", io->start);
-				temp_end = io->end;
-				start_address = io->end + 1;
-				ibmphp_remove_resource (io);
-			}
-
-			/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
-		} else {
-			/* This is Memory */
-			if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
-				debug ("start address of pfmem is %x\n", start_address);
-
-				if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
-					err ("cannot find corresponding PFMEM resource to remove\n");
-					return -EIO;
-				}
-				if (pfmem)
-					debug ("pfmem->start = %x\n", pfmem->start);
-
-				ibmphp_remove_resource (pfmem);
-
-				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					count += 1;
-				}
-
-			} else {
-				/* regular memory */
-				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
-				debug ("start address of mem is %x\n", start_address);
-				if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
-					err ("cannot find corresponding MEM resource to remove\n");
-					return -EIO;
-				}
-				if (mem)
-					debug ("mem->start = %x\n", mem->start);
-
-				ibmphp_remove_resource (mem);
-
-				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					count += 1;
-				}
-			}
-		}	/* end of mem */
-	}	/* end of for */
-
-	return 0;
-}
-
-static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
-{
-	int count;
-	int bus_no, pri_no, sub_no, sec_no = 0;
-	u32 start_address, tmp_address;
-	u8 sec_number, sub_number, pri_number;
-	struct resource_node *io = NULL;
-	struct resource_node *mem = NULL;
-	struct resource_node *pfmem = NULL;
-	struct bus_node *bus;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		0
-	};
-	unsigned int devfn;
-
-	devfn = PCI_DEVFN(device, function);
-	ibmphp_pci_bus->number = busno;
-	bus_no = (int) busno;
-	debug ("busno is %x\n", busno);
-	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
-	debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number);
-
-	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-	debug ("sec_number is %x\n", sec_number);
-	sec_no = (int) sec_number;
-	pri_no = (int) pri_number;
-	if (pri_no != bus_no) {
-		err ("primary numbers in our structures and pci config space don't match.\n");
-		return -EINVAL;
-	}
-
-	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-	sec_no = (int) sec_no;
-
-	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
-	sub_no = (int) sub_number;
-	debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
-	if (sec_no != sub_number) {
-		err ("there're more buses behind this bridge.  Hot removal is not supported.  Please choose another card\n");
-		return -ENODEV;
-	}
-
-	bus = ibmphp_find_res_bus (sec_number);
-	debug ("bus->busno is %x\n", bus->busno);
-	debug ("sec_number is %x\n", sec_number);
-	if (!bus) {
-		err ("cannot find Bus structure for the bridged device\n");
-		return -EINVAL;
-	}
-
-	ibmphp_remove_bus (bus, busno);
-
-	for (count = 0; address[count]; count++) {
-		/* for 2 BARs */
-		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
-
-		if (!start_address) {
-			/* This BAR is not implemented */
-			continue;
-		}
-
-		tmp_address = start_address;
-
-		if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			start_address &= PCI_BASE_ADDRESS_IO_MASK;
-			if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
-				err ("cannot find corresponding IO resource to remove\n");
-				return -EIO;
-			}
-			if (io)
-				debug ("io->start = %x\n", io->start);
-
-			ibmphp_remove_resource (io);
-
-			/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
-		} else {
-			/* This is Memory */
-			if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
-				if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
-					err ("cannot find corresponding PFMEM resource to remove\n");
-					return -EINVAL;
-				}
-				if (pfmem)
-					debug ("pfmem->start = %x\n", pfmem->start);
-
-				ibmphp_remove_resource (pfmem);
-
-				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					count += 1;
-				}
-
-			} else {
-				/* regular memory */
-				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
-				if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
-					err ("cannot find corresponding MEM resource to remove\n");
-					return -EINVAL;
-				}
-				if (mem)
-					debug ("mem->start = %x\n", mem->start);
-
-				ibmphp_remove_resource (mem);
-
-				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					count += 1;
-				}
-			}
-		}	/* end of mem */
-	}	/* end of for */
-	debug ("%s - exiting, returning success\n", __FUNCTION__);
-	return 0;
-}
-
-static int unconfigure_boot_card (struct slot *slot_cur)
-{
-	u16 vendor_id;
-	u32 class;
-	u8 hdr_type;
-	u8 device;
-	u8 busno;
-	u8 function;
-	int rc;
-	unsigned int devfn;
-	u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
-
-	debug ("%s - enter\n", __FUNCTION__);
-
-	device = slot_cur->device;
-	busno = slot_cur->bus;
-
-	debug ("b4 for loop, device is %x\n", device);
-	/* For every function on the card */
-	for (function = 0x0; function < 0x08; function++) {
-		devfn = PCI_DEVFN(device, function);
-		ibmphp_pci_bus->number = busno;
-
-		pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
-
-		if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
-			/* found correct device!!! */
-			++valid_device;
-
-			debug ("%s - found correct device\n", __FUNCTION__);
-
-			/* header: x x x x x x x x
-			 *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
-			 *         |_=> 0 = single function device, 1 = multi-function device
-			 */
-
-			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
-			pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
-
-			debug ("hdr_type %x, class %x\n", hdr_type, class);
-			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
-			if (class == PCI_CLASS_NOT_DEFINED_VGA) {
-				err ("The device %x function %x is VGA compatible and is not supported for hot removing. "
-				     "Please choose another device.\n", device, function);
-				return -ENODEV;
-			} else if (class == PCI_CLASS_DISPLAY_VGA) {
-				err ("The device %x function %x is not supported for hot removing. "
-				     "Please choose another device.\n", device, function);
-				return -ENODEV;
-			}
-
-			switch (hdr_type) {
-				case PCI_HEADER_TYPE_NORMAL:
-					rc = unconfigure_boot_device (busno, device, function);
-					if (rc) {
-						err ("was not able to unconfigure device %x func %x on bus %x. bailing out... \n",
-						     device, function, busno);
-						return rc;
-					}
-					function = 0x8;
-					break;
-				case PCI_HEADER_TYPE_MULTIDEVICE:
-					rc = unconfigure_boot_device (busno, device, function);
-					if (rc) {
-						err ("was not able to unconfigure device %x func %x on bus %x. bailing out... \n",
-						     device, function, busno);
-						return rc;
-					}
-					break;
-				case PCI_HEADER_TYPE_BRIDGE:
-					class >>= 8;
-					if (class != PCI_CLASS_BRIDGE_PCI) {
-						err ("This device %x function %x is not PCI-to-PCI bridge, "
-						     "and is not supported for hot-removing. "
-						     "Please try another card.\n", device, function);
-						return -ENODEV;
-					}
-					rc = unconfigure_boot_bridge (busno, device, function);
-					if (rc != 0) {
-						err ("was not able to hot-remove PPB properly.\n");
-						return rc;
-					}
-
-					function = 0x8;
-					break;
-				case PCI_HEADER_TYPE_MULTIBRIDGE:
-					class >>= 8;
-					if (class != PCI_CLASS_BRIDGE_PCI) {
-						err ("This device %x function %x is not PCI-to-PCI bridge, "
-						     "and is not supported for hot-removing. "
-						     "Please try another card.\n", device, function);
-						return -ENODEV;
-					}
-					rc = unconfigure_boot_bridge (busno, device, function);
-					if (rc != 0) {
-						err ("was not able to hot-remove PPB properly.\n");
-						return rc;
-					}
-					break;
-				default:
-					err ("MAJOR PROBLEM!!!! Cannot read device's header \n");
-					return -1;
-					break;
-			}	/* end of switch */
-		}	/* end of valid device */
-	}	/* end of for */
-
-	if (!valid_device) {
-		err ("Could not find device to unconfigure.  Or could not read the card. \n");
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * free the resources of the card (multi, single, or bridged)
- * Parameters: slot, flag to say if this is for removing entire module or just
- * unconfiguring the device
- * TO DO:  will probably need to add some code in case there was some resource,
- * to remove it... this is from when we have errors in the configure_card...
- * 			!!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!!
- * Returns: 0, -1, -ENODEV 
- */
-int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
-{
-	int i;
-	int count;
-	int rc;
-	struct slot *sl = *slot_cur;
-	struct pci_func *cur_func = NULL;
-	struct pci_func *temp_func;
-
-	debug ("%s - enter\n", __FUNCTION__);
-
-	if (!the_end) {
-		/* Need to unconfigure the card */
-		rc = unconfigure_boot_card (sl);
-		if ((rc == -ENODEV) || (rc == -EIO) || (rc == -EINVAL)) {
-			/* In all other cases, will still need to get rid of func structure if it exists */
-			return rc;
-		}
-	}
-
-	if (sl->func) {
-		cur_func = sl->func;
-		while (cur_func) {
-			/* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
-			if (cur_func->bus) {
-				/* in other words, it's a PPB */
-				count = 2;
-			} else {
-				count = 6;
-			}
-
-			for (i = 0; i < count; i++) {
-				if (cur_func->io[i]) {
-					debug ("io[%d] exists \n", i);
-					if (the_end > 0)
-						ibmphp_remove_resource (cur_func->io[i]);
-					cur_func->io[i] = NULL;
-				}
-				if (cur_func->mem[i]) {
-					debug ("mem[%d] exists \n", i);
-					if (the_end > 0)
-						ibmphp_remove_resource (cur_func->mem[i]);
-					cur_func->mem[i] = NULL;
-				}
-				if (cur_func->pfmem[i]) {
-					debug ("pfmem[%d] exists \n", i);
-					if (the_end > 0)
-						ibmphp_remove_resource (cur_func->pfmem[i]);
-					cur_func->pfmem[i] = NULL;
-				}
-			}
-
-			temp_func = cur_func->next;
-			kfree (cur_func);
-			cur_func = temp_func;
-		}
-	}
-
-	sl->func = NULL;
-	*slot_cur = sl;
-	debug ("%s - exit\n", __FUNCTION__);
-	return 0;
-}
-
-/*
- * add a new bus resulting from hot-plugging a PPB bridge with devices
- *
- * Input: bus and the amount of resources needed (we know we can assign those,
- *        since they've been checked already
- * Output: bus added to the correct spot
- *         0, -1, error 
- */
-static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)
-{
-	struct range_node *io_range = NULL;
-	struct range_node *mem_range = NULL;
-	struct range_node *pfmem_range = NULL;
-	struct bus_node *cur_bus = NULL;
-
-	/* Trying to find the parent bus number */
-	if (parent_busno != 0xFF) {
-		cur_bus	= ibmphp_find_res_bus (parent_busno);
-		if (!cur_bus) {
-			err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
-			return -ENODEV;
-		}
-	
-		list_add (&bus->bus_list, &cur_bus->bus_list);
-	}
-	if (io) {
-		io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-		if (!io_range) {
-			err ("out of system memory \n");
-			return -ENOMEM;
-		}
-		memset (io_range, 0, sizeof (struct range_node));
-		io_range->start = io->start;
-		io_range->end = io->end;
-		io_range->rangeno = 1;
-		bus->noIORanges = 1;
-		bus->rangeIO = io_range;
-	}
-	if (mem) {
-		mem_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-		if (!mem_range) {
-			err ("out of system memory \n");
-			return -ENOMEM;
-		}
-		memset (mem_range, 0, sizeof (struct range_node));
-		mem_range->start = mem->start;
-		mem_range->end = mem->end;
-		mem_range->rangeno = 1;
-		bus->noMemRanges = 1;
-		bus->rangeMem = mem_range;
-	}
-	if (pfmem) {
-		pfmem_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-		if (!pfmem_range) {	
-			err ("out of system memory \n");
-			return -ENOMEM;
-		}
-		memset (pfmem_range, 0, sizeof (struct range_node));
-		pfmem_range->start = pfmem->start;
-		pfmem_range->end = pfmem->end;
-		pfmem_range->rangeno = 1;
-		bus->noPFMemRanges = 1;
-		bus->rangePFMem = pfmem_range;
-	}
-	return 0;
-}
-
-/*
- * find the 1st available bus number for PPB to set as its secondary bus
- * Parameters: bus_number of the primary bus
- * Returns: bus_number of the secondary bus or 0xff in case of failure
- */
-static u8 find_sec_number (u8 primary_busno, u8 slotno)
-{
-	int min, max;
-	u8 busno;
-	struct bus_info *bus;
-	struct bus_node *bus_cur;
-
-	bus = ibmphp_find_same_bus_num (primary_busno);
-	if (!bus) {
-		err ("cannot get slot range of the bus from the BIOS\n");
-		return 0xff;
-	}
-	max = bus->slot_max;
-	min = bus->slot_min;
-	if ((slotno > max) || (slotno < min)) {
-		err ("got the wrong range\n");
-		return 0xff;
-	}
-	busno = (u8) (slotno - (u8) min);
-	busno += primary_busno + 0x01;
-	bus_cur = ibmphp_find_res_bus (busno);
-	/* either there is no such bus number, or there are no ranges, which
-	 * can only happen if we removed the bridged device in previous load
-	 * of the driver, and now only have the skeleton bus struct
-	 */
-	if ((!bus_cur) || (!(bus_cur->rangeIO) && !(bus_cur->rangeMem) && !(bus_cur->rangePFMem)))
-		return busno;
-	return 0xff;
-}
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/ibmphp_res.c linux-2.5.70-bk10/drivers/hotplug/ibmphp_res.c
--- linux-2.5.70-bk9/drivers/hotplug/ibmphp_res.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/ibmphp_res.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,2157 +0,0 @@
-/*
- * IBM Hot Plug Controller Driver
- *
- * Written By: Irene Zubarev, IBM Corporation
- *
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001,2002 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gregkh@us.ibm.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/list.h>
-#include <linux/init.h>
-#include "ibmphp.h"
-
-static int flags = 0;		/* for testing */
-
-static void update_resources (struct bus_node *bus_cur, int type, int rangeno);
-static int once_over (void);
-static int remove_ranges (struct bus_node *, struct bus_node *);
-static int update_bridge_ranges (struct bus_node **);
-static int add_range (int type, struct range_node *, struct bus_node *);
-static void fix_resources (struct bus_node *);
-static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
-
-static LIST_HEAD(gbuses);
-LIST_HEAD(ibmphp_res_head);
-
-static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 busno, int flag)
-{
-	struct bus_node * newbus;
-
-	if (!(curr) && !(flag)) {
-		err ("NULL pointer passed \n");
-		return NULL;
-	}
-
-	newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
-	if (!newbus) {
-		err ("out of system memory \n");
-		return NULL;
-	}
-
-	memset (newbus, 0, sizeof (struct bus_node));
-	if (flag)
-		newbus->busno = busno;
-	else
-		newbus->busno = curr->bus_num;
-	list_add_tail (&newbus->bus_list, &gbuses);
-	return newbus;
-}
-
-static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr)
-{
-	struct resource_node *rs;
-	
-	if (!curr) {
-		err ("NULL passed to allocate \n");
-		return NULL;
-	}
-
-	rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-	if (!rs) {
-		err ("out of system memory \n");
-		return NULL;
-	}
-	memset (rs, 0, sizeof (struct resource_node));
-	rs->busno = curr->bus_num;
-	rs->devfunc = curr->dev_fun;
-	rs->start = curr->start_addr;
-	rs->end = curr->end_addr;
-	rs->len = curr->end_addr - curr->start_addr + 1;
-	return rs;
-}
-
-static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
-{
-	struct bus_node * newbus;
-	struct range_node *newrange;
-	u8 num_ranges = 0;
-
-	if (first_bus) {
-		newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
-		if (!newbus) {
-			err ("out of system memory. \n");
-			return -ENOMEM;
-		}
-		memset (newbus, 0, sizeof (struct bus_node));
-		newbus->busno = curr->bus_num;
-	} else {
-		newbus = *new_bus;
-		switch (flag) {
-			case MEM:
-				num_ranges = newbus->noMemRanges;
-				break;
-			case PFMEM:
-				num_ranges = newbus->noPFMemRanges;
-				break;
-			case IO:
-				num_ranges = newbus->noIORanges;
-				break;
-		}
-	}
-
-	newrange = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-	if (!newrange) {
-		if (first_bus)
-			kfree (newbus);
-		err ("out of system memory \n");
-		return -ENOMEM;
-	}
-	memset (newrange, 0, sizeof (struct range_node));
-	newrange->start = curr->start_addr;
-	newrange->end = curr->end_addr;
-		
-	if (first_bus || (!num_ranges))
-		newrange->rangeno = 1;
-	else {
-		/* need to insert our range */
-		add_range (flag, newrange, newbus);
-		debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
-	}
-
-	switch (flag) {
-		case MEM:
-			newbus->rangeMem = newrange;
-			if (first_bus)
-				newbus->noMemRanges = 1;
-			else {
-				debug ("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-				++newbus->noMemRanges;
-				fix_resources (newbus);
-			}
-			break;
-		case IO:
-			newbus->rangeIO = newrange;
-			if (first_bus)
-				newbus->noIORanges = 1;
-			else {
-				debug ("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-				++newbus->noIORanges;
-				fix_resources (newbus);
-			}
-			break;
-		case PFMEM:
-			newbus->rangePFMem = newrange;
-			if (first_bus)
-				newbus->noPFMemRanges = 1;
-			else {	
-				debug ("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-				++newbus->noPFMemRanges;
-				fix_resources (newbus);
-			}
-
-			break;
-	}
-
-	*new_bus = newbus;
-	*new_range = newrange;
-	return 0;
-}
-
-
-/* Notes:
- * 1. The ranges are ordered.  The buses are not ordered.  (First come)
- *
- * 2. If cannot allocate out of PFMem range, allocate from Mem ranges.  PFmemFromMem
- * are not sorted. (no need since use mem node). To not change the entire code, we
- * also add mem node whenever this case happens so as not to change
- * ibmphp_check_mem_resource etc (and since it really is taking Mem resource)
- */
-
-/*****************************************************************************
- * This is the Resource Management initialization function.  It will go through
- * the Resource list taken from EBDA and fill in this module's data structures
- *
- * THIS IS NOT TAKING INTO CONSIDERATION IO RESTRICTIONS OF PRIMARY BUSES, 
- * SINCE WE'RE GOING TO ASSUME FOR NOW WE DON'T HAVE THOSE ON OUR BUSES FOR NOW
- *
- * Input: ptr to the head of the resource list from EBDA
- * Output: 0, -1 or error codes
- ***************************************************************************/
-int __init ibmphp_rsrc_init (void)
-{
-	struct ebda_pci_rsrc *curr;
-	struct range_node *newrange = NULL;
-	struct bus_node *newbus = NULL;
-	struct bus_node *bus_cur;
-	struct bus_node *bus_prev;
-	struct list_head *tmp;
-	struct resource_node *new_io = NULL;
-	struct resource_node *new_mem = NULL;
-	struct resource_node *new_pfmem = NULL;
-	int rc;
-	struct list_head *tmp_ebda;
-
-	list_for_each (tmp_ebda, &ibmphp_ebda_pci_rsrc_head) {
-		curr = list_entry (tmp_ebda, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
-		if (!(curr->rsrc_type & PCIDEVMASK)) {
-			/* EBDA still lists non PCI devices, so ignore... */
-			debug ("this is not a PCI DEVICE in rsrc_init, please take care\n");
-			// continue;
-		}
-
-		/* this is a primary bus resource */
-		if (curr->rsrc_type & PRIMARYBUSMASK) {
-			/* memory */
-			if ((curr->rsrc_type & RESTYPE) == MMASK) {
-				/* no bus structure exists in place yet */
-				if (list_empty (&gbuses)) {
-					if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
-						return rc;
-					list_add_tail (&newbus->bus_list, &gbuses);
-					debug ("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-				} else {
-					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
-					/* found our bus */
-					if (bus_cur) {
-						rc = alloc_bus_range (&bus_cur, &newrange, curr, MEM, 0);
-						if (rc)
-							return rc;
-					} else {
-						/* went through all the buses and didn't find ours, need to create a new bus node */
-						if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
-							return rc;
-
-						list_add_tail (&newbus->bus_list, &gbuses);
-						debug ("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-					}
-				}
-			} else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
-				/* prefetchable memory */
-				if (list_empty (&gbuses)) {
-					/* no bus structure exists in place yet */
-					if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
-						return rc;
-					list_add_tail (&newbus->bus_list, &gbuses);
-					debug ("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-				} else {
-					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
-					if (bus_cur) {
-						/* found our bus */
-						rc = alloc_bus_range (&bus_cur, &newrange, curr, PFMEM, 0);
-						if (rc)
-							return rc;
-					} else {
-						/* went through all the buses and didn't find ours, need to create a new bus node */
-						if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
-							return rc;
-						list_add_tail (&newbus->bus_list, &gbuses);
-						debug ("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-					}
-				}
-			} else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
-				/* IO */
-				if (list_empty (&gbuses)) {
-					/* no bus structure exists in place yet */
-					if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
-						return rc;
-					list_add_tail (&newbus->bus_list, &gbuses);
-					debug ("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-				} else {
-					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
-					if (bus_cur) {
-						rc = alloc_bus_range (&bus_cur, &newrange, curr, IO, 0);
-						if (rc)
-							return rc;
-					} else {
-						/* went through all the buses and didn't find ours, need to create a new bus node */
-						if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
-							return rc;
-						list_add_tail (&newbus->bus_list, &gbuses);
-						debug ("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
-					}
-				}
-
-			} else {
-				;	/* type is reserved  WHAT TO DO IN THIS CASE???
-					   NOTHING TO DO??? */
-			}
-		} else {
-			/* regular pci device resource */
-			if ((curr->rsrc_type & RESTYPE) == MMASK) {
-				/* Memory resource */
-				new_mem = alloc_resources (curr);
-				if (!new_mem)
-					return -ENOMEM;
-				new_mem->type = MEM;
-				/*
-				 * if it didn't find the bus, means PCI dev
-				 * came b4 the Primary Bus info, so need to
-				 * create a bus rangeno becomes a problem...
-				 * assign a -1 and then update once the range
-				 * actually appears...
-				 */
-				if (ibmphp_add_resource (new_mem) < 0) {
-					newbus = alloc_error_bus (curr, 0, 0);
-					if (!newbus)
-						return -ENOMEM;
-					newbus->firstMem = new_mem;
-					++newbus->needMemUpdate;
-					new_mem->rangeno = -1;
-				}
-				debug ("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
-
-			} else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
-				/* PFMemory resource */
-				new_pfmem = alloc_resources (curr);
-				if (!new_pfmem)
-					return -ENOMEM;
-				new_pfmem->type = PFMEM;
-				new_pfmem->fromMem = FALSE;
-				if (ibmphp_add_resource (new_pfmem) < 0) {
-					newbus = alloc_error_bus (curr, 0, 0);
-					if (!newbus)
-						return -ENOMEM;
-					newbus->firstPFMem = new_pfmem;
-					++newbus->needPFMemUpdate;
-					new_pfmem->rangeno = -1;
-				}
-
-				debug ("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
-			} else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
-				/* IO resource */
-				new_io = alloc_resources (curr);
-				if (!new_io)
-					return -ENOMEM;
-				new_io->type = IO;
-
-				/*
-				 * if it didn't find the bus, means PCI dev
-				 * came b4 the Primary Bus info, so need to
-				 * create a bus rangeno becomes a problem...
-				 * Can assign a -1 and then update once the
-				 * range actually appears...
-				 */
-				if (ibmphp_add_resource (new_io) < 0) {
-					newbus = alloc_error_bus (curr, 0, 0);
-					if (!newbus)
-						return -ENOMEM;
-					newbus->firstIO = new_io;
-					++newbus->needIOUpdate;
-					new_io->rangeno = -1;
-				}
-				debug ("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
-			}
-		}
-	}
-
-	list_for_each (tmp, &gbuses) {
-		bus_cur = list_entry (tmp, struct bus_node, bus_list);
-		/* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
-		rc = update_bridge_ranges (&bus_cur);
-		if (rc)
-			return rc;
-	}
-	rc = once_over ();  /* This is to align ranges (so no -1) */
-	if (rc)
-		return rc;
-	return 0;
-}
-
-/********************************************************************************
- * This function adds a range into a sorted list of ranges per bus for a particular
- * range type, it then calls another routine to update the range numbers on the
- * pci devices' resources for the appropriate resource
- *
- * Input: type of the resource, range to add, current bus
- * Output: 0 or -1, bus and range ptrs 
- ********************************************************************************/
-static int add_range (int type, struct range_node *range, struct bus_node *bus_cur)
-{
-	struct range_node *range_cur = NULL;
-	struct range_node *range_prev;
-	int count = 0, i_init;
-	int noRanges = 0;
-
-	switch (type) {
-		case MEM:
-			range_cur = bus_cur->rangeMem;
-			noRanges = bus_cur->noMemRanges;
-			break;
-		case PFMEM:
-			range_cur = bus_cur->rangePFMem;
-			noRanges = bus_cur->noPFMemRanges;
-			break;
-		case IO:
-			range_cur = bus_cur->rangeIO;
-			noRanges = bus_cur->noIORanges;
-			break;
-	}
-
-	range_prev = NULL;
-	while (range_cur) {
-		if (range->start < range_cur->start)
-			break;
-		range_prev = range_cur;
-		range_cur = range_cur->next;
-		count = count + 1;
-	}
-	if (!count) {
-		/* our range will go at the beginning of the list */
-		switch (type) {
-			case MEM:
-				bus_cur->rangeMem = range;
-				break;
-			case PFMEM:
-				bus_cur->rangePFMem = range;
-				break;
-			case IO:
-				bus_cur->rangeIO = range;
-				break;
-		}
-		range->next = range_cur;
-		range->rangeno = 1;
-		i_init = 0;
-	} else if (!range_cur) {
-		/* our range will go at the end of the list */
-		range->next = NULL;
-		range_prev->next = range;
-		range->rangeno = range_prev->rangeno + 1;
-		return 0;
-	} else {
-		/* the range is in the middle */
-		range_prev->next = range;
-		range->next = range_cur;
-		range->rangeno = range_cur->rangeno;
-		i_init = range_prev->rangeno;
-	}
-
-	for (count = i_init; count < noRanges; ++count) {
-		++range_cur->rangeno;
-		range_cur = range_cur->next;
-	}
-
-	update_resources (bus_cur, type, i_init + 1);
-	return 0;
-}
-
-/*******************************************************************************
- * This routine goes through the list of resources of type 'type' and updates
- * the range numbers that they correspond to.  It was called from add_range fnc
- *
- * Input: bus, type of the resource, the rangeno starting from which to update
- ******************************************************************************/
-static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
-{
-	struct resource_node *res = NULL;
-	u8 eol = FALSE;	/* end of list indicator */
-
-	switch (type) {
-		case MEM:
-			if (bus_cur->firstMem) 
-				res = bus_cur->firstMem;
-			break;
-		case PFMEM:
-			if (bus_cur->firstPFMem)
-				res = bus_cur->firstPFMem;
-			break;
-		case IO:
-			if (bus_cur->firstIO)
-				res = bus_cur->firstIO;
-			break;
-	}
-
-	if (res) {
-		while (res) {
-			if (res->rangeno == rangeno)
-				break;
-			if (res->next)
-				res = res->next;
-			else if (res->nextRange)
-				res = res->nextRange;
-			else {
-				eol = TRUE;
-				break;
-			}
-		}
-
-		if (!eol) {
-			/* found the range */
-			while (res) {
-				++res->rangeno;
-				res = res->next;
-			}
-		}
-	}
-}
-
-static void fix_me (struct resource_node *res, struct bus_node *bus_cur, struct range_node *range)
-{
-	char * str = "";
-	switch (res->type) {
-		case IO:
-			str = "io";
-			break;
-		case MEM:
-			str = "mem";
-			break;
-		case PFMEM:
-			str = "pfmem";
-			break;
-	}
-
-	while (res) {
-		if (res->rangeno == -1) {
-			while (range) {
-				if ((res->start >= range->start) && (res->end <= range->end)) {
-					res->rangeno = range->rangeno;
-					debug ("%s->rangeno in fix_resources is %d\n", str, res->rangeno);
-					switch (res->type) {
-						case IO:
-							--bus_cur->needIOUpdate;
-							break;
-						case MEM:
-							--bus_cur->needMemUpdate;
-							break;
-						case PFMEM:
-							--bus_cur->needPFMemUpdate;
-							break;
-					}
-					break;
-				}
-				range = range->next;
-			}
-		}
-		if (res->next)
-			res = res->next;
-		else
-			res = res->nextRange;
-	}
-
-}
-
-/*****************************************************************************
- * This routine reassigns the range numbers to the resources that had a -1
- * This case can happen only if upon initialization, resources taken by pci dev
- * appear in EBDA before the resources allocated for that bus, since we don't
- * know the range, we assign -1, and this routine is called after a new range
- * is assigned to see the resources with unknown range belong to the added range
- *
- * Input: current bus
- * Output: none, list of resources for that bus are fixed if can be
- *******************************************************************************/
-static void fix_resources (struct bus_node *bus_cur)
-{
-	struct range_node *range;
-	struct resource_node *res;
-
-	debug ("%s - bus_cur->busno = %d\n", __FUNCTION__, bus_cur->busno);
-
-	if (bus_cur->needIOUpdate) {
-		res = bus_cur->firstIO;
-		range = bus_cur->rangeIO;
-		fix_me (res, bus_cur, range);
-	}
-	if (bus_cur->needMemUpdate) {
-		res = bus_cur->firstMem;
-		range = bus_cur->rangeMem;
-		fix_me (res, bus_cur, range);
-	}
-	if (bus_cur->needPFMemUpdate) {
-		res = bus_cur->firstPFMem;
-		range = bus_cur->rangePFMem;
-		fix_me (res, bus_cur, range);
-	}
-}
-
-/*******************************************************************************
- * This routine adds a resource to the list of resources to the appropriate bus 
- * based on their resource type and sorted by their starting addresses.  It assigns
- * the ptrs to next and nextRange if needed.
- *
- * Input: resource ptr
- * Output: ptrs assigned (to the node)
- * 0 or -1
- *******************************************************************************/
-int ibmphp_add_resource (struct resource_node *res)
-{
-	struct resource_node *res_cur;
-	struct resource_node *res_prev;
-	struct bus_node *bus_cur;
-	struct range_node *range_cur = NULL;
-	struct resource_node *res_start = NULL;
-
-	debug ("%s - enter\n", __FUNCTION__);
-
-	if (!res) {
-		err ("NULL passed to add \n");
-		return -ENODEV;
-	}
-	
-	bus_cur = find_bus_wprev (res->busno, NULL, 0);
-	
-	if (!bus_cur) {
-		/* didn't find a bus, smth's wrong!!! */
-		debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
-		return -ENODEV;
-	}
-
-	/* Normal case */
-	switch (res->type) {
-		case IO:
-			range_cur = bus_cur->rangeIO;
-			res_start = bus_cur->firstIO;
-			break;
-		case MEM:
-			range_cur = bus_cur->rangeMem;
-			res_start = bus_cur->firstMem;
-			break;
-		case PFMEM:
-			range_cur = bus_cur->rangePFMem;
-			res_start = bus_cur->firstPFMem;
-			break;
-		default:
-			err ("cannot read the type of the resource to add... problem \n");
-			return -EINVAL;
-	}
-	while (range_cur) {
-		if ((res->start >= range_cur->start) && (res->end <= range_cur->end)) {
-			res->rangeno = range_cur->rangeno;
-			break;
-		}
-		range_cur = range_cur->next;
-	}
-
-	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	 * this is again the case of rangeno = -1
-	 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	 */
-
-	if (!range_cur) {
-		switch (res->type) {
-			case IO:
-				++bus_cur->needIOUpdate;					
-				break;
-			case MEM:
-				++bus_cur->needMemUpdate;
-				break;
-			case PFMEM:
-				++bus_cur->needPFMemUpdate;
-				break;
-		}
-		res->rangeno = -1;
-	}
-	
-	debug ("The range is %d\n", res->rangeno);
-	if (!res_start) {
-		/* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */
-		switch (res->type) {
-			case IO:
-				bus_cur->firstIO = res;					
-				break;
-			case MEM:
-				bus_cur->firstMem = res;
-				break;
-			case PFMEM:
-				bus_cur->firstPFMem = res;
-				break;
-		}	
-		res->next = NULL;
-		res->nextRange = NULL;
-	} else {
-		res_cur = res_start;
-		res_prev = NULL;
-
-		debug ("res_cur->rangeno is %d\n", res_cur->rangeno);
-
-		while (res_cur) {
-			if (res_cur->rangeno >= res->rangeno)
-				break;
-			res_prev = res_cur;
-			if (res_cur->next)
-				res_cur = res_cur->next;
-			else
-				res_cur = res_cur->nextRange;
-		}
-
-		if (!res_cur) {
-			/* at the end of the resource list */
-			debug ("i should be here, [%x - %x]\n", res->start, res->end);
-			res_prev->nextRange = res;
-			res->next = NULL;
-			res->nextRange = NULL;
-		} else if (res_cur->rangeno == res->rangeno) {
-			/* in the same range */
-			while (res_cur) {
-				if (res->start < res_cur->start)
-					break;
-				res_prev = res_cur;
-				res_cur = res_cur->next;
-			}
-			if (!res_cur) {
-				/* the last resource in this range */
-				res_prev->next = res;
-				res->next = NULL;
-				res->nextRange = res_prev->nextRange;
-				res_prev->nextRange = NULL;
-			} else if (res->start < res_cur->start) {
-				/* at the beginning or middle of the range */
-				if (!res_prev)	{
-					switch (res->type) {
-						case IO:
-							bus_cur->firstIO = res;
-							break;
-						case MEM:
-							bus_cur->firstMem = res;
-							break;
-						case PFMEM:
-							bus_cur->firstPFMem = res;
-							break;
-					}
-				} else if (res_prev->rangeno == res_cur->rangeno)
-					res_prev->next = res;
-				else
-					res_prev->nextRange = res;
-
-				res->next = res_cur;
-				res->nextRange = NULL;
-			}
-		} else {
-			/* this is the case where it is 1st occurrence of the range */
-			if (!res_prev) {
-				/* at the beginning of the resource list */
-				res->next = NULL;
-				switch (res->type) {
-					case IO:
-						res->nextRange = bus_cur->firstIO;
-						bus_cur->firstIO = res;
-						break;
-					case MEM:
-						res->nextRange = bus_cur->firstMem;
-						bus_cur->firstMem = res;
-						break;
-					case PFMEM:
-						res->nextRange = bus_cur->firstPFMem;
-						bus_cur->firstPFMem = res;
-						break;
-				}
-			} else if (res_cur->rangeno > res->rangeno) {
-				/* in the middle of the resource list */
-				res_prev->nextRange = res;
-				res->next = NULL;
-				res->nextRange = res_cur;
-			}
-		}
-	}
-
-	debug ("%s - exit\n", __FUNCTION__);
-	return 0;
-}
-
-/****************************************************************************
- * This routine will remove the resource from the list of resources
- *
- * Input: io, mem, and/or pfmem resource to be deleted
- * Ouput: modified resource list
- *        0 or error code
- ****************************************************************************/
-int ibmphp_remove_resource (struct resource_node *res)
-{
-	struct bus_node *bus_cur;
-	struct resource_node *res_cur = NULL;
-	struct resource_node *res_prev;
-	struct resource_node *mem_cur;
-	char * type = "";
-
-	if (!res)  {
-		err ("resource to remove is NULL \n");
-		return -ENODEV;
-	}
-
-	bus_cur = find_bus_wprev (res->busno, NULL, 0);
-
-	if (!bus_cur) {
-		err ("cannot find corresponding bus of the io resource to remove  "
-			"bailing out...\n");
-		return -ENODEV;
-	}
-
-	switch (res->type) {
-		case IO:
-			res_cur = bus_cur->firstIO;
-			type = "io";
-			break;
-		case MEM:
-			res_cur = bus_cur->firstMem;
-			type = "mem";
-			break;
-		case PFMEM:
-			res_cur = bus_cur->firstPFMem;
-			type = "pfmem";
-			break;
-		default:
-			err ("unknown type for resource to remove \n");
-			return -EINVAL;
-	}
-	res_prev = NULL;
-
-	while (res_cur) {
-		if ((res_cur->start == res->start) && (res_cur->end == res->end))
-			break;
-		res_prev = res_cur;
-		if (res_cur->next)
-			res_cur = res_cur->next;
-		else
-			res_cur = res_cur->nextRange;
-	}
-
-	if (!res_cur) {
-		if (res->type == PFMEM) {
-			/* 
-			 * case where pfmem might be in the PFMemFromMem list
-			 * so will also need to remove the corresponding mem
-			 * entry
-			 */
-			res_cur = bus_cur->firstPFMemFromMem;
-			res_prev = NULL;
-
-			while (res_cur) {
-				if ((res_cur->start == res->start) && (res_cur->end == res->end)) {
-					mem_cur = bus_cur->firstMem;
-					while (mem_cur) {
-						if ((mem_cur->start == res_cur->start)
-						    && (mem_cur->end == res_cur->end))
-							break;
-						if (mem_cur->next)
-							mem_cur = mem_cur->next;
-						else
-							mem_cur = mem_cur->nextRange;
-					}
-					if (!mem_cur) {
-						err ("cannot find corresponding mem node for pfmem...\n");
-						return -EINVAL;
-					}
-
-					ibmphp_remove_resource (mem_cur);
-					if (!res_prev)
-						bus_cur->firstPFMemFromMem = res_cur->next;
-					else
-						res_prev->next = res_cur->next;
-					kfree (res_cur);
-					return 0;
-				}
-				res_prev = res_cur;
-				if (res_cur->next)
-					res_cur = res_cur->next;
-				else
-					res_cur = res_cur->nextRange;
-			}
-			if (!res_cur) {
-				err ("cannot find pfmem to delete...\n");
-				return -EINVAL;
-			}
-		} else {
-			err ("the %s resource is not in the list to be deleted...\n", type);
-			return -EINVAL;
-		}
-	}
-	if (!res_prev) {
-		/* first device to be deleted */
-		if (res_cur->next) {
-			switch (res->type) {
-				case IO:
-					bus_cur->firstIO = res_cur->next;
-					break;
-				case MEM:
-					bus_cur->firstMem = res_cur->next;
-					break;
-				case PFMEM:
-					bus_cur->firstPFMem = res_cur->next;
-					break;
-			}
-		} else if (res_cur->nextRange) {
-			switch (res->type) {
-				case IO:
-					bus_cur->firstIO = res_cur->nextRange;
-					break;
-				case MEM:
-					bus_cur->firstMem = res_cur->nextRange;
-					break;
-				case PFMEM:
-					bus_cur->firstPFMem = res_cur->nextRange;
-					break;
-			}
-		} else {
-			switch (res->type) {
-				case IO:
-					bus_cur->firstIO = NULL;
-					break;
-				case MEM:
-					bus_cur->firstMem = NULL;
-					break;
-				case PFMEM:
-					bus_cur->firstPFMem = NULL;
-					break;
-			}
-		}
-		kfree (res_cur);
-		return 0;
-	} else {
-		if (res_cur->next) {
-			if (res_prev->rangeno == res_cur->rangeno)
-				res_prev->next = res_cur->next;
-			else
-				res_prev->nextRange = res_cur->next;
-		} else if (res_cur->nextRange) {
-			res_prev->next = NULL;
-			res_prev->nextRange = res_cur->nextRange;
-		} else {
-			res_prev->next = NULL;
-			res_prev->nextRange = NULL;
-		}
-		kfree (res_cur);
-		return 0;
-	}
-
-	return 0;
-}
-
-static struct range_node * find_range (struct bus_node *bus_cur, struct resource_node * res)
-{
-	struct range_node * range = NULL;
-
-	switch (res->type) {
-		case IO:
-			range = bus_cur->rangeIO;
-			break;
-		case MEM:
-			range = bus_cur->rangeMem;
-			break;
-		case PFMEM:
-			range = bus_cur->rangePFMem;
-			break;
-		default:
-			err ("cannot read resource type in find_range \n");
-	}
-
-	while (range) {
-		if (res->rangeno == range->rangeno)
-			break;
-		range = range->next;
-	}
-	return range;
-}
-
-/*****************************************************************************
- * This routine will check to make sure the io/mem/pfmem->len that the device asked for 
- * can fit w/i our list of available IO/MEM/PFMEM resources.  If cannot, returns -EINVAL,
- * otherwise, returns 0
- *
- * Input: resource
- * Ouput: the correct start and end address are inputted into the resource node,
- *        0 or -EINVAL
- *****************************************************************************/
-int ibmphp_check_resource (struct resource_node *res, u8 bridge)
-{
-	struct bus_node *bus_cur;
-	struct range_node *range = NULL;
-	struct resource_node *res_prev;
-	struct resource_node *res_cur = NULL;
-	u32 len_cur = 0, start_cur = 0, len_tmp = 0;
-	int noranges = 0;
-	u32 tmp_start;		/* this is to make sure start address is divisible by the length needed */
-	u32 tmp_divide;
-	u8 flag = FALSE;
-
-	if (!res)
-		return -EINVAL;
-
-	if (bridge) {
-		/* The rules for bridges are different, 4K divisible for IO, 1M for (pf)mem*/
-		if (res->type == IO)
-			tmp_divide = IOBRIDGE;
-		else
-			tmp_divide = MEMBRIDGE;
-	} else
-		tmp_divide = res->len;
-
-	bus_cur = find_bus_wprev (res->busno, NULL, 0);
-
-	if (!bus_cur) {
-		/* didn't find a bus, smth's wrong!!! */
-		debug ("no bus in the system, either pci_dev's wrong or allocation failed \n");
-		return -EINVAL;
-	}
-
-	debug ("%s - enter\n", __FUNCTION__);
-	debug ("bus_cur->busno is %d\n", bus_cur->busno);
-
-	/* This is a quick fix to not mess up with the code very much.  i.e.,
-	 * 2000-2fff, len = 1000, but when we compare, we need it to be fff */
-	res->len -= 1;
-
-	switch (res->type) {
-		case IO:
-			res_cur = bus_cur->firstIO;
-			noranges = bus_cur->noIORanges;
-			break;
-		case MEM:
-			res_cur = bus_cur->firstMem;
-			noranges = bus_cur->noMemRanges;
-			break;
-		case PFMEM:
-			res_cur = bus_cur->firstPFMem;
-			noranges = bus_cur->noPFMemRanges;
-			break;
-		default:
-			err ("wrong type of resource to check \n");
-			return -EINVAL;
-	}
-	res_prev = NULL;
-
-	while (res_cur) {
-		range = find_range (bus_cur, res_cur);
-		debug ("%s - rangeno = %d\n", __FUNCTION__, res_cur->rangeno);
-
-		if (!range) {
-			err ("no range for the device exists... bailing out...\n");
-			return -EINVAL;
-		}
-
-		/* found our range */
-		if (!res_prev) {
-			/* first time in the loop */
-			if ((res_cur->start != range->start) && ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
-				debug ("len_tmp = %x\n", len_tmp);
-
-				if ((len_tmp < len_cur) || (len_cur == 0)) {
-
-					if ((range->start % tmp_divide) == 0) {
-						/* just perfect, starting address is divisible by length */
-						flag = TRUE;
-						len_cur = len_tmp;
-						start_cur = range->start;
-					} else {
-						/* Needs adjusting */
-						tmp_start = range->start;
-						flag = FALSE;
-
-						while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
-							if ((tmp_start % tmp_divide) == 0) {
-								flag = TRUE;
-								len_cur = len_tmp;
-								start_cur = tmp_start;
-								break;
-							}
-							tmp_start += tmp_divide - tmp_start % tmp_divide;
-							if (tmp_start >= res_cur->start - 1)
-								break;
-						}
-					}
-			
-					if (flag && len_cur == res->len) {
-						debug ("but we are not here, right?\n");
-						res->start = start_cur;
-						res->len += 1; /* To restore the balance */
-						res->end = res->start + res->len - 1;
-						return 0;
-					}
-				}
-			}
-		}
-		if (!res_cur->next) {
-			/* last device on the range */
-			if ((range->end != res_cur->end) && ((len_tmp = range->end - (res_cur->end + 1)) >= res->len)) {
-				debug ("len_tmp = %x\n", len_tmp);
-				if ((len_tmp < len_cur) || (len_cur == 0)) {
-
-					if (((res_cur->end + 1) % tmp_divide) == 0) {
-						/* just perfect, starting address is divisible by length */
-						flag = TRUE;
-						len_cur = len_tmp;
-						start_cur = res_cur->end + 1;
-					} else {
-						/* Needs adjusting */
-						tmp_start = res_cur->end + 1;
-						flag = FALSE;
-
-						while ((len_tmp = range->end - tmp_start) >= res->len) {
-							if ((tmp_start % tmp_divide) == 0) {
-								flag = TRUE;
-								len_cur = len_tmp;
-								start_cur = tmp_start;
-								break;
-							}
-							tmp_start += tmp_divide - tmp_start % tmp_divide;
-							if (tmp_start >= range->end)
-								break;
-						}
-					}
-					if (flag && len_cur == res->len) {
-						res->start = start_cur;
-						res->len += 1; /* To restore the balance */
-						res->end = res->start + res->len - 1;
-						return 0;
-					}
-				}
-			}
-		}
-
-		if (res_prev) {
-			if (res_prev->rangeno != res_cur->rangeno) {
-				/* 1st device on this range */
-				if ((res_cur->start != range->start) && 
-					((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
-					if ((len_tmp < len_cur) || (len_cur == 0)) {
-						if ((range->start % tmp_divide) == 0) {	
-							/* just perfect, starting address is divisible by length */
-							flag = TRUE;
-							len_cur = len_tmp;
-							start_cur = range->start;
-						} else {
-							/* Needs adjusting */
-							tmp_start = range->start;
-							flag = FALSE;
-
-							while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
-								if ((tmp_start % tmp_divide) == 0) {
-									flag = TRUE;
-									len_cur = len_tmp;
-									start_cur = tmp_start;
-									break;
-								}
-								tmp_start += tmp_divide - tmp_start % tmp_divide;
-								if (tmp_start >= res_cur->start - 1)
-									break;
-							}
-						}
-
-						if (flag && len_cur == res->len) {
-							res->start = start_cur;
-							res->len += 1; /* To restore the balance */
-							res->end = res->start + res->len - 1;
-							return 0;
-						}
-					}
-				}
-			} else {
-				/* in the same range */
-				if ((len_tmp = res_cur->start - 1 - res_prev->end - 1) >= res->len) {
-					if ((len_tmp < len_cur) || (len_cur == 0)) {
-						if (((res_prev->end + 1) % tmp_divide) == 0) {
-							/* just perfect, starting address's divisible by length */
-							flag = TRUE;
-							len_cur = len_tmp;
-							start_cur = res_prev->end + 1;
-						} else {
-							/* Needs adjusting */
-							tmp_start = res_prev->end + 1;
-							flag = FALSE;
-
-							while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
-								if ((tmp_start % tmp_divide) == 0) {
-									flag = TRUE;
-									len_cur = len_tmp;
-									start_cur = tmp_start;
-									break;
-								}
-								tmp_start += tmp_divide - tmp_start % tmp_divide;
-								if (tmp_start >= res_cur->start - 1)
-									break;
-							}
-						}
-
-						if (flag && len_cur == res->len) {
-							res->start = start_cur;
-							res->len += 1; /* To restore the balance */
-							res->end = res->start + res->len - 1;
-							return 0;
-						}
-					}
-				}
-			}
-		}
-		/* end if (res_prev) */
-		res_prev = res_cur;
-		if (res_cur->next)
-			res_cur = res_cur->next;
-		else
-			res_cur = res_cur->nextRange;
-	}	/* end of while */
-
-
-	if (!res_prev) {
-		/* 1st device ever */
-		/* need to find appropriate range */
-		switch (res->type) {
-			case IO:
-				range = bus_cur->rangeIO;
-				break;
-			case MEM:
-				range = bus_cur->rangeMem;
-				break;
-			case PFMEM:
-				range = bus_cur->rangePFMem;
-				break;
-		}
-		while (range) {
-			if ((len_tmp = range->end - range->start) >= res->len) {
-				if ((len_tmp < len_cur) || (len_cur == 0)) {
-					if ((range->start % tmp_divide) == 0) {
-						/* just perfect, starting address's divisible by length */
-						flag = TRUE;
-						len_cur = len_tmp;
-						start_cur = range->start;
-					} else {
-						/* Needs adjusting */
-						tmp_start = range->start;
-						flag = FALSE;
-
-						while ((len_tmp = range->end - tmp_start) >= res->len) {
-							if ((tmp_start % tmp_divide) == 0) {
-								flag = TRUE;
-								len_cur = len_tmp;
-								start_cur = tmp_start;
-								break;
-							}
-							tmp_start += tmp_divide - tmp_start % tmp_divide;
-							if (tmp_start >= range->end)
-								break;
-						}
-					}
-
-					if (flag && len_cur == res->len) {
-						res->start = start_cur;
-						res->len += 1; /* To restore the balance */
-						res->end = res->start + res->len - 1;
-						return 0;
-					}
-				}
-			}
-			range = range->next;
-		}		/* end of while */
-
-		if ((!range) && (len_cur == 0)) {
-			/* have gone through the list of devices and ranges and haven't found n.e.thing */
-			err ("no appropriate range.. bailing out...\n");
-			return -EINVAL;
-		} else if (len_cur) {
-			res->start = start_cur;
-			res->len += 1; /* To restore the balance */
-			res->end = res->start + res->len - 1;
-			return 0;
-		}
-	}
-
-	if (!res_cur) {
-		debug ("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges);
-		if (res_prev->rangeno < noranges) {
-			/* if there're more ranges out there to check */
-			switch (res->type) {
-				case IO:
-					range = bus_cur->rangeIO;
-					break;
-				case MEM:
-					range = bus_cur->rangeMem;
-					break;
-				case PFMEM:
-					range = bus_cur->rangePFMem;
-					break;
-			}
-			while (range) {
-				if ((len_tmp = range->end - range->start) >= res->len) {
-					if ((len_tmp < len_cur) || (len_cur == 0)) {
-						if ((range->start % tmp_divide) == 0) {
-							/* just perfect, starting address's divisible by length */
-							flag = TRUE;
-							len_cur = len_tmp;
-							start_cur = range->start;
-						} else {
-							/* Needs adjusting */
-							tmp_start = range->start;
-							flag = FALSE;
-
-							while ((len_tmp = range->end - tmp_start) >= res->len) {
-								if ((tmp_start % tmp_divide) == 0) {
-									flag = TRUE;
-									len_cur = len_tmp;
-									start_cur = tmp_start;
-									break;
-								}
-								tmp_start += tmp_divide - tmp_start % tmp_divide;
-								if (tmp_start >= range->end)
-									break;
-							}
-						}
-
-						if (flag && len_cur == res->len) {
-							res->start = start_cur;
-							res->len += 1; /* To restore the balance */
-							res->end = res->start + res->len - 1;
-							return 0;
-						}
-					}
-				}
-				range = range->next;
-			}	/* end of while */
-
-			if ((!range) && (len_cur == 0)) {
-				/* have gone through the list of devices and ranges and haven't found n.e.thing */
-				err ("no appropriate range.. bailing out...\n");
-				return -EINVAL;
-			} else if (len_cur) {
-				res->start = start_cur;
-				res->len += 1; /* To restore the balance */
-				res->end = res->start + res->len - 1;
-				return 0;
-			}
-		} else {
-			/* no more ranges to check on */
-			if (len_cur) {
-				res->start = start_cur;
-				res->len += 1; /* To restore the balance */
-				res->end = res->start + res->len - 1;
-				return 0;
-			} else {
-				/* have gone through the list of devices and haven't found n.e.thing */
-				err ("no appropriate range.. bailing out...\n");
-				return -EINVAL;
-			}
-		}
-	}	/* end if(!res_cur) */
-	return -EINVAL;
-}
-
-/********************************************************************************
- * This routine is called from remove_card if the card contained PPB.
- * It will remove all the resources on the bus as well as the bus itself
- * Input: Bus
- * Ouput: 0, -ENODEV
- ********************************************************************************/
-int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
-{
-	struct resource_node *res_cur;
-	struct resource_node *res_tmp;
-	struct bus_node *prev_bus;
-	int rc;
-
-	prev_bus = find_bus_wprev (parent_busno, NULL, 0);	
-
-	if (!prev_bus) {
-		debug ("something terribly wrong. Cannot find parent bus to the one to remove\n");
-		return -ENODEV;
-	}
-
-	debug ("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno);
-
-	rc = remove_ranges (bus, prev_bus);
-	if (rc)
-		return rc;
-
-	if (bus->firstIO) {
-		res_cur = bus->firstIO;
-		while (res_cur) {
-			res_tmp = res_cur;
-			if (res_cur->next)
-				res_cur = res_cur->next;
-			else
-				res_cur = res_cur->nextRange;
-			kfree (res_tmp);
-			res_tmp = NULL;
-		}
-		bus->firstIO = NULL;
-	}
-	if (bus->firstMem) {
-		res_cur = bus->firstMem;
-		while (res_cur) {
-			res_tmp = res_cur;
-			if (res_cur->next)
-				res_cur = res_cur->next;
-			else
-				res_cur = res_cur->nextRange;
-			kfree (res_tmp);
-			res_tmp = NULL;
-		}
-		bus->firstMem = NULL;
-	}
-	if (bus->firstPFMem) {
-		res_cur = bus->firstPFMem;
-		while (res_cur) {
-			res_tmp = res_cur;
-			if (res_cur->next)
-				res_cur = res_cur->next;
-			else
-				res_cur = res_cur->nextRange;
-			kfree (res_tmp);
-			res_tmp = NULL;
-		}
-		bus->firstPFMem = NULL;
-	}
-
-	if (bus->firstPFMemFromMem) {
-		res_cur = bus->firstPFMemFromMem;
-		while (res_cur) {
-			res_tmp = res_cur;
-			res_cur = res_cur->next;
-
-			kfree (res_tmp);
-			res_tmp = NULL;
-		}
-		bus->firstPFMemFromMem = NULL;
-	}
-
-	list_del (&bus->bus_list);
-	kfree (bus);
-	return 0;
-}
-
-/******************************************************************************
- * This routine deletes the ranges from a given bus, and the entries from the 
- * parent's bus in the resources
- * Input: current bus, previous bus
- * Output: 0, -EINVAL
- ******************************************************************************/
-static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
-{
-	struct range_node *range_cur;
-	struct range_node *range_tmp;
-	int i;
-	struct resource_node *res = NULL;
-
-	if (bus_cur->noIORanges) {
-		range_cur = bus_cur->rangeIO;
-		for (i = 0; i < bus_cur->noIORanges; i++) {
-			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, IO) < 0)
-				return -EINVAL;
-			ibmphp_remove_resource (res);
-
-			range_tmp = range_cur;
-			range_cur = range_cur->next;
-			kfree (range_tmp);
-			range_tmp = NULL;
-		}
-		bus_cur->rangeIO = NULL;
-	}
-	if (bus_cur->noMemRanges) {
-		range_cur = bus_cur->rangeMem;
-		for (i = 0; i < bus_cur->noMemRanges; i++) {
-			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, MEM) < 0) 
-				return -EINVAL;
-
-			ibmphp_remove_resource (res);
-			range_tmp = range_cur;
-			range_cur = range_cur->next;
-			kfree (range_tmp);
-			range_tmp = NULL;
-		}
-		bus_cur->rangeMem = NULL;
-	}
-	if (bus_cur->noPFMemRanges) {
-		range_cur = bus_cur->rangePFMem;
-		for (i = 0; i < bus_cur->noPFMemRanges; i++) {
-			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, PFMEM) < 0) 
-				return -EINVAL;
-
-			ibmphp_remove_resource (res);
-			range_tmp = range_cur;
-			range_cur = range_cur->next;
-			kfree (range_tmp);
-			range_tmp = NULL;
-		}
-		bus_cur->rangePFMem = NULL;
-	}
-	return 0;
-}
-
-/*
- * find the resource node in the bus 
- * Input: Resource needed, start address of the resource, type of resource
- */
-int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
-{
-	struct resource_node *res_cur = NULL;
-	char * type = "";
-
-	if (!bus) {
-		err ("The bus passed in NULL to find resource \n");
-		return -ENODEV;
-	}
-
-	switch (flag) {
-		case IO:
-			res_cur = bus->firstIO;
-			type = "io";
-			break;
-		case MEM:
-			res_cur = bus->firstMem;
-			type = "mem";
-			break;
-		case PFMEM:
-			res_cur = bus->firstPFMem;
-			type = "pfmem";
-			break;
-		default:
-			err ("wrong type of flag \n");
-			return -EINVAL;
-	}
-	
-	while (res_cur) {
-		if (res_cur->start == start_address) {
-			*res = res_cur;
-			break;
-		}
-		if (res_cur->next)
-			res_cur = res_cur->next;
-		else
-			res_cur = res_cur->nextRange;
-	}
-
-	if (!res_cur) {
-		if (flag == PFMEM) {
-			res_cur = bus->firstPFMemFromMem;
-			while (res_cur) {
-				if (res_cur->start == start_address) {
-					*res = res_cur;
-					break;
-				}
-				res_cur = res_cur->next;
-			}
-			if (!res_cur) {
-				debug ("SOS...cannot find %s resource in the bus. \n", type);
-				return -EINVAL;
-			}
-		} else {
-			debug ("SOS... cannot find %s resource in the bus. \n", type);
-			return -EINVAL;
-		}
-	}
-
-	if (*res)
-		debug ("*res->start = %x \n", (*res)->start);
-
-	return 0;
-}
-
-/***********************************************************************
- * This routine will free the resource structures used by the
- * system.  It is called from cleanup routine for the module
- * Parameters: none
- * Returns: none
- ***********************************************************************/
-void ibmphp_free_resources (void)
-{
-	struct bus_node *bus_cur = NULL;
-	struct bus_node *bus_tmp;
-	struct range_node *range_cur;
-	struct range_node *range_tmp;
-	struct resource_node *res_cur;
-	struct resource_node *res_tmp;
-	struct list_head *tmp;
-	struct list_head *next;
-	int i = 0;
-	flags = 1;
-
-	list_for_each_safe (tmp, next, &gbuses) {
-		bus_cur = list_entry (tmp, struct bus_node, bus_list);
-		if (bus_cur->noIORanges) {
-			range_cur = bus_cur->rangeIO;
-			for (i = 0; i < bus_cur->noIORanges; i++) {
-				if (!range_cur)
-					break;
-				range_tmp = range_cur;
-				range_cur = range_cur->next;
-				kfree (range_tmp);
-				range_tmp = NULL;
-			}
-		}
-		if (bus_cur->noMemRanges) {
-			range_cur = bus_cur->rangeMem;
-			for (i = 0; i < bus_cur->noMemRanges; i++) {
-				if (!range_cur)
-					break;
-				range_tmp = range_cur;
-				range_cur = range_cur->next;
-				kfree (range_tmp);
-				range_tmp = NULL;
-			}
-		}
-		if (bus_cur->noPFMemRanges) {
-			range_cur = bus_cur->rangePFMem;
-			for (i = 0; i < bus_cur->noPFMemRanges; i++) {
-				if (!range_cur)
-					break;
-				range_tmp = range_cur;
-				range_cur = range_cur->next;
-				kfree (range_tmp);
-				range_tmp = NULL;
-			}
-		}
-
-		if (bus_cur->firstIO) {
-			res_cur = bus_cur->firstIO;
-			while (res_cur) {
-				res_tmp = res_cur;
-				if (res_cur->next)
-					res_cur = res_cur->next;
-				else
-					res_cur = res_cur->nextRange;
-				kfree (res_tmp);
-				res_tmp = NULL;
-			}
-			bus_cur->firstIO = NULL;
-		}
-		if (bus_cur->firstMem) {
-			res_cur = bus_cur->firstMem;
-			while (res_cur) {
-				res_tmp = res_cur;
-				if (res_cur->next)
-					res_cur = res_cur->next;
-				else
-					res_cur = res_cur->nextRange;
-				kfree (res_tmp);
-				res_tmp = NULL;
-			}
-			bus_cur->firstMem = NULL;
-		}
-		if (bus_cur->firstPFMem) {
-			res_cur = bus_cur->firstPFMem;
-			while (res_cur) {
-				res_tmp = res_cur;
-				if (res_cur->next)
-					res_cur = res_cur->next;
-				else
-					res_cur = res_cur->nextRange;
-				kfree (res_tmp);
-				res_tmp = NULL;
-			}
-			bus_cur->firstPFMem = NULL;
-		}
-
-		if (bus_cur->firstPFMemFromMem) {
-			res_cur = bus_cur->firstPFMemFromMem;
-			while (res_cur) {
-				res_tmp = res_cur;
-				res_cur = res_cur->next;
-
-				kfree (res_tmp);
-				res_tmp = NULL;
-			}
-			bus_cur->firstPFMemFromMem = NULL;
-		}
-
-		bus_tmp = bus_cur;
-		list_del (&bus_cur->bus_list);
-		kfree (bus_tmp);
-		bus_tmp = NULL;
-	}
-}
-
-/*********************************************************************************
- * This function will go over the PFmem resources to check if the EBDA allocated
- * pfmem out of memory buckets of the bus.  If so, it will change the range numbers
- * and a flag to indicate that this resource is out of memory. It will also move the
- * Pfmem out of the pfmem resource list to the PFMemFromMem list, and will create
- * a new Mem node
- * This routine is called right after initialization
- *******************************************************************************/
-static int __init once_over (void)
-{
-	struct resource_node *pfmem_cur;
-	struct resource_node *pfmem_prev;
-	struct resource_node *mem;
-	struct bus_node *bus_cur;
-	struct list_head *tmp;
-
-	list_for_each (tmp, &gbuses) {
-		bus_cur = list_entry (tmp, struct bus_node, bus_list);
-		if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) {
-			for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) {
-				pfmem_cur->fromMem = TRUE;
-				if (pfmem_prev)
-					pfmem_prev->next = pfmem_cur->next;
-				else
-					bus_cur->firstPFMem = pfmem_cur->next;
-
-				if (!bus_cur->firstPFMemFromMem)
-					pfmem_cur->next = NULL;
-				else
-					/* we don't need to sort PFMemFromMem since we're using mem node for
-					   all the real work anyways, so just insert at the beginning of the
-					   list
-					 */
-					pfmem_cur->next = bus_cur->firstPFMemFromMem;
-
-				bus_cur->firstPFMemFromMem = pfmem_cur;
-
-				mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);		
-				if (!mem) {
-					err ("out of system memory \n");
-					return -ENOMEM;
-				}
-				memset (mem, 0, sizeof (struct resource_node));
-				mem->type = MEM;
-				mem->busno = pfmem_cur->busno;
-				mem->devfunc = pfmem_cur->devfunc;
-				mem->start = pfmem_cur->start;
-				mem->end = pfmem_cur->end;
-				mem->len = pfmem_cur->len;
-				if (ibmphp_add_resource (mem) < 0)
-					err ("Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n");
-				pfmem_cur->rangeno = mem->rangeno;
-			}	/* end for pfmem */
-		}	/* end if */
-	}	/* end list_for_each bus */
-	return 0; 
-}
-
-int ibmphp_add_pfmem_from_mem (struct resource_node *pfmem)
-{
-	struct bus_node *bus_cur = find_bus_wprev (pfmem->busno, NULL, 0);
-
-	if (!bus_cur) {
-		err ("cannot find bus of pfmem to add...\n");
-		return -ENODEV;
-	}
-
-	if (bus_cur->firstPFMemFromMem)
-		pfmem->next = bus_cur->firstPFMemFromMem;
-	else
-		pfmem->next = NULL;
-
-	bus_cur->firstPFMemFromMem = pfmem;
-
-	return 0;
-}
-
-/* This routine just goes through the buses to see if the bus already exists.
- * It is called from ibmphp_find_sec_number, to find out a secondary bus number for
- * bridged cards
- * Parameters: bus_number
- * Returns: Bus pointer or NULL
- */
-struct bus_node *ibmphp_find_res_bus (u8 bus_number)
-{
-	return find_bus_wprev (bus_number, NULL, 0);
-}
-
-static inline struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u8 flag)
-{
-	struct bus_node *bus_cur;
-	struct list_head *tmp;
-	struct list_head *tmp_prev;
-
-	list_for_each (tmp, &gbuses) {
-		tmp_prev = tmp->prev;
-		bus_cur = list_entry (tmp, struct bus_node, bus_list);
-		if (flag) 
-			*prev = list_entry (tmp_prev, struct bus_node, bus_list);
-		if (bus_cur->busno == bus_number) 
-			return bus_cur;
-	}
-
-	return NULL;
-}
-
-void ibmphp_print_test (void)
-{
-	int i = 0;
-	struct bus_node *bus_cur = NULL;
-	struct range_node *range;
-	struct resource_node *res;
-	struct list_head *tmp;
-	
-	debug_pci ("*****************START**********************\n");
-
-	if ((!list_empty(&gbuses)) && flags) {
-		err ("The GBUSES is not NULL?!?!?!?!?\n");
-		return;
-	}
-
-	list_for_each (tmp, &gbuses) {
-		bus_cur = list_entry (tmp, struct bus_node, bus_list);
-		debug_pci ("This is bus # %d.  There are \n", bus_cur->busno);
-		debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
-		debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
-		debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
-		debug_pci ("The IO Ranges are as follows:\n");
-		if (bus_cur->rangeIO) {
-			range = bus_cur->rangeIO;
-			for (i = 0; i < bus_cur->noIORanges; i++) {
-				debug_pci ("rangeno is %d\n", range->rangeno);
-				debug_pci ("[%x - %x]\n", range->start, range->end);
-				range = range->next;
-			}
-		}
-
-		debug_pci ("The Mem Ranges are as follows:\n");
-		if (bus_cur->rangeMem) {
-			range = bus_cur->rangeMem;
-			for (i = 0; i < bus_cur->noMemRanges; i++) {
-				debug_pci ("rangeno is %d\n", range->rangeno);
-				debug_pci ("[%x - %x]\n", range->start, range->end);
-				range = range->next;
-			}
-		}
-
-		debug_pci ("The PFMem Ranges are as follows:\n");
-
-		if (bus_cur->rangePFMem) {
-			range = bus_cur->rangePFMem;
-			for (i = 0; i < bus_cur->noPFMemRanges; i++) {
-				debug_pci ("rangeno is %d\n", range->rangeno);
-				debug_pci ("[%x - %x]\n", range->start, range->end);
-				range = range->next;
-			}
-		}
-
-		debug_pci ("The resources on this bus are as follows\n");
-
-		debug_pci ("IO...\n");
-		if (bus_cur->firstIO) {
-			res = bus_cur->firstIO;
-			while (res) {
-				debug_pci ("The range # is %d\n", res->rangeno);
-				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
-				if (res->next)
-					res = res->next;
-				else if (res->nextRange)
-					res = res->nextRange;
-				else
-					break;
-			}
-		}
-		debug_pci ("Mem...\n");
-		if (bus_cur->firstMem) {
-			res = bus_cur->firstMem;
-			while (res) {
-				debug_pci ("The range # is %d\n", res->rangeno);
-				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
-				if (res->next)
-					res = res->next;
-				else if (res->nextRange)
-					res = res->nextRange;
-				else
-					break;
-			}
-		}
-		debug_pci ("PFMem...\n");
-		if (bus_cur->firstPFMem) {
-			res = bus_cur->firstPFMem;
-			while (res) {
-				debug_pci ("The range # is %d\n", res->rangeno);
-				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
-				if (res->next)
-					res = res->next;
-				else if (res->nextRange)
-					res = res->nextRange;
-				else
-					break;
-			}
-		}
-
-		debug_pci ("PFMemFromMem...\n");
-		if (bus_cur->firstPFMemFromMem) {
-			res = bus_cur->firstPFMemFromMem;
-			while (res) {
-				debug_pci ("The range # is %d\n", res->rangeno);
-				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
-				res = res->next;
-			}
-		}
-	}
-	debug_pci ("***********************END***********************\n");
-}
-
-static int range_exists_already (struct range_node * range, struct bus_node * bus_cur, u8 type)
-{
-	struct range_node * range_cur = NULL;
-	switch (type) {
-		case IO:
-			range_cur = bus_cur->rangeIO;
-			break;
-		case MEM:
-			range_cur = bus_cur->rangeMem;
-			break;
-		case PFMEM:
-			range_cur = bus_cur->rangePFMem;
-			break;
-		default:
-			err ("wrong type passed to find out if range already exists \n");
-			return -ENODEV;
-	}
-
-	while (range_cur) {
-		if ((range_cur->start == range->start) && (range_cur->end == range->end))
-			return 1;
-		range_cur = range_cur->next;
-	}
-	
-	return 0;
-}
-
-/* This routine will read the windows for any PPB we have and update the
- * range info for the secondary bus, and will also input this info into
- * primary bus, since BIOS doesn't. This is for PPB that are in the system
- * on bootup.  For bridged cards that were added during previous load of the
- * driver, only the ranges and the bus structure are added, the devices are
- * added from NVRAM
- * Input: primary busno
- * Returns: none
- * Note: this function doesn't take into account IO restrictions etc,
- *	 so will only work for bridges with no video/ISA devices behind them It
- *	 also will not work for onboard PPB's that can have more than 1 *bus
- *	 behind them All these are TO DO.
- *	 Also need to add more error checkings... (from fnc returns etc)
- */
-static int __init update_bridge_ranges (struct bus_node **bus)
-{
-	u8 sec_busno, device, function, hdr_type, start_io_address, end_io_address;
-	u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
-	u32 start_address, end_address, upper_start, upper_end;
-	struct bus_node *bus_sec;
-	struct bus_node *bus_cur;
-	struct resource_node *io;
-	struct resource_node *mem;
-	struct resource_node *pfmem;
-	struct range_node *range;
-	unsigned int devfn;
-
-	bus_cur = *bus;
-	if (!bus_cur)
-		return -ENODEV;
-	ibmphp_pci_bus->number = bus_cur->busno;
-
-	debug ("inside %s \n", __FUNCTION__);
-	debug ("bus_cur->busno = %x\n", bus_cur->busno);
-
-	for (device = 0; device < 32; device++) {
-		for (function = 0x00; function < 0x08; function++) {
-			devfn = PCI_DEVFN(device, function);
-			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
-
-			if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
-				/* found correct device!!! */
-				pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
-
-				switch (hdr_type) {
-					case PCI_HEADER_TYPE_NORMAL:
-						function = 0x8;
-						break;
-					case PCI_HEADER_TYPE_MULTIDEVICE:
-						break;
-					case PCI_HEADER_TYPE_BRIDGE:
-						function = 0x8;
-					case PCI_HEADER_TYPE_MULTIBRIDGE:
-						/* We assume here that only 1 bus behind the bridge 
-						   TO DO: add functionality for several:
-						   temp = secondary;
-						   while (temp < subordinate) {
-						   ...
-						   temp++;
-						   }
-						 */
-						pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno);
-						bus_sec = find_bus_wprev (sec_busno, NULL, 0); 
-						/* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
-						if (!bus_sec) {
-							bus_sec = alloc_error_bus (NULL, sec_busno, 1);
-							/* the rest will be populated during NVRAM call */
-							return 0;
-						}
-						pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address);
-						pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address);
-						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start);
-						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end);
-						start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8;
-						start_address |= (upper_io_start << 16);
-						end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
-						end_address |= (upper_io_end << 16);
-
-						if ((start_address) && (start_address <= end_address)) {
-							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-							if (!range) {
-								err ("out of system memory \n");
-								return -ENOMEM;
-							}
-							memset (range, 0, sizeof (struct range_node));
-							range->start = start_address;
-							range->end = end_address + 0xfff;
-
-							if (bus_sec->noIORanges > 0) {
-								if (!range_exists_already (range, bus_sec, IO)) {
-									add_range (IO, range, bus_sec);
-									++bus_sec->noIORanges;
-								} else {
-									kfree (range);
-									range = NULL;
-								}
-							} else {
-								/* 1st IO Range on the bus */
-								range->rangeno = 1;
-								bus_sec->rangeIO = range;
-								++bus_sec->noIORanges;
-							}
-							fix_resources (bus_sec);
-
-							if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
-								io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);							
-								if (!io) {
-									kfree (range);
-									err ("out of system memory \n");
-									return -ENOMEM;
-								}
-								memset (io, 0, sizeof (struct resource_node));
-								io->type = IO;
-								io->busno = bus_cur->busno;
-								io->devfunc = ((device << 3) | (function & 0x7));
-								io->start = start_address;
-								io->end = end_address + 0xfff;
-								io->len = io->end - io->start + 1;
-								ibmphp_add_resource (io);
-							}
-						}	
-
-						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);
-						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address);
-
-						start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
-						end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
-
-						if ((start_address) && (start_address <= end_address)) {
-
-							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-							if (!range) {
-								err ("out of system memory \n");
-								return -ENOMEM;
-							}
-							memset (range, 0, sizeof (struct range_node));
-							range->start = start_address;
-							range->end = end_address + 0xfffff;
-
-							if (bus_sec->noMemRanges > 0) {
-								if (!range_exists_already (range, bus_sec, MEM)) {
-									add_range (MEM, range, bus_sec);
-									++bus_sec->noMemRanges;
-								} else {
-									kfree (range);
-									range = NULL;
-								}
-							} else {
-								/* 1st Mem Range on the bus */
-								range->rangeno = 1;
-								bus_sec->rangeMem = range;
-								++bus_sec->noMemRanges;
-							}
-
-							fix_resources (bus_sec);
-
-							if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
-								mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-								if (!mem) {
-									kfree (range);
-									err ("out of system memory \n");
-									return -ENOMEM;
-								}
-								memset (mem, 0, sizeof (struct resource_node));
-								mem->type = MEM;
-								mem->busno = bus_cur->busno;
-								mem->devfunc = ((device << 3) | (function & 0x7));
-								mem->start = start_address;
-								mem->end = end_address + 0xfffff;
-								mem->len = mem->end - mem->start + 1;
-								ibmphp_add_resource (mem);
-							}
-						}
-						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
-						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
-						pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start);
-						pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end);
-						start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
-						end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
-#if BITS_PER_LONG == 64
-						start_address |= ((long) upper_start) << 32;
-						end_address |= ((long) upper_end) << 32;
-#endif
-
-						if ((start_address) && (start_address <= end_address)) {
-
-							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-							if (!range) {
-								err ("out of system memory \n");
-								return -ENOMEM;
-							}
-							memset (range, 0, sizeof (struct range_node));
-							range->start = start_address;
-							range->end = end_address + 0xfffff;
-
-							if (bus_sec->noPFMemRanges > 0) {
-								if (!range_exists_already (range, bus_sec, PFMEM)) {
-									add_range (PFMEM, range, bus_sec);
-									++bus_sec->noPFMemRanges;
-								} else {
-									kfree (range);
-									range = NULL;
-								}
-							} else {
-								/* 1st PFMem Range on the bus */
-								range->rangeno = 1;
-								bus_sec->rangePFMem = range;
-								++bus_sec->noPFMemRanges;
-							}
-
-							fix_resources (bus_sec);
-							if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
-								pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-								if (!pfmem) {
-									kfree (range);
-									err ("out of system memory \n");
-									return -ENOMEM;
-								}
-								memset (pfmem, 0, sizeof (struct resource_node));
-								pfmem->type = PFMEM;
-								pfmem->busno = bus_cur->busno;
-								pfmem->devfunc = ((device << 3) | (function & 0x7));
-								pfmem->start = start_address;
-								pfmem->end = end_address + 0xfffff;
-								pfmem->len = pfmem->end - pfmem->start + 1;
-								pfmem->fromMem = FALSE;
-
-								ibmphp_add_resource (pfmem);
-							}
-						}
-						break;
-				}	/* end of switch */
-			}	/* end if vendor */
-		}	/* end for function */
-	}	/* end for device */
-
-	bus = &bus_cur;
-	return 0;
-}
diff -urN linux-2.5.70-bk9/drivers/hotplug/pci_hotplug.h linux-2.5.70-bk10/drivers/hotplug/pci_hotplug.h
--- linux-2.5.70-bk9/drivers/hotplug/pci_hotplug.h	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/pci_hotplug.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,146 +0,0 @@
-/*
- * PCI HotPlug Core Functions
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-#ifndef _PCI_HOTPLUG_H
-#define _PCI_HOTPLUG_H
-
-
-/* These values come from the PCI Hotplug Spec */
-enum pci_bus_speed {
-	PCI_SPEED_33MHz			= 0x00,
-	PCI_SPEED_66MHz			= 0x01,
-	PCI_SPEED_66MHz_PCIX		= 0x02,
-	PCI_SPEED_100MHz_PCIX		= 0x03,
-	PCI_SPEED_133MHz_PCIX		= 0x04,
-	PCI_SPEED_66MHz_PCIX_266	= 0x09,
-	PCI_SPEED_100MHz_PCIX_266	= 0x0a,
-	PCI_SPEED_133MHz_PCIX_266	= 0x0b,
-	PCI_SPEED_66MHz_PCIX_533	= 0x11,
-	PCI_SPEED_100MHz_PCIX_533	= 0X12,
-	PCI_SPEED_133MHz_PCIX_533	= 0x13,
-	PCI_SPEED_UNKNOWN		= 0xff,
-};
-
-struct hotplug_slot;
-struct hotplug_slot_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct hotplug_slot *, char *);
-	ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
-};
-/**
- * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
- * @owner: The module owner of this structure
- * @enable_slot: Called when the user wants to enable a specific pci slot
- * @disable_slot: Called when the user wants to disable a specific pci slot
- * @set_attention_status: Called to set the specific slot's attention LED to
- * the specified value
- * @hardware_test: Called to run a specified hardware test on the specified
- * slot.
- * @get_power_status: Called to get the current power status of a slot.
- * 	If this field is NULL, the value passed in the struct hotplug_slot_info
- * 	will be used when this value is requested by a user.
- * @get_attention_status: Called to get the current attention status of a slot.
- *	If this field is NULL, the value passed in the struct hotplug_slot_info
- *	will be used when this value is requested by a user.
- * @get_latch_status: Called to get the current latch status of a slot.
- *	If this field is NULL, the value passed in the struct hotplug_slot_info
- *	will be used when this value is requested by a user.
- * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
- *	If this field is NULL, the value passed in the struct hotplug_slot_info
- *	will be used when this value is requested by a user.
- * @get_max_bus_speed: Called to get the max bus speed for a slot.
- *	If this field is NULL, the value passed in the struct hotplug_slot_info
- *	will be used when this value is requested by a user.
- * @get_cur_bus_speed: Called to get the current bus speed for a slot.
- *	If this field is NULL, the value passed in the struct hotplug_slot_info
- *	will be used when this value is requested by a user.
- *
- * The table of function pointers that is passed to the hotplug pci core by a
- * hotplug pci driver.  These functions are called by the hotplug pci core when
- * the user wants to do something to a specific slot (query it for information,
- * set an LED, enable / disable power, etc.)
- */
-struct hotplug_slot_ops {
-	struct module *owner;
-	int (*enable_slot)		(struct hotplug_slot *slot);
-	int (*disable_slot)		(struct hotplug_slot *slot);
-	int (*set_attention_status)	(struct hotplug_slot *slot, u8 value);
-	int (*hardware_test)		(struct hotplug_slot *slot, u32 value);
-	int (*get_power_status)		(struct hotplug_slot *slot, u8 *value);
-	int (*get_attention_status)	(struct hotplug_slot *slot, u8 *value);
-	int (*get_latch_status)		(struct hotplug_slot *slot, u8 *value);
-	int (*get_adapter_status)	(struct hotplug_slot *slot, u8 *value);
-	int (*get_max_bus_speed)	(struct hotplug_slot *slot, enum pci_bus_speed *value);
-	int (*get_cur_bus_speed)	(struct hotplug_slot *slot, enum pci_bus_speed *value);
-};
-
-/**
- * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
- * @power: if power is enabled or not (1/0)
- * @attention_status: if the attention light is enabled or not (1/0)
- * @latch_status: if the latch (if any) is open or closed (1/0)
- * @adapter_present: if there is a pci board present in the slot or not (1/0)
- *
- * Used to notify the hotplug pci core of the status of a specific slot.
- */
-struct hotplug_slot_info {
-	u8	power_status;
-	u8	attention_status;
-	u8	latch_status;
-	u8	adapter_status;
-	enum pci_bus_speed	max_bus_speed;
-	enum pci_bus_speed	cur_bus_speed;
-};
-
-/**
- * struct hotplug_slot - used to register a physical slot with the hotplug pci core
- * @name: the name of the slot being registered.  This string must
- * be unique amoung slots registered on this system.
- * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
- * @info: pointer to the &struct hotplug_slot_info for the inital values for
- * this slot.
- * @private: used by the hotplug pci controller driver to store whatever it
- * needs.
- */
-struct hotplug_slot {
-	char				*name;
-	struct hotplug_slot_ops		*ops;
-	struct hotplug_slot_info	*info;
-	void				*private;
-
-	/* Variables below this are for use only by the hotplug pci core. */
-	struct list_head		slot_list;
-	struct kobject			kobj;
-};
-
-extern int pci_hp_register		(struct hotplug_slot *slot);
-extern int pci_hp_deregister		(struct hotplug_slot *slot);
-extern int pci_hp_change_slot_info	(struct hotplug_slot *slot,
-					 struct hotplug_slot_info *info);
-
-#endif
-
diff -urN linux-2.5.70-bk9/drivers/hotplug/pci_hotplug_core.c linux-2.5.70-bk10/drivers/hotplug/pci_hotplug_core.c
--- linux-2.5.70-bk9/drivers/hotplug/pci_hotplug_core.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/pci_hotplug_core.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,666 +0,0 @@
-/*
- * PCI HotPlug Controller Core
- *
- * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001-2002 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/pagemap.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/mount.h>
-#include <linux/namei.h>
-#include <linux/pci.h>
-#include <asm/uaccess.h>
-#include <linux/kobject.h>
-#include <linux/sysfs.h>
-#include "pci_hotplug.h"
-
-
-#if !defined(CONFIG_HOTPLUG_PCI_MODULE)
-	#define MY_NAME	"pci_hotplug"
-#else
-	#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
-
-
-/* local variables */
-static int debug;
-
-#define DRIVER_VERSION	"0.5"
-#define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>"
-#define DRIVER_DESC	"PCI Hot Plug PCI Core"
-
-
-//////////////////////////////////////////////////////////////////
-
-static LIST_HEAD(pci_hotplug_slot_list);
-
-static struct subsystem hotplug_slots_subsys;
-
-static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
-		struct attribute *attr, char *buf)
-{
-	struct hotplug_slot *slot=container_of(kobj,
-			struct hotplug_slot,kobj);
-	struct hotplug_slot_attribute *attribute =
-		container_of(attr, struct hotplug_slot_attribute, attr);
-	return attribute->show ? attribute->show(slot, buf) : 0;
-}
-
-static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
-		struct attribute *attr, const char *buf, size_t len)
-{
-	struct hotplug_slot *slot=container_of(kobj,
-			struct hotplug_slot,kobj);
-	struct hotplug_slot_attribute *attribute =
-		container_of(attr, struct hotplug_slot_attribute, attr);
-	return attribute->store ? attribute->store(slot, buf, len) : 0;
-}
-
-static struct sysfs_ops hotplug_slot_sysfs_ops = {
-	.show = hotplug_slot_attr_show,
-	.store = hotplug_slot_attr_store,
-};
-
-static struct kobj_type hotplug_slot_ktype = {
-	.sysfs_ops = &hotplug_slot_sysfs_ops
-};
-
-static decl_subsys(hotplug_slots, &hotplug_slot_ktype, NULL);
-
-
-/* these strings match up with the values in pci_bus_speed */
-static char *pci_bus_speed_strings[] = {
-	"33 MHz PCI",		/* 0x00 */
-	"66 MHz PCI",		/* 0x01 */
-	"66 MHz PCIX", 		/* 0x02 */
-	"100 MHz PCIX",		/* 0x03 */
-	"133 MHz PCIX",		/* 0x04 */
-	NULL,			/* 0x05 */
-	NULL,			/* 0x06 */
-	NULL,			/* 0x07 */
-	NULL,			/* 0x08 */
-	"66 MHz PCIX 266",	/* 0x09 */
-	"100 MHz PCIX 266",	/* 0x0a */
-	"133 MHz PCIX 266",	/* 0x0b */
-	NULL,			/* 0x0c */
-	NULL,			/* 0x0d */
-	NULL,			/* 0x0e */
-	NULL,			/* 0x0f */
-	NULL,			/* 0x10 */
-	"66 MHz PCIX 533",	/* 0x11 */
-	"100 MHz PCIX 533",	/* 0x12 */
-	"133 MHz PCIX 533",	/* 0x13 */
-};
-
-#ifdef CONFIG_HOTPLUG_PCI_CPCI
-extern int cpci_hotplug_init(int debug);
-extern void cpci_hotplug_exit(void);
-#else
-static inline int cpci_hotplug_init(int debug) { return 0; }
-static inline void cpci_hotplug_exit(void) { }
-#endif
-
-/* Weee, fun with macros... */
-#define GET_STATUS(name,type)	\
-static int get_##name (struct hotplug_slot *slot, type *value)		\
-{									\
-	struct hotplug_slot_ops *ops = slot->ops;			\
-	int retval = 0;							\
-	if (try_module_get(ops->owner)) {				\
-		if (ops->get_##name)					\
-			retval = ops->get_##name (slot, value);		\
-		else							\
-			*value = slot->info->name;			\
-		module_put(ops->owner);					\
-	}								\
-	return retval;							\
-}
-
-GET_STATUS(power_status, u8)
-GET_STATUS(attention_status, u8)
-GET_STATUS(latch_status, u8)
-GET_STATUS(adapter_status, u8)
-GET_STATUS(max_bus_speed, enum pci_bus_speed)
-GET_STATUS(cur_bus_speed, enum pci_bus_speed)
-
-static ssize_t power_read_file (struct hotplug_slot *slot, char *buf)
-{
-	int retval;
-	u8 value;
-
-	retval = get_power_status (slot, &value);
-	if (retval)
-		goto exit;
-	retval = sprintf (buf, "%d\n", value);
-exit:
-	return retval;
-}
-
-static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
-		size_t count)
-{
-	unsigned long lpower;
-	u8 power;
-	int retval = 0;
-
-	lpower = simple_strtoul (buf, NULL, 10);
-	power = (u8)(lpower & 0xff);
-	dbg ("power = %d\n", power);
-
-	if (!try_module_get(slot->ops->owner)) {
-		retval = -ENODEV;
-		goto exit;
-	}
-	switch (power) {
-		case 0:
-			if (slot->ops->disable_slot)
-				retval = slot->ops->disable_slot(slot);
-			break;
-
-		case 1:
-			if (slot->ops->enable_slot)
-				retval = slot->ops->enable_slot(slot);
-			break;
-
-		default:
-			err ("Illegal value specified for power\n");
-			retval = -EINVAL;
-	}
-	module_put(slot->ops->owner);
-
-exit:	
-	if (retval)
-		return retval;
-	return count;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_power = {
-	.attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},
-	.show = power_read_file,
-	.store = power_write_file
-};
-
-static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf)
-{
-	int retval;
-	u8 value;
-
-	retval = get_attention_status (slot, &value);
-	if (retval)
-		goto exit;
-	retval = sprintf (buf, "%d\n", value);
-
-exit:
-	return retval;
-}
-
-static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,
-		size_t count)
-{
-	unsigned long lattention;
-	u8 attention;
-	int retval = 0;
-
-	lattention = simple_strtoul (buf, NULL, 10);
-	attention = (u8)(lattention & 0xff);
-	dbg (" - attention = %d\n", attention);
-
-	if (!try_module_get(slot->ops->owner)) {
-		retval = -ENODEV;
-		goto exit;
-	}
-	if (slot->ops->set_attention_status)
-		retval = slot->ops->set_attention_status(slot, attention);
-	module_put(slot->ops->owner);
-
-exit:	
-	if (retval)
-		return retval;
-	return count;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_attention = {
-	.attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},
-	.show = attention_read_file,
-	.store = attention_write_file
-};
-
-static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf)
-{
-	int retval;
-	u8 value;
-
-	retval = get_latch_status (slot, &value);
-	if (retval)
-		goto exit;
-	retval = sprintf (buf, "%d\n", value);
-
-exit:
-	return retval;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
-	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO | S_IWUSR},
-	.show = latch_read_file,
-};
-
-static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf)
-{
-	int retval;
-	u8 value;
-
-	retval = get_adapter_status (slot, &value);
-	if (retval)
-		goto exit;
-	retval = sprintf (buf, "%d\n", value);
-
-exit:
-	return retval;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
-	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO | S_IWUSR},
-	.show = presence_read_file,
-};
-
-static char *unknown_speed = "Unknown bus speed";
-
-static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
-{
-	char *speed_string;
-	int retval;
-	enum pci_bus_speed value;
-	
-	retval = get_max_bus_speed (slot, &value);
-	if (retval)
-		goto exit;
-
-	if (value == PCI_SPEED_UNKNOWN)
-		speed_string = unknown_speed;
-	else
-		speed_string = pci_bus_speed_strings[value];
-	
-	retval = sprintf (buf, "%s\n", speed_string);
-
-exit:
-	return retval;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
-	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
-	.show = max_bus_speed_read_file,
-};
-
-static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
-{
-	char *speed_string;
-	int retval;
-	enum pci_bus_speed value;
-
-	retval = get_cur_bus_speed (slot, &value);
-	if (retval)
-		goto exit;
-
-	if (value == PCI_SPEED_UNKNOWN)
-		speed_string = unknown_speed;
-	else
-		speed_string = pci_bus_speed_strings[value];
-	
-	retval = sprintf (buf, "%s\n", speed_string);
-
-exit:
-	return retval;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
-	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
-	.show = cur_bus_speed_read_file,
-};
-
-static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
-		size_t count)
-{
-	unsigned long ltest;
-	u32 test;
-	int retval = 0;
-
-	ltest = simple_strtoul (buf, NULL, 10);
-	test = (u32)(ltest & 0xffffffff);
-	dbg ("test = %d\n", test);
-
-	if (!try_module_get(slot->ops->owner)) {
-		retval = -ENODEV;
-		goto exit;
-	}
-	if (slot->ops->hardware_test)
-		retval = slot->ops->hardware_test(slot, test);
-	module_put(slot->ops->owner);
-
-exit:	
-	if (retval)
-		return retval;
-	return count;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_test = {
-	.attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR},
-	.store = test_write_file
-};
-
-static int has_power_file (struct hotplug_slot *slot)
-{
-	if ((!slot) || (!slot->ops))
-		return -ENODEV;
-	if ((slot->ops->enable_slot) ||
-	    (slot->ops->disable_slot) ||
-	    (slot->ops->get_power_status))
-		return 0;
-	return -ENOENT;
-}
-
-static int has_attention_file (struct hotplug_slot *slot)
-{
-	if ((!slot) || (!slot->ops))
-		return -ENODEV;
-	if ((slot->ops->set_attention_status) ||
-	    (slot->ops->get_attention_status))
-		return 0;
-	return -ENOENT;
-}
-
-static int has_latch_file (struct hotplug_slot *slot)
-{
-	if ((!slot) || (!slot->ops))
-		return -ENODEV;
-	if (slot->ops->get_latch_status)
-		return 0;
-	return -ENOENT;
-}
-
-static int has_adapter_file (struct hotplug_slot *slot)
-{
-	if ((!slot) || (!slot->ops))
-		return -ENODEV;
-	if (slot->ops->get_adapter_status)
-		return 0;
-	return -ENOENT;
-}
-
-static int has_max_bus_speed_file (struct hotplug_slot *slot)
-{
-	if ((!slot) || (!slot->ops))
-		return -ENODEV;
-	if (slot->ops->get_max_bus_speed)
-		return 0;
-	return -ENOENT;
-}
-
-static int has_cur_bus_speed_file (struct hotplug_slot *slot)
-{
-	if ((!slot) || (!slot->ops))
-		return -ENODEV;
-	if (slot->ops->get_cur_bus_speed)
-		return 0;
-	return -ENOENT;
-}
-
-static int has_test_file (struct hotplug_slot *slot)
-{
-	if ((!slot) || (!slot->ops))
-		return -ENODEV;
-	if (slot->ops->hardware_test)
-		return 0;
-	return -ENOENT;
-}
-
-static int fs_add_slot (struct hotplug_slot *slot)
-{
-	if (has_power_file(slot) == 0)
-		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
-
-	if (has_attention_file(slot) == 0)
-		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
-
-	if (has_latch_file(slot) == 0)
-		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
-
-	if (has_adapter_file(slot) == 0)
-		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
-
-	if (has_max_bus_speed_file(slot) == 0)
-		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
-
-	if (has_cur_bus_speed_file(slot) == 0)
-		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
-
-	if (has_test_file(slot) == 0)
-		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr);
-
-	return 0;
-}
-
-static void fs_remove_slot (struct hotplug_slot *slot)
-{
-	if (has_power_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
-
-	if (has_attention_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
-
-	if (has_latch_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
-
-	if (has_adapter_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
-
-	if (has_max_bus_speed_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
-
-	if (has_cur_bus_speed_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
-
-	if (has_test_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
-}
-
-static struct hotplug_slot *get_slot_from_name (const char *name)
-{
-	struct hotplug_slot *slot;
-	struct list_head *tmp;
-
-	list_for_each (tmp, &pci_hotplug_slot_list) {
-		slot = list_entry (tmp, struct hotplug_slot, slot_list);
-		if (strcmp(slot->name, name) == 0)
-			return slot;
-	}
-	return NULL;
-}
-
-/**
- * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem
- * @slot: pointer to the &struct hotplug_slot to register
- *
- * Registers a hotplug slot with the pci hotplug subsystem, which will allow
- * userspace interaction to the slot.
- *
- * Returns 0 if successful, anything else for an error.
- */
-int pci_hp_register (struct hotplug_slot *slot)
-{
-	int result;
-
-	if (slot == NULL)
-		return -ENODEV;
-	if ((slot->info == NULL) || (slot->ops == NULL))
-		return -EINVAL;
-
-	strlcpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
-	kobj_set_kset_s(slot, hotplug_slots_subsys);
-
-	/* this can fail if we have already registered a slot with the same name */
-	if (kobject_register(&slot->kobj)) {
-		err("Unable to register kobject");
-		return -EINVAL;
-	}
-		
-	list_add (&slot->slot_list, &pci_hotplug_slot_list);
-
-	result = fs_add_slot (slot);
-	dbg ("Added slot %s to the list\n", slot->name);
-	return result;
-}
-
-/**
- * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem
- * @slot: pointer to the &struct hotplug_slot to deregister
- *
- * The @slot must have been registered with the pci hotplug subsystem
- * previously with a call to pci_hp_register().
- *
- * Returns 0 if successful, anything else for an error.
- */
-int pci_hp_deregister (struct hotplug_slot *slot)
-{
-	struct hotplug_slot *temp;
-
-	if (slot == NULL)
-		return -ENODEV;
-
-	temp = get_slot_from_name (slot->name);
-	if (temp != slot) {
-		return -ENODEV;
-	}
-	list_del (&slot->slot_list);
-
-	fs_remove_slot (slot);
-	dbg ("Removed slot %s from the list\n", slot->name);
-	kobject_unregister(&slot->kobj);
-	return 0;
-}
-
-/**
- * pci_hp_change_slot_info - changes the slot's information structure in the core
- * @slot: pointer to the slot whose info has changed
- * @info: pointer to the info copy into the slot's info structure
- *
- * @slot must have been registered with the pci 
- * hotplug subsystem previously with a call to pci_hp_register().
- *
- * Returns 0 if successful, anything else for an error.
- */
-int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info)
-{
-	if ((slot == NULL) || (info == NULL))
-		return -ENODEV;
-
-	/*
-	* check all fields in the info structure, and update timestamps
-	* for the files referring to the fields that have now changed.
-	*/
-	if ((has_power_file(slot) == 0) &&
-	    (slot->info->power_status != info->power_status))
-		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr);
-
-	if ((has_attention_file(slot) == 0) &&
-	    (slot->info->attention_status != info->attention_status))
-		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
-
-	if ((has_latch_file(slot) == 0) &&
-	    (slot->info->latch_status != info->latch_status))
-		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
-
-	if ((has_adapter_file(slot) == 0) &&
-	    (slot->info->adapter_status != info->adapter_status))
-		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
-
-	if ((has_max_bus_speed_file(slot) == 0) &&
-	    (slot->info->max_bus_speed != info->max_bus_speed))
-		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
-
-	if ((has_cur_bus_speed_file(slot) == 0) &&
-	    (slot->info->cur_bus_speed != info->cur_bus_speed))
-		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
-
-	memcpy (slot->info, info, sizeof (struct hotplug_slot_info));
-
-	return 0;
-}
-
-static int __init pci_hotplug_init (void)
-{
-	int result;
-
-	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
-	result = subsystem_register(&hotplug_slots_subsys);
-	if (result) {
-		err("Register subsys with error %d\n", result);
-		goto exit;
-	}
-	result = cpci_hotplug_init(debug);
-	if (result) {
-		err ("cpci_hotplug_init with error %d\n", result);
-		goto err_subsys;
-	}
-
-	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
-	goto exit;
-	
-err_subsys:
-	subsystem_unregister(&hotplug_slots_subsys);
-exit:
-	return result;
-}
-
-static void __exit pci_hotplug_exit (void)
-{
-	cpci_hotplug_exit();
-	subsystem_unregister(&hotplug_slots_subsys);
-}
-
-module_init(pci_hotplug_init);
-module_exit(pci_hotplug_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-
-EXPORT_SYMBOL_GPL(pci_hp_register);
-EXPORT_SYMBOL_GPL(pci_hp_deregister);
-EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
diff -urN linux-2.5.70-bk9/drivers/hotplug/pcihp_skeleton.c linux-2.5.70-bk10/drivers/hotplug/pcihp_skeleton.c
--- linux-2.5.70-bk9/drivers/hotplug/pcihp_skeleton.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/drivers/hotplug/pcihp_skeleton.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,432 +0,0 @@
-/*
- * PCI Hot Plug Controller Skeleton Driver - 0.1
- *
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This driver is to be used as a skeleton driver to be show how to interface
- * with the pci hotplug core easily.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include "pci_hotplug.h"
-
-
-#define SLOT_MAGIC	0x67267322
-struct slot {
-	u32 magic;
-	u8 number;
-	struct hotplug_slot *hotplug_slot;
-	struct list_head slot_list;
-};
-
-static LIST_HEAD(slot_list);
-
-#if !defined(CONFIG_HOTPLUG_PCI_SKELETON_MODULE)
-	#define MY_NAME	"pcihp_skeleton"
-#else
-	#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...)					\
-	do {							\
-		if (debug)					\
-			printk (KERN_DEBUG "%s: " format "\n",	\
-				MY_NAME , ## arg); 		\
-	} while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
-
-
-
-/* local variables */
-static int debug;
-static int num_slots;
-
-#define DRIVER_VERSION	"0.1"
-#define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>"
-#define DRIVER_DESC	"Hot Plug PCI Controller Skeleton Driver"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-
-static int enable_slot		(struct hotplug_slot *slot);
-static int disable_slot		(struct hotplug_slot *slot);
-static int set_attention_status (struct hotplug_slot *slot, u8 value);
-static int hardware_test	(struct hotplug_slot *slot, u32 value);
-static int get_power_status	(struct hotplug_slot *slot, u8 *value);
-static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
-static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
-static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
-
-static struct hotplug_slot_ops skel_hotplug_slot_ops = {
-	.owner =		THIS_MODULE,
-	.enable_slot =		enable_slot,
-	.disable_slot =		disable_slot,
-	.set_attention_status =	set_attention_status,
-	.hardware_test =	hardware_test,
-	.get_power_status =	get_power_status,
-	.get_attention_status =	get_attention_status,
-	.get_latch_status =	get_latch_status,
-	.get_adapter_status =	get_adapter_status,
-};
-
-
-/* Inline functions to check the sanity of a pointer that is passed to us */
-static inline int slot_paranoia_check (struct slot *slot, const char *function)
-{
-	if (!slot) {
-		dbg("%s - slot == NULL", function);
-		return -1;
-	}
-	if (slot->magic != SLOT_MAGIC) {
-		dbg("%s - bad magic number for slot", function);
-		return -1;
-	}
-	if (!slot->hotplug_slot) {
-		dbg("%s - slot->hotplug_slot == NULL!", function);
-		return -1;
-	}
-	return 0;
-}
-
-static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
-{ 
-	struct slot *slot;
-
-	if (!hotplug_slot) {
-		dbg("%s - hotplug_slot == NULL\n", function);
-		return NULL;
-	}
-
-	slot = (struct slot *)hotplug_slot->private;
-	if (slot_paranoia_check (slot, function))
-                return NULL;
-	return slot;
-}               
-
-
-static int enable_slot (struct hotplug_slot *hotplug_slot)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	int retval = 0;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg ("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	/*
-	 * Fill in code here to enable the specified slot
-	 */
-
-	return retval;
-}
-
-
-static int disable_slot (struct hotplug_slot *hotplug_slot)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	int retval = 0;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg ("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	/*
-	 * Fill in code here to disable the specified slot
-	 */
-
-	return retval;
-}
-
-static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	int retval = 0;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg ("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	switch (status) {
-		case 0:
-			/*
-			 * Fill in code here to turn light off
-			 */
-			break;
-
-		case 1:
-		default:
-			/*
-			 * Fill in code here to turn light on
-			 */
-			break;
-	}
-
-	return retval;
-}
-
-static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	int retval = 0;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg ("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-
-	err ("No hardware tests are defined for this driver");
-	retval = -ENODEV;
-
-	/* Or you can specify a test if you want to */
-	
-	return retval;
-}
-
-static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	int retval = 0;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
-
-	/*
-	 * Fill in logic to get the current power status of the specific
-	 * slot and store it in the *value location.
-	 */
-
-	return retval;
-}
-
-static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	int retval = 0;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
-
-	/*
-	 * Fill in logic to get the current attention status of the specific
-	 * slot and store it in the *value location.
-	 */
-
-	return retval;
-}
-
-static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	int retval = 0;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
-
-	/*
-	 * Fill in logic to get the current latch status of the specific
-	 * slot and store it in the *value location.
-	 */
-
-	return retval;
-}
-
-static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
-	int retval = 0;
-	
-	if (slot == NULL)
-		return -ENODEV;
-	
-	dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
-
-	/*
-	 * Fill in logic to get the current adapter status of the specific
-	 * slot and store it in the *value location.
-	 */
-
-	return retval;
-}
-
-#define SLOT_NAME_SIZE	10
-static void make_slot_name (struct slot *slot)
-{
-	/*
-	 * Stupid way to make a filename out of the slot name.
-	 * replace this if your hardware provides a better way to name slots.
-	 */
-	snprintf (slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d", slot->number);
-}
-
-static int init_slots (void)
-{
-	struct slot *slot;
-	struct hotplug_slot *hotplug_slot;
-	struct hotplug_slot_info *info;
-	char *name;
-	int retval = 0;
-	int i;
-
-	/*
-	 * Create a structure for each slot, and register that slot
-	 * with the pci_hotplug subsystem.
-	 */
-	for (i = 0; i < num_slots; ++i) {
-		slot = kmalloc (sizeof (struct slot), GFP_KERNEL);
-		if (!slot)
-			return -ENOMEM;
-		memset(slot, 0, sizeof(struct slot));
-
-		hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
-		if (!hotplug_slot) {
-			kfree (slot);
-			return -ENOMEM;
-		}
-		memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
-		slot->hotplug_slot = hotplug_slot;
-
-		info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
-		if (!info) {
-			kfree (hotplug_slot);
-			kfree (slot);
-			return -ENOMEM;
-		}
-		memset(info, 0, sizeof (struct hotplug_slot_info));
-		hotplug_slot->info = info;
-
-		name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
-		if (!name) {
-			kfree (info);
-			kfree (hotplug_slot);
-			kfree (slot);
-			return -ENOMEM;
-		}
-		hotplug_slot->name = name;
-
-		slot->magic = SLOT_MAGIC;
-		slot->number = i;
-
-		hotplug_slot->private = slot;
-		make_slot_name (slot);
-		hotplug_slot->ops = &skel_hotplug_slot_ops;
-		
-		/*
-		 * Initilize the slot info structure with some known
-		 * good values.
-		 */
-		info->power_status = get_skel_power_status(slot);
-		info->attention_status = get_skel_attention_status(slot);
-		info->latch_status = get_skel_latch_status(slot);
-		info->adapter_status = get_skel_adapter_status(slot);
-		
-		dbg ("registering slot %d\n", i);
-		retval = pci_hp_register (slot->hotplug_slot);
-		if (retval) {
-			err ("pci_hp_register failed with error %d\n", retval);
-			kfree (info);
-			kfree (name);
-			kfree (hotplug_slot);
-			kfree (slot);
-			return retval;
-		}
-
-		/* add slot to our internal list */
-		list_add (&slot->slot_list, &slot_list);
-	}
-
-	return retval;
-}
-		
-static void cleanup_slots (void)
-{
-	struct list_head *tmp;
-	struct slot *slot;
-
-	/*
-	 * Unregister all of our slots with the pci_hotplug subsystem,
-	 * and free up all memory that we had allocated.
-	 */
-	list_for_each (tmp, &slot_list) {
-		slot = list_entry (tmp, struct slot, slot_list);
-		list_del (&slot->slot_list);
-		pci_hp_deregister (slot->hotplug_slot);
-		kfree (slot->hotplug_slot->info);
-		kfree (slot->hotplug_slot->name);
-		kfree (slot->hotplug_slot);
-		kfree (slot);
-	}
-
-	return;
-}
-		
-static int __init pcihp_skel_init(void)
-{
-	int retval;
-
-	/*
-	 * Do specific initialization stuff for your driver here
-	 * Like initilizing your controller hardware (if any) and
-	 * determining the number of slots you have in the system
-	 * right now.
-	 */
-	num_slots = 5;
-
-	retval = init_slots();
-	if (retval)
-		return retval;
-
-	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
-	return 0;
-}
-
-static void __exit pcihp_skel_exit(void)
-{
-	/*
-	 * Clean everything up.
-	 */
-	cleanup_slots();
-}
-
-module_init(pcihp_skel_init);
-module_exit(pcihp_skel_exit);
-
diff -urN linux-2.5.70-bk9/drivers/ide/pci/cs5530.c linux-2.5.70-bk10/drivers/ide/pci/cs5530.c
--- linux-2.5.70-bk9/drivers/ide/pci/cs5530.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk10/drivers/ide/pci/cs5530.c	2003-06-05 04:41:36.000000000 -0700
@@ -281,16 +281,15 @@
 	}
 #endif /* DISPLAY_CS5530_TIMINGS && CONFIG_PROC_FS */
 
-	pci_for_each_dev (dev) {
-		if (dev->vendor == PCI_VENDOR_ID_CYRIX) {
-			switch (dev->device) {
-				case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
-					master_0 = dev;
-					break;
-				case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
-					cs5530_0 = dev;
-					break;
-			}
+	dev = NULL;
+	while ((dev = pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
+		switch (dev->device) {
+			case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
+				master_0 = dev;
+				break;
+			case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
+				cs5530_0 = dev;
+				break;
 		}
 	}
 	if (!master_0) {
diff -urN linux-2.5.70-bk9/drivers/ide/pci/hpt366.c linux-2.5.70-bk10/drivers/ide/pci/hpt366.c
--- linux-2.5.70-bk9/drivers/ide/pci/hpt366.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/drivers/ide/pci/hpt366.c	2003-06-05 04:41:36.000000000 -0700
@@ -1100,7 +1100,7 @@
 	if (PCI_FUNC(dev->devfn) & 1)
 		return;
 
-	pci_for_each_dev(findev) {
+	while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
 		if ((findev->vendor == dev->vendor) &&
 		    (findev->device == dev->device) &&
 		    ((findev->devfn - dev->devfn) == 1) &&
@@ -1150,7 +1150,7 @@
 	d->channels = 1;
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1);
-	pci_for_each_dev(findev) {
+	while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
 		if ((findev->vendor == dev->vendor) &&
 		    (findev->device == dev->device) &&
 		    ((findev->devfn - dev->devfn) == 1) &&
diff -urN linux-2.5.70-bk9/drivers/ide/pci/pdc202xx_new.c linux-2.5.70-bk10/drivers/ide/pci/pdc202xx_new.c
--- linux-2.5.70-bk9/drivers/ide/pci/pdc202xx_new.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk10/drivers/ide/pci/pdc202xx_new.c	2003-06-05 04:41:36.000000000 -0700
@@ -579,7 +579,7 @@
 
 static void __init init_setup_pdc20270 (struct pci_dev *dev, ide_pci_device_t *d)
 {
-	struct pci_dev *findev;
+	struct pci_dev *findev = NULL;
 
 	if ((dev->bus->self &&
 	     dev->bus->self->vendor == PCI_VENDOR_ID_DEC) &&
@@ -588,7 +588,7 @@
 			return;
 		}
 		d->extra = 0;
-		pci_for_each_dev(findev) {
+		while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
 			if ((findev->vendor == dev->vendor) &&
 			    (findev->device == dev->device) &&
 			    (PCI_SLOT(findev->devfn) & 2)) {
diff -urN linux-2.5.70-bk9/drivers/ide/setup-pci.c linux-2.5.70-bk10/drivers/ide/setup-pci.c
--- linux-2.5.70-bk9/drivers/ide/setup-pci.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/drivers/ide/setup-pci.c	2003-06-05 04:41:36.000000000 -0700
@@ -870,13 +870,13 @@
  	
 void __init ide_scan_pcibus (int scan_direction)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	struct pci_driver *d;
 	struct list_head *l, *n;
 
 	pre_init = 0;
 	if (!scan_direction) {
-		pci_for_each_dev(dev) {
+		while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 			ide_scan_pcidev(dev);
 		}
 	} else {
diff -urN linux-2.5.70-bk9/drivers/macintosh/via-pmu.c linux-2.5.70-bk10/drivers/macintosh/via-pmu.c
--- linux-2.5.70-bk9/drivers/macintosh/via-pmu.c	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk10/drivers/macintosh/via-pmu.c	2003-06-05 04:41:36.000000000 -0700
@@ -1713,10 +1713,10 @@
 pbook_alloc_pci_save(void)
 {
 	int npci;
-	struct pci_dev *pd;
+	struct pci_dev *pd = NULL;
 
 	npci = 0;
-	pci_for_each_dev(pd) {
+	while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
 		++npci;
 	}
 	if (npci == 0)
@@ -1740,13 +1740,13 @@
 pbook_pci_save(void)
 {
 	struct pci_save *ps = pbook_pci_saves;
-	struct pci_dev *pd;
+	struct pci_dev *pd = NULL;
 	int npci = pbook_npci_saves;
 	
 	if (ps == NULL)
 		return;
 
-	pci_for_each_dev(pd) {
+	while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
 		if (npci-- == 0)
 			return;
 #ifndef HACKED_PCI_SAVE
@@ -1772,11 +1772,11 @@
 {
 	u16 cmd;
 	struct pci_save *ps = pbook_pci_saves - 1;
-	struct pci_dev *pd;
+	struct pci_dev *pd = NULL;
 	int npci = pbook_npci_saves;
 	int j;
 
-	pci_for_each_dev(pd) {
+	while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
 #ifdef HACKED_PCI_SAVE
 		int i;
 		if (npci-- == 0)
diff -urN linux-2.5.70-bk9/drivers/md/md.c linux-2.5.70-bk10/drivers/md/md.c
--- linux-2.5.70-bk9/drivers/md/md.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/drivers/md/md.c	2003-06-05 04:41:36.000000000 -0700
@@ -2860,7 +2860,7 @@
 	loff_t l = *pos;
 	mddev_t *mddev;
 
-	if (l > 0x10000)
+	if (l >= 0x10000)
 		return NULL;
 	if (!l--)
 		/* header */
@@ -2875,7 +2875,9 @@
 			return mddev;
 		}
 	spin_unlock(&all_mddevs_lock);
-	return (void*)2;/* tail */
+	if (!l--)
+		return (void*)2;/* tail */
+	return NULL;
 }
 
 static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
diff -urN linux-2.5.70-bk9/drivers/md/raid0.c linux-2.5.70-bk10/drivers/md/raid0.c
--- linux-2.5.70-bk9/drivers/md/raid0.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/drivers/md/raid0.c	2003-06-05 04:41:36.000000000 -0700
@@ -85,10 +85,8 @@
 	conf->devlist = kmalloc(sizeof(mdk_rdev_t*)*
 				conf->nr_strip_zones*mddev->raid_disks,
 				GFP_KERNEL);
-	if (!conf->devlist) {
-		kfree(conf);
+	if (!conf->devlist)
 		return 1;
-	}
 
 	memset(conf->strip_zone, 0,sizeof(struct strip_zone)*
 				   conf->nr_strip_zones);
@@ -193,8 +191,6 @@
 	printk("raid0: done.\n");
 	return 0;
  abort:
-	kfree(conf->devlist);
-	kfree(conf->strip_zone);
 	return 1;
 }
 
@@ -235,6 +231,8 @@
 		goto out;
 	mddev->private = (void *)conf;
  
+	conf->strip_zone = NULL;
+	conf->devlist = NULL;
 	if (create_strip_zones (mddev)) 
 		goto out_free_conf;
 
@@ -273,7 +271,7 @@
 				nb_zone*sizeof(struct strip_zone*));
 	conf->hash_table = kmalloc (sizeof (struct strip_zone *)*nb_zone, GFP_KERNEL);
 	if (!conf->hash_table)
-		goto out_free_zone_conf;
+		goto out_free_conf;
 	size = conf->strip_zone[cur].size;
 
 	for (i=0; i< nb_zone; i++) {
@@ -296,12 +294,11 @@
 	blk_queue_merge_bvec(&mddev->queue, raid0_mergeable_bvec);
 	return 0;
 
-out_free_zone_conf:
-	kfree(conf->strip_zone);
-	conf->strip_zone = NULL;
-
 out_free_conf:
-	kfree (conf->devlist);
+	if (conf->strip_zone)
+		kfree(conf->strip_zone);
+	if (conf->devlist)
+		kfree (conf->devlist);
 	kfree(conf);
 	mddev->private = NULL;
 out:
diff -urN linux-2.5.70-bk9/drivers/md/raid1.c linux-2.5.70-bk10/drivers/md/raid1.c
--- linux-2.5.70-bk9/drivers/md/raid1.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/drivers/md/raid1.c	2003-06-05 04:41:36.000000000 -0700
@@ -462,7 +462,7 @@
 	mirror_info_t *mirror;
 	r1bio_t *r1_bio;
 	struct bio *read_bio;
-	int i, sum_bios = 0, disks = conf->raid_disks;
+	int i, disks = conf->raid_disks;
 
 	/*
 	 * Register the new request and wait if the reconstruction
@@ -525,6 +525,9 @@
 			r1_bio->write_bios[i] = NULL;
 	}
 	spin_unlock_irq(&conf->device_lock);
+
+	atomic_set(&r1_bio->remaining, 1);
+	md_write_start(mddev);
 	for (i = 0; i < disks; i++) {
 		struct bio *mbio;
 		if (!r1_bio->write_bios[i])
@@ -539,37 +542,7 @@
 		mbio->bi_rw = r1_bio->cmd;
 		mbio->bi_private = r1_bio;
 
-		sum_bios++;
-	}
-	if (!sum_bios) {
-		/*
-		 * If all mirrors are non-operational
-		 * then return an IO error:
-		 */
-		md_write_end(mddev);
-		raid_end_bio_io(r1_bio);
-		return 0;
-	}
-	atomic_set(&r1_bio->remaining, sum_bios+1);
-
-	/*
-	 * We have to be a bit careful about the semaphore above, thats
-	 * why we start the requests separately. Since generic_make_request()
-	 * can sleep, this is the safer solution. Imagine, raid1_end_request
-	 * decreasing the semaphore before we could have set it up ...
-	 * We could play tricks with the semaphore (presetting it and
-	 * correcting at the end if sum_bios is not 'n' but we have to
-	 * do raid1_end_request by hand if all requests finish until we had a
-	 * chance to set up the semaphore correctly ... lots of races).
-	 */
-
-	md_write_start(mddev);
-	for (i=disks; i--; ) {
-		struct bio *mbio;
-		mbio = r1_bio->write_bios[i];
-		if (!mbio)
-			continue;
-
+		atomic_inc(&r1_bio->remaining);
 		generic_make_request(mbio);
 	}
 
@@ -802,7 +775,7 @@
 static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
 {
 	conf_t *conf = mddev_to_conf(mddev);
-	int i, sum_bios = 0;
+	int i;
 	int disks = conf->raid_disks;
 	struct bio *bio, *mbio;
 
@@ -849,7 +822,8 @@
 	}
 	spin_unlock_irq(&conf->device_lock);
 
-	for (i = 0; i < disks ; i++) {
+	atomic_set(&r1_bio->remaining, 1);
+	for (i = disks; i-- ; ) {
 		if (!r1_bio->write_bios[i])
 			continue;
 		mbio = bio_clone(bio, GFP_NOIO);
@@ -860,32 +834,14 @@
 		mbio->bi_rw = WRITE;
 		mbio->bi_private = r1_bio;
 
-		sum_bios++;
+		atomic_inc(&r1_bio->remaining);
+		md_sync_acct(conf->mirrors[i].rdev, mbio->bi_size >> 9);
+		generic_make_request(mbio);
 	}
-	if (i != disks)
-		BUG();
-	atomic_set(&r1_bio->remaining, sum_bios);
 
-
-	if (!sum_bios) {
-		/*
-		 * Nowhere to write this to... I guess we
-		 * must be done
-		 */
-		printk(KERN_ALERT "raid1: sync aborting as there is nowhere"
-			" to write sector %llu\n", 
-			(unsigned long long)r1_bio->sector);
+	if (atomic_dec_and_test(&r1_bio->remaining)) {
 		md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 0);
 		put_buf(r1_bio);
-		return;
-	}
-	for (i = 0; i < disks ; i++) {
-		mbio = r1_bio->write_bios[i];
-		if (!mbio)
-			continue;
-
-		md_sync_acct(conf->mirrors[i].rdev, mbio->bi_size >> 9);
-		generic_make_request(mbio);
 	}
 }
 
diff -urN linux-2.5.70-bk9/drivers/md/raid5.c linux-2.5.70-bk10/drivers/md/raid5.c
--- linux-2.5.70-bk9/drivers/md/raid5.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/drivers/md/raid5.c	2003-06-05 04:41:36.000000000 -0700
@@ -940,7 +940,7 @@
 			/* and fail all 'written' */
 			bi = sh->dev[i].written;
 			sh->dev[i].written = NULL;
-			while (bi && bi->bi_sector < dev->sector + STRIPE_SECTORS) {
+			while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) {
 				struct bio *bi2 = bi->bi_next;
 				clear_bit(BIO_UPTODATE, &bi->bi_flags);
 				if (--bi->bi_phys_segments == 0) {
diff -urN linux-2.5.70-bk9/drivers/media/radio/radio-cadet.c linux-2.5.70-bk10/drivers/media/radio/radio-cadet.c
--- linux-2.5.70-bk9/drivers/media/radio/radio-cadet.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/drivers/media/radio/radio-cadet.c	2003-06-05 04:41:36.000000000 -0700
@@ -389,9 +389,6 @@
 				        v->flags|=VIDEO_TUNER_STEREO_ON;
 			        }
 				v->flags|=cadet_getrds();
-			        if(copy_to_user(arg,&v, sizeof(v))) {
-				        return -EFAULT;
-			        }
 			        break;
 			        case 1:
 			        strcpy(v->name,"AM");
@@ -402,9 +399,6 @@
 			        v->mode=0;
 			        v->mode|=VIDEO_MODE_AUTO;
 			        v->signal=sigstrength;
-			        if(copy_to_user(arg,&v, sizeof(v))) {
-				        return -EFAULT;
-			        }
 			        break;
 			}
 			return 0;
diff -urN linux-2.5.70-bk9/drivers/media/video/bw-qcam.c linux-2.5.70-bk10/drivers/media/video/bw-qcam.c
--- linux-2.5.70-bk9/drivers/media/video/bw-qcam.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk10/drivers/media/video/bw-qcam.c	2003-06-05 04:41:36.000000000 -0700
@@ -723,8 +723,6 @@
 			/* Good question.. its composite or SVHS so.. */
 			v->type = VIDEO_TYPE_CAMERA;
 			strcpy(v->name, "Camera");
-			if(copy_to_user(arg, &v, sizeof(v)))
-				return -EFAULT;
 			return 0;
 		}
 		case VIDIOCSCHAN:
diff -urN linux-2.5.70-bk9/drivers/media/video/zr36120.c linux-2.5.70-bk10/drivers/media/video/zr36120.c
--- linux-2.5.70-bk9/drivers/media/video/zr36120.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/drivers/media/video/zr36120.c	2003-06-05 04:41:36.000000000 -0700
@@ -1693,12 +1693,12 @@
 			for (x=0; optr+1<eptr && x<-done->w; x++)
 			{
 				unsigned char a = iptr[x*2];
-				*optr++ = a;
-				*optr++ = a;
+				__put_user(a, optr++);
+				__put_user(a, optr++);
 			}
 			/* and clear the rest of the line */
 			for (x*=2; optr<eptr && x<done->bpl; x++)
-				*optr++ = 0;
+				__put_user(0, optr++);
 			/* next line */
 			iptr += done->bpl;
 		}
@@ -1715,10 +1715,10 @@
 		{
 			/* copy to doubled data to userland */
 			for (x=0; optr<eptr && x<-done->w; x++)
-				*optr++ = iptr[x*2];
+				__put_user(iptr[x*2], optr++);
 			/* and clear the rest of the line */
 			for (;optr<eptr && x<done->bpl; x++)
-				*optr++ = 0;
+				__put_user(0, optr++);
 			/* next line */
 			iptr += done->bpl;
 		}
@@ -1727,7 +1727,7 @@
 	/* API compliance:
 	 * place the framenumber (half fieldnr) in the last long
 	 */
-	((ulong*)eptr)[-1] = done->fieldnr/2;
+	__put_user(done->fieldnr/2, ((ulong*)eptr)[-1]);
 	}
 
 	/* keep the engine running */
diff -urN linux-2.5.70-bk9/drivers/message/fusion/mptbase.c linux-2.5.70-bk10/drivers/message/fusion/mptbase.c
--- linux-2.5.70-bk9/drivers/message/fusion/mptbase.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk10/drivers/message/fusion/mptbase.c	2003-06-05 04:41:36.000000000 -0700
@@ -1152,7 +1152,7 @@
 static int __init
 mpt_pci_scan(void)
 {
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 	struct pci_dev *pdev2;
 	int found = 0;
 	int count = 0;
@@ -1164,11 +1164,8 @@
 	 *  NOTE: The 929, 929X, 1030 and 1035 will appear as 2 separate PCI devices,
 	 *  one for each channel.
 	 */
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_VENDOR_ID_LSI_LOGIC, PCI_ANY_ID, pdev)) != NULL) {
 		pdev2 = NULL;
-		if (pdev->vendor != 0x1000)
-			continue;
-
 		if ((pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC909) &&
 		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929) &&
 		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919) &&
diff -urN linux-2.5.70-bk9/drivers/message/i2o/i2o_core.c linux-2.5.70-bk10/drivers/message/i2o/i2o_core.c
--- linux-2.5.70-bk9/drivers/message/i2o/i2o_core.c	2003-06-05 04:41:31.000000000 -0700
+++ linux-2.5.70-bk10/drivers/message/i2o/i2o_core.c	2003-06-05 04:41:36.000000000 -0700
@@ -3645,12 +3645,12 @@
  
 int __init i2o_pci_scan(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	int count=0;
 	
 	printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
 
-	pci_for_each_dev(dev)	
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
 	{
 		if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
 			continue;
diff -urN linux-2.5.70-bk9/drivers/net/3c509.c linux-2.5.70-bk10/drivers/net/3c509.c
--- linux-2.5.70-bk9/drivers/net/3c509.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/3c509.c	2003-06-05 04:41:36.000000000 -0700
@@ -300,17 +300,11 @@
  *
  * Both call el3_common_init/el3_common_remove. */
 
-static int __init el3_common_init (struct net_device *dev)
+static void __init el3_common_init(struct net_device *dev)
 {
 	struct el3_private *lp = dev->priv;
 	short i;
 
-	el3_cards++;
-	if (!lp->dev)				/* probed devices are not chained */
-	{
-			lp->next_dev = el3_root_dev;
-			el3_root_dev = dev;
-	}
 	spin_lock_init(&lp->lock);
 
 	if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
@@ -343,8 +337,6 @@
 	dev->tx_timeout = el3_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->do_ioctl = netdev_ioctl;
-
-	return 0;
 }
 
 static void el3_common_remove (struct net_device *dev)
@@ -374,6 +366,7 @@
 	int ioaddr, irq, if_port;
 	u16 phys_addr[3];
 	static int current_tag;
+	int err = -ENODEV;
 #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 	static int pnp_cards;
 	struct pnp_dev *idev = NULL;
@@ -413,7 +406,8 @@
 					phys_addr[j] =
 						htons(read_eeprom(ioaddr, j));
 			if_port = read_eeprom(ioaddr, 8) >> 14;
-			if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) {
+			dev = alloc_etherdev(sizeof (struct el3_private));
+			if (!dev) {
 					release_region(ioaddr, EL3_IO_EXTENT);
 					pnp_device_detach(idev);
 					return -ENOMEM;
@@ -421,6 +415,8 @@
 
 			SET_MODULE_OWNER(dev);
 			pnp_cards++;
+
+			netdev_boot_setup_check(dev);
 			goto found;
 		}
 	}
@@ -514,28 +510,29 @@
 		irq = 13;
 #endif
 
-	if (!(dev = init_etherdev(NULL, sizeof(struct el3_private))))
-			return -ENOMEM;
+	dev = alloc_etherdev(sizeof (struct el3_private));
+	if (!dev)
+		return -ENOMEM;
 
 	SET_MODULE_OWNER(dev);
+
+	netdev_boot_setup_check(dev);
 	
 	/* Set passed-in IRQ or I/O Addr. */
 	if (dev->irq > 1  &&  dev->irq < 16)
 			irq = dev->irq;
 
 	if (dev->base_addr) {
-			if (dev->mem_end == 0x3c509 			/* Magic key */
-				&& dev->base_addr >= 0x200  &&  dev->base_addr <= 0x3e0)
-					ioaddr = dev->base_addr & 0x3f0;
-			else if (dev->base_addr != ioaddr) {
-					unregister_netdev (dev);
-					return -ENODEV;
-			}
+		if (dev->mem_end == 0x3c509 	/* Magic key */
+		    && dev->base_addr >= 0x200  &&  dev->base_addr <= 0x3e0)
+			ioaddr = dev->base_addr & 0x3f0;
+		else if (dev->base_addr != ioaddr)
+			goto out;
 	}
 
 	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) {
-			unregister_netdev (dev);
-			return -EBUSY;
+		err = -EBUSY;
+		goto out;
 	}
 
 	/* Set the adaptor tag so that the next card can be found. */
@@ -549,11 +546,8 @@
 #endif
 
 	EL3WINDOW(0);
-	if (inw(ioaddr) != 0x6d50) {
-		unregister_netdev (dev);
-		release_region(ioaddr, EL3_IO_EXTENT);
-		return -ENODEV;
-	}
+	if (inw(ioaddr) != 0x6d50)
+		goto out1;
 
 	/* Free the interrupt so that some other card can use it. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
@@ -570,6 +564,11 @@
 #if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 	lp->dev = &idev->dev;
 #endif
+	el3_common_init(dev);
+
+	err = register_netdev(dev);
+	if (err)
+		goto out1;
 
 #ifdef CONFIG_PM
 	/* register power management */
@@ -581,7 +580,22 @@
 	}
 #endif
 
-	return el3_common_init (dev);
+	el3_cards++;
+#if !defined(__ISAPNP__) || defined(CONFIG_X86_PC9800)
+	lp->next_dev = el3_root_dev;
+	el3_root_dev = dev;
+#endif
+	return 0;
+
+out1:
+	release_region(ioaddr, EL3_IO_EXTENT);
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+	if (idev)
+		pnp_device_detach(idev);
+#endif
+out:
+	kfree(dev);
+	return err;
 }
 
 #ifdef CONFIG_MCA
@@ -602,6 +616,7 @@
 		u_char pos4, pos5;
 		struct mca_device *mdev = to_mca_device(device);
 		int slot = mdev->slot;
+		int err;
 
 		pos4 = mca_device_read_stored_pos(mdev, 4);
 		pos5 = mca_device_read_stored_pos(mdev, 5);
@@ -630,13 +645,14 @@
 				phys_addr[i] = htons(read_eeprom(ioaddr, i));
 		}
 
-		dev = init_etherdev(NULL, sizeof(struct el3_private));
+		dev = alloc_etherdev(sizeof (struct el3_private));
 		if (dev == NULL) {
 				release_region(ioaddr, EL3_IO_EXTENT);
 				return -ENOMEM;
 		}
 
 		SET_MODULE_OWNER(dev);
+		netdev_boot_setup_check(dev);
 
 		memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
 		dev->base_addr = ioaddr;
@@ -646,8 +662,16 @@
 		lp->dev = device;
 		lp->type = EL3_MCA;
 		device->driver_data = dev;
+		el3_common_init(dev);
+
+		err = register_netdev(dev);
+		if (err) {
+			release_region(ioaddr, EL3_IO_EXTENT);
+			return -ENOMEM;
+		}
 
-		return el3_common_init (dev);
+		el3_cards++;
+		return 0;
 }
 		
 #endif /* CONFIG_MCA */
@@ -661,6 +685,7 @@
 	u16 phys_addr[3];
 	struct net_device *dev = NULL;
 	struct eisa_device *edev;
+	int err;
 
 	/* Yeepee, The driver framework is calling us ! */
 	edev = to_eisa_device (device);
@@ -680,7 +705,7 @@
 	/* Restore the "Product ID" to the EEPROM read register. */
 	read_eeprom(ioaddr, 3);
 
-	dev = init_etherdev(NULL, sizeof(struct el3_private));
+	dev = alloc_etherdev(sizeof (struct el3_private));
 	if (dev == NULL) {
 			release_region(ioaddr, EL3_IO_EXTENT);
 			return -ENOMEM;
@@ -688,6 +713,8 @@
 
 	SET_MODULE_OWNER(dev);
 
+	netdev_boot_setup_check(dev);
+
 	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
@@ -696,8 +723,16 @@
 	lp->dev = device;
 	lp->type = EL3_EISA;
 	eisa_set_drvdata (edev, dev);
+	el3_common_init(dev);
+
+	err = register_netdev(dev);
+	if (err) {
+		release_region(ioaddr, EL3_IO_EXTENT);
+		return err;
+	}
 
-	return el3_common_init (dev);
+	el3_cards++;
+	return 0;
 }
 #endif
 
diff -urN linux-2.5.70-bk9/drivers/net/e100/e100_main.c linux-2.5.70-bk10/drivers/net/e100/e100_main.c
--- linux-2.5.70-bk9/drivers/net/e100/e100_main.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/e100/e100_main.c	2003-06-05 04:41:36.000000000 -0700
@@ -4272,13 +4272,13 @@
 static int
 e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
 {
-        struct pci_dev *pdev;
+        struct pci_dev *pdev = NULL;
 	
         switch(event) {
         case SYS_DOWN:
         case SYS_HALT:
         case SYS_POWER_OFF:
-                pci_for_each_dev(pdev) {
+		while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
                         if(pci_dev_driver(pdev) == &e100_driver) {
 				/* If net_device struct is allocated? */
                                 if (pci_get_drvdata(pdev))
diff -urN linux-2.5.70-bk9/drivers/net/e1000/e1000_main.c linux-2.5.70-bk10/drivers/net/e1000/e1000_main.c
--- linux-2.5.70-bk9/drivers/net/e1000/e1000_main.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/e1000/e1000_main.c	2003-06-05 04:41:36.000000000 -0700
@@ -2649,7 +2649,7 @@
 	case SYS_DOWN:
 	case SYS_HALT:
 	case SYS_POWER_OFF:
-		pci_for_each_dev(pdev) {
+		while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 			if(pci_dev_driver(pdev) == &e1000_driver)
 				e1000_suspend(pdev, 3);
 		}
diff -urN linux-2.5.70-bk9/drivers/net/hamradio/dmascc.c linux-2.5.70-bk10/drivers/net/hamradio/dmascc.c
--- linux-2.5.70-bk9/drivers/net/hamradio/dmascc.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/hamradio/dmascc.c	2003-06-05 04:41:36.000000000 -0700
@@ -250,8 +250,6 @@
 
 
 /* Function declarations */
-
-int dmascc_init(void) __init;
 static int setup_adapter(int card_base, int type, int n) __init;
 
 static void write_scc(struct scc_priv *priv, int reg, int val);
@@ -299,23 +297,12 @@
 static unsigned long rand;
 
 
-/* Module functions */
-
-#ifdef MODULE
-
-
 MODULE_AUTHOR("Klaus Kudielka");
 MODULE_DESCRIPTION("Driver for high-speed SCC boards");
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i");
 MODULE_LICENSE("GPL");
 
-
-int init_module(void) {
-  return dmascc_init();
-}
-
-
-void cleanup_module(void) {
+static void __exit dmascc_exit(void) {
   int i;
   struct scc_info *info;
 
@@ -341,24 +328,16 @@
   }
 }
 
-
-#else
-
-
+#ifndef MODULE
 void __init dmascc_setup(char *str, int *ints) {
    int i;
 
    for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
       io[i] = ints[i+1];
 }
-
-
 #endif
 
-
-/* Initialization functions */
-
-int __init dmascc_init(void) {
+static int __init dmascc_init(void) {
   int h, i, j, n;
   int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS],
     t1[MAX_NUM_DEVS];
@@ -461,6 +440,9 @@
   return -EIO;
 }
 
+module_init(dmascc_init);
+module_exit(dmascc_exit);
+
 
 int __init setup_adapter(int card_base, int type, int n) {
   int i, irq, chip;
@@ -580,6 +562,7 @@
     if (sizeof(dev->name) == sizeof(char *)) dev->name = priv->name;
 #endif
     sprintf(dev->name, "dmascc%i", 2*n+i);
+    SET_MODULE_OWNER(dev);
     dev->base_addr = card_base;
     dev->irq = irq;
     dev->open = scc_open;
@@ -707,12 +690,9 @@
   struct scc_info *info = priv->info;
   int card_base = priv->card_base;
 
-  MOD_INC_USE_COUNT;
-
   /* Request IRQ if not already used by other channel */
   if (!info->irq_used) {
     if (request_irq(dev->irq, scc_isr, 0, "dmascc", info)) {
-      MOD_DEC_USE_COUNT;
       return -EAGAIN;
     }
   }
@@ -722,7 +702,6 @@
   if (priv->param.dma >= 0) {
     if (request_dma(priv->param.dma, "dmascc")) {
       if (--info->irq_used == 0) free_irq(dev->irq, info);
-      MOD_DEC_USE_COUNT;
       return -EAGAIN;
     } else {
       unsigned long flags = claim_dma_lock();
@@ -866,7 +845,6 @@
   }
   if (--info->irq_used == 0) free_irq(dev->irq, info);
 
-  MOD_DEC_USE_COUNT;
   return 0;
 }
 
diff -urN linux-2.5.70-bk9/drivers/net/ixgb/ixgb_main.c linux-2.5.70-bk10/drivers/net/ixgb/ixgb_main.c
--- linux-2.5.70-bk9/drivers/net/ixgb/ixgb_main.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/ixgb/ixgb_main.c	2003-06-05 04:41:36.000000000 -0700
@@ -2315,7 +2315,7 @@
 	case SYS_DOWN:
 	case SYS_HALT:
 	case SYS_POWER_OFF:
-		pci_for_each_dev(pdev) {
+		while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 			if (pci_dev_driver(pdev) == &ixgb_driver)
 				ixgb_suspend(pdev, 3);
 		}
diff -urN linux-2.5.70-bk9/drivers/net/setup.c linux-2.5.70-bk10/drivers/net/setup.c
--- linux-2.5.70-bk9/drivers/net/setup.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/setup.c	2003-06-05 04:41:36.000000000 -0700
@@ -9,8 +9,6 @@
 #include <linux/init.h>
 #include <linux/netlink.h>
 
-extern int dmascc_init(void);
-
 extern int scc_enet_init(void); 
 extern int fec_enet_init(void); 
 
@@ -29,10 +27,6 @@
 	/*
 	 *	Early setup devices
 	 */
-
-#if defined(CONFIG_DMASCC)
-	{dmascc_init, 0},
-#endif	
 #if defined(CONFIG_SCC_ENET)
         {scc_enet_init, 0},
 #endif
diff -urN linux-2.5.70-bk9/drivers/net/sk98lin/h/skdrv2nd.h linux-2.5.70-bk10/drivers/net/sk98lin/h/skdrv2nd.h
--- linux-2.5.70-bk9/drivers/net/sk98lin/h/skdrv2nd.h	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/sk98lin/h/skdrv2nd.h	2003-06-05 04:41:36.000000000 -0700
@@ -383,6 +383,7 @@
 	int             Mtu;
 	int             Up;
 	SK_AC   *pAC;
+	struct proc_dir_entry *proc;
 };  
 
 typedef struct s_TxPort		TX_PORT;
diff -urN linux-2.5.70-bk9/drivers/net/sk98lin/skge.c linux-2.5.70-bk10/drivers/net/sk98lin/skge.c
--- linux-2.5.70-bk9/drivers/net/sk98lin/skge.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/sk98lin/skge.c	2003-06-05 04:41:36.000000000 -0700
@@ -351,11 +351,7 @@
 static const char SK_Root_Dir_entry[] = "sk98lin";
 static struct proc_dir_entry *pSkRootDir;
 
-
-//extern struct proc_dir_entry Our_Proc_Dir;
-extern int sk_proc_read(char *buffer, char **buffer_location,
-	off_t offset, int buffer_length, int *eof, void *data);
-
+extern struct file_operations sk_proc_fops;
 
 #ifdef DEBUG
 static void	DumpMsg(struct sk_buff*, char*);
@@ -399,7 +395,6 @@
 	struct 		pci_dev	*pdev = NULL;
 	unsigned long		base_address;
 	struct net_device *dev = NULL;
-	struct proc_dir_entry	*pProcFile;
 
 	if (probed)
 		return -ENODEV;
@@ -420,7 +415,6 @@
 	while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
 				      PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
 
-		dev = NULL;
 		pNet = NULL;
 
 		if (pci_enable_device(pdev))
@@ -431,7 +425,8 @@
 		    pci_set_dma_mask(pdev, (u64) 0xffffffff))
 				continue;
 
-		if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == 0) {
+		dev = alloc_etherdev(sizeof(DEV_NET));
+		if (!dev) {
 			printk(KERN_ERR "Unable to allocate etherdev "
 			       "structure!\n");
 			break;
@@ -440,7 +435,7 @@
 		pNet = dev->priv;
 		pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
 		if (pNet->pAC == NULL){
-			kfree(dev->priv);
+			kfree(dev);
 			printk(KERN_ERR "Unable to allocate adapter "
 			       "structure!\n");
 			break;
@@ -477,15 +472,6 @@
 			proc_root_initialized = 1;
 		}
 
-		pProcFile = create_proc_entry(dev->name, 
-			S_IFREG | 0444, pSkRootDir);
- 		pProcFile->read_proc = sk_proc_read;
-		pProcFile->write_proc = NULL;
-		pProcFile->nlink = 1;
-		pProcFile->size = sizeof(dev->name+1);
-		pProcFile->data = (void*)pProcFile;
-		pProcFile->owner = THIS_MODULE;
-
 		/*
 		 * Dummy value.
 		 */
@@ -532,11 +518,29 @@
 		pNet->PortNr = 0;
 		pNet->NetNr = 0;
 
+		if (register_netdev(dev) != 0) {
+			printk(KERN_ERR "Unable to register etherdev\n");
+			sk98lin_root_dev = pAC->Next;
+			remove_proc_entry(dev->name, pSkRootDir);
+			FreeResources(dev);
+			kfree(dev);
+			continue;
+		}
+
+		pNet->proc = create_proc_entry(dev->name, 
+						S_IFREG | 0444, pSkRootDir);
+		if (pNet->proc) {
+			pNet->proc->data = dev;
+			pNet->proc->owner = THIS_MODULE;
+			pNet->proc->proc_fops = &sk_proc_fops;
+		}
+
 		boards_found++;
 
 		/* More then one port found */
 		if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
-			if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) {
+			dev = alloc_etherdev(sizeof(DEV_NET));
+			if (!dev) {
 				printk(KERN_ERR "Unable to allocate etherdev "
 					"structure!\n");
 				break;
@@ -559,20 +563,25 @@
 			dev->do_ioctl =		&SkGeIoctl;
 			dev->change_mtu =	&SkGeChangeMtu;
 
-			pProcFile = create_proc_entry(dev->name, 
-				S_IFREG | 0444, pSkRootDir);
-			pProcFile->read_proc = sk_proc_read;
-			pProcFile->write_proc = NULL;
-			pProcFile->nlink = 1;
-			pProcFile->size = sizeof(dev->name+1);
-			pProcFile->data = (void*)pProcFile;
-			pProcFile->owner = THIS_MODULE;
-
 			memcpy((caddr_t) &dev->dev_addr,
 			(caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
 	
 			printk("%s: %s\n", dev->name, pAC->DeviceStr);
 			printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
+
+			if (register_netdev(dev) != 0) {
+				printk(KERN_ERR "Unable to register etherdev\n");
+				kfree(dev);
+				break;
+			}
+
+			pNet->proc = create_proc_entry(dev->name, 
+						S_IFREG | 0444, pSkRootDir);
+			if (pNet->proc) {
+				pNet->proc->data = dev;
+				pNet->proc->owner = THIS_MODULE;
+				pNet->proc->proc_fops = &sk_proc_fops;
+			}
 		
 		}
 
@@ -740,6 +749,7 @@
 	return cards ? 0 : -ENODEV;
 } /* skge_init_module */
 
+spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED;
 
 /*****************************************************************************
  *
@@ -766,6 +776,11 @@
 
 		netif_stop_queue(sk98lin_root_dev);
 		SkGeYellowLED(pAC, pAC->IoBase, 0);
+		if (pNet->proc) {
+			spin_lock(&sk_devs_lock);
+			pNet->proc->data = NULL;
+			spin_unlock(&sk_devs_lock);
+		}
 
 		if(pAC->BoardLevel == 2) {
 			/* board is still alive */
@@ -792,6 +807,12 @@
 		}
 
 		if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
+			pNet = (DEV_NET*) pAC->dev[1]->priv;
+			if (pNet->proc) {
+				spin_lock(&sk_devs_lock);
+				pNet->proc->data = NULL;
+				spin_unlock(&sk_devs_lock);
+			}
 			unregister_netdev(pAC->dev[1]);
 			kfree(pAC->dev[1]);
 		}
diff -urN linux-2.5.70-bk9/drivers/net/sk98lin/skproc.c linux-2.5.70-bk10/drivers/net/sk98lin/skproc.c
--- linux-2.5.70-bk9/drivers/net/sk98lin/skproc.c	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/sk98lin/skproc.c	2003-06-05 04:41:36.000000000 -0700
@@ -46,378 +46,168 @@
 
 #include "h/skdrv1st.h"
 #include "h/skdrv2nd.h"
-#define ZEROPAD	1		/* pad with zero */
-#define SIGN	2		/* unsigned/signed long */
-#define PLUS	4		/* show plus */
-#define SPACE	8		/* space if plus */
-#define LEFT	16		/* left justified */
-//#define SPECIAL	32		/* 0x */
-#define LARGE	64
-
-extern char * SkNumber(char * str, long long num, int base, int size, 
-				int precision ,int type);
-int proc_read(char *buffer,
-				char **buffer_location,
-				off_t offset,
-				int buffer_length,
-				int *eof,
-				void *data);
-
-
-extern struct net_device *sk98lin_root_dev;
-
-/*****************************************************************************
- *
- * 	proc_read - print "summaries" entry 
- *
- * Description:
- *  This function fills the proc entry with statistic data about 
- *  the ethernet device.
- *  
- *
- * Returns: buffer with statistic data
- *	
- */
-int sk_proc_read(char *buffer,
-char **buffer_location,
-off_t offset,
-int buffer_length,
-int *eof,
-void *data)
+
+extern spinlock_t sk_devs_lock;
+
+static int sk_show_dev(struct net_device *dev, char *buf)
 {
+	DEV_NET	*pNet = (DEV_NET*) dev->priv;
+	SK_AC *pAC = pNet->pAC;
+	int t = pNet->PortNr;
+	SK_RLMT_NET *rlmt = &pAC->Rlmt.Net[t];
+	unsigned long Flags;		
+	unsigned Size;
 	int len = 0;
-	int t;
 	int i;
-	DEV_NET				*pNet;
-	SK_AC				*pAC;
-	char 				test_buf[100];
-	unsigned long			Flags;		
-	unsigned int			Size;
-	struct net_device 		*next;
-	struct net_device 		*SkgeProcDev = sk98lin_root_dev;
 
-	SK_PNMI_STRUCT_DATA 	*pPnmiStruct;
+	SK_PNMI_STRUCT_DATA 	*pPnmiStruct = &pAC->PnmiStruct;
 	SK_PNMI_STAT		*pPnmiStat;
-	struct proc_dir_entry *file = (struct proc_dir_entry*) data;
 
-	while (SkgeProcDev) {
-		pNet = (DEV_NET*) SkgeProcDev->priv;
-		pAC = pNet->pAC;
-		next = pAC->Next;
-		pPnmiStruct = &pAC->PnmiStruct;
-		/* NetIndex in GetStruct is now required, zero is only dummy */
-
-		for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
-			if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
-				t--;
-			
-			spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-			Size = SK_PNMI_STRUCT_SIZE;
-			SkPnmiGetStruct(pAC, pAC->IoBase, 
-				pPnmiStruct, &Size, t-1);
-			spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-	
-			if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
-				pPnmiStat = &pPnmiStruct->Stat[0];
-				len = sprintf(buffer, 
-					"\nDetailed statistic for device %s\n",
-					pAC->dev[t-1]->name);
-				len += sprintf(buffer + len,
-					"==================================\n");
-	
-				/* Board statistics */
-				len += sprintf(buffer + len, 
-					"\nBoard statistics\n\n");
-				len += sprintf(buffer + len,
-					"Active Port               %c\n",
-					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-					Net[t-1].PrefPort]->PortNumber);
-				len += sprintf(buffer + len,
-					"Preferred Port            %c\n",
-					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-					Net[t-1].PrefPort]->PortNumber);
-
-				len += sprintf(buffer + len,
-					"Bus speed (Mhz)           %d\n",
-					pPnmiStruct->BusSpeed);
-
-				len += sprintf(buffer + len,
-					"Bus width (Bit)           %d\n",
-					pPnmiStruct->BusWidth);
-
-				for (i=0; i < SK_MAX_SENSORS; i ++) {
-					if (strcmp(pAC->I2c.SenTable[i].SenDesc,
-							"Temperature") == 0 ) {
-						len += sprintf(buffer + len,
-							"Temperature (C)           %d.%d\n",
-							pAC->I2c.SenTable[i].SenValue / 10,
-							pAC->I2c.SenTable[i].SenValue % 10);
-						len += sprintf(buffer + len,
-							"Temperature (F)           %d.%d\n",
-							((((pAC->I2c.SenTable[i].SenValue)
-							*10)*9)/5 + 3200)/100,
-							((((pAC->I2c.SenTable[i].SenValue)
-							*10)*9)/5 + 3200) % 10);
-					} else if (strcmp(pAC->I2c.SenTable[i].SenDesc,
-							"Speed Fan") == 0 ) {
-						len += sprintf(buffer + len,
-							"Speed Fan                 %d\n",
-							pAC->I2c.SenTable[i].SenValue);
-					} else {
-						len += sprintf(buffer + len,
-							"%-20s      %d.%d\n",
-							pAC->I2c.SenTable[i].SenDesc,
-							pAC->I2c.SenTable[i].SenValue / 1000,
-							pAC->I2c.SenTable[i].SenValue % 1000);
-					}
-				}
-				
-				/*Receive statistics */
-				
-				len += sprintf(buffer + len, 
-				"\nReceive statistics\n\n");
-
-				len += sprintf(buffer + len,
-					"Received bytes            %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxOctetsOkCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Received packets          %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxOkCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Received errors           %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxFcsCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Received dropped          %s\n",
-					SkNumber(test_buf, pPnmiStruct->RxNoBufCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Received multicast        %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxMulticastOkCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Received errors types\n");
-				len += sprintf(buffer + len,
-					"   length errors          %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxRuntCts,
-					10, 0, -1, 0));
-				len += sprintf(buffer + len,
-					"   over errors            %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
-					10, 0, -1, 0));
-				len += sprintf(buffer + len,
-					"   crc errors             %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxFcsCts,
-					10, 0, -1, 0));
-				len += sprintf(buffer + len,
-					"   frame errors           %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxFramingCts,
-					10, 0, -1, 0));
-				len += sprintf(buffer + len,
-					"   fifo errors            %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
-					10, 0, -1, 0));
-				len += sprintf(buffer + len,
-					"   missed errors          %s\n",
-					SkNumber(test_buf, pPnmiStat->StatRxMissedCts,
-					10, 0, -1, 0));
-				
-				/*Transmit statistics */
-				len += sprintf(buffer + len, 
-				"\nTransmit statistics\n\n");
-				
-				len += sprintf(buffer + len,
-					"Transmit bytes            %s\n",
-					SkNumber(test_buf, pPnmiStat->StatTxOctetsOkCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Transmit packets          %s\n",
-					SkNumber(test_buf, pPnmiStat->StatTxOkCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Transmit errors           %s\n",
-					SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Transmit dropped          %s\n",
-					SkNumber(test_buf, pPnmiStruct->TxNoBufCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Transmit collisions       %s\n",
-					SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
-					10,0,-1,0));
-				len += sprintf(buffer + len,
-					"Transmited errors types\n");
-				len += sprintf(buffer + len,
-					"   aborted errors         %ld\n",
-					pAC->stats.tx_aborted_errors);
-				len += sprintf(buffer + len,
-					"   carrier errors         %s\n",
-					SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
-					10, 0, -1, 0));
-				len += sprintf(buffer + len,
-					"   fifo errors            %s\n",
-					SkNumber(test_buf, pPnmiStat->StatTxFifoUnderrunCts,
-					10, 0, -1, 0));
-				len += sprintf(buffer + len,
-					"   heartbeat errors       %s\n",
-					SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
-					10, 0, -1, 0));
-				len += sprintf(buffer + len,
-					"   window errors          %ld\n",
-					pAC->stats.tx_window_errors);
-			}
+	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+	Size = SK_PNMI_STRUCT_SIZE;
+	SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t);
+	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+	pPnmiStat = &pPnmiStruct->Stat[0];
+
+	len = sprintf(buf, "\nDetailed statistic for device %s\n", dev->name);
+	len += sprintf(buf + len, "==================================\n");
+
+	/* Board statistics */
+	len += sprintf(buf + len, "\nBoard statistics\n\n");
+	len += sprintf(buf + len, "Active Port               %c\n",
+		'A' + rlmt->Port[rlmt->ActivePort]->PortNumber);
+	len += sprintf(buf + len, "Preferred Port            %c\n",
+		'A' + rlmt->Port[rlmt->PrefPort]->PortNumber);
+
+	len += sprintf(buf + len, "Bus speed (Mhz)           %d\n",
+		pPnmiStruct->BusSpeed);
+
+	len += sprintf(buf + len, "Bus width (Bit)           %d\n",
+		pPnmiStruct->BusWidth);
+
+	for (i=0; i < SK_MAX_SENSORS; i ++) {
+		SK_SENSOR *sens = &pAC->I2c.SenTable[i];
+		SK_I32 val = sens->SenValue;
+		if (strcmp(sens->SenDesc, "Temperature") == 0 ) {
+			len += sprintf(buf + len,
+				"Temperature (C)           %d.%d\n",
+				val / 10, val % 10);
+			val = val * 18 + 3200;
+			len += sprintf(buf + len,
+				"Temperature (F)           %d.%d\n",
+				val/100, val % 10);
+		} else if (strcmp(sens->SenDesc, "Speed Fan") == 0 ) {
+			len += sprintf(buf + len,
+				"Speed Fan                 %d\n",
+				val);
+		} else {
+			len += sprintf(buf + len,
+				"%-20s      %d.%d\n",
+				sens->SenDesc, val / 1000, val % 1000);
 		}
-		SkgeProcDev = next;
-	}
-	if (offset >= len) {
-		*eof = 1;
-		return 0;
 	}
+	
+	/*Receive statistics */
+	
+	len += sprintf(buf + len, "\nReceive statistics\n\n");
 
-	*buffer_location = buffer + offset;
-	if (buffer_length >= len - offset) {
-		*eof = 1;
-	}
-	return (min_t(int, buffer_length, len - offset));
+	len += sprintf(buf + len, "Received bytes            %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxOctetsOkCts);
+	len += sprintf(buf + len, "Received packets          %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxOkCts);
+	len += sprintf(buf + len, "Received errors           %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxFcsCts);
+	len += sprintf(buf + len, "Received dropped          %Ld\n",
+		(unsigned long long) pPnmiStruct->RxNoBufCts);
+	len += sprintf(buf + len, "Received multicast        %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxMulticastOkCts);
+	len += sprintf(buf + len, "Received errors types\n");
+	len += sprintf(buf + len, "   length errors          %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxRuntCts);
+	len += sprintf(buf + len, "   over errors            %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
+	len += sprintf(buf + len, "   crc errors             %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxFcsCts);
+	len += sprintf(buf + len, "   frame errors           %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxFramingCts);
+	len += sprintf(buf + len, "   fifo errors            %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
+	len += sprintf(buf + len, "   missed errors          %Ld\n",
+		(unsigned long long) pPnmiStat->StatRxMissedCts);
+	
+	/*Transmit statistics */
+	len += sprintf(buf + len, "\nTransmit statistics\n\n");
+	
+	len += sprintf(buf + len, "Transmit bytes            %Ld\n",
+		(unsigned long long) pPnmiStat->StatTxOctetsOkCts);
+	len += sprintf(buf + len, "Transmit packets          %Ld\n",
+		(unsigned long long) pPnmiStat->StatTxOkCts);
+	len += sprintf(buf + len, "Transmit errors           %Ld\n",
+		(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+	len += sprintf(buf + len, "Transmit dropped          %Ld\n",
+		(unsigned long long) pPnmiStruct->TxNoBufCts);
+	len += sprintf(buf + len, "Transmit collisions       %Ld\n",
+		(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+	len += sprintf(buf + len, "Transmited errors types\n");
+	len += sprintf(buf + len, "   aborted errors         %ld\n",
+		pAC->stats.tx_aborted_errors);
+	len += sprintf(buf + len, "   carrier errors         %Ld\n",
+		(unsigned long long) pPnmiStat->StatTxCarrierCts);
+	len += sprintf(buf + len, "   fifo errors            %Ld\n",
+		(unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
+	len += sprintf(buf + len, "   heartbeat errors       %Ld\n",
+		(unsigned long long) pPnmiStat->StatTxCarrierCts);
+	len += sprintf(buf + len, "   window errors          %ld\n",
+		pAC->stats.tx_window_errors);
+	return len;
 }
 
-
-
-
-
-/*****************************************************************************
- *
- * SkDoDiv - convert 64bit number
- *
- * Description:
- *	This function "converts" a long long number.
- *
- * Returns:
- *	remainder of division
- */
-static long SkDoDiv (long long Dividend, int Divisor, long long *pErg)
+static ssize_t sk_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
 {
- long   	Rest;
- long long 	Ergebnis;
- long   	Akku;
-
-
- Akku  = Dividend >> 32;
-
- Ergebnis = ((long long) (Akku / Divisor)) << 32;
- Rest = Akku % Divisor ;
-
- Akku = Rest << 16;
- Akku |= ((Dividend & 0xFFFF0000) >> 16);
-
-
- Ergebnis += ((long long) (Akku / Divisor)) << 16;
- Rest = Akku % Divisor ;
-
- Akku = Rest << 16;
- Akku |= (Dividend & 0xFFFF);
+	struct inode * inode = file->f_dentry->d_inode;
+	struct proc_dir_entry *entry = PDE(inode);
+	char *page = (char *)__get_free_page(GFP_KERNEL);
+	struct net_device *dev;
+	loff_t pos = *ppos;
+	ssize_t res = 0;
+	int len = 0;
 
- Ergebnis += (Akku / Divisor);
- Rest = Akku % Divisor ;
+	if (!page)
+		return -ENOMEM;
 
- *pErg = Ergebnis;
- return (Rest);
+	spin_lock(&sk_devs_lock);
+	dev = entry->data;
+	if (dev)
+		len = sk_show_dev(dev, page);
+	spin_unlock(&sk_devs_lock);
+
+	if (pos >= 0 && pos < len) {
+		res = nbytes;
+		if (res > len - pos)
+			res = len - pos;
+		if (copy_to_user(page + pos, buf, nbytes))
+			res = -EFAULT;
+		else
+			*ppos = pos + res;
+	}
+	free_page((unsigned long) page);
+	return nbytes;
 }
 
-
-#if 0
-#define do_div(n,base) ({ \
-long long __res; \
-__res = ((unsigned long long) n) % (unsigned) base; \
-n = ((unsigned long long) n) / (unsigned) base; \
-__res; })
-
-#endif
-
-
-/*****************************************************************************
- *
- * SkNumber - Print results
- *
- * Description:
- *	This function converts a long long number into a string.
- *
- * Returns:
- *	number as string
- */
-char * SkNumber(char * str, long long num, int base, int size, int precision
-	,int type)
+static loff_t sk_lseek(struct file *file, loff_t offset, int orig)
 {
-	char c,sign,tmp[66], *strorg = str;
-	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
-	int i;
-
-	if (type & LARGE)
-		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-	if (type & LEFT)
-		type &= ~ZEROPAD;
-	if (base < 2 || base > 36)
-		return 0;
-	c = (type & ZEROPAD) ? '0' : ' ';
-	sign = 0;
-	if (type & SIGN) {
-		if (num < 0) {
-			sign = '-';
-			num = -num;
-			size--;
-		} else if (type & PLUS) {
-			sign = '+';
-			size--;
-		} else if (type & SPACE) {
-			sign = ' ';
-			size--;
-		}
-	}
-	if (type & SPECIAL) {
-		if (base == 16)
-			size -= 2;
-		else if (base == 8)
-			size--;
-	}
-	i = 0;
-	if (num == 0)
-		tmp[i++]='0';
-	else while (num != 0)
-		tmp[i++] = digits[SkDoDiv(num,base, &num)];
-
-	if (i > precision)
-		precision = i;
-	size -= precision;
-	if (!(type&(ZEROPAD+LEFT)))
-		while(size-->0)
-			*str++ = ' ';
-	if (sign)
-		*str++ = sign;
-	if (type & SPECIAL) {
-		if (base==8)
-			*str++ = '0';
-		else if (base==16) {
-			*str++ = '0';
-			*str++ = digits[33];
-		}
+	switch (orig) {
+	    case 1:
+		offset += file->f_pos;
+	    case 0:
+		if (offset >= 0)
+			return file->f_pos = offset;
 	}
-	if (!(type & LEFT))
-		while (size-- > 0)
-			*str++ = c;
-	while (i < precision--)
-		*str++ = '0';
-	while (i-- > 0)
-		*str++ = tmp[i];
-	while (size-- > 0)
-		*str++ = ' ';
-	
-	str[0] = '\0';
-	
-	return strorg;
+	return -EINVAL;
 }
 
-
-
+struct file_operations sk_proc_fops = {
+	.read = sk_read,
+	.llseek	= sk_lseek,
+};
diff -urN linux-2.5.70-bk9/drivers/net/wan/sdla.c linux-2.5.70-bk10/drivers/net/wan/sdla.c
--- linux-2.5.70-bk9/drivers/net/wan/sdla.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/drivers/net/wan/sdla.c	2003-06-05 04:41:36.000000000 -0700
@@ -1682,11 +1682,13 @@
 
 static void __exit exit_sdla(void)
 {
+#ifdef MODULE
 	unregister_netdev(&sdla0);
 	if (sdla0.priv)
 		kfree(sdla0.priv);
 	if (sdla0.irq)
 		free_irq(sdla0.irq, &sdla0);
+#endif
 }
 
 MODULE_LICENSE("GPL");
diff -urN linux-2.5.70-bk9/drivers/parport/parport_pc.c linux-2.5.70-bk10/drivers/parport/parport_pc.c
--- linux-2.5.70-bk9/drivers/parport/parport_pc.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk10/drivers/parport/parport_pc.c	2003-06-05 04:41:36.000000000 -0700
@@ -2979,10 +2979,10 @@
 static int __init parport_pc_init_superio (int autoirq, int autodma)
 {
 	const struct pci_device_id *id;
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 	int ret = 0;
 
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		id = pci_match_device (parport_pc_pci_tbl, pdev);
 		if (id == NULL || id->driver_data >= last_sio)
 			continue;
diff -urN linux-2.5.70-bk9/drivers/pci/Makefile linux-2.5.70-bk10/drivers/pci/Makefile
--- linux-2.5.70-bk9/drivers/pci/Makefile	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/Makefile	2003-06-05 04:41:36.000000000 -0700
@@ -12,6 +12,9 @@
 obj-$(CONFIG_PCI) += setup-res.o
 endif
 
+# Build the PCI Hotplug drivers if we were asked to
+obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
+
 #
 # Some architectures use the generic PCI setup functions
 #
diff -urN linux-2.5.70-bk9/drivers/pci/access.c linux-2.5.70-bk10/drivers/pci/access.c
--- linux-2.5.70-bk9/drivers/pci/access.c	2003-05-26 18:01:02.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/access.c	2003-06-05 04:41:36.000000000 -0700
@@ -7,7 +7,7 @@
  * configuration space.
  */
 
-spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  *  Wrappers for all PCI configuration access functions.  They just check
@@ -60,4 +60,3 @@
 EXPORT_SYMBOL(pci_bus_write_config_byte);
 EXPORT_SYMBOL(pci_bus_write_config_word);
 EXPORT_SYMBOL(pci_bus_write_config_dword);
-EXPORT_SYMBOL(pci_lock);
diff -urN linux-2.5.70-bk9/drivers/pci/bus.c linux-2.5.70-bk10/drivers/pci/bus.c
--- linux-2.5.70-bk9/drivers/pci/bus.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/bus.c	2003-06-05 04:41:36.000000000 -0700
@@ -94,9 +94,7 @@
 
 		device_add(&dev->dev);
 		list_add_tail(&dev->global_list, &pci_devices);
-#ifdef CONFIG_PROC_FS
 		pci_proc_attach_device(dev);
-#endif
 		pci_create_sysfs_dev_files(dev);
 
 	}
@@ -129,6 +127,5 @@
 	}
 }
 
-EXPORT_SYMBOL(pci_bus_alloc_resource);
 EXPORT_SYMBOL(pci_bus_add_devices);
 EXPORT_SYMBOL(pci_enable_bridges);
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/Kconfig linux-2.5.70-bk10/drivers/pci/hotplug/Kconfig
--- linux-2.5.70-bk9/drivers/pci/hotplug/Kconfig	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/Kconfig	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,120 @@
+#
+# PCI Hotplug support
+#
+
+menu "PCI Hotplug Support"
+	depends on HOTPLUG
+
+config HOTPLUG_PCI
+	tristate "Support for PCI Hotplug (EXPERIMENTAL)"
+	depends on PCI && EXPERIMENTAL
+	---help---
+	  Say Y here if you have a motherboard with a PCI Hotplug controller.
+	  This allows you to add and remove PCI cards while the machine is
+	  powered up and running.  The file system pcihpfs must be mounted
+	  in order to interact with any PCI Hotplug controllers.
+
+	  This code is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called pci_hotplug. If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_COMPAQ
+	tristate "Compaq PCI Hotplug driver"
+	depends on HOTPLUG_PCI && X86
+	help
+	  Say Y here if you have a motherboard with a Compaq PCI Hotplug
+	  controller.
+
+	  This code is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called cpqphp. If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_COMPAQ_NVRAM
+	bool "Save configuration into NVRAM on Compaq servers"
+	depends on HOTPLUG_PCI_COMPAQ
+	help
+	  Say Y here if you have a Compaq server that has a PCI Hotplug
+	  controller.  This will allow the PCI Hotplug driver to store the PCI
+	  system configuration options in NVRAM.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_IBM
+	tristate "IBM PCI Hotplug driver"
+	depends on HOTPLUG_PCI && X86_IO_APIC && X86
+	help
+	  Say Y here if you have a motherboard with a IBM PCI Hotplug
+	  controller.
+
+	  This code is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called cpqphp. If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_ACPI
+	tristate "ACPI PCI Hotplug driver"
+	depends on ACPI_BUS && HOTPLUG_PCI
+	help
+	  Say Y here if you have a system that supports PCI Hotplug using
+	  ACPI.
+
+	  This code is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called acpiphp. If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_CPCI
+	tristate "CompactPCI Hotplug driver"
+	depends on HOTPLUG_PCI
+	help
+	  Say Y here if you have a CompactPCI system card with CompactPCI
+	  hotswap support per the PICMG 2.1 specification.
+
+	  This code is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called cpci_hotplug. If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_CPCI_ZT5550
+	tristate "Ziatech ZT5550 CompactPCI Hotplug driver"
+	depends on HOTPLUG_PCI_CPCI && X86
+	help
+	  Say Y here if you have an Performance Technologies (formerly Intel,
+          formerly just Ziatech) Ziatech ZT5550 CompactPCI system card.
+
+	  This code is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called cpcihp_zt5550. If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_CPCI_GENERIC
+	tristate "Generic port I/O CompactPCI Hotplug driver"
+	depends on HOTPLUG_PCI_CPCI && X86
+	help
+	  Say Y here if you have a CompactPCI system card that exposes the #ENUM
+	  hotswap signal as a bit in a system register that can be read through
+	  standard port I/O.
+
+	  This code is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called cpcihp_generic. If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+
+	  When in doubt, say N.
+
+endmenu
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/Makefile linux-2.5.70-bk10/drivers/pci/hotplug/Makefile
--- linux-2.5.70-bk9/drivers/pci/hotplug/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/Makefile	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,44 @@
+#
+# Makefile for the Linux kernel pci hotplug controller drivers.
+#
+
+obj-$(CONFIG_HOTPLUG_PCI)		+= pci_hotplug.o
+obj-$(CONFIG_HOTPLUG_PCI_COMPAQ)	+= cpqphp.o
+obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
+obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
+obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)	+= cpcihp_zt5550.o
+obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC)	+= cpcihp_generic.o
+
+pci_hotplug-objs	:=	pci_hotplug_core.o
+
+ifdef CONFIG_HOTPLUG_PCI_CPCI
+pci_hotplug-objs	+=	cpci_hotplug_core.o	\
+				cpci_hotplug_pci.o
+endif
+
+cpqphp-objs		:=	cpqphp_core.o	\
+				cpqphp_ctrl.o	\
+				cpqphp_sysfs.o	\
+				cpqphp_pci.o
+
+ibmphp-objs		:=	ibmphp_core.o	\
+				ibmphp_ebda.o	\
+				ibmphp_pci.o	\
+				ibmphp_res.o	\
+				ibmphp_hpc.o
+
+acpiphp-objs		:=	acpiphp_core.o	\
+				acpiphp_glue.o	\
+				acpiphp_pci.o	\
+				acpiphp_res.o
+
+ifdef CONFIG_HOTPLUG_PCI_ACPI
+  EXTRA_CFLAGS  += -D_LINUX -I$(TOPDIR)/drivers/acpi
+  ifdef CONFIG_ACPI_DEBUG
+    EXTRA_CFLAGS += -DACPI_DEBUG_OUTPUT
+  endif
+endif
+
+ifeq ($(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM),y)
+	cpqphp-objs += cpqphp_nvram.o
+endif
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp.h linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp.h
--- linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp.h	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,262 @@
+/*
+ * ACPI PCI Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>,
+ *		    <h-aono@ap.jp.nec.com>,
+ *		    <t-kouchi@cq.jp.nec.com>
+ *
+ */
+
+#ifndef _ACPIPHP_H
+#define _ACPIPHP_H
+
+#include <linux/acpi.h>
+#include "pci_hotplug.h"
+
+#define dbg(format, arg...)					\
+	do {							\
+		if (acpiphp_debug)				\
+			printk(KERN_DEBUG "%s: " format,	\
+				MY_NAME , ## arg); 		\
+	} while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+
+#define SLOT_MAGIC	0x67267322
+/* name size which is used for entries in pcihpfs */
+#define SLOT_NAME_SIZE	32		/* ACPI{_SUN}-{BUS}:{DEV} */
+
+struct acpiphp_bridge;
+struct acpiphp_slot;
+struct pci_resource;
+
+/*
+ * struct slot - slot information for each *physical* slot
+ */
+struct slot {
+	u32 magic;
+	u8 number;
+	struct hotplug_slot	*hotplug_slot;
+	struct list_head	slot_list;
+
+	struct acpiphp_slot	*acpi_slot;
+};
+
+/*
+ * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
+ */
+struct pci_resource {
+	struct pci_resource * next;
+	u64 base;
+	u32 length;
+};
+
+/**
+ * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
+ * @cache_line_size in DWORD
+ * @latency_timer in PCI clock
+ * @enable_SERR 0 or 1
+ * @enable_PERR 0 or 1
+ */
+struct hpp_param {
+	u8 cache_line_size;
+	u8 latency_timer;
+	u8 enable_SERR;
+	u8 enable_PERR;
+};
+
+
+/**
+ * struct acpiphp_bridge - PCI bridge information
+ *
+ * for each bridge device in ACPI namespace
+ */
+struct acpiphp_bridge {
+	struct list_head list;
+	acpi_handle handle;
+	struct acpiphp_slot *slots;
+	int type;
+	int nr_slots;
+
+	u8 seg;
+	u8 bus;
+	u8 sub;
+
+	u32 flags;
+
+	/* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
+	struct pci_bus *pci_bus;
+
+	/* PCI-to-PCI bridge device */
+	struct pci_dev *pci_dev;
+
+	/* ACPI 2.0 _HPP parameters */
+	struct hpp_param hpp;
+
+	spinlock_t res_lock;
+
+	/* available resources on this bus */
+	struct pci_resource *mem_head;
+	struct pci_resource *p_mem_head;
+	struct pci_resource *io_head;
+	struct pci_resource *bus_head;
+};
+
+
+/**
+ * struct acpiphp_slot - PCI slot information
+ *
+ * PCI slot information for each *physical* PCI slot
+ */
+struct acpiphp_slot {
+	struct acpiphp_slot *next;
+	struct acpiphp_bridge *bridge;	/* parent */
+	struct list_head funcs;		/* one slot may have different
+					   objects (i.e. for each function) */
+	struct semaphore crit_sect;
+
+	u32		id;		/* slot id (serial #) for hotplug core */
+	u8		device;		/* pci device# */
+
+	u32		sun;		/* ACPI _SUN (slot unique number) */
+	u32		slotno;		/* slot number relative to bridge */
+	u32		flags;		/* see below */
+};
+
+
+/**
+ * struct acpiphp_func - PCI function information
+ *
+ * PCI function information for each object in ACPI namespace
+ * typically 8 objects per slot (i.e. for each PCI function)
+ */
+struct acpiphp_func {
+	struct acpiphp_slot *slot;	/* parent */
+
+	struct list_head sibling;
+	struct pci_dev *pci_dev;
+
+	acpi_handle	handle;
+
+	u8		function;	/* pci function# */
+	u32		flags;		/* see below */
+
+	/* resources used for this function */
+	struct pci_resource *mem_head;
+	struct pci_resource *p_mem_head;
+	struct pci_resource *io_head;
+	struct pci_resource *bus_head;
+};
+
+
+/* PCI bus bridge HID */
+#define ACPI_PCI_HOST_HID		"PNP0A03"
+
+/* PCI BRIDGE type */
+#define BRIDGE_TYPE_HOST		0
+#define BRIDGE_TYPE_P2P			1
+
+/* ACPI _STA method value (ignore bit 4; battery present) */
+#define ACPI_STA_PRESENT		(0x00000001)
+#define ACPI_STA_ENABLED		(0x00000002)
+#define ACPI_STA_SHOW_IN_UI		(0x00000004)
+#define ACPI_STA_FUNCTIONING		(0x00000008)
+#define ACPI_STA_ALL			(0x0000000f)
+
+/* bridge flags */
+#define BRIDGE_HAS_STA		(0x00000001)
+#define BRIDGE_HAS_EJ0		(0x00000002)
+#define BRIDGE_HAS_HPP		(0x00000004)
+#define BRIDGE_HAS_PS0		(0x00000010)
+#define BRIDGE_HAS_PS1		(0x00000020)
+#define BRIDGE_HAS_PS2		(0x00000040)
+#define BRIDGE_HAS_PS3		(0x00000080)
+
+/* slot flags */
+
+#define SLOT_POWEREDON		(0x00000001)
+#define SLOT_ENABLED		(0x00000002)
+#define SLOT_MULTIFUNCTION	(x000000004)
+
+/* function flags */
+
+#define FUNC_HAS_STA		(0x00000001)
+#define FUNC_HAS_EJ0		(0x00000002)
+#define FUNC_HAS_PS0		(0x00000010)
+#define FUNC_HAS_PS1		(0x00000020)
+#define FUNC_HAS_PS2		(0x00000040)
+#define FUNC_HAS_PS3		(0x00000080)
+
+/* not yet */
+#define SLOT_SUPPORT_66MHZ	(0x00010000)
+#define SLOT_SUPPORT_100MHZ	(0x00020000)
+#define SLOT_SUPPORT_133MHZ	(0x00040000)
+#define SLOT_SUPPORT_PCIX	(0x00080000)
+
+/* function prototypes */
+
+/* acpiphp_glue.c */
+extern int acpiphp_glue_init (void);
+extern void acpiphp_glue_exit (void);
+extern int acpiphp_get_num_slots (void);
+extern struct acpiphp_slot *get_slot_from_id (int id);
+typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
+extern int acpiphp_for_each_slot (acpiphp_callback fn, void *data);
+
+extern int acpiphp_check_bridge (struct acpiphp_bridge *bridge);
+extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
+extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
+extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot);
+extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot);
+extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
+extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
+
+/* acpiphp_pci.c */
+extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
+extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
+extern int acpiphp_configure_function (struct acpiphp_func *func);
+extern int acpiphp_unconfigure_function (struct acpiphp_func *func);
+extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
+extern int acpiphp_init_func_resource (struct acpiphp_func *func);
+
+/* acpiphp_res.c */
+extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
+extern struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size);
+extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
+extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
+extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
+extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
+extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
+extern void acpiphp_free_resource (struct pci_resource **res);
+extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
+extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
+
+/* variables */
+extern int acpiphp_debug;
+
+#endif /* _ACPIPHP_H */
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp_core.c linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp_core.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp_core.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp_core.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,505 @@
+/*
+ * ACPI PCI Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>,
+ *                  <h-aono@ap.jp.nec.com>,
+ *		    <t-kouchi@cq.jp.nec.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include "pci_hotplug.h"
+#include "acpiphp.h"
+
+static LIST_HEAD(slot_list);
+
+#if !defined(CONFIG_HOTPLUG_PCI_ACPI_MODULE)
+	#define MY_NAME	"acpiphp"
+#else
+	#define MY_NAME	THIS_MODULE->name
+#endif
+
+static int debug;
+int acpiphp_debug;
+
+/* local variables */
+static int num_slots;
+
+#define DRIVER_VERSION	"0.4"
+#define DRIVER_AUTHOR	"Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kouchi@cq.jp.nec.com>"
+#define DRIVER_DESC	"ACPI Hot Plug PCI Controller Driver"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+
+static int enable_slot		(struct hotplug_slot *slot);
+static int disable_slot		(struct hotplug_slot *slot);
+static int set_attention_status (struct hotplug_slot *slot, u8 value);
+static int hardware_test	(struct hotplug_slot *slot, u32 value);
+static int get_power_status	(struct hotplug_slot *slot, u8 *value);
+static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
+static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
+static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
+static int get_max_bus_speed	(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
+static int get_cur_bus_speed	(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
+
+static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
+	.owner			= THIS_MODULE,
+	.enable_slot		= enable_slot,
+	.disable_slot		= disable_slot,
+	.set_attention_status	= set_attention_status,
+	.hardware_test		= hardware_test,
+	.get_power_status	= get_power_status,
+	.get_attention_status	= get_attention_status,
+	.get_latch_status	= get_latch_status,
+	.get_adapter_status	= get_adapter_status,
+	.get_max_bus_speed	= get_max_bus_speed,
+	.get_cur_bus_speed	= get_cur_bus_speed,
+};
+
+
+/* Inline functions to check the sanity of a pointer that is passed to us */
+static inline int slot_paranoia_check (struct slot *slot, const char *function)
+{
+	if (!slot) {
+		dbg("%s - slot == NULL\n", function);
+		return -1;
+	}
+	if (slot->magic != SLOT_MAGIC) {
+		dbg("%s - bad magic number for slot\n", function);
+		return -1;
+	}
+	if (!slot->hotplug_slot) {
+		dbg("%s - slot->hotplug_slot == NULL!\n", function);
+		return -1;
+	}
+	return 0;
+}
+
+
+static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
+{
+	struct slot *slot;
+
+	if (!hotplug_slot) {
+		dbg("%s - hotplug_slot == NULL\n", function);
+		return NULL;
+	}
+
+	slot = (struct slot *)hotplug_slot->private;
+	if (slot_paranoia_check(slot, function))
+                return NULL;
+	return slot;
+}
+
+
+/**
+ * enable_slot - power on and enable a slot
+ * @hotplug_slot: slot to enable
+ *
+ * Actual tasks are done in acpiphp_enable_slot()
+ *
+ */
+static int enable_slot (struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	int retval = 0;
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	/* enable the specified slot */
+	retval = acpiphp_enable_slot(slot->acpi_slot);
+
+	return retval;
+}
+
+
+/**
+ * disable_slot - disable and power off a slot
+ * @hotplug_slot: slot to disable
+ *
+ * Actual tasks are done in acpiphp_disable_slot()
+ *
+ */
+static int disable_slot (struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	int retval = 0;
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	/* disable the specified slot */
+	retval = acpiphp_disable_slot(slot->acpi_slot);
+
+	return retval;
+}
+
+
+/**
+ * set_attention_status - set attention LED
+ *
+ * TBD:
+ * ACPI doesn't have known method to manipulate
+ * attention status LED.
+ *
+ */
+static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
+{
+	int retval = 0;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	switch (status) {
+		case 0:
+			/* FIXME turn light off */
+			hotplug_slot->info->attention_status = 0;
+			break;
+
+		case 1:
+		default:
+			/* FIXME turn light on */
+			hotplug_slot->info->attention_status = 1;
+			break;
+	}
+
+	return retval;
+}
+
+
+/**
+ * hardware_test - hardware test
+ *
+ * We have nothing to do for now...
+ *
+ */
+static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	int retval = 0;
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	err("No hardware tests are defined for this driver\n");
+	retval = -ENODEV;
+
+	return retval;
+}
+
+
+/**
+ * get_power_status - get power status of a slot
+ * @hotplug_slot: slot to get status
+ * @value: pointer to store status
+ *
+ * Some platforms may not implement _STA method properly.
+ * In that case, the value returned may not be reliable.
+ *
+ */
+static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	int retval = 0;
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	*value = acpiphp_get_power_status(slot->acpi_slot);
+
+	return retval;
+}
+
+
+/**
+ * get_attention_status - get attention LED status
+ *
+ * TBD:
+ * ACPI doesn't provide any formal means to access attention LED status.
+ *
+ */
+static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	int retval = 0;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	*value = hotplug_slot->info->attention_status;
+
+	return retval;
+}
+
+
+/**
+ * get_latch_status - get latch status of a slot
+ * @hotplug_slot: slot to get status
+ * @value: pointer to store status
+ *
+ * ACPI doesn't provide any formal means to access latch status.
+ * Instead, we fake latch status from _STA
+ *
+ */
+static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	int retval = 0;
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	*value = acpiphp_get_latch_status(slot->acpi_slot);
+
+	return retval;
+}
+
+
+/**
+ * get_adapter_status - get adapter status of a slot
+ * @hotplug_slot: slot to get status
+ * @value: pointer to store status
+ *
+ * ACPI doesn't provide any formal means to access adapter status.
+ * Instead, we fake adapter status from _STA
+ *
+ */
+static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	int retval = 0;
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	*value = acpiphp_get_adapter_status(slot->acpi_slot);
+
+	return retval;
+}
+
+
+/* return dummy value because ACPI doesn't provide any method... */
+static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	*value = PCI_SPEED_UNKNOWN;
+
+	return 0;
+}
+
+
+/* return dummy value because ACPI doesn't provide any method... */
+static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	*value = PCI_SPEED_UNKNOWN;
+
+	return 0;
+}
+
+
+static int init_acpi (void)
+{
+	int retval;
+
+	/* initialize internal data structure etc. */
+	retval = acpiphp_glue_init();
+
+	/* read initial number of slots */
+	if (!retval) {
+		num_slots = acpiphp_get_num_slots();
+		if (num_slots == 0)
+			retval = -ENODEV;
+	}
+
+	return retval;
+}
+
+
+/**
+ * make_slot_name - make a slot name that appears in pcihpfs
+ * @slot: slot to name
+ *
+ */
+static void make_slot_name (struct slot *slot)
+{
+	snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "ACPI%d-%02x:%02x",
+		 slot->acpi_slot->sun,
+		 slot->acpi_slot->bridge->bus,
+		 slot->acpi_slot->device);
+}
+
+/**
+ * init_slots - initialize 'struct slot' structures for each slot
+ *
+ */
+static int init_slots (void)
+{
+	struct slot *slot;
+	int retval = 0;
+	int i;
+
+	for (i = 0; i < num_slots; ++i) {
+		slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
+		if (!slot)
+			return -ENOMEM;
+		memset(slot, 0, sizeof(struct slot));
+
+		slot->hotplug_slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
+		if (!slot->hotplug_slot) {
+			kfree(slot);
+			return -ENOMEM;
+		}
+		memset(slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
+
+		slot->hotplug_slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
+		if (!slot->hotplug_slot->info) {
+			kfree(slot->hotplug_slot);
+			kfree(slot);
+			return -ENOMEM;
+		}
+		memset(slot->hotplug_slot->info, 0, sizeof(struct hotplug_slot_info));
+
+		slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
+		if (!slot->hotplug_slot->name) {
+			kfree(slot->hotplug_slot->info);
+			kfree(slot->hotplug_slot);
+			kfree(slot);
+			return -ENOMEM;
+		}
+
+		slot->magic = SLOT_MAGIC;
+		slot->number = i;
+
+		slot->hotplug_slot->private = slot;
+		slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
+
+		slot->acpi_slot = get_slot_from_id(i);
+		slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
+		slot->hotplug_slot->info->attention_status = acpiphp_get_attention_status(slot->acpi_slot);
+		slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
+		slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
+
+		make_slot_name(slot);
+
+		retval = pci_hp_register(slot->hotplug_slot);
+		if (retval) {
+			err("pci_hp_register failed with error %d\n", retval);
+			kfree(slot->hotplug_slot->info);
+			kfree(slot->hotplug_slot->name);
+			kfree(slot->hotplug_slot);
+			kfree(slot);
+			return retval;
+		}
+
+		/* add slot to our internal list */
+		list_add(&slot->slot_list, &slot_list);
+		info("Slot [%s] registered\n", slot->hotplug_slot->name);
+	}
+
+	return retval;
+}
+
+
+static void cleanup_slots (void)
+{
+	struct list_head *tmp, *n;
+	struct slot *slot;
+
+	list_for_each_safe (tmp, n, &slot_list) {
+		slot = list_entry(tmp, struct slot, slot_list);
+		list_del(&slot->slot_list);
+		pci_hp_deregister(slot->hotplug_slot);
+		kfree(slot->hotplug_slot->info);
+		kfree(slot->hotplug_slot->name);
+		kfree(slot->hotplug_slot);
+		kfree(slot);
+	}
+
+	return;
+}
+
+
+static int __init acpiphp_init(void)
+{
+	int retval;
+
+	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+
+	acpiphp_debug = debug;
+
+	/* read all the ACPI info from the system */
+	retval = init_acpi();
+	if (retval)
+		return retval;
+
+	retval = init_slots();
+	if (retval)
+		return retval;
+
+	return 0;
+}
+
+
+static void __exit acpiphp_exit(void)
+{
+	cleanup_slots();
+	/* deallocate internal data structures etc. */
+	acpiphp_glue_exit();
+}
+
+module_init(acpiphp_init);
+module_exit(acpiphp_exit);
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp_glue.c linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp_glue.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp_glue.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp_glue.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,1336 @@
+/*
+ * ACPI PCI HotPlug glue functions to ACPI CA subsystem
+ *
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <t-kouchi@cq.jp.nec.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <asm/semaphore.h>
+
+#include "../pci.h"
+#include "pci_hotplug.h"
+#include "acpiphp.h"
+
+static LIST_HEAD(bridge_list);
+
+#define MY_NAME "acpiphp_glue"
+
+static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
+static void handle_hotplug_event_func (acpi_handle, u32, void *);
+
+/*
+ * initialization & terminatation routines
+ */
+
+/**
+ * is_ejectable - determine if a slot is ejectable
+ * @handle: handle to acpi namespace
+ *
+ * Ejectable slot should satisfy at least these conditions:
+ *
+ *  1. has _ADR method
+ *  2. has _EJ0 method
+ *
+ * optionally
+ *
+ *  1. has _STA method
+ *  2. has _PS0 method
+ *  3. has _PS3 method
+ *  4. ..
+ *
+ */
+static int is_ejectable (acpi_handle handle)
+{
+	acpi_status status;
+	acpi_handle tmp;
+
+	status = acpi_get_handle(handle, "_ADR", &tmp);
+	if (ACPI_FAILURE(status)) {
+		return 0;
+	}
+
+	status = acpi_get_handle(handle, "_EJ0", &tmp);
+	if (ACPI_FAILURE(status)) {
+		return 0;
+	}
+
+	return 1;
+}
+
+
+/* callback routine to check the existence of ejectable slots */
+static acpi_status
+is_ejectable_slot (acpi_handle handle, u32 lvl,	void *context, void **rv)
+{
+	int *count = (int *)context;
+
+	if (is_ejectable(handle)) {
+		(*count)++;
+		/* only one ejectable slot is enough */
+		return AE_CTRL_TERMINATE;
+	} else {
+		return AE_OK;
+	}
+}
+
+
+/* callback routine to register each ACPI PCI slot object */
+static acpi_status
+register_slot (acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context;
+	struct acpiphp_slot *slot;
+	struct acpiphp_func *newfunc;
+	acpi_handle tmp;
+	acpi_status status = AE_OK;
+	unsigned long adr, sun;
+	int device, function;
+	static int num_slots = 0;	/* XXX if we support I/O node hotplug... */
+
+	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
+
+	if (ACPI_FAILURE(status))
+		return AE_OK;
+
+	status = acpi_get_handle(handle, "_EJ0", &tmp);
+
+	if (ACPI_FAILURE(status))
+		return AE_OK;
+
+	device = (adr >> 16) & 0xffff;
+	function = adr & 0xffff;
+
+	newfunc = kmalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
+	if (!newfunc)
+		return AE_NO_MEMORY;
+	memset(newfunc, 0, sizeof(struct acpiphp_func));
+
+	INIT_LIST_HEAD(&newfunc->sibling);
+	newfunc->handle = handle;
+	newfunc->function = function;
+	newfunc->flags = FUNC_HAS_EJ0;
+
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp)))
+		newfunc->flags |= FUNC_HAS_STA;
+
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS0", &tmp)))
+		newfunc->flags |= FUNC_HAS_PS0;
+
+	if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp)))
+		newfunc->flags |= FUNC_HAS_PS3;
+
+	status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
+	if (ACPI_FAILURE(status))
+		sun = -1;
+
+	/* search for objects that share the same slot */
+	for (slot = bridge->slots; slot; slot = slot->next)
+		if (slot->device == device) {
+			if (slot->sun != sun)
+				warn("sibling found, but _SUN doesn't match!\n");
+			break;
+		}
+
+	if (!slot) {
+		slot = kmalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
+		if (!slot) {
+			kfree(newfunc);
+			return AE_NO_MEMORY;
+		}
+
+		memset(slot, 0, sizeof(struct acpiphp_slot));
+		slot->bridge = bridge;
+		slot->id = num_slots++;
+		slot->device = device;
+		slot->sun = sun;
+		INIT_LIST_HEAD(&slot->funcs);
+		init_MUTEX(&slot->crit_sect);
+
+		slot->next = bridge->slots;
+		bridge->slots = slot;
+
+		bridge->nr_slots++;
+
+		dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
+		    slot->bridge->bus, slot->device, slot->sun);
+	}
+
+	newfunc->slot = slot;
+	list_add_tail(&newfunc->sibling, &slot->funcs);
+
+	/* associate corresponding pci_dev */
+	newfunc->pci_dev = pci_find_slot(bridge->bus,
+					 PCI_DEVFN(device, function));
+	if (newfunc->pci_dev) {
+		if (acpiphp_init_func_resource(newfunc) < 0) {
+			kfree(newfunc);
+			return AE_ERROR;
+		}
+		slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
+	}
+
+	/* install notify handler */
+	status = acpi_install_notify_handler(handle,
+					     ACPI_SYSTEM_NOTIFY,
+					     handle_hotplug_event_func,
+					     newfunc);
+
+	if (ACPI_FAILURE(status)) {
+		err("failed to register interrupt notify handler\n");
+		kfree(newfunc);
+		return status;
+	}
+
+	return AE_OK;
+}
+
+
+/* see if it's worth looking at this bridge */
+static int detect_ejectable_slots (acpi_handle *bridge_handle)
+{
+	acpi_status status;
+	int count;
+
+	count = 0;
+
+	/* only check slots defined directly below bridge object */
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
+				     is_ejectable_slot, (void *)&count, NULL);
+
+	return count;
+}
+
+
+/* decode ACPI _CRS data and convert into our internal resource list
+ * TBD: _TRA, etc.
+ */
+static acpi_status
+decode_acpi_resource (struct acpi_resource *resource, void *context)
+{
+	struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
+	struct acpi_resource_address64 address;
+	struct pci_resource *res;
+
+	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS64)
+		return AE_OK;
+
+	acpi_resource_to_address64(resource, &address);
+
+	if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
+		dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type, address.min_address_range, address.max_address_range);
+		res = acpiphp_make_resource(address.min_address_range,
+				    address.address_length);
+		if (!res) {
+			err("out of memory\n");
+			return AE_OK;
+		}
+
+		switch (address.resource_type) {
+		case ACPI_MEMORY_RANGE:
+			if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
+				res->next = bridge->p_mem_head;
+				bridge->p_mem_head = res;
+			} else {
+				res->next = bridge->mem_head;
+				bridge->mem_head = res;
+			}
+			break;
+		case ACPI_IO_RANGE:
+			res->next = bridge->io_head;
+			bridge->io_head = res;
+			break;
+		case ACPI_BUS_NUMBER_RANGE:
+			res->next = bridge->bus_head;
+			bridge->bus_head = res;
+			break;
+		default:
+			/* invalid type */
+			kfree(res);
+			break;
+		}
+	}
+
+	return AE_OK;
+}
+
+/* decode ACPI 2.0 _HPP hot plug parameters */
+static void decode_hpp(struct acpiphp_bridge *bridge)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
+				      .pointer = NULL};
+	union acpi_object *package;
+	int i;
+
+	/* default numbers */
+	bridge->hpp.cache_line_size = 0x10;
+	bridge->hpp.latency_timer = 0x40;
+	bridge->hpp.enable_SERR = 0;
+	bridge->hpp.enable_PERR = 0;
+
+	status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer);
+
+	if (ACPI_FAILURE(status)) {
+		dbg("_HPP evaluation failed\n");
+		return;
+	}
+
+	package = (union acpi_object *) buffer.pointer;
+
+	if (!package || package->type != ACPI_TYPE_PACKAGE ||
+	    package->package.count != 4 || !package->package.elements) {
+		err("invalid _HPP object; ignoring\n");
+		goto err_exit;
+	}
+
+	for (i = 0; i < 4; i++) {
+		if (package->package.elements[i].type != ACPI_TYPE_INTEGER) {
+			err("invalid _HPP parameter type; ignoring\n");
+			goto err_exit;
+		}
+	}
+
+	bridge->hpp.cache_line_size = package->package.elements[0].integer.value;
+	bridge->hpp.latency_timer = package->package.elements[1].integer.value;
+	bridge->hpp.enable_SERR = package->package.elements[2].integer.value;
+	bridge->hpp.enable_PERR = package->package.elements[3].integer.value;
+
+	dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n",
+	    bridge->hpp.cache_line_size,
+	    bridge->hpp.latency_timer,
+	    bridge->hpp.enable_SERR,
+	    bridge->hpp.enable_PERR);
+
+	bridge->flags |= BRIDGE_HAS_HPP;
+
+ err_exit:
+	kfree(buffer.pointer);
+}
+
+
+/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
+static void init_bridge_misc (struct acpiphp_bridge *bridge)
+{
+	acpi_status status;
+
+	/* decode ACPI 2.0 _HPP (hot plug parameters) */
+	decode_hpp(bridge);
+
+	/* subtract all resources already allocated */
+	acpiphp_detect_pci_resource(bridge);
+
+	/* register all slot objects under this bridge */
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
+				     register_slot, bridge, NULL);
+
+	/* install notify handler */
+	status = acpi_install_notify_handler(bridge->handle,
+					     ACPI_SYSTEM_NOTIFY,
+					     handle_hotplug_event_bridge,
+					     bridge);
+
+	if (ACPI_FAILURE(status)) {
+		err("failed to register interrupt notify handler\n");
+	}
+
+	list_add(&bridge->list, &bridge_list);
+
+	dbg("Bridge resource:\n");
+	acpiphp_dump_resource(bridge);
+}
+
+
+/* allocate and initialize host bridge data structure */
+static void add_host_bridge (acpi_handle *handle, int seg, int bus)
+{
+	acpi_status status;
+	struct acpiphp_bridge *bridge;
+
+	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
+	if (bridge == NULL)
+		return;
+
+	memset(bridge, 0, sizeof(struct acpiphp_bridge));
+
+	bridge->type = BRIDGE_TYPE_HOST;
+	bridge->handle = handle;
+	bridge->seg = seg;
+	bridge->bus = bus;
+
+	bridge->pci_bus = pci_find_bus(bus);
+
+	bridge->res_lock = SPIN_LOCK_UNLOCKED;
+
+	/* to be overridden when we decode _CRS	*/
+	bridge->sub = bridge->bus;
+
+	/* decode resources */
+
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+		decode_acpi_resource, bridge);
+
+	if (ACPI_FAILURE(status)) {
+		err("failed to decode bridge resources\n");
+		kfree(bridge);
+		return;
+	}
+
+	acpiphp_resource_sort_and_combine(&bridge->io_head);
+	acpiphp_resource_sort_and_combine(&bridge->mem_head);
+	acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
+	acpiphp_resource_sort_and_combine(&bridge->bus_head);
+
+	dbg("ACPI _CRS resource:\n");
+	acpiphp_dump_resource(bridge);
+
+	if (bridge->bus_head) {
+		bridge->bus = bridge->bus_head->base;
+		bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
+	}
+
+	init_bridge_misc(bridge);
+}
+
+
+/* allocate and initialize PCI-to-PCI bridge data structure */
+static void add_p2p_bridge (acpi_handle *handle, int seg, int bus, int dev, int fn)
+{
+	struct acpiphp_bridge *bridge;
+	u8 tmp8;
+	u16 tmp16;
+	u64 base64, limit64;
+	u32 base, limit, base32u, limit32u;
+
+	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
+	if (bridge == NULL) {
+		err("out of memory\n");
+		return;
+	}
+
+	memset(bridge, 0, sizeof(struct acpiphp_bridge));
+
+	bridge->type = BRIDGE_TYPE_P2P;
+	bridge->handle = handle;
+	bridge->seg = seg;
+
+	bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
+	if (!bridge->pci_dev) {
+		err("Can't get pci_dev\n");
+		kfree(bridge);
+		return;
+	}
+
+	bridge->pci_bus = bridge->pci_dev->subordinate;
+	if (!bridge->pci_bus) {
+		err("This is not a PCI-to-PCI bridge!\n");
+		kfree(bridge);
+		return;
+	}
+
+	bridge->res_lock = SPIN_LOCK_UNLOCKED;
+
+	bridge->bus = bridge->pci_bus->number;
+	bridge->sub = bridge->pci_bus->subordinate;
+
+	/*
+	 * decode resources under this P2P bridge
+	 */
+
+	/* I/O resources */
+	pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
+	base = tmp8;
+	pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
+	limit = tmp8;
+
+	switch (base & PCI_IO_RANGE_TYPE_MASK) {
+	case PCI_IO_RANGE_TYPE_16:
+		base = (base << 8) & 0xf000;
+		limit = ((limit << 8) & 0xf000) + 0xfff;
+		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
+		if (!bridge->io_head) {
+			err("out of memory\n");
+			kfree(bridge);
+			return;
+		}
+		dbg("16bit I/O range: %04x-%04x\n",
+		    (u32)bridge->io_head->base,
+		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
+		break;
+	case PCI_IO_RANGE_TYPE_32:
+		pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
+		base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
+		pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
+		limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
+		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
+		if (!bridge->io_head) {
+			err("out of memory\n");
+			kfree(bridge);
+			return;
+		}
+		dbg("32bit I/O range: %08x-%08x\n",
+		    (u32)bridge->io_head->base,
+		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
+		break;
+	case 0x0f:
+		dbg("I/O space unsupported\n");
+		break;
+	default:
+		warn("Unknown I/O range type\n");
+	}
+
+	/* Memory resources (mandatory for P2P bridge) */
+	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
+	base = (tmp16 & 0xfff0) << 16;
+	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
+	limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
+	bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
+	if (!bridge->mem_head) {
+		err("out of memory\n");
+		kfree(bridge);
+		return;
+	}
+	dbg("32bit Memory range: %08x-%08x\n",
+	    (u32)bridge->mem_head->base,
+	    (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
+
+	/* Prefetchable Memory resources (optional) */
+	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
+	base = tmp16;
+	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
+	limit = tmp16;
+
+	switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
+	case PCI_PREF_RANGE_TYPE_32:
+		base = (base & 0xfff0) << 16;
+		limit = ((limit & 0xfff0) << 16) | 0xfffff;
+		bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
+		if (!bridge->p_mem_head) {
+			err("out of memory\n");
+			kfree(bridge);
+			return;
+		}
+		dbg("32bit Prefetchable memory range: %08x-%08x\n",
+		    (u32)bridge->p_mem_head->base,
+		    (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
+		break;
+	case PCI_PREF_RANGE_TYPE_64:
+		pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
+		pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
+		base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
+		limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
+
+		bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
+		if (!bridge->p_mem_head) {
+			err("out of memory\n");
+			kfree(bridge);
+			return;
+		}
+		dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
+		    (u32)(bridge->p_mem_head->base >> 32),
+		    (u32)(bridge->p_mem_head->base & 0xffffffff),
+		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
+		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
+		break;
+	case 0x0f:
+		break;
+	default:
+		warn("Unknown prefetchale memory type\n");
+	}
+
+	init_bridge_misc(bridge);
+}
+
+
+/* callback routine to find P2P bridges */
+static acpi_status
+find_p2p_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	acpi_handle dummy_handle;
+	unsigned long *segbus = context;
+	unsigned long tmp;
+	int seg, bus, device, function;
+	struct pci_dev *dev;
+
+	/* get PCI address */
+	seg = (*segbus >> 8) & 0xff;
+	bus = *segbus & 0xff;
+
+	status = acpi_get_handle(handle, "_ADR", &dummy_handle);
+	if (ACPI_FAILURE(status))
+		return AE_OK;		/* continue */
+
+	status = acpi_evaluate_integer(handle, "_ADR", NULL, &tmp);
+	if (ACPI_FAILURE(status)) {
+		dbg("%s: _ADR evaluation failure\n", __FUNCTION__);
+		return AE_OK;
+	}
+
+	device = (tmp >> 16) & 0xffff;
+	function = tmp & 0xffff;
+
+	dev = pci_find_slot(bus, PCI_DEVFN(device, function));
+
+	if (!dev)
+		return AE_OK;
+
+	if (!dev->subordinate)
+		return AE_OK;
+
+	/* check if this bridge has ejectable slots */
+	if (detect_ejectable_slots(handle) > 0) {
+		dbg("found PCI-to-PCI bridge at PCI %s\n", dev->slot_name);
+		add_p2p_bridge(handle, seg, bus, device, function);
+	}
+
+	return AE_OK;
+}
+
+
+/* find hot-pluggable slots, and then find P2P bridge */
+static int add_bridges(struct acpi_device *device)
+{
+	acpi_handle *handle = device->handle;
+	acpi_status status;
+	unsigned long tmp;
+	int seg, bus;
+	acpi_handle dummy_handle;
+
+	/* if the bridge doesn't have _STA, we assume it is always there */
+	status = acpi_get_handle(handle, "_STA", &dummy_handle);
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
+		if (ACPI_FAILURE(status)) {
+			dbg("%s: _STA evaluation failure\n", __FUNCTION__);
+			return 0;
+		}
+		if ((tmp & ACPI_STA_FUNCTIONING) == 0)
+			/* don't register this object */
+			return 0;
+	}
+
+	/* get PCI segment number */
+	status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
+
+	seg = ACPI_SUCCESS(status) ? tmp : 0;
+
+	/* get PCI bus number */
+	status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
+
+	if (ACPI_SUCCESS(status)) {
+		bus = tmp;
+	} else {
+		warn("can't get bus number, assuming 0\n");
+		bus = 0;
+	}
+
+	/* check if this bridge has ejectable slots */
+	if (detect_ejectable_slots(handle) > 0) {
+		dbg("found PCI host-bus bridge with hot-pluggable slots\n");
+		add_host_bridge(handle, seg, bus);
+		return 0;
+	}
+
+	tmp = seg << 8 | bus;
+
+	/* search P2P bridges under this host bridge */
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
+				     find_p2p_bridge, &tmp, NULL);
+
+	if (ACPI_FAILURE(status))
+		warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
+
+	return 0;
+}
+
+
+static int power_on_slot (struct acpiphp_slot *slot)
+{
+	acpi_status status;
+	struct acpiphp_func *func;
+	struct list_head *l;
+	int retval = 0;
+
+	/* is this already enabled? */
+	if (slot->flags & SLOT_POWEREDON)
+		goto err_exit;
+
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+
+		if (func->flags & FUNC_HAS_PS0) {
+			dbg("%s: executing _PS0 on %s\n", __FUNCTION__,
+			    func->pci_dev->slot_name);
+			status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
+			if (ACPI_FAILURE(status)) {
+				warn("%s: _PS0 failed\n", __FUNCTION__);
+				retval = -1;
+				goto err_exit;
+			}
+		}
+	}
+
+	/* TBD: evaluate _STA to check if the slot is enabled */
+
+	slot->flags |= SLOT_POWEREDON;
+
+ err_exit:
+	return retval;
+}
+
+
+static int power_off_slot (struct acpiphp_slot *slot)
+{
+	acpi_status status;
+	struct acpiphp_func *func;
+	struct list_head *l;
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+
+	int retval = 0;
+
+	/* is this already enabled? */
+	if ((slot->flags & SLOT_POWEREDON) == 0)
+		goto err_exit;
+
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+
+		if (func->flags & FUNC_HAS_PS3) {
+			dbg("%s: executing _PS3 on %s\n", __FUNCTION__,
+			    func->pci_dev->slot_name);
+			status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
+			if (ACPI_FAILURE(status)) {
+				warn("%s: _PS3 failed\n", __FUNCTION__);
+				retval = -1;
+				goto err_exit;
+			}
+		}
+	}
+
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+
+		if (func->flags & FUNC_HAS_EJ0) {
+			dbg("%s: executing _EJ0 on %s\n", __FUNCTION__,
+			    func->pci_dev->slot_name);
+
+			/* _EJ0 method take one argument */
+			arg_list.count = 1;
+			arg_list.pointer = &arg;
+			arg.type = ACPI_TYPE_INTEGER;
+			arg.integer.value = 1;
+
+			status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
+			if (ACPI_FAILURE(status)) {
+				warn("%s: _EJ0 failed\n", __FUNCTION__);
+				retval = -1;
+				goto err_exit;
+			}
+		}
+	}
+
+	/* TBD: evaluate _STA to check if the slot is disabled */
+
+	slot->flags &= (~SLOT_POWEREDON);
+
+ err_exit:
+	return retval;
+}
+
+
+/**
+ * enable_device - enable, configure a slot
+ * @slot: slot to be enabled
+ *
+ * This function should be called per *physical slot*,
+ * not per each slot object in ACPI namespace.
+ *
+ */
+static int enable_device (struct acpiphp_slot *slot)
+{
+	u8 bus;
+	struct pci_dev *dev;
+	struct pci_bus *child;
+	struct list_head *l;
+	struct acpiphp_func *func;
+	int retval = 0;
+	int num;
+
+	if (slot->flags & SLOT_ENABLED)
+		goto err_exit;
+
+	/* sanity check: dev should be NULL when hot-plugged in */
+	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
+	if (dev) {
+		/* This case shouldn't happen */
+		err("pci_dev structure already exists.\n");
+		retval = -1;
+		goto err_exit;
+	}
+
+	/* allocate resources to device */
+	retval = acpiphp_configure_slot(slot);
+	if (retval)
+		goto err_exit;
+
+	/* returned `dev' is the *first function* only! */
+	num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
+	if (num)
+		pci_bus_add_devices(slot->bridge->pci_bus);
+	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
+
+	if (!dev) {
+		err("No new device found\n");
+		retval = -1;
+		goto err_exit;
+	}
+
+	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+		pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
+		child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
+		pci_do_scan_bus(child);
+	}
+
+	/* associate pci_dev to our representation */
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+
+		func->pci_dev = pci_find_slot(slot->bridge->bus,
+					      PCI_DEVFN(slot->device,
+							func->function));
+		if (!func->pci_dev)
+			continue;
+
+		/* configure device */
+		retval = acpiphp_configure_function(func);
+		if (retval)
+			goto err_exit;
+	}
+
+	slot->flags |= SLOT_ENABLED;
+
+	dbg("Available resources:\n");
+	acpiphp_dump_resource(slot->bridge);
+
+ err_exit:
+	return retval;
+}
+
+
+/**
+ * disable_device - disable a slot
+ */
+static int disable_device (struct acpiphp_slot *slot)
+{
+	int retval = 0;
+	struct acpiphp_func *func;
+	struct list_head *l;
+
+	/* is this slot already disabled? */
+	if (!(slot->flags & SLOT_ENABLED))
+		goto err_exit;
+
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+
+		if (func->pci_dev) {
+			if (acpiphp_unconfigure_function(func) == 0) {
+				func->pci_dev = NULL;
+			} else {
+				err("failed to unconfigure device\n");
+				retval = -1;
+				goto err_exit;
+			}
+		}
+	}
+
+	slot->flags &= (~SLOT_ENABLED);
+
+ err_exit:
+	return retval;
+}
+
+
+/**
+ * get_slot_status - get ACPI slot status
+ *
+ * if a slot has _STA for each function and if any one of them
+ * returned non-zero status, return it
+ *
+ * if a slot doesn't have _STA and if any one of its functions'
+ * configuration space is configured, return 0x0f as a _STA
+ *
+ * otherwise return 0
+ */
+static unsigned int get_slot_status (struct acpiphp_slot *slot)
+{
+	acpi_status status;
+	unsigned long sta = 0;
+	u32 dvid;
+	struct list_head *l;
+	struct acpiphp_func *func;
+
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+
+		if (func->flags & FUNC_HAS_STA) {
+			status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta);
+			if (ACPI_SUCCESS(status) && sta)
+				break;
+		} else {
+			pci_bus_read_config_dword(slot->bridge->pci_bus,
+						  PCI_DEVFN(slot->device,
+							    func->function),
+						  PCI_VENDOR_ID, &dvid);
+			if (dvid != 0xffffffff) {
+				sta = ACPI_STA_ALL;
+				break;
+			}
+		}
+	}
+
+	return (unsigned int)sta;
+}
+
+
+/*
+ * ACPI event handlers
+ */
+
+/**
+ * handle_hotplug_event_bridge - handle ACPI event on bridges
+ *
+ * @handle: Notify()'ed acpi_handle
+ * @type: Notify code
+ * @context: pointer to acpiphp_bridge structure
+ *
+ * handles ACPI event notification on {host,p2p} bridges
+ *
+ */
+static void handle_hotplug_event_bridge (acpi_handle handle, u32 type, void *context)
+{
+	struct acpiphp_bridge *bridge;
+	char objname[64];
+	struct acpi_buffer buffer = { .length = sizeof(objname),
+				      .pointer = objname };
+
+	bridge = (struct acpiphp_bridge *)context;
+
+	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+	switch (type) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		/* bus re-enumerate */
+		dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
+		acpiphp_check_bridge(bridge);
+		break;
+
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		/* device check */
+		dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
+		acpiphp_check_bridge(bridge);
+		break;
+
+	case ACPI_NOTIFY_DEVICE_WAKE:
+		/* wake event */
+		dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
+		break;
+
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		/* request device eject */
+		dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
+		break;
+
+	default:
+		warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
+		break;
+	}
+}
+
+
+/**
+ * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
+ *
+ * @handle: Notify()'ed acpi_handle
+ * @type: Notify code
+ * @context: pointer to acpiphp_func structure
+ *
+ * handles ACPI event notification on slots
+ *
+ */
+static void handle_hotplug_event_func (acpi_handle handle, u32 type, void *context)
+{
+	struct acpiphp_func *func;
+	char objname[64];
+	struct acpi_buffer buffer = { .length = sizeof(objname),
+				      .pointer = objname };
+
+	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+	func = (struct acpiphp_func *)context;
+
+	switch (type) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		/* bus re-enumerate */
+		dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
+		acpiphp_enable_slot(func->slot);
+		break;
+
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		/* device check : re-enumerate from parent bus */
+		dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
+		acpiphp_check_bridge(func->slot->bridge);
+		break;
+
+	case ACPI_NOTIFY_DEVICE_WAKE:
+		/* wake event */
+		dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
+		break;
+
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		/* request device eject */
+		dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
+		acpiphp_disable_slot(func->slot);
+		break;
+
+	default:
+		warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
+		break;
+	}
+}
+
+static struct acpi_driver acpi_pci_hp_driver = {
+	.name =		"pci_hp",
+	.class =	"",
+	.ids =		ACPI_PCI_HOST_HID,
+	.ops =	{
+		.add =	add_bridges,
+	}
+};
+
+/**
+ * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
+ *
+ */
+int acpiphp_glue_init (void)
+{
+	acpi_status status;
+
+	if (list_empty(&pci_root_buses))
+		return -1;
+
+	status = acpi_bus_register_driver(&acpi_pci_hp_driver);
+
+	if (ACPI_FAILURE(status)) {
+		err("%s: acpi_walk_namespace() failed\n", __FUNCTION__);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/**
+ * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures
+ *
+ * This function frees all data allocated in acpiphp_glue_init()
+ */
+void acpiphp_glue_exit (void)
+{
+	struct list_head *l1, *l2, *n1, *n2;
+	struct acpiphp_bridge *bridge;
+	struct acpiphp_slot *slot, *next;
+	struct acpiphp_func *func;
+	acpi_status status;
+
+	list_for_each_safe (l1, n1, &bridge_list) {
+		bridge = (struct acpiphp_bridge *)l1;
+		slot = bridge->slots;
+		while (slot) {
+			next = slot->next;
+			list_for_each_safe (l2, n2, &slot->funcs) {
+				func = list_entry(l2, struct acpiphp_func, sibling);
+				acpiphp_free_resource(&func->io_head);
+				acpiphp_free_resource(&func->mem_head);
+				acpiphp_free_resource(&func->p_mem_head);
+				acpiphp_free_resource(&func->bus_head);
+				status = acpi_remove_notify_handler(func->handle,
+								    ACPI_SYSTEM_NOTIFY,
+								    handle_hotplug_event_func);
+				if (ACPI_FAILURE(status))
+					err("failed to remove notify handler\n");
+				kfree(func);
+			}
+			kfree(slot);
+			slot = next;
+		}
+		status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
+						    handle_hotplug_event_bridge);
+		if (ACPI_FAILURE(status))
+			err("failed to remove notify handler\n");
+
+		acpiphp_free_resource(&bridge->io_head);
+		acpiphp_free_resource(&bridge->mem_head);
+		acpiphp_free_resource(&bridge->p_mem_head);
+		acpiphp_free_resource(&bridge->bus_head);
+
+		kfree(bridge);
+	}
+}
+
+
+/**
+ * acpiphp_get_num_slots - count number of slots in a system
+ */
+int acpiphp_get_num_slots (void)
+{
+	struct list_head *node;
+	struct acpiphp_bridge *bridge;
+	int num_slots;
+
+	num_slots = 0;
+
+	list_for_each (node, &bridge_list) {
+		bridge = (struct acpiphp_bridge *)node;
+		dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
+		num_slots += bridge->nr_slots;
+	}
+
+	dbg("Total %dslots\n", num_slots);
+	return num_slots;
+}
+
+
+/**
+ * acpiphp_for_each_slot - call function for each slot
+ * @fn: callback function
+ * @data: context to be passed to callback function
+ *
+ */
+int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
+{
+	struct list_head *node;
+	struct acpiphp_bridge *bridge;
+	struct acpiphp_slot *slot;
+	int retval = 0;
+
+	list_for_each (node, &bridge_list) {
+		bridge = (struct acpiphp_bridge *)node;
+		for (slot = bridge->slots; slot; slot = slot->next) {
+			retval = fn(slot, data);
+			if (!retval)
+				goto err_exit;
+		}
+	}
+
+ err_exit:
+	return retval;
+}
+
+
+/* search matching slot from id  */
+struct acpiphp_slot *get_slot_from_id (int id)
+{
+	struct list_head *node;
+	struct acpiphp_bridge *bridge;
+	struct acpiphp_slot *slot;
+
+	list_for_each (node, &bridge_list) {
+		bridge = (struct acpiphp_bridge *)node;
+		for (slot = bridge->slots; slot; slot = slot->next)
+			if (slot->id == id)
+				return slot;
+	}
+
+	/* should never happen! */
+	err("%s: no object for id %d\n",__FUNCTION__, id);
+	return 0;
+}
+
+
+/**
+ * acpiphp_enable_slot - power on slot
+ */
+int acpiphp_enable_slot (struct acpiphp_slot *slot)
+{
+	int retval;
+
+	down(&slot->crit_sect);
+
+	/* wake up all functions */
+	retval = power_on_slot(slot);
+	if (retval)
+		goto err_exit;
+
+	if (get_slot_status(slot) == ACPI_STA_ALL)
+		/* configure all functions */
+		retval = enable_device(slot);
+
+ err_exit:
+	up(&slot->crit_sect);
+	return retval;
+}
+
+
+/**
+ * acpiphp_disable_slot - power off slot
+ */
+int acpiphp_disable_slot (struct acpiphp_slot *slot)
+{
+	int retval = 0;
+
+	down(&slot->crit_sect);
+
+	/* unconfigure all functions */
+	retval = disable_device(slot);
+	if (retval)
+		goto err_exit;
+
+	/* power off all functions */
+	retval = power_off_slot(slot);
+	if (retval)
+		goto err_exit;
+
+	acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
+	acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
+	acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
+	acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
+	dbg("Available resources:\n");
+	acpiphp_dump_resource(slot->bridge);
+
+ err_exit:
+	up(&slot->crit_sect);
+	return retval;
+}
+
+
+/**
+ * acpiphp_check_bridge - re-enumerate devices
+ */
+int acpiphp_check_bridge (struct acpiphp_bridge *bridge)
+{
+	struct acpiphp_slot *slot;
+	unsigned int sta;
+	int retval = 0;
+	int enabled, disabled;
+
+	enabled = disabled = 0;
+
+	for (slot = bridge->slots; slot; slot = slot->next) {
+		sta = get_slot_status(slot);
+		if (slot->flags & SLOT_ENABLED) {
+			/* if enabled but not present, disable */
+			if (sta != ACPI_STA_ALL) {
+				retval = acpiphp_disable_slot(slot);
+				if (retval) {
+					err("Error occurred in enabling\n");
+					up(&slot->crit_sect);
+					goto err_exit;
+				}
+				enabled++;
+			}
+		} else {
+			/* if disabled but present, enable */
+			if (sta == ACPI_STA_ALL) {
+				retval = acpiphp_enable_slot(slot);
+				if (retval) {
+					err("Error occurred in enabling\n");
+					up(&slot->crit_sect);
+					goto err_exit;
+				}
+				disabled++;
+			}
+		}
+	}
+
+	dbg("%s: %d enabled, %d disabled\n", __FUNCTION__, enabled, disabled);
+
+ err_exit:
+	return retval;
+}
+
+
+/*
+ * slot enabled:  1
+ * slot disabled: 0
+ */
+u8 acpiphp_get_power_status (struct acpiphp_slot *slot)
+{
+	unsigned int sta;
+
+	sta = get_slot_status(slot);
+
+	return (sta & ACPI_STA_ENABLED) ? 1 : 0;
+}
+
+
+/*
+ * attention LED ON: 1
+ *              OFF: 0
+ *
+ * TBD
+ * no direct attention led status information via ACPI
+ *
+ */
+u8 acpiphp_get_attention_status (struct acpiphp_slot *slot)
+{
+	return 0;
+}
+
+
+/*
+ * latch closed:  1
+ * latch   open:  0
+ */
+u8 acpiphp_get_latch_status (struct acpiphp_slot *slot)
+{
+	unsigned int sta;
+
+	sta = get_slot_status(slot);
+
+	return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0;
+}
+
+
+/*
+ * adapter presence : 1
+ *          absence : 0
+ */
+u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot)
+{
+	unsigned int sta;
+
+	sta = get_slot_status(slot);
+
+	return (sta == 0) ? 0 : 1;
+}
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp_pci.c linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp_pci.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp_pci.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp_pci.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,511 @@
+/*
+ * ACPI PCI HotPlug PCI configuration space management
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <t-kouchi@cq.jp.nec.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include "../pci.h"
+#include "pci_hotplug.h"
+#include "acpiphp.h"
+
+#define MY_NAME "acpiphp_pci"
+
+
+/* allocate mem/pmem/io resource to a new function */
+static int init_config_space (struct acpiphp_func *func)
+{
+	u32 bar, len;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	int count;
+	struct acpiphp_bridge *bridge;
+	struct pci_resource *res;
+	struct pci_bus *pbus;
+	int bus, device, function;
+	unsigned int devfn;
+	u16 tmp;
+
+	bridge = func->slot->bridge;
+	pbus = bridge->pci_bus;
+	bus = bridge->bus;
+	device = func->slot->device;
+	function = func->function;
+	devfn = PCI_DEVFN(device, function);
+
+	for (count = 0; address[count]; count++) {	/* for 6 BARs */
+		pci_bus_write_config_dword(pbus, devfn,
+					   address[count], 0xFFFFFFFF);
+		pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
+
+		if (!bar)	/* This BAR is not implemented */
+			continue;
+
+		dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
+
+		if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+
+			len = bar & 0xFFFFFFFC;
+			len = ~len + 1;
+
+			dbg("len in IO %x, BAR %d\n", len, count);
+
+			spin_lock(&bridge->res_lock);
+			res = acpiphp_get_io_resource(&bridge->io_head, len);
+			spin_unlock(&bridge->res_lock);
+
+			if (!res) {
+				err("cannot allocate requested io for %02x:%02x.%d len %x\n",
+				    bus, device, function, len);
+				return -1;
+			}
+			pci_bus_write_config_dword(pbus, devfn,
+						   address[count],
+						   (u32)res->base);
+			res->next = func->io_head;
+			func->io_head = res;
+
+		} else {
+			/* This is Memory */
+			if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+
+				len = bar & 0xFFFFFFF0;
+				len = ~len + 1;
+
+				dbg("len in PFMEM %x, BAR %d\n", len, count);
+
+				spin_lock(&bridge->res_lock);
+				res = acpiphp_get_resource(&bridge->p_mem_head, len);
+				spin_unlock(&bridge->res_lock);
+
+				if (!res) {
+					err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
+					    bus, device, function, len);
+					return -1;
+				}
+
+				pci_bus_write_config_dword(pbus, devfn,
+							   address[count],
+							   (u32)res->base);
+
+				if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
+					dbg("inside the pfmem 64 case, count %d\n", count);
+					count += 1;
+					pci_bus_write_config_dword(pbus, devfn,
+								   address[count],
+								   (u32)(res->base >> 32));
+				}
+
+				res->next = func->p_mem_head;
+				func->p_mem_head = res;
+
+			} else {
+				/* regular memory */
+
+				len = bar & 0xFFFFFFF0;
+				len = ~len + 1;
+
+				dbg("len in MEM %x, BAR %d\n", len, count);
+
+				spin_lock(&bridge->res_lock);
+				res = acpiphp_get_resource(&bridge->mem_head, len);
+				spin_unlock(&bridge->res_lock);
+
+				if (!res) {
+					err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
+					    bus, device, function, len);
+					return -1;
+				}
+
+				pci_bus_write_config_dword(pbus, devfn,
+							   address[count],
+							   (u32)res->base);
+
+				if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					dbg("inside mem 64 case, reg. mem, count %d\n", count);
+					count += 1;
+					pci_bus_write_config_dword(pbus, devfn,
+								   address[count],
+								   (u32)(res->base >> 32));
+				}
+
+				res->next = func->mem_head;
+				func->mem_head = res;
+
+			}
+		}
+	}
+
+	/* disable expansion rom */
+	pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
+
+	/* set PCI parameters from _HPP */
+	pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
+				  bridge->hpp.cache_line_size);
+	pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
+				  bridge->hpp.latency_timer);
+
+	pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
+	if (bridge->hpp.enable_SERR)
+		tmp |= PCI_COMMAND_SERR;
+	if (bridge->hpp.enable_PERR)
+		tmp |= PCI_COMMAND_PARITY;
+	pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
+
+	return 0;
+}
+
+/* detect_used_resource - subtract resource under dev from bridge */
+static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
+{
+	u32 bar, len;
+	u64 base;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	int count;
+	struct pci_resource *res;
+
+	dbg("Device %s\n", dev->slot_name);
+
+	for (count = 0; address[count]; count++) {	/* for 6 BARs */
+		pci_read_config_dword(dev, address[count], &bar);
+
+		if (!bar)	/* This BAR is not implemented */
+			continue;
+
+		pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
+		pci_read_config_dword(dev, address[count], &len);
+
+		if (len & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			base = bar & 0xFFFFFFFC;
+			len &= 0xFFFFFFFC;
+			len = ~len + 1;
+
+			dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
+
+			spin_lock(&bridge->res_lock);
+			res = acpiphp_get_resource_with_base(&bridge->io_head, base, len);
+			spin_unlock(&bridge->res_lock);
+			if (res)
+				kfree(res);
+		} else {
+			/* This is Memory */
+			base = bar & 0xFFFFFFF0;
+			if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+
+				len &= 0xFFFFFFF0;
+				len = ~len + 1;
+
+				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
+					dbg("prefetch mem 64\n");
+					count += 1;
+				}
+				dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
+				spin_lock(&bridge->res_lock);
+				res = acpiphp_get_resource_with_base(&bridge->p_mem_head, base, len);
+				spin_unlock(&bridge->res_lock);
+				if (res)
+					kfree(res);
+			} else {
+				/* regular memory */
+
+				len &= 0xFFFFFFF0;
+				len = ~len + 1;
+
+				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					dbg("mem 64\n");
+					count += 1;
+				}
+				dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
+				spin_lock(&bridge->res_lock);
+				res = acpiphp_get_resource_with_base(&bridge->mem_head, base, len);
+				spin_unlock(&bridge->res_lock);
+				if (res)
+					kfree(res);
+			}
+		}
+
+		pci_write_config_dword(dev, address[count], bar);
+	}
+
+	return 0;
+}
+
+
+/* detect_pci_resource_bus - subtract resource under pci_bus */
+static void detect_used_resource_bus(struct acpiphp_bridge *bridge, struct pci_bus *bus)
+{
+	struct list_head *l;
+	struct pci_dev *dev;
+
+	list_for_each (l, &bus->devices) {
+		dev = pci_dev_b(l);
+		detect_used_resource(bridge, dev);
+		/* XXX recursive call */
+		if (dev->subordinate)
+			detect_used_resource_bus(bridge, dev->subordinate);
+	}
+}
+
+
+/**
+ * acpiphp_detect_pci_resource - detect resources under bridge
+ * @bridge: detect all resources already used under this bridge
+ *
+ * collect all resources already allocated for all devices under a bridge.
+ */
+int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
+{
+	detect_used_resource_bus(bridge, bridge->pci_bus);
+
+	return 0;
+}
+
+
+/**
+ * acpiphp_init_slot_resource - gather resource usage information of a slot
+ * @slot: ACPI slot object to be checked, should have valid pci_dev member
+ *
+ * TBD: PCI-to-PCI bridge case
+ *      use pci_dev->resource[]
+ */
+int acpiphp_init_func_resource (struct acpiphp_func *func)
+{
+	u64 base;
+	u32 bar, len;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	int count;
+	struct pci_resource *res;
+	struct pci_dev *dev;
+
+	dev = func->pci_dev;
+	dbg("Hot-pluggable device %s\n", dev->slot_name);
+
+	for (count = 0; address[count]; count++) {	/* for 6 BARs */
+		pci_read_config_dword(dev, address[count], &bar);
+
+		if (!bar)	/* This BAR is not implemented */
+			continue;
+
+		pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
+		pci_read_config_dword(dev, address[count], &len);
+
+		if (len & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			base = bar & 0xFFFFFFFC;
+			len &= 0xFFFFFFFC;
+			len = ~len + 1;
+
+			dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
+
+			res = acpiphp_make_resource(base, len);
+			if (!res)
+				goto no_memory;
+
+			res->next = func->io_head;
+			func->io_head = res;
+
+		} else {
+			/* This is Memory */
+			base = bar & 0xFFFFFFF0;
+			if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+
+				len &= 0xFFFFFFF0;
+				len = ~len + 1;
+
+				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
+					dbg("prefetch mem 64\n");
+					count += 1;
+				}
+				dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
+				res = acpiphp_make_resource(base, len);
+				if (!res)
+					goto no_memory;
+
+				res->next = func->p_mem_head;
+				func->p_mem_head = res;
+
+			} else {
+				/* regular memory */
+
+				len &= 0xFFFFFFF0;
+				len = ~len + 1;
+
+				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					dbg("mem 64\n");
+					count += 1;
+				}
+				dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
+				res = acpiphp_make_resource(base, len);
+				if (!res)
+					goto no_memory;
+
+				res->next = func->mem_head;
+				func->mem_head = res;
+
+			}
+		}
+
+		pci_write_config_dword(dev, address[count], bar);
+	}
+#if 1
+	acpiphp_dump_func_resource(func);
+#endif
+
+	return 0;
+
+ no_memory:
+	err("out of memory\n");
+	acpiphp_free_resource(&func->io_head);
+	acpiphp_free_resource(&func->mem_head);
+	acpiphp_free_resource(&func->p_mem_head);
+
+	return -1;
+}
+
+
+/**
+ * acpiphp_configure_slot - allocate PCI resources
+ * @slot: slot to be configured
+ *
+ * initializes a PCI functions on a device inserted
+ * into the slot
+ *
+ */
+int acpiphp_configure_slot (struct acpiphp_slot *slot)
+{
+	struct acpiphp_func *func;
+	struct list_head *l;
+	u8 hdr;
+	u32 dvid;
+	int retval = 0;
+	int is_multi = 0;
+
+	pci_bus_read_config_byte(slot->bridge->pci_bus,
+				 PCI_DEVFN(slot->device, 0),
+				 PCI_HEADER_TYPE, &hdr);
+
+	if (hdr & 0x80)
+		is_multi = 1;
+
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+		if (is_multi || func->function == 0) {
+			pci_bus_read_config_dword(slot->bridge->pci_bus,
+						  PCI_DEVFN(slot->device,
+							    func->function),
+						  PCI_VENDOR_ID, &dvid);
+			if (dvid != 0xffffffff) {
+				retval = init_config_space(func);
+				if (retval)
+					break;
+			}
+		}
+	}
+
+	return retval;
+}
+
+/**
+ * acpiphp_configure_function - configure PCI function
+ * @func: function to be configured
+ *
+ * initializes a PCI functions on a device inserted
+ * into the slot
+ *
+ */
+int acpiphp_configure_function (struct acpiphp_func *func)
+{
+	/* all handled by the pci core now */
+	return 0;
+}
+
+/**
+ * acpiphp_unconfigure_function - unconfigure PCI function
+ * @func: function to be unconfigured
+ *
+ */
+int acpiphp_unconfigure_function (struct acpiphp_func *func)
+{
+	struct acpiphp_bridge *bridge;
+	int retval = 0;
+
+	/* if pci_dev is NULL, ignore it */
+	if (!func->pci_dev)
+		goto err_exit;
+
+	pci_remove_bus_device(func->pci_dev);
+
+	/* free all resources */
+	bridge = func->slot->bridge;
+
+	spin_lock(&bridge->res_lock);
+	acpiphp_move_resource(&func->io_head, &bridge->io_head);
+	acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
+	acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
+	acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
+	spin_unlock(&bridge->res_lock);
+
+ err_exit:
+	return retval;
+}
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp_res.c linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp_res.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/acpiphp_res.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/acpiphp_res.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,699 @@
+/*
+ * ACPI PCI HotPlug Utility functions
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ * Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
+ * Copyright (c) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>,<h-aono@ap.jp.nec.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include <linux/pci.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+
+#include <linux/ioctl.h>
+#include <linux/fcntl.h>
+
+#include <linux/list.h>
+
+#include "pci_hotplug.h"
+#include "acpiphp.h"
+
+#define MY_NAME "acpiphp_res"
+
+
+/*
+ * sort_by_size - sort nodes by their length, smallest first
+ */
+static int sort_by_size(struct pci_resource **head)
+{
+	struct pci_resource *current_res;
+	struct pci_resource *next_res;
+	int out_of_order = 1;
+
+	if (!(*head))
+		return 1;
+
+	if (!((*head)->next))
+		return 0;
+
+	while (out_of_order) {
+		out_of_order = 0;
+
+		/* Special case for swapping list head */
+		if (((*head)->next) &&
+		    ((*head)->length > (*head)->next->length)) {
+			out_of_order++;
+			current_res = *head;
+			*head = (*head)->next;
+			current_res->next = (*head)->next;
+			(*head)->next = current_res;
+		}
+
+		current_res = *head;
+
+		while (current_res->next && current_res->next->next) {
+			if (current_res->next->length > current_res->next->next->length) {
+				out_of_order++;
+				next_res = current_res->next;
+				current_res->next = current_res->next->next;
+				current_res = current_res->next;
+				next_res->next = current_res->next;
+				current_res->next = next_res;
+			} else
+				current_res = current_res->next;
+		}
+	}  /* End of out_of_order loop */
+
+	return 0;
+}
+
+
+/*
+ * sort_by_max_size - sort nodes by their length, largest first
+ */
+static int sort_by_max_size(struct pci_resource **head)
+{
+	struct pci_resource *current_res;
+	struct pci_resource *next_res;
+	int out_of_order = 1;
+
+	if (!(*head))
+		return 1;
+
+	if (!((*head)->next))
+		return 0;
+
+	while (out_of_order) {
+		out_of_order = 0;
+
+		/* Special case for swapping list head */
+		if (((*head)->next) &&
+		    ((*head)->length < (*head)->next->length)) {
+			out_of_order++;
+			current_res = *head;
+			*head = (*head)->next;
+			current_res->next = (*head)->next;
+			(*head)->next = current_res;
+		}
+
+		current_res = *head;
+
+		while (current_res->next && current_res->next->next) {
+			if (current_res->next->length < current_res->next->next->length) {
+				out_of_order++;
+				next_res = current_res->next;
+				current_res->next = current_res->next->next;
+				current_res = current_res->next;
+				next_res->next = current_res->next;
+				current_res->next = next_res;
+			} else
+				current_res = current_res->next;
+		}
+	}  /* End of out_of_order loop */
+
+	return 0;
+}
+
+/**
+ * get_io_resource - get resource for I/O ports
+ *
+ * this function sorts the resource list by size and then
+ * returns the first node of "size" length that is not in the
+ * ISA aliasing window.  If it finds a node larger than "size"
+ * it will split it up.
+ *
+ * size must be a power of two.
+ *
+ * difference from get_resource is handling of ISA aliasing space.
+ *
+ */
+struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *prevnode;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u64 temp_qword;
+
+	if (!(*head))
+		return NULL;
+
+	if (acpiphp_resource_sort_and_combine(head))
+		return NULL;
+
+	if (sort_by_size(head))
+		return NULL;
+
+	for (node = *head; node; node = node->next) {
+		if (node->length < size)
+			continue;
+
+		if (node->base & (size - 1)) {
+			/* this one isn't base aligned properly
+			   so we'll make a new entry and split it up */
+			temp_qword = (node->base | (size-1)) + 1;
+
+			/* Short circuit if adjusted size is too small */
+			if ((node->length - (temp_qword - node->base)) < size)
+				continue;
+
+			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
+
+			if (!split_node)
+				return NULL;
+
+			node->base = temp_qword;
+			node->length -= split_node->length;
+
+			/* Put it in the list */
+			split_node->next = node->next;
+			node->next = split_node;
+		} /* End of non-aligned base */
+
+		/* Don't need to check if too small since we already did */
+		if (node->length > size) {
+			/* this one is longer than we need
+			   so we'll make a new entry and split it up */
+			split_node = acpiphp_make_resource(node->base + size, node->length - size);
+
+			if (!split_node)
+				return NULL;
+
+			node->length = size;
+
+			/* Put it in the list */
+			split_node->next = node->next;
+			node->next = split_node;
+		}  /* End of too big on top end */
+
+		/* For IO make sure it's not in the ISA aliasing space */
+		if (node->base & 0x300L)
+			continue;
+
+		/* If we got here, then it is the right size
+		   Now take it out of the list */
+		if (*head == node) {
+			*head = node->next;
+		} else {
+			prevnode = *head;
+			while (prevnode->next != node)
+				prevnode = prevnode->next;
+
+			prevnode->next = node->next;
+		}
+		node->next = NULL;
+		/* Stop looping */
+		break;
+	}
+
+	return node;
+}
+
+
+/**
+ * get_max_resource - get the largest resource
+ *
+ * Gets the largest node that is at least "size" big from the
+ * list pointed to by head.  It aligns the node on top and bottom
+ * to "size" alignment before returning it.
+ */
+struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *max;
+	struct pci_resource *temp;
+	struct pci_resource *split_node;
+	u64 temp_qword;
+
+	if (!(*head))
+		return NULL;
+
+	if (acpiphp_resource_sort_and_combine(head))
+		return NULL;
+
+	if (sort_by_max_size(head))
+		return NULL;
+
+	for (max = *head;max; max = max->next) {
+
+		/* If not big enough we could probably just bail,
+		   instead we'll continue to the next. */
+		if (max->length < size)
+			continue;
+
+		if (max->base & (size - 1)) {
+			/* this one isn't base aligned properly
+			   so we'll make a new entry and split it up */
+			temp_qword = (max->base | (size-1)) + 1;
+
+			/* Short circuit if adjusted size is too small */
+			if ((max->length - (temp_qword - max->base)) < size)
+				continue;
+
+			split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
+
+			if (!split_node)
+				return NULL;
+
+			max->base = temp_qword;
+			max->length -= split_node->length;
+
+			/* Put it next in the list */
+			split_node->next = max->next;
+			max->next = split_node;
+		}
+
+		if ((max->base + max->length) & (size - 1)) {
+			/* this one isn't end aligned properly at the top
+			   so we'll make a new entry and split it up */
+			temp_qword = ((max->base + max->length) & ~(size - 1));
+
+			split_node = acpiphp_make_resource(temp_qword,
+							   max->length + max->base - temp_qword);
+
+			if (!split_node)
+				return NULL;
+
+			max->length -= split_node->length;
+
+			/* Put it in the list */
+			split_node->next = max->next;
+			max->next = split_node;
+		}
+
+		/* Make sure it didn't shrink too much when we aligned it */
+		if (max->length < size)
+			continue;
+
+		/* Now take it out of the list */
+		temp = (struct pci_resource*) *head;
+		if (temp == max) {
+			*head = max->next;
+		} else {
+			while (temp && temp->next != max) {
+				temp = temp->next;
+			}
+
+			temp->next = max->next;
+		}
+
+		max->next = NULL;
+		return max;
+	}
+
+	/* If we get here, we couldn't find one */
+	return NULL;
+}
+
+
+/**
+ * get_resource - get resource (mem, pfmem)
+ *
+ * this function sorts the resource list by size and then
+ * returns the first node of "size" length.  If it finds a node
+ * larger than "size" it will split it up.
+ *
+ * size must be a power of two.
+ *
+ */
+struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *prevnode;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u64 temp_qword;
+
+	if (!(*head))
+		return NULL;
+
+	if (acpiphp_resource_sort_and_combine(head))
+		return NULL;
+
+	if (sort_by_size(head))
+		return NULL;
+
+	for (node = *head; node; node = node->next) {
+		dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
+		    __FUNCTION__, size, node, (u32)node->base, node->length);
+		if (node->length < size)
+			continue;
+
+		if (node->base & (size - 1)) {
+			dbg("%s: not aligned\n", __FUNCTION__);
+			/* this one isn't base aligned properly
+			   so we'll make a new entry and split it up */
+			temp_qword = (node->base | (size-1)) + 1;
+
+			/* Short circuit if adjusted size is too small */
+			if ((node->length - (temp_qword - node->base)) < size)
+				continue;
+
+			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
+
+			if (!split_node)
+				return NULL;
+
+			node->base = temp_qword;
+			node->length -= split_node->length;
+
+			/* Put it in the list */
+			split_node->next = node->next;
+			node->next = split_node;
+		} /* End of non-aligned base */
+
+		/* Don't need to check if too small since we already did */
+		if (node->length > size) {
+			dbg("%s: too big\n", __FUNCTION__);
+			/* this one is longer than we need
+			   so we'll make a new entry and split it up */
+			split_node = acpiphp_make_resource(node->base + size, node->length - size);
+
+			if (!split_node)
+				return NULL;
+
+			node->length = size;
+
+			/* Put it in the list */
+			split_node->next = node->next;
+			node->next = split_node;
+		}  /* End of too big on top end */
+
+		dbg("%s: got one!!!\n", __FUNCTION__);
+		/* If we got here, then it is the right size
+		   Now take it out of the list */
+		if (*head == node) {
+			*head = node->next;
+		} else {
+			prevnode = *head;
+			while (prevnode->next != node)
+				prevnode = prevnode->next;
+
+			prevnode->next = node->next;
+		}
+		node->next = NULL;
+		/* Stop looping */
+		break;
+	}
+	return node;
+}
+
+/**
+ * get_resource_with_base - get resource with specific base address
+ *
+ * this function
+ * returns the first node of "size" length located at specified base address.
+ * If it finds a node larger than "size" it will split it up.
+ *
+ * size must be a power of two.
+ *
+ */
+struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)
+{
+	struct pci_resource *prevnode;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u64 temp_qword;
+
+	if (!(*head))
+		return NULL;
+
+	if (acpiphp_resource_sort_and_combine(head))
+		return NULL;
+
+	for (node = *head; node; node = node->next) {
+		dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
+		    (u32)base, size, node, (u32)node->base, node->length);
+		if (node->base > base)
+			continue;
+
+		if ((node->base + node->length) < (base + size))
+			continue;
+
+		if (node->base < base) {
+			dbg(": split 1\n");
+			/* this one isn't base aligned properly
+			   so we'll make a new entry and split it up */
+			temp_qword = base;
+
+			/* Short circuit if adjusted size is too small */
+			if ((node->length - (temp_qword - node->base)) < size)
+				continue;
+
+			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
+
+			if (!split_node)
+				return NULL;
+
+			node->base = temp_qword;
+			node->length -= split_node->length;
+
+			/* Put it in the list */
+			split_node->next = node->next;
+			node->next = split_node;
+		}
+
+		dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
+		    (u32)base, size, node, (u32)node->base, node->length);
+
+		/* Don't need to check if too small since we already did */
+		if (node->length > size) {
+			dbg(": split 2\n");
+			/* this one is longer than we need
+			   so we'll make a new entry and split it up */
+			split_node = acpiphp_make_resource(node->base + size, node->length - size);
+
+			if (!split_node)
+				return NULL;
+
+			node->length = size;
+
+			/* Put it in the list */
+			split_node->next = node->next;
+			node->next = split_node;
+		}  /* End of too big on top end */
+
+		dbg(": got one!!!\n");
+		/* If we got here, then it is the right size
+		   Now take it out of the list */
+		if (*head == node) {
+			*head = node->next;
+		} else {
+			prevnode = *head;
+			while (prevnode->next != node)
+				prevnode = prevnode->next;
+
+			prevnode->next = node->next;
+		}
+		node->next = NULL;
+		/* Stop looping */
+		break;
+	}
+	return node;
+}
+
+
+/**
+ * acpiphp_resource_sort_and_combine
+ *
+ * Sorts all of the nodes in the list in ascending order by
+ * their base addresses.  Also does garbage collection by
+ * combining adjacent nodes.
+ *
+ * returns 0 if success
+ */
+int acpiphp_resource_sort_and_combine (struct pci_resource **head)
+{
+	struct pci_resource *node1;
+	struct pci_resource *node2;
+	int out_of_order = 1;
+
+	if (!(*head))
+		return 1;
+
+	dbg("*head->next = %p\n",(*head)->next);
+
+	if (!(*head)->next)
+		return 0;	/* only one item on the list, already sorted! */
+
+	dbg("*head->base = 0x%x\n",(u32)(*head)->base);
+	dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base);
+	while (out_of_order) {
+		out_of_order = 0;
+
+		/* Special case for swapping list head */
+		if (((*head)->next) &&
+		    ((*head)->base > (*head)->next->base)) {
+			node1 = *head;
+			(*head) = (*head)->next;
+			node1->next = (*head)->next;
+			(*head)->next = node1;
+			out_of_order++;
+		}
+
+		node1 = (*head);
+
+		while (node1->next && node1->next->next) {
+			if (node1->next->base > node1->next->next->base) {
+				out_of_order++;
+				node2 = node1->next;
+				node1->next = node1->next->next;
+				node1 = node1->next;
+				node2->next = node1->next;
+				node1->next = node2;
+			} else
+				node1 = node1->next;
+		}
+	}  /* End of out_of_order loop */
+
+	node1 = *head;
+
+	while (node1 && node1->next) {
+		if ((node1->base + node1->length) == node1->next->base) {
+			/* Combine */
+			dbg("8..\n");
+			node1->length += node1->next->length;
+			node2 = node1->next;
+			node1->next = node1->next->next;
+			kfree(node2);
+		} else
+			node1 = node1->next;
+	}
+
+	return 0;
+}
+
+
+/**
+ * acpiphp_make_resource - make resource structure
+ * @base: base address of a resource
+ * @length: length of a resource
+ */
+struct pci_resource *acpiphp_make_resource (u64 base, u32 length)
+{
+	struct pci_resource *res;
+
+	res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+	if (res) {
+		memset(res, 0, sizeof(struct pci_resource));
+		res->base = base;
+		res->length = length;
+	}
+
+	return res;
+}
+
+
+/**
+ * acpiphp_move_resource - move linked resources from one to another
+ * @from: head of linked resource list
+ * @to: head of linked resource list
+ */
+void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)
+{
+	struct pci_resource *tmp;
+
+	while (*from) {
+		tmp = (*from)->next;
+		(*from)->next = *to;
+		*to = *from;
+		*from = tmp;
+	}
+
+	/* *from = NULL is guaranteed */
+}
+
+
+/**
+ * acpiphp_free_resource - free all linked resources
+ * @res: head of linked resource list
+ */
+void acpiphp_free_resource (struct pci_resource **res)
+{
+	struct pci_resource *tmp;
+
+	while (*res) {
+		tmp = (*res)->next;
+		kfree(*res);
+		*res = tmp;
+	}
+
+	/* *res = NULL is guaranteed */
+}
+
+
+/* debug support functions;  will go away sometime :) */
+static void dump_resource(struct pci_resource *head)
+{
+	struct pci_resource *p;
+	int cnt;
+
+	p = head;
+	cnt = 0;
+
+	while (p) {
+		dbg("[%02d] %08x - %08x\n",
+		    cnt++, (u32)p->base, (u32)p->base + p->length - 1);
+		p = p->next;
+	}
+}
+
+void acpiphp_dump_resource(struct acpiphp_bridge *bridge)
+{
+	dbg("I/O resource:\n");
+	dump_resource(bridge->io_head);
+	dbg("MEM resource:\n");
+	dump_resource(bridge->mem_head);
+	dbg("PMEM resource:\n");
+	dump_resource(bridge->p_mem_head);
+	dbg("BUS resource:\n");
+	dump_resource(bridge->bus_head);
+}
+
+void acpiphp_dump_func_resource(struct acpiphp_func *func)
+{
+	dbg("I/O resource:\n");
+	dump_resource(func->io_head);
+	dbg("MEM resource:\n");
+	dump_resource(func->mem_head);
+	dbg("PMEM resource:\n");
+	dump_resource(func->p_mem_head);
+	dbg("BUS resource:\n");
+	dump_resource(func->bus_head);
+}
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpci_hotplug.h linux-2.5.70-bk10/drivers/pci/hotplug/cpci_hotplug.h
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpci_hotplug.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpci_hotplug.h	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,100 @@
+/*
+ * CompactPCI Hot Plug Core Functions
+ *
+ * Copyright (c) 2002 SOMA Networks, Inc.
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <scottm@somanetworks.com>
+ */
+
+#ifndef _CPCI_HOTPLUG_H
+#define _CPCI_HOTPLUG_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+
+/* PICMG 2.12 R2.0 HS CSR bits: */
+#define HS_CSR_INS	0x0080
+#define HS_CSR_EXT	0x0040
+#define HS_CSR_PI	0x0030
+#define HS_CSR_LOO	0x0008
+#define HS_CSR_PIE	0x0004
+#define HS_CSR_EIM	0x0002
+#define HS_CSR_DHA	0x0001
+
+#define SLOT_MAGIC	0x67267322
+struct slot {
+	u32 magic;
+	u8 number;
+	unsigned int devfn;
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	unsigned int extracting;
+	struct hotplug_slot *hotplug_slot;
+	struct list_head slot_list;
+};
+
+struct cpci_hp_controller_ops {
+	int (*query_enum) (void);
+	int (*enable_irq) (void);
+	int (*disable_irq) (void);
+	int (*check_irq) (void *dev_id);
+	int (*hardware_test) (struct slot* slot, u32 value);
+	u8  (*get_power) (struct slot* slot);
+	int (*set_power) (struct slot* slot, int value);
+};
+
+struct cpci_hp_controller {
+	unsigned int irq;
+	unsigned long irq_flags;
+	char *devname;
+	void *dev_id;
+	char *name;
+	struct cpci_hp_controller_ops *ops;
+};
+
+extern int cpci_hp_register_controller(struct cpci_hp_controller *controller);
+extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
+extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
+extern int cpci_hp_unregister_bus(struct pci_bus *bus);
+extern struct slot *cpci_find_slot(struct pci_bus *bus, unsigned int devfn);
+extern int cpci_hp_start(void);
+extern int cpci_hp_stop(void);
+
+/*
+ * Internal function prototypes, these functions should not be used by
+ * board/chassis drivers.
+ */
+extern u8 cpci_get_attention_status(struct slot *slot);
+extern u8 cpci_get_latch_status(struct slot *slot);
+extern u8 cpci_get_adapter_status(struct slot *slot);
+extern u16 cpci_get_hs_csr(struct slot * slot);
+extern u16 cpci_set_hs_csr(struct slot * slot, u16 hs_csr);
+extern int cpci_set_attention_status(struct slot *slot, int status);
+extern int cpci_check_and_clear_ins(struct slot * slot);
+extern int cpci_check_ext(struct slot * slot);
+extern int cpci_clear_ext(struct slot * slot);
+extern int cpci_led_on(struct slot * slot);
+extern int cpci_led_off(struct slot * slot);
+extern int cpci_configure_slot(struct slot *slot);
+extern int cpci_unconfigure_slot(struct slot *slot);
+
+#endif	/* _CPCI_HOTPLUG_H */
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpci_hotplug_core.c linux-2.5.70-bk10/drivers/pci/hotplug/cpci_hotplug_core.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpci_hotplug_core.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpci_hotplug_core.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,919 @@
+/*
+ * CompactPCI Hot Plug Driver
+ *
+ * Copyright (c) 2002 SOMA Networks, Inc.
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <scottm@somanetworks.com>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+#include "pci_hotplug.h"
+#include "cpci_hotplug.h"
+
+#define DRIVER_VERSION	"0.2"
+#define DRIVER_AUTHOR	"Scott Murray <scottm@somanetworks.com>"
+#define DRIVER_DESC	"CompactPCI Hot Plug Core"
+
+#if !defined(CONFIG_HOTPLUG_CPCI_MODULE)
+#define MY_NAME	"cpci_hotplug"
+#else
+#define MY_NAME	THIS_MODULE->name
+#endif
+
+#define dbg(format, arg...)					\
+	do {							\
+		if(cpci_debug)					\
+			printk (KERN_DEBUG "%s: " format "\n",	\
+				MY_NAME , ## arg); 		\
+	} while(0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+
+/* local variables */
+static spinlock_t list_lock;
+static LIST_HEAD(slot_list);
+static int slots;
+int cpci_debug;
+static struct cpci_hp_controller *controller;
+static struct semaphore event_semaphore;	/* mutex for process loop (up if something to process) */
+static struct semaphore thread_exit;		/* guard ensure thread has exited before calling it quits */
+static int thread_finished = 1;
+
+static int enable_slot(struct hotplug_slot *slot);
+static int disable_slot(struct hotplug_slot *slot);
+static int set_attention_status(struct hotplug_slot *slot, u8 value);
+static int get_power_status(struct hotplug_slot *slot, u8 * value);
+static int get_attention_status(struct hotplug_slot *slot, u8 * value);
+static int get_latch_status(struct hotplug_slot *slot, u8 * value);
+static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
+
+static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
+	.owner = THIS_MODULE,
+	.enable_slot = enable_slot,
+	.disable_slot = disable_slot,
+	.set_attention_status = set_attention_status,
+	.hardware_test = NULL,
+	.get_power_status = get_power_status,
+	.get_attention_status = get_attention_status,
+	.get_latch_status = get_latch_status,
+	.get_adapter_status = get_adapter_status,
+};
+
+/* Inline functions to check the sanity of a pointer that is passed to us */
+static inline int
+slot_paranoia_check(struct slot *slot, const char *function)
+{
+	if(!slot) {
+		dbg("%s - slot == NULL", function);
+		return -1;
+	}
+	if(slot->magic != SLOT_MAGIC) {
+		dbg("%s - bad magic number for slot", function);
+		return -1;
+	}
+	if(!slot->hotplug_slot) {
+		dbg("%s - slot->hotplug_slot == NULL!", function);
+		return -1;
+	}
+	return 0;
+}
+
+static inline struct slot *
+get_slot(struct hotplug_slot *hotplug_slot, const char *function)
+{
+	struct slot *slot;
+
+	if(!hotplug_slot) {
+		dbg("%s - hotplug_slot == NULL", function);
+		return NULL;
+	}
+
+	slot = (struct slot *) hotplug_slot->private;
+	if(slot_paranoia_check(slot, function))
+		return NULL;
+	return slot;
+}
+
+static int
+update_latch_status(struct hotplug_slot *hotplug_slot, u8 value)
+{
+	struct hotplug_slot_info info;
+
+	if(!(hotplug_slot && hotplug_slot->info))
+		return -EINVAL;
+	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
+	info.latch_status = value;
+	return pci_hp_change_slot_info(hotplug_slot, &info);
+}
+
+static int
+update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
+{
+	struct hotplug_slot_info info;
+
+	if(!(hotplug_slot && hotplug_slot->info))
+		return -EINVAL;
+	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
+	info.adapter_status = value;
+	return pci_hp_change_slot_info(hotplug_slot, &info);
+}
+
+static int
+enable_slot(struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	int retval = 0;
+
+	if(slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	if(controller->ops->set_power) {
+		retval = controller->ops->set_power(slot, 1);
+	}
+
+	return retval;
+}
+
+static int
+disable_slot(struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+	int retval = 0;
+
+	if(slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+
+	/* Unconfigure device */
+	dbg("%s - unconfiguring slot %s",
+	    __FUNCTION__, slot->hotplug_slot->name);
+	if((retval = cpci_unconfigure_slot(slot))) {
+		err("%s - could not unconfigure slot %s",
+		    __FUNCTION__, slot->hotplug_slot->name);
+		return retval;
+	}
+	dbg("%s - finished unconfiguring slot %s",
+	    __FUNCTION__, slot->hotplug_slot->name);
+
+	/* Clear EXT (by setting it) */
+	if(cpci_clear_ext(slot)) {
+		err("%s - could not clear EXT for slot %s",
+		    __FUNCTION__, slot->hotplug_slot->name);
+		retval = -ENODEV;
+	}
+	cpci_led_on(slot);
+
+	if(controller->ops->set_power) {
+		retval = controller->ops->set_power(slot, 0);
+	}
+
+	if(update_adapter_status(slot->hotplug_slot, 0)) {
+		warn("failure to update adapter file");
+	}
+
+	slot->extracting = 0;
+
+	return retval;
+}
+
+static u8
+cpci_get_power_status(struct slot *slot)
+{
+	u8 power = 1;
+
+	if(controller->ops->get_power) {
+		power = controller->ops->get_power(slot);
+	}
+	return power;
+}
+
+static int
+get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+
+	if(slot == NULL)
+		return -ENODEV;
+	*value = cpci_get_power_status(slot);
+	return 0;
+}
+
+static int
+get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+
+	if(slot == NULL)
+		return -ENODEV;
+	*value = cpci_get_attention_status(slot);
+	return 0;
+}
+
+static int
+set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
+{
+	struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+
+	if(slot == NULL)
+		return -ENODEV;
+	switch (status) {
+	case 0:
+		cpci_set_attention_status(slot, 0);
+		break;
+
+	case 1:
+	default:
+		cpci_set_attention_status(slot, 1);
+		break;
+	}
+
+	return 0;
+}
+
+static int
+get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	if(hotplug_slot == NULL || hotplug_slot->info == NULL)
+		return -ENODEV;
+	*value = hotplug_slot->info->latch_status;
+	return 0;
+}
+
+static int
+get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	if(hotplug_slot == NULL || hotplug_slot->info == NULL)
+		return -ENODEV;
+	*value = hotplug_slot->info->adapter_status;
+	return 0;
+}
+
+#define SLOT_NAME_SIZE	6
+static void
+make_slot_name(struct slot *slot)
+{
+	snprintf(slot->hotplug_slot->name,
+		 SLOT_NAME_SIZE, "%02x:%02x", slot->bus->number, slot->number);
+}
+
+int
+cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
+{
+	struct slot *slot;
+	struct hotplug_slot *hotplug_slot;
+	struct hotplug_slot_info *info;
+	char *name;
+	int status = 0;
+	int i;
+
+	if(!(controller && bus)) {
+		return -ENODEV;
+	}
+	if(last < first) {
+		return -EINVAL;
+	}
+
+	/*
+	 * Create a structure for each slot, and register that slot
+	 * with the pci_hotplug subsystem.
+	 */
+	for (i = first; i <= last; ++i) {
+		slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
+		if(!slot)
+			return -ENOMEM;
+		memset(slot, 0, sizeof (struct slot));
+
+		hotplug_slot =
+		    kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
+		if(!hotplug_slot) {
+			kfree(slot);
+			return -ENOMEM;
+		}
+		memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
+		slot->hotplug_slot = hotplug_slot;
+
+		info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
+		if(!info) {
+			kfree(hotplug_slot);
+			kfree(slot);
+			return -ENOMEM;
+		}
+		memset(info, 0, sizeof (struct hotplug_slot_info));
+		hotplug_slot->info = info;
+
+		name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
+		if(!name) {
+			kfree(info);
+			kfree(hotplug_slot);
+			kfree(slot);
+			return -ENOMEM;
+		}
+		hotplug_slot->name = name;
+
+		slot->magic = SLOT_MAGIC;
+		slot->bus = bus;
+		slot->number = i;
+		slot->devfn = PCI_DEVFN(i, 0);
+
+		hotplug_slot->private = slot;
+		make_slot_name(slot);
+		hotplug_slot->ops = &cpci_hotplug_slot_ops;
+
+		/*
+		 * Initialize the slot info structure with some known
+		 * good values.
+		 */
+		dbg("initializing slot %s", slot->hotplug_slot->name);
+		info->power_status = cpci_get_power_status(slot);
+		info->attention_status = cpci_get_attention_status(slot);
+
+		dbg("registering slot %s", slot->hotplug_slot->name);
+		status = pci_hp_register(slot->hotplug_slot);
+		if(status) {
+			err("pci_hp_register failed with error %d", status);
+			kfree(info);
+			kfree(name);
+			kfree(hotplug_slot);
+			kfree(slot);
+			return status;
+		}
+
+		/* Add slot to our internal list */
+		spin_lock(&list_lock);
+		list_add(&slot->slot_list, &slot_list);
+		slots++;
+		spin_unlock(&list_lock);
+	}
+	return status;
+}
+
+int
+cpci_hp_unregister_bus(struct pci_bus *bus)
+{
+	struct slot *slot;
+	struct list_head *tmp;
+	int status;
+
+	if(!bus) {
+		return -ENODEV;
+	}
+
+	spin_lock(&list_lock);
+	if(!slots) {
+		spin_unlock(&list_lock);
+		return -1;
+	}
+	list_for_each(tmp, &slot_list) {
+		slot = list_entry(tmp, struct slot, slot_list);
+		if(slot->bus == bus) {
+			dbg("deregistering slot %s", slot->hotplug_slot->name);
+			status = pci_hp_deregister(slot->hotplug_slot);
+			if(status) {
+				err("pci_hp_deregister failed with error %d",
+				    status);
+				return status;
+			}
+
+			list_del(&slot->slot_list);
+			kfree(slot->hotplug_slot->info);
+			kfree(slot->hotplug_slot->name);
+			kfree(slot->hotplug_slot);
+			kfree(slot);
+
+			slots--;
+		}
+	}
+	spin_unlock(&list_lock);
+	return 0;
+}
+
+struct slot *
+cpci_find_slot(struct pci_bus *bus, unsigned int devfn)
+{
+	struct slot *slot;
+	struct slot *found;
+	struct list_head *tmp;
+
+	if(!bus) {
+		return NULL;
+	}
+
+	spin_lock(&list_lock);
+	if(!slots) {
+		spin_unlock(&list_lock);
+		return NULL;
+	}
+	found = NULL;
+	list_for_each(tmp, &slot_list) {
+		slot = list_entry(tmp, struct slot, slot_list);
+		if(slot->bus == bus && slot->devfn == devfn) {
+			found = slot;
+			break;
+		}
+	}
+	spin_unlock(&list_lock);
+	return found;
+}
+
+/* This is the interrupt mode interrupt handler */
+irqreturn_t
+cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
+{
+	dbg("entered cpci_hp_intr");
+
+	/* Check to see if it was our interrupt */
+	if((controller->irq_flags & SA_SHIRQ) &&
+	    !controller->ops->check_irq(controller->dev_id)) {
+		dbg("exited cpci_hp_intr, not our interrupt");
+		return IRQ_NONE;
+	}
+
+	/* Disable ENUM interrupt */
+	controller->ops->disable_irq();
+
+	/* Trigger processing by the event thread */
+	dbg("Signal event_semaphore");
+	up(&event_semaphore);
+	dbg("exited cpci_hp_intr");
+	return IRQ_HANDLED;
+}
+
+/*
+ * According to PICMG 2.12 R2.0, section 6.3.2, upon
+ * initialization, the system driver shall clear the
+ * INS bits of the cold-inserted devices.
+ */
+static int
+init_slots(void)
+{
+	struct slot *slot;
+	struct list_head *tmp;
+	struct pci_dev* dev;
+
+	dbg("%s - enter", __FUNCTION__);
+	spin_lock(&list_lock);
+	if(!slots) {
+		spin_unlock(&list_lock);
+		return -1;
+	}
+	list_for_each(tmp, &slot_list) {
+		slot = list_entry(tmp, struct slot, slot_list);
+		dbg("%s - looking at slot %s",
+		    __FUNCTION__, slot->hotplug_slot->name);
+		if(cpci_check_and_clear_ins(slot)) {
+			dbg("%s - cleared INS for slot %s",
+			    __FUNCTION__, slot->hotplug_slot->name);
+			dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0));
+			if(dev) {
+				if(update_adapter_status(slot->hotplug_slot, 1)) {
+					warn("failure to update adapter file");
+				}
+				if(update_latch_status(slot->hotplug_slot, 1)) {
+					warn("failure to update latch file");
+				}
+				slot->dev = dev;
+			} else {
+				err("%s - no driver attached to device in slot %s",
+				    __FUNCTION__, slot->hotplug_slot->name);
+			}
+		}
+	}
+	spin_unlock(&list_lock);
+	dbg("%s - exit", __FUNCTION__);
+	return 0;
+}
+
+static int
+check_slots(void)
+{
+	struct slot *slot;
+	struct list_head *tmp;
+	int extracted;
+	int inserted;
+
+	spin_lock(&list_lock);
+	if(!slots) {
+		spin_unlock(&list_lock);
+		err("no slots registered, shutting down");
+		return -1;
+	}
+	extracted = inserted = 0;
+	list_for_each(tmp, &slot_list) {
+		slot = list_entry(tmp, struct slot, slot_list);
+		dbg("%s - looking at slot %s",
+		    __FUNCTION__, slot->hotplug_slot->name);
+		if(cpci_check_and_clear_ins(slot)) {
+			u16 hs_csr;
+
+			/* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
+			if(slot->dev) {
+				warn("slot %s already inserted", slot->hotplug_slot->name);
+				inserted++;
+				continue;
+			}
+
+			/* Process insertion */
+			dbg("%s - slot %s inserted",
+			    __FUNCTION__, slot->hotplug_slot->name);
+
+			/* GSM, debug */
+			hs_csr = cpci_get_hs_csr(slot);
+			dbg("%s - slot %s HS_CSR (1) = %04x",
+			    __FUNCTION__, slot->hotplug_slot->name, hs_csr);
+
+			/* Configure device */
+			dbg("%s - configuring slot %s",
+			    __FUNCTION__, slot->hotplug_slot->name);
+			if(cpci_configure_slot(slot)) {
+				err("%s - could not configure slot %s",
+				    __FUNCTION__, slot->hotplug_slot->name);
+				continue;
+			}
+			dbg("%s - finished configuring slot %s",
+			    __FUNCTION__, slot->hotplug_slot->name);
+
+			/* GSM, debug */
+			hs_csr = cpci_get_hs_csr(slot);
+			dbg("%s - slot %s HS_CSR (2) = %04x",
+			    __FUNCTION__, slot->hotplug_slot->name, hs_csr);
+
+			if(update_latch_status(slot->hotplug_slot, 1)) {
+				warn("failure to update latch file");
+			}
+
+			if(update_adapter_status(slot->hotplug_slot, 1)) {
+				warn("failure to update adapter file");
+			}
+
+			cpci_led_off(slot);
+
+			/* GSM, debug */
+			hs_csr = cpci_get_hs_csr(slot);
+			dbg("%s - slot %s HS_CSR (3) = %04x",
+			    __FUNCTION__, slot->hotplug_slot->name, hs_csr);
+
+			inserted++;
+		} else if(cpci_check_ext(slot)) {
+			u16 hs_csr;
+
+			/* Process extraction request */
+			dbg("%s - slot %s extracted",
+			    __FUNCTION__, slot->hotplug_slot->name);
+
+			/* GSM, debug */
+			hs_csr = cpci_get_hs_csr(slot);
+			dbg("%s - slot %s HS_CSR = %04x",
+			    __FUNCTION__, slot->hotplug_slot->name, hs_csr);
+
+			if(!slot->extracting) {
+				if(update_latch_status(slot->hotplug_slot, 0)) {
+					warn("failure to update latch file");
+				}
+				slot->extracting = 1;
+			}
+			extracted++;
+		}
+	}
+	spin_unlock(&list_lock);
+	if(inserted || extracted) {
+		return extracted;
+	}
+	else {
+		err("cannot find ENUM# source, shutting down");
+		return -1;
+	}
+}
+
+/* This is the interrupt mode worker thread body */
+static int
+event_thread(void *data)
+{
+	int rc;
+	struct slot *slot;
+	struct list_head *tmp;
+
+	lock_kernel();
+	daemonize("cpci_hp_eventd");
+	unlock_kernel();
+
+	dbg("%s - event thread started", __FUNCTION__);
+	while(1) {
+		dbg("event thread sleeping");
+		down_interruptible(&event_semaphore);
+		dbg("event thread woken, thread_finished = %d",
+		    thread_finished);
+		if(thread_finished || signal_pending(current))
+			break;
+		while(controller->ops->query_enum()) {
+			rc = check_slots();
+			if(rc > 0) {
+				/* Give userspace a chance to handle extraction */
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(HZ / 2);
+			} else if(rc < 0) {
+				dbg("%s - error checking slots", __FUNCTION__);
+				thread_finished = 1;
+				break;
+			}
+		}
+		/* Check for someone yanking out a board */
+		list_for_each(tmp, &slot_list) {
+			slot = list_entry(tmp, struct slot, slot_list);
+			if(slot->extracting) {
+				/*
+				 * Hmmm, we're likely hosed at this point, should we
+				 * bother trying to tell the driver or not?
+				 */
+				err("card in slot %s was improperly removed",
+				    slot->hotplug_slot->name);
+				if(update_adapter_status(slot->hotplug_slot, 0)) {
+					warn("failure to update adapter file");
+				}
+				slot->extracting = 0;
+			}
+		}
+
+		/* Re-enable ENUM# interrupt */
+		dbg("%s - re-enabling irq", __FUNCTION__);
+		controller->ops->enable_irq();
+	}
+
+	dbg("%s - event thread signals exit", __FUNCTION__);
+	up(&thread_exit);
+	return 0;
+}
+
+/* This is the polling mode worker thread body */
+static int
+poll_thread(void *data)
+{
+	int rc;
+	struct slot *slot;
+	struct list_head *tmp;
+
+	lock_kernel();
+	daemonize("cpci_hp_polld");
+	unlock_kernel();
+
+	while(1) {
+		if(thread_finished || signal_pending(current))
+			break;
+
+		while(controller->ops->query_enum()) {
+			rc = check_slots();
+			if(rc > 0) {
+				/* Give userspace a chance to handle extraction */
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(HZ / 2);
+			} else if(rc < 0) {
+				dbg("%s - error checking slots", __FUNCTION__);
+				thread_finished = 1;
+				break;
+			}
+		}
+		/* Check for someone yanking out a board */
+		list_for_each(tmp, &slot_list) {
+			slot = list_entry(tmp, struct slot, slot_list);
+			if(slot->extracting) {
+				/*
+				 * Hmmm, we're likely hosed at this point, should we
+				 * bother trying to tell the driver or not?
+				 */
+				err("card in slot %s was improperly removed",
+				    slot->hotplug_slot->name);
+				if(update_adapter_status(slot->hotplug_slot, 0)) {
+					warn("failure to update adapter file");
+				}
+				slot->extracting = 0;
+			}
+		}
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ / 10);
+	}
+	dbg("poll thread signals exit");
+	up(&thread_exit);
+	return 0;
+}
+
+static int
+cpci_start_thread(void)
+{
+	int pid;
+
+	/* initialize our semaphores */
+	init_MUTEX_LOCKED(&event_semaphore);
+	init_MUTEX_LOCKED(&thread_exit);
+	thread_finished = 0;
+
+	if(controller->irq) {
+		pid = kernel_thread(event_thread, 0, 0);
+	} else {
+		pid = kernel_thread(poll_thread, 0, 0);
+	}
+	if(pid < 0) {
+		err("Can't start up our thread");
+		return -1;
+	}
+	dbg("Our thread pid = %d", pid);
+	return 0;
+}
+
+static void
+cpci_stop_thread(void)
+{
+	thread_finished = 1;
+	dbg("thread finish command given");
+	if(controller->irq) {
+		up(&event_semaphore);
+	}
+	dbg("wait for thread to exit");
+	down(&thread_exit);
+}
+
+int
+cpci_hp_register_controller(struct cpci_hp_controller *new_controller)
+{
+	int status = 0;
+
+	if(!controller) {
+		controller = new_controller;
+		if(controller->irq) {
+			if(request_irq(controller->irq,
+					cpci_hp_intr,
+					controller->irq_flags,
+					MY_NAME, controller->dev_id)) {
+				err("Can't get irq %d for the hotplug cPCI controller", controller->irq);
+				status = -ENODEV;
+			}
+			dbg("%s - acquired controller irq %d", __FUNCTION__,
+			    controller->irq);
+		}
+	} else {
+		err("cPCI hotplug controller already registered");
+		status = -1;
+	}
+	return status;
+}
+
+int
+cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
+{
+	int status = 0;
+
+	if(controller) {
+		if(!thread_finished) {
+			cpci_stop_thread();
+		}
+		if(controller->irq) {
+			free_irq(controller->irq, controller->dev_id);
+		}
+		controller = NULL;
+	} else {
+		status = -ENODEV;
+	}
+	return status;
+}
+
+int
+cpci_hp_start(void)
+{
+	static int first = 1;
+	int status;
+
+	dbg("%s - enter", __FUNCTION__);
+	if(!controller) {
+		return -ENODEV;
+	}
+
+	spin_lock(&list_lock);
+	if(!slots) {
+		spin_unlock(&list_lock);
+		return -ENODEV;
+	}
+	spin_unlock(&list_lock);
+
+	if(first) {
+		status = init_slots();
+		if(status) {
+			return status;
+		}
+		first = 0;
+	}
+
+	status = cpci_start_thread();
+	if(status) {
+		return status;
+	}
+	dbg("%s - thread started", __FUNCTION__);
+
+	if(controller->irq) {
+		/* Start enum interrupt processing */
+		dbg("%s - enabling irq", __FUNCTION__);
+		controller->ops->enable_irq();
+	}
+	dbg("%s - exit", __FUNCTION__);
+	return 0;
+}
+
+int
+cpci_hp_stop(void)
+{
+	if(!controller) {
+		return -ENODEV;
+	}
+
+	if(controller->irq) {
+		/* Stop enum interrupt processing */
+		dbg("%s - disabling irq", __FUNCTION__);
+		controller->ops->disable_irq();
+	}
+	cpci_stop_thread();
+	return 0;
+}
+
+static void __exit
+cleanup_slots(void)
+{
+	struct list_head *tmp;
+	struct slot *slot;
+
+	/*
+	 * Unregister all of our slots with the pci_hotplug subsystem,
+	 * and free up all memory that we had allocated.
+	 */
+	spin_lock(&list_lock);
+	if(!slots) {
+		goto null_cleanup;
+	}
+	list_for_each(tmp, &slot_list) {
+		slot = list_entry(tmp, struct slot, slot_list);
+		list_del(&slot->slot_list);
+		pci_hp_deregister(slot->hotplug_slot);
+		kfree(slot->hotplug_slot->info);
+		kfree(slot->hotplug_slot->name);
+		kfree(slot->hotplug_slot);
+		kfree(slot);
+	}
+      null_cleanup:
+	spin_unlock(&list_lock);
+	return;
+}
+
+int __init
+cpci_hotplug_init(int debug)
+{
+	spin_lock_init(&list_lock);
+	cpci_debug = debug;
+
+	info(DRIVER_DESC " version: " DRIVER_VERSION);
+	return 0;
+}
+
+void __exit
+cpci_hotplug_exit(void)
+{
+	/*
+	 * Clean everything up.
+	 */
+	cleanup_slots();
+}
+
+
+EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
+EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
+EXPORT_SYMBOL_GPL(cpci_hp_register_bus);
+EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);
+EXPORT_SYMBOL_GPL(cpci_find_slot);
+EXPORT_SYMBOL_GPL(cpci_hp_start);
+EXPORT_SYMBOL_GPL(cpci_hp_stop);
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpci_hotplug_pci.c linux-2.5.70-bk10/drivers/pci/hotplug/cpci_hotplug_pci.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpci_hotplug_pci.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpci_hotplug_pci.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,647 @@
+/*
+ * CompactPCI Hot Plug Driver PCI functions
+ *
+ * Copyright (c) 2002 by SOMA Networks, Inc.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <scottm@somanetworks.com>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include "../pci.h"
+#include "pci_hotplug.h"
+#include "cpci_hotplug.h"
+
+#if !defined(CONFIG_HOTPLUG_CPCI_MODULE)
+#define MY_NAME	"cpci_hotplug"
+#else
+#define MY_NAME	THIS_MODULE->name
+#endif
+
+extern int cpci_debug;
+
+#define dbg(format, arg...)					\
+	do {							\
+		if(cpci_debug)					\
+			printk (KERN_DEBUG "%s: " format "\n",	\
+				MY_NAME , ## arg); 		\
+	} while(0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+
+#define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
+
+
+u8 cpci_get_attention_status(struct slot* slot)
+{
+	int hs_cap;
+	u16 hs_csr;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return 0;
+	}
+
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &hs_csr)) {
+		return 0;
+	}
+	return hs_csr & 0x0008 ? 1 : 0;
+}
+
+int cpci_set_attention_status(struct slot* slot, int status)
+{
+	int hs_cap;
+	u16 hs_csr;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return 0;
+	}
+
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &hs_csr)) {
+		return 0;
+	}
+	if(status) {
+		hs_csr |= HS_CSR_LOO;
+	} else {
+		hs_csr &= ~HS_CSR_LOO;
+	}
+	if(pci_bus_write_config_word(slot->bus,
+				      slot->devfn,
+				      hs_cap + 2,
+				      hs_csr)) {
+		return 0;
+	}
+	return 1;
+}
+
+u16 cpci_get_hs_csr(struct slot* slot)
+{
+	int hs_cap;
+	u16 hs_csr;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return 0xFFFF;
+	}
+
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &hs_csr)) {
+		return 0xFFFF;
+	}
+	return hs_csr;
+}
+
+u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
+{
+	int hs_cap;
+	u16 new_hs_csr;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return 0xFFFF;
+	}
+
+	/* Write out the new value */
+	if(pci_bus_write_config_word(slot->bus,
+				      slot->devfn,
+				      hs_cap + 2,
+				      hs_csr)) {
+		return 0xFFFF;
+	}
+
+	/* Read back what we just wrote out */
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &new_hs_csr)) {
+		return 0xFFFF;
+	}
+	return new_hs_csr;
+}
+
+int cpci_check_and_clear_ins(struct slot* slot)
+{
+	int hs_cap;
+	u16 hs_csr;
+	int ins = 0;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return 0;
+	}
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &hs_csr)) {
+		return 0;
+	}
+	if(hs_csr & HS_CSR_INS) {
+		/* Clear INS (by setting it) */
+		if(pci_bus_write_config_word(slot->bus,
+					      slot->devfn,
+					      hs_cap + 2,
+					      hs_csr)) {
+			ins = 0;
+		}
+		ins = 1;
+	}
+	return ins;
+}
+
+int cpci_check_ext(struct slot* slot)
+{
+	int hs_cap;
+	u16 hs_csr;
+	int ext = 0;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return 0;
+	}
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &hs_csr)) {
+		return 0;
+	}
+	if(hs_csr & HS_CSR_EXT) {
+		ext = 1;
+	}
+	return ext;
+}
+
+int cpci_clear_ext(struct slot* slot)
+{
+	int hs_cap;
+	u16 hs_csr;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return -ENODEV;
+	}
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &hs_csr)) {
+		return -ENODEV;
+	}
+	if(hs_csr & HS_CSR_EXT) {
+		/* Clear EXT (by setting it) */
+		if(pci_bus_write_config_word(slot->bus,
+					      slot->devfn,
+					      hs_cap + 2,
+					      hs_csr)) {
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
+
+int cpci_led_on(struct slot* slot)
+{
+	int hs_cap;
+	u16 hs_csr;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return -ENODEV;
+	}
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &hs_csr)) {
+		return -ENODEV;
+	}
+	if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
+		/* Set LOO */
+		hs_csr |= HS_CSR_LOO;
+		if(pci_bus_write_config_word(slot->bus,
+					      slot->devfn,
+					      hs_cap + 2,
+					      hs_csr)) {
+			err("Could not set LOO for slot %s",
+			    slot->hotplug_slot->name);
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
+
+int cpci_led_off(struct slot* slot)
+{
+	int hs_cap;
+	u16 hs_csr;
+
+	hs_cap = pci_bus_find_capability(slot->bus,
+					 slot->devfn,
+					 PCI_CAP_ID_CHSWP);
+	if(!hs_cap) {
+		return -ENODEV;
+	}
+	if(pci_bus_read_config_word(slot->bus,
+				     slot->devfn,
+				     hs_cap + 2,
+				     &hs_csr)) {
+		return -ENODEV;
+	}
+	if(hs_csr & HS_CSR_LOO) {
+		/* Clear LOO */
+		hs_csr &= ~HS_CSR_LOO;
+		if(pci_bus_write_config_word(slot->bus,
+					      slot->devfn,
+					      hs_cap + 2,
+					      hs_csr)) {
+			err("Could not clear LOO for slot %s",
+			    slot->hotplug_slot->name);
+			return -ENODEV;
+		}
+	}
+	return 0;
+}
+
+
+/*
+ * Device configuration functions
+ */
+
+static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
+{
+	u8 irq_pin;
+	int r;
+
+	dbg("%s - enter", __FUNCTION__);
+
+	/* NOTE: device already setup from prior scan */
+
+	/* FIXME: How would we know if we need to enable the expansion ROM? */
+	pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
+
+	/* Assign resources */
+	dbg("assigning resources for %02x:%02x.%x",
+	    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+	for (r = 0; r < 6; r++) {
+		struct resource *res = dev->resource + r;
+		if(res->flags)
+			pci_assign_resource(dev, r);
+	}
+	dbg("finished assigning resources for %02x:%02x.%x",
+	    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+
+	/* Does this function have an interrupt at all? */
+	dbg("checking for function interrupt");
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
+	if(irq_pin) {
+		dbg("function uses interrupt pin %d", irq_pin);
+	}
+
+	/*
+	 * Need to explicitly set irq field to 0 so that it'll get assigned
+	 * by the pcibios platform dependent code called by pci_enable_device.
+	 */
+	dev->irq = 0;
+
+	dbg("enabling device");
+	pci_enable_device(dev);	/* XXX check return */
+	dbg("now dev->irq = %d", dev->irq);
+	if(irq_pin && dev->irq) {
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	}
+
+	/* Can't use pci_insert_device at the moment, do it manually for now */
+	pci_proc_attach_device(dev);
+	dbg("notifying drivers");
+	//pci_announce_device_to_drivers(dev);
+	dbg("%s - exit", __FUNCTION__);
+	return 0;
+}
+
+static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
+{
+	int rc;
+	struct pci_bus* child;
+	struct resource* r;
+	u8 max, n;
+	u16 command;
+
+	dbg("%s - enter", __FUNCTION__);
+
+	/* Do basic bridge initialization */
+	rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
+	if(rc) {
+		printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
+	}
+	rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
+	if(rc) {
+		printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
+	}
+	rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
+	if(rc) {
+		printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
+	}
+
+	/*
+	 * Set parent bridge's subordinate field so that configuration space
+	 * access will work in pci_scan_bridge and friends.
+	 */
+	max = pci_max_busnr();
+	bus->subordinate = max + 1;
+	pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
+
+	/* Scan behind bridge */
+	n = pci_scan_bridge(bus, dev, max, 2);
+	child = pci_find_bus(max + 1);
+	if (!child)
+		return -ENODEV;
+	pci_proc_attach_bus(child);
+
+	/*
+	 * Update parent bridge's subordinate field if there were more bridges
+	 * behind the bridge that was scanned.
+	 */
+	if(n > max) {
+		bus->subordinate = n;
+		pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
+	}
+
+	/*
+	 * Update the bridge resources of the bridge to accommodate devices
+	 * behind it.
+	 */
+	pci_bus_size_bridges(child);
+	pci_bus_assign_resources(child);
+
+	/* Enable resource mapping via command register */
+	command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+	r = child->resource[0];
+	if(r && r->start) {
+		command |= PCI_COMMAND_IO;
+	}
+	r = child->resource[1];
+	if(r && r->start) {
+		command |= PCI_COMMAND_MEMORY;
+	}
+	r = child->resource[2];
+	if(r && r->start) {
+		command |= PCI_COMMAND_MEMORY;
+	}
+	rc = pci_write_config_word(dev, PCI_COMMAND, command);
+	if(rc) {
+		err("Error setting command register");
+		return rc;
+	}
+
+	/* Set bridge control register */
+	command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
+	rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
+	if(rc) {
+		err("Error setting bridge control register");
+		return rc;
+	}
+	dbg("%s - exit", __FUNCTION__);
+	return 0;
+}
+
+static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
+			struct pci_bus_wrapped *wrapped_bus)
+{
+	int rc;
+	struct pci_dev *dev = wrapped_dev->dev;
+	struct pci_bus *bus = wrapped_bus->bus;
+	struct slot* slot;
+
+	dbg("%s - enter", __FUNCTION__);
+
+	/*
+	 * We need to fix up the hotplug representation with the Linux
+	 * representation.
+	 */
+	slot = cpci_find_slot(dev->bus, dev->devfn);
+	if(slot) {
+		slot->dev = dev;
+	}
+
+	/* If it's a bridge, scan behind it for devices */
+	if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+		rc = cpci_configure_bridge(bus, dev);
+		if(rc)
+			return rc;
+	}
+
+	/* Actually configure device */
+	if(dev) {
+		rc = cpci_configure_dev(bus, dev);
+		if(rc)
+			return rc;
+	}
+	dbg("%s - exit", __FUNCTION__);
+	return 0;
+}
+
+static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
+					    struct pci_bus_wrapped *wrapped_bus)
+{
+	struct pci_dev *dev = wrapped_dev->dev;
+	struct slot* slot;
+
+	dbg("%s - enter", __FUNCTION__);
+	if(!dev)
+		return -ENODEV;
+
+	/* Remove the Linux representation */
+	if(pci_remove_device_safe(dev) == 0) {
+		kfree(dev);
+	} else {
+		err("Could not remove device\n");
+		return -1;
+	}
+
+	/*
+	 * Now remove the hotplug representation.
+	 */
+	slot = cpci_find_slot(dev->bus, dev->devfn);
+	if(slot) {
+		slot->dev = NULL;
+	} else {
+		dbg("No hotplug representation for %02x:%02x.%x",
+		    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+	}
+	dbg("%s - exit", __FUNCTION__);
+	return 0;
+}
+
+static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
+					    struct pci_dev_wrapped *wrapped_dev)
+{
+	struct pci_bus *bus = wrapped_bus->bus;
+	struct pci_bus *parent = bus->self->bus;
+
+	dbg("%s - enter", __FUNCTION__);
+
+	/* The cleanup code for proc entries regarding buses should be in the kernel... */
+	if(bus->procdir)
+		dbg("detach_pci_bus %s", bus->procdir->name);
+	pci_proc_detach_bus(bus);
+
+	/* The cleanup code should live in the kernel... */
+	bus->self->subordinate = NULL;
+
+	/* unlink from parent bus */
+	list_del(&bus->node);
+
+	/* Now, remove */
+	if(bus)
+		kfree(bus);
+
+	/* Update parent's subordinate field */
+	if(parent) {
+		u8 n = pci_bus_max_busnr(parent);
+		if(n < parent->subordinate) {
+			parent->subordinate = n;
+			pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
+		}
+	}
+	dbg("%s - exit", __FUNCTION__);
+	return 0;
+}
+
+static struct pci_visit configure_functions = {
+	.visit_pci_dev = configure_visit_pci_dev,
+};
+
+static struct pci_visit unconfigure_functions_phase2 = {
+	.post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
+	.post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
+};
+
+
+int cpci_configure_slot(struct slot* slot)
+{
+	int rc = 0;
+
+	dbg("%s - enter", __FUNCTION__);
+
+	if(slot->dev == NULL) {
+		dbg("pci_dev null, finding %02x:%02x:%x",
+		    slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
+		slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
+	}
+
+	/* Still NULL? Well then scan for it! */
+	if(slot->dev == NULL) {
+		dbg("pci_dev still null");
+
+		/*
+		 * This will generate pci_dev structures for all functions, but
+		 * we will only call this case when lookup fails.
+		 */
+		slot->dev = pci_scan_slot(slot->bus, slot->devfn);
+		if(slot->dev == NULL) {
+			err("Could not find PCI device for slot %02x", slot->number);
+			return 0;
+		}
+	}
+	dbg("slot->dev = %p", slot->dev);
+	if(slot->dev) {
+		struct pci_dev *dev;
+		struct pci_dev_wrapped wrapped_dev;
+		struct pci_bus_wrapped wrapped_bus;
+		int i;
+
+		memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
+		memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
+
+		for (i = 0; i < 8; i++) {
+			dev = pci_find_slot(slot->bus->number,
+					    PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
+			if(!dev)
+				continue;
+			wrapped_dev.dev = dev;
+			wrapped_bus.bus = slot->dev->bus;
+			rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
+		}
+	}
+
+	dbg("%s - exit, rc = %d", __FUNCTION__, rc);
+	return rc;
+}
+
+int cpci_unconfigure_slot(struct slot* slot)
+{
+	int rc = 0;
+	int i;
+	struct pci_dev_wrapped wrapped_dev;
+	struct pci_bus_wrapped wrapped_bus;
+	struct pci_dev *dev;
+
+	dbg("%s - enter", __FUNCTION__);
+
+	if(!slot->dev) {
+		err("No device for slot %02x\n", slot->number);
+		return -ENODEV;
+	}
+
+	memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
+	memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
+
+	for (i = 0; i < 8; i++) {
+		dev = pci_find_slot(slot->bus->number,
+				    PCI_DEVFN(PCI_SLOT(slot->devfn), i));
+		if(dev) {
+			wrapped_dev.dev = dev;
+			wrapped_bus.bus = dev->bus;
+			dbg("%s - unconfigure phase 2", __FUNCTION__);
+			rc = pci_visit_dev(&unconfigure_functions_phase2,
+					   &wrapped_dev, &wrapped_bus);
+			if(rc)
+				break;
+		}
+	}
+	dbg("%s - exit, rc = %d", __FUNCTION__, rc);
+	return rc;
+}
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpcihp_generic.c linux-2.5.70-bk10/drivers/pci/hotplug/cpcihp_generic.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpcihp_generic.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpcihp_generic.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,290 @@
+/*
+ * cpcihp_generic.c
+ *
+ * Generic port I/O CompactPCI driver
+ *
+ * Copyright 2002 SOMA Networks, Inc.
+ * Copyright 2001 Intel San Luis Obispo
+ * Copyright 2000,2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * This generic CompactPCI hotplug driver should allow using the PCI hotplug
+ * mechanism on any CompactPCI board that exposes the #ENUM signal as a bit
+ * in a system register that can be read through standard port I/O.
+ *
+ * Send feedback to <scottm@somanetworks.com>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include "cpci_hotplug.h"
+
+#define DRIVER_VERSION	"0.1"
+#define DRIVER_AUTHOR	"Scott Murray <scottm@somanetworks.com>"
+#define DRIVER_DESC	"Generic port I/O CompactPCI Hot Plug Driver"
+
+#if !defined(CONFIG_HOTPLUG_CPCI_GENERIC_MODULE)
+#define MY_NAME	"cpcihp_generic"
+#else
+#define MY_NAME	THIS_MODULE->name
+#endif
+
+#define dbg(format, arg...)					\
+	do {							\
+		if(debug)					\
+			printk (KERN_DEBUG "%s: " format "\n",	\
+				MY_NAME , ## arg); 		\
+	} while(0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+
+/* local variables */
+static int debug;
+static char* bridge;
+static u8 bridge_busnr;
+static u8 bridge_slot;
+static struct pci_bus *bus;
+static u8 first_slot;
+static u8 last_slot;
+static u16 port;
+static unsigned int enum_bit;
+static u8 enum_mask;
+
+static struct cpci_hp_controller_ops generic_hpc_ops;
+static struct cpci_hp_controller generic_hpc;
+
+/* The following allows configuring the driver when it's compiled into the kernel */
+#ifndef MODULE
+static int __init cpcihp_generic_setup(char* str)
+{
+	char* p;
+	unsigned long tmp;
+
+	if(!str)
+		return -EINVAL;
+	bridge = str;
+
+	p = strchr(str, ',');
+	str = p + 1;
+	if(!(p && *str && *p == ','))
+		goto setup_error;
+	tmp = simple_strtoul(str, &p, 0);
+	if(p == str || tmp > 0xff) {
+		err("hotplug bus first slot number out of range");
+		goto setup_error;
+	}
+	first_slot = (u8) tmp;
+
+	str = p + 1;		
+	if(!(*str && *p == ','))
+		return -EINVAL;
+	tmp = simple_strtoul(str, &p, 0);
+	if(p == str || tmp > 0xff) {
+		err("hotplug bus last slot number out of range");
+		goto setup_error;
+	}
+	last_slot = (u8) tmp;
+
+	str = p + 1;
+	if(!(*str && *p == ','))
+		goto setup_error;
+	tmp = simple_strtoul(str, &p, 0);
+	if(p == str || tmp > 0xffff) {
+		err("port number out of range");
+		goto setup_error;
+	}
+	port = (u16) tmp;
+
+	str = p + 1;
+	if(!(*str && *p == ','))
+		goto setup_error;
+	tmp = simple_strtoul(str, &p, 0);
+	if(p == str) {
+		err("invalid #ENUM bit number");
+		goto setup_error;
+	}
+	enum_bit = (u8) tmp;
+
+	str = p + 1;
+	if(*str && *p == ',') {
+		tmp = simple_strtoul(str, &p, 0);
+		if(p != str)
+			debug = (int) tmp;
+	}
+	return 0;
+setup_error:
+	bridge = NULL;
+	return -EINVAL;
+}
+
+__setup("cpcihp_generic=", cpcihp_generic_setup);
+#endif
+
+static int __init validate_parameters(void)
+{
+	char* str;
+	char* p;
+	unsigned long tmp;
+
+	if(!bridge) {
+		info("not configured, disabling.");
+		return 1;
+	}
+	str = bridge;
+	if(!*str)
+		return -EINVAL;
+
+	tmp = simple_strtoul(str, &p, 16);
+	if(p == str || tmp > 0xff) {
+		err("Invalid hotplug bus bridge device bus number");
+		return -EINVAL;
+	}
+	bridge_busnr = (u8) tmp;
+	dbg("bridge_busnr = 0x%02x", bridge_busnr);
+	if(*p != ':') {
+		err("Invalid hotplug bus bridge device");
+		return -EINVAL;
+	}
+	str = p + 1;
+	tmp = simple_strtoul(str, &p, 16);
+	if(p == str || tmp > 0x1f) {
+		err("Invalid hotplug bus bridge device slot number");
+		return -EINVAL;
+	}
+	bridge_slot = (u8) tmp;
+	dbg("bridge_slot = 0x%02x", bridge_slot);
+
+	dbg("first_slot = 0x%02x", first_slot);
+	dbg("last_slot = 0x%02x", last_slot);
+	if(!(first_slot && last_slot)) {
+		err("Need to specify first_slot and last_slot");
+		return -EINVAL;
+	}
+	if(last_slot < first_slot) {
+		err("first_slot must be less than last_slot");
+		return -EINVAL;
+	}
+
+	dbg("port = 0x%04x", port);
+	dbg("enum_bit = 0x%02x", enum_bit);
+	if(enum_bit > 7) {
+		err("Invalid #ENUM bit");
+		return -EINVAL;
+	}
+	enum_mask = 1 << enum_bit;
+	return 0;
+}
+
+static int query_enum(void)
+{
+	u8 value;
+
+	value = inb_p(port);
+	return ((value & enum_mask) == enum_mask);
+}
+
+static int __init cpcihp_generic_init(void)
+{
+	int status;
+	struct resource* r;
+	struct pci_dev* dev;
+
+	info(DRIVER_DESC " version: " DRIVER_VERSION);
+	status = validate_parameters();
+	if(status != 0)
+		return status;
+
+	r = request_region(port, 1, "#ENUM hotswap signal register");
+	if(!r)
+		return -EBUSY;
+
+	dev = pci_find_slot(bridge_busnr, PCI_DEVFN(bridge_slot, 0));
+	if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
+		err("Invalid bridge device %s", bridge);
+		return -EINVAL;
+	}
+	bus = dev->subordinate;
+
+	memset(&generic_hpc, 0, sizeof (struct cpci_hp_controller));
+	generic_hpc_ops.query_enum = query_enum;
+	generic_hpc.ops = &generic_hpc_ops;
+
+	status = cpci_hp_register_controller(&generic_hpc);
+	if(status != 0) {
+		err("Could not register cPCI hotplug controller");
+		return -ENODEV;
+	}
+	dbg("registered controller");
+
+	status = cpci_hp_register_bus(bus, first_slot, last_slot);
+	if(status != 0) {
+		err("Could not register cPCI hotplug bus");
+		goto init_bus_register_error;
+	}
+	dbg("registered bus");
+
+	status = cpci_hp_start();
+	if(status != 0) {
+		err("Could not started cPCI hotplug system");
+		goto init_start_error;
+	}
+	dbg("started cpci hp system");
+	return 0;
+init_start_error:
+	cpci_hp_unregister_bus(bus);
+init_bus_register_error:
+	cpci_hp_unregister_controller(&generic_hpc);
+	err("status = %d", status);
+	return status;
+
+}
+
+static void __exit cpcihp_generic_exit(void)
+{
+	cpci_hp_stop();
+	cpci_hp_unregister_bus(bus);
+	cpci_hp_unregister_controller(&generic_hpc);
+	release_region(port, 1);
+}
+
+module_init(cpcihp_generic_init);
+module_exit(cpcihp_generic_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+MODULE_PARM(bridge, "s");
+MODULE_PARM_DESC(bridge, "Hotswap bus bridge device, <bus>:<slot> (bus and slot are in hexadecimal)");
+MODULE_PARM(first_slot, "b");
+MODULE_PARM_DESC(first_slot, "Hotswap bus first slot number");
+MODULE_PARM(last_slot, "b");
+MODULE_PARM_DESC(last_slot, "Hotswap bus last slot number");
+MODULE_PARM(port, "h");
+MODULE_PARM_DESC(port, "#ENUM signal I/O port");
+MODULE_PARM(enum_bit, "i");
+MODULE_PARM_DESC(enum_bit, "#ENUM signal bit (0-7)");
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpcihp_zt5550.c linux-2.5.70-bk10/drivers/pci/hotplug/cpcihp_zt5550.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpcihp_zt5550.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpcihp_zt5550.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,306 @@
+/*
+ * cpcihp_zt5550.c
+ *
+ * Intel/Ziatech ZT5550 CompactPCI Host Controller driver
+ *
+ * Copyright 2002 SOMA Networks, Inc.
+ * Copyright 2001 Intel San Luis Obispo
+ * Copyright 2000,2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <scottm@somanetworks.com>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include "cpci_hotplug.h"
+#include "cpcihp_zt5550.h"
+
+#define DRIVER_VERSION	"0.2"
+#define DRIVER_AUTHOR	"Scott Murray <scottm@somanetworks.com>"
+#define DRIVER_DESC	"ZT5550 CompactPCI Hot Plug Driver"
+
+#if !defined(CONFIG_HOTPLUG_PCI_CPCI_ZT5550_MODULE)
+#define MY_NAME	"cpcihp_zt5550"
+#else
+#define MY_NAME	THIS_MODULE->name
+#endif
+
+#define dbg(format, arg...)					\
+	do {							\
+		if(debug)					\
+			printk (KERN_DEBUG "%s: " format "\n",	\
+				MY_NAME , ## arg); 		\
+	} while(0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+
+/* local variables */
+static int debug;
+static int poll;
+static struct cpci_hp_controller_ops zt5550_hpc_ops;
+static struct cpci_hp_controller zt5550_hpc;
+
+/* Primary cPCI bus bridge device */
+static struct pci_dev *bus0_dev;
+static struct pci_bus *bus0;
+
+/* Host controller device */
+static struct pci_dev *hc_dev;
+
+/* Host controller register addresses */
+static void *hc_registers;
+static void *csr_hc_index;
+static void *csr_hc_data;
+static void *csr_int_status;
+static void *csr_int_mask;
+
+
+static int zt5550_hc_config(struct pci_dev *pdev)
+{
+	/* Since we know that no boards exist with two HC chips, treat it as an error */
+	if(hc_dev) {
+		err("too many host controller devices?");
+		return -EBUSY;
+	}
+	hc_dev = pdev;
+	dbg("hc_dev = %p", hc_dev);
+	dbg("pci resource start %lx", pci_resource_start(hc_dev, 1));
+	dbg("pci resource len %lx", pci_resource_len(hc_dev, 1));
+
+	if(!request_mem_region(pci_resource_start(hc_dev, 1),
+				pci_resource_len(hc_dev, 1), MY_NAME)) {
+		err("cannot reserve MMIO region");
+		return -ENOMEM;
+	}
+
+	hc_registers =
+	    ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1));
+	if(!hc_registers) {
+		err("cannot remap MMIO region %lx @ %lx",
+		    pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1));
+		release_mem_region(pci_resource_start(hc_dev, 1),
+				   pci_resource_len(hc_dev, 1));
+		return -ENODEV;
+	}
+
+	csr_hc_index = hc_registers + CSR_HCINDEX;
+	csr_hc_data = hc_registers + CSR_HCDATA;
+	csr_int_status = hc_registers + CSR_INTSTAT;
+	csr_int_mask = hc_registers + CSR_INTMASK;
+
+	/*
+	 * Disable host control, fault and serial interrupts
+	 */
+	dbg("disabling host control, fault and serial interrupts");
+	writeb((u8) HC_INT_MASK_REG, csr_hc_index);
+	writeb((u8) ALL_INDEXED_INTS_MASK, csr_hc_data);
+	dbg("disabled host control, fault and serial interrupts");
+
+	/*
+	 * Disable timer0, timer1 and ENUM interrupts
+	 */
+	dbg("disabling timer0, timer1 and ENUM interrupts");
+	writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask);
+	dbg("disabled timer0, timer1 and ENUM interrupts");
+	return 0;
+}
+
+static int zt5550_hc_cleanup(void)
+{
+	if(!hc_dev)
+		return -ENODEV;
+	release_mem_region(pci_resource_start(hc_dev, 1),
+			   pci_resource_len(hc_dev, 1));
+	return 0;
+}
+
+static int zt5550_hc_query_enum(void)
+{
+	u8 value;
+
+	value = inb_p(ENUM_PORT);
+	return ((value & ENUM_MASK) == ENUM_MASK);
+}
+
+static int zt5550_hc_check_irq(void *dev_id)
+{
+	int ret;
+	u8 reg;
+
+	ret = 0;
+	if(dev_id == zt5550_hpc.dev_id) {
+		reg = readb(csr_int_status);
+		if(reg)
+			ret = 1;
+	}
+	return ret;
+}
+
+static int zt5550_hc_enable_irq(void)
+{
+	u8 reg;
+
+	if(hc_dev == NULL) {
+		return -ENODEV;
+	}
+	reg = readb(csr_int_mask);
+	reg = reg & ~ENUM_INT_MASK;
+	writeb(reg, csr_int_mask);
+	return 0;
+}
+
+int zt5550_hc_disable_irq(void)
+{
+	u8 reg;
+
+	if(hc_dev == NULL) {
+		return -ENODEV;
+	}
+
+	reg = readb(csr_int_mask);
+	reg = reg | ENUM_INT_MASK;
+	writeb(reg, csr_int_mask);
+	return 0;
+}
+
+static int __devinit zt5550_hc_init_one (struct pci_dev *pdev,
+					 const struct pci_device_id *ent)
+{
+	int status;
+
+	status = zt5550_hc_config(pdev);
+	if(status != 0) {
+		return status;
+	}
+	dbg("returned from zt5550_hc_config");
+
+	memset(&zt5550_hpc, 0, sizeof (struct cpci_hp_controller));
+	zt5550_hpc_ops.query_enum = zt5550_hc_query_enum;
+	zt5550_hpc.ops = &zt5550_hpc_ops;
+	if(!poll) {
+		zt5550_hpc.irq = hc_dev->irq;
+		zt5550_hpc.irq_flags = SA_SHIRQ;
+		zt5550_hpc.dev_id = hc_dev;
+
+		zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq;
+		zt5550_hpc_ops.disable_irq = zt5550_hc_disable_irq;
+		zt5550_hpc_ops.check_irq = zt5550_hc_check_irq;
+	} else {
+		info("using ENUM# polling mode");
+	}
+
+	status = cpci_hp_register_controller(&zt5550_hpc);
+	if(status != 0) {
+		err("could not register cPCI hotplug controller");
+		goto init_hc_error;
+	}
+	dbg("registered controller");
+
+	/* Look for first device matching cPCI bus's bridge vendor and device IDs */
+	if(!(bus0_dev = pci_find_device(PCI_VENDOR_ID_DEC,
+					 PCI_DEVICE_ID_DEC_21154, NULL))) {
+		status = -ENODEV;
+		goto init_register_error;
+	}
+	bus0 = bus0_dev->subordinate;
+
+	status = cpci_hp_register_bus(bus0, 0x0a, 0x0f);
+	if(status != 0) {
+		err("could not register cPCI hotplug bus");
+		goto init_register_error;
+	}
+	dbg("registered bus");
+
+	status = cpci_hp_start();
+	if(status != 0) {
+		err("could not started cPCI hotplug system");
+		cpci_hp_unregister_bus(bus0);
+		goto init_register_error;
+	}
+	dbg("started cpci hp system");
+
+	return 0;
+init_register_error:
+	cpci_hp_unregister_controller(&zt5550_hpc);
+init_hc_error:
+	err("status = %d", status);
+	zt5550_hc_cleanup();
+	return status;
+
+}
+
+static void __devexit zt5550_hc_remove_one(struct pci_dev *pdev)
+{
+	cpci_hp_stop();
+	cpci_hp_unregister_bus(bus0);
+	cpci_hp_unregister_controller(&zt5550_hpc);
+	zt5550_hc_cleanup();
+}
+
+
+static struct pci_device_id zt5550_hc_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_ZIATECH, PCI_DEVICE_ID_ZIATECH_5550_HC, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, zt5550_hc_pci_tbl);
+	
+static struct pci_driver zt5550_hc_driver = {
+	.name		= "zt5550_hc",
+	.id_table	= zt5550_hc_pci_tbl,
+	.probe		= zt5550_hc_init_one,
+	.remove		= __devexit_p(zt5550_hc_remove_one),
+};
+
+static int __init zt5550_init(void)
+{
+	struct resource* r;
+
+	info(DRIVER_DESC " version: " DRIVER_VERSION);
+	r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register");
+	if(!r)
+		return -EBUSY;
+
+	return pci_module_init(&zt5550_hc_driver);
+}
+
+static void __exit
+zt5550_exit(void)
+{
+	pci_unregister_driver(&zt5550_hc_driver);
+	release_region(ENUM_PORT, 1);
+}
+
+module_init(zt5550_init);
+module_exit(zt5550_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+MODULE_PARM(poll, "i");
+MODULE_PARM_DESC(poll, "#ENUM polling mode enabled or not");
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpcihp_zt5550.h linux-2.5.70-bk10/drivers/pci/hotplug/cpcihp_zt5550.h
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpcihp_zt5550.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpcihp_zt5550.h	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,79 @@
+/*
+ * cpcihp_zt5550.h
+ *
+ * Intel/Ziatech ZT5550 CompactPCI Host Controller driver definitions
+ *
+ * Copyright 2002 SOMA Networks, Inc.
+ * Copyright 2001 Intel San Luis Obispo
+ * Copyright 2000,2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <scottm@somanetworks.com>
+ */
+
+#ifndef _CPCIHP_ZT5550_H
+#define _CPCIHP_ZT5550_H
+
+/* Direct registers */
+#define CSR_HCINDEX		0x00
+#define CSR_HCDATA		0x04
+#define CSR_INTSTAT		0x08
+#define CSR_INTMASK		0x09
+#define CSR_CNT0CMD		0x0C
+#define CSR_CNT1CMD		0x0E
+#define CSR_CNT0		0x10
+#define CSR_CNT1		0x14
+
+/* Masks for interrupt bits in CSR_INTMASK direct register */
+#define CNT0_INT_MASK		0x01
+#define CNT1_INT_MASK		0x02
+#define ENUM_INT_MASK		0x04
+#define ALL_DIRECT_INTS_MASK	0x07
+
+/* Indexed registers (through CSR_INDEX, CSR_DATA) */
+#define HC_INT_MASK_REG		0x04
+#define HC_STATUS_REG		0x08
+#define HC_CMD_REG		0x0C
+#define ARB_CONFIG_GNT_REG	0x10
+#define ARB_CONFIG_CFG_REG	0x12
+#define ARB_CONFIG_REG	 	0x10
+#define ISOL_CONFIG_REG		0x18
+#define FAULT_STATUS_REG	0x20
+#define FAULT_CONFIG_REG	0x24
+#define WD_CONFIG_REG		0x2C
+#define HC_DIAG_REG		0x30
+#define SERIAL_COMM_REG		0x34
+#define SERIAL_OUT_REG		0x38
+#define SERIAL_IN_REG		0x3C
+
+/* Masks for interrupt bits in HC_INT_MASK_REG indexed register */
+#define SERIAL_INT_MASK		0x01
+#define FAULT_INT_MASK		0x02
+#define HCF_INT_MASK		0x04
+#define ALL_INDEXED_INTS_MASK	0x07
+
+/* Digital I/O port storing ENUM# */
+#define ENUM_PORT	0xE1
+/* Mask to get to the ENUM# bit on the bus */
+#define ENUM_MASK	0x40
+
+#endif				/* _CPCIHP_ZT5550_H */
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp.h linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp.h
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp.h	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,912 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+#ifndef _CPQPHP_H
+#define _CPQPHP_H
+
+#include "pci_hotplug.h"
+#include <linux/interrupt.h>
+#include <asm/io.h>		/* for read? and write? functions */
+#include <linux/delay.h>	/* for delays */
+
+#if !defined(CONFIG_HOTPLUG_PCI_COMPAQ_MODULE)
+	#define MY_NAME	"cpqphp.o"
+#else
+	#define MY_NAME	THIS_MODULE->name
+#endif
+
+#define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+
+
+
+struct smbios_system_slot {
+	u8 type;
+	u8 length;
+	u16 handle;
+	u8 name_string_num;
+	u8 slot_type;
+	u8 slot_width;
+	u8 slot_current_usage;
+	u8 slot_length;
+	u16 slot_number;
+	u8 properties1;
+	u8 properties2;
+} __attribute__ ((packed));
+
+/* offsets to the smbios generic type based on the above structure layout */
+enum smbios_system_slot_offsets {
+	SMBIOS_SLOT_GENERIC_TYPE =	offsetof(struct smbios_system_slot, type),
+	SMBIOS_SLOT_GENERIC_LENGTH =	offsetof(struct smbios_system_slot, length),
+	SMBIOS_SLOT_GENERIC_HANDLE =	offsetof(struct smbios_system_slot, handle),
+	SMBIOS_SLOT_NAME_STRING_NUM =	offsetof(struct smbios_system_slot, name_string_num),
+	SMBIOS_SLOT_TYPE =		offsetof(struct smbios_system_slot, slot_type),
+	SMBIOS_SLOT_WIDTH =		offsetof(struct smbios_system_slot, slot_width),
+	SMBIOS_SLOT_CURRENT_USAGE =	offsetof(struct smbios_system_slot, slot_current_usage),
+	SMBIOS_SLOT_LENGTH =		offsetof(struct smbios_system_slot, slot_length),
+	SMBIOS_SLOT_NUMBER =		offsetof(struct smbios_system_slot, slot_number),
+	SMBIOS_SLOT_PROPERTIES1 =	offsetof(struct smbios_system_slot, properties1),
+	SMBIOS_SLOT_PROPERTIES2 =	offsetof(struct smbios_system_slot, properties2),
+};
+
+struct smbios_generic {
+	u8 type;
+	u8 length;
+	u16 handle;
+} __attribute__ ((packed));
+
+/* offsets to the smbios generic type based on the above structure layout */
+enum smbios_generic_offsets {
+	SMBIOS_GENERIC_TYPE =	offsetof(struct smbios_generic, type),
+	SMBIOS_GENERIC_LENGTH =	offsetof(struct smbios_generic, length),
+	SMBIOS_GENERIC_HANDLE =	offsetof(struct smbios_generic, handle),
+};
+
+struct smbios_entry_point {
+	char anchor[4];
+	u8 ep_checksum;
+	u8 ep_length;
+	u8 major_version;
+	u8 minor_version;
+	u16 max_size_entry;
+	u8 ep_rev;
+	u8 reserved[5];
+	char int_anchor[5];
+	u8 int_checksum;
+	u16 st_length;
+	u32 st_address;
+	u16 number_of_entrys;
+	u8 bcd_rev;
+} __attribute__ ((packed));
+
+/* offsets to the smbios entry point based on the above structure layout */
+enum smbios_entry_point_offsets {
+	ANCHOR =		offsetof(struct smbios_entry_point, anchor[0]),
+	EP_CHECKSUM =		offsetof(struct smbios_entry_point, ep_checksum),
+	EP_LENGTH =		offsetof(struct smbios_entry_point, ep_length),
+	MAJOR_VERSION =		offsetof(struct smbios_entry_point, major_version),
+	MINOR_VERSION =		offsetof(struct smbios_entry_point, minor_version),
+	MAX_SIZE_ENTRY =	offsetof(struct smbios_entry_point, max_size_entry),
+	EP_REV =		offsetof(struct smbios_entry_point, ep_rev),
+	INT_ANCHOR =		offsetof(struct smbios_entry_point, int_anchor[0]),
+	INT_CHECKSUM =		offsetof(struct smbios_entry_point, int_checksum),
+	ST_LENGTH =		offsetof(struct smbios_entry_point, st_length),
+	ST_ADDRESS =		offsetof(struct smbios_entry_point, st_address),
+	NUMBER_OF_ENTRYS =	offsetof(struct smbios_entry_point, number_of_entrys),
+	BCD_REV =		offsetof(struct smbios_entry_point, bcd_rev),
+};
+
+struct ctrl_reg {			/* offset */
+	u8	slot_RST;		/* 0x00 */
+	u8	slot_enable;		/* 0x01 */
+	u16	misc;			/* 0x02 */
+	u32	led_control;		/* 0x04 */
+	u32	int_input_clear;	/* 0x08 */
+	u32	int_mask;		/* 0x0a */
+	u8	reserved0;		/* 0x10 */
+	u8	reserved1;		/* 0x11 */
+	u8	reserved2;		/* 0x12 */
+	u8	gen_output_AB;		/* 0x13 */
+	u32	non_int_input;		/* 0x14 */
+	u32	reserved3;		/* 0x18 */
+	u32	reserved4;		/* 0x1a */
+	u32	reserved5;		/* 0x20 */
+	u8	reserved6;		/* 0x24 */
+	u8	reserved7;		/* 0x25 */
+	u16	reserved8;		/* 0x26 */
+	u8	slot_mask;		/* 0x28 */
+	u8	reserved9;		/* 0x29 */
+	u8	reserved10;		/* 0x2a */
+	u8	reserved11;		/* 0x2b */
+	u8	slot_SERR;		/* 0x2c */
+	u8	slot_power;		/* 0x2d */
+	u8	reserved12;		/* 0x2e */
+	u8	reserved13;		/* 0x2f */
+	u8	next_curr_freq;		/* 0x30 */
+	u8	reset_freq_mode;	/* 0x31 */
+} __attribute__ ((packed));
+
+/* offsets to the controller registers based on the above structure layout */
+enum ctrl_offsets {
+	SLOT_RST = 		offsetof(struct ctrl_reg, slot_RST),
+	SLOT_ENABLE =		offsetof(struct ctrl_reg, slot_enable),
+	MISC =			offsetof(struct ctrl_reg, misc),
+	LED_CONTROL =		offsetof(struct ctrl_reg, led_control),
+	INT_INPUT_CLEAR =	offsetof(struct ctrl_reg, int_input_clear),
+	INT_MASK = 		offsetof(struct ctrl_reg, int_mask),
+	CTRL_RESERVED0 = 	offsetof(struct ctrl_reg, reserved0),
+	CTRL_RESERVED1 =	offsetof(struct ctrl_reg, reserved1),
+	CTRL_RESERVED2 =	offsetof(struct ctrl_reg, reserved1),
+	GEN_OUTPUT_AB = 	offsetof(struct ctrl_reg, gen_output_AB),
+	NON_INT_INPUT = 	offsetof(struct ctrl_reg, non_int_input),
+	CTRL_RESERVED3 =	offsetof(struct ctrl_reg, reserved3),
+	CTRL_RESERVED4 =	offsetof(struct ctrl_reg, reserved4),
+	CTRL_RESERVED5 =	offsetof(struct ctrl_reg, reserved5),
+	CTRL_RESERVED6 =	offsetof(struct ctrl_reg, reserved6),
+	CTRL_RESERVED7 =	offsetof(struct ctrl_reg, reserved7),
+	CTRL_RESERVED8 =	offsetof(struct ctrl_reg, reserved8),
+	SLOT_MASK = 		offsetof(struct ctrl_reg, slot_mask),
+	CTRL_RESERVED9 = 	offsetof(struct ctrl_reg, reserved9),
+	CTRL_RESERVED10 =	offsetof(struct ctrl_reg, reserved10),
+	CTRL_RESERVED11 =	offsetof(struct ctrl_reg, reserved11),
+	SLOT_SERR =		offsetof(struct ctrl_reg, slot_SERR),
+	SLOT_POWER =		offsetof(struct ctrl_reg, slot_power),
+	NEXT_CURR_FREQ =	offsetof(struct ctrl_reg, next_curr_freq),
+	RESET_FREQ_MODE =	offsetof(struct ctrl_reg, reset_freq_mode),
+};
+
+struct hrt {
+	char sig0;
+	char sig1;
+	char sig2;
+	char sig3;
+	u16 unused_IRQ;
+	u16 PCIIRQ;
+	u8 number_of_entries;
+	u8 revision;
+	u16 reserved1;
+	u32 reserved2;
+} __attribute__ ((packed));
+
+/* offsets to the hotplug resource table registers based on the above structure layout */
+enum hrt_offsets {
+	SIG0 =			offsetof(struct hrt, sig0),
+	SIG1 =			offsetof(struct hrt, sig1),
+	SIG2 =			offsetof(struct hrt, sig2),
+	SIG3 =			offsetof(struct hrt, sig3),
+	UNUSED_IRQ =		offsetof(struct hrt, unused_IRQ),
+	PCIIRQ =		offsetof(struct hrt, PCIIRQ),
+	NUMBER_OF_ENTRIES =	offsetof(struct hrt, number_of_entries),
+	REVISION =		offsetof(struct hrt, revision),
+	HRT_RESERVED1 =		offsetof(struct hrt, reserved1),
+	HRT_RESERVED2 =		offsetof(struct hrt, reserved2),
+};
+
+struct slot_rt {
+	u8 dev_func;
+	u8 primary_bus;
+	u8 secondary_bus;
+	u8 max_bus;
+	u16 io_base;
+	u16 io_length;
+	u16 mem_base;
+	u16 mem_length;
+	u16 pre_mem_base;
+	u16 pre_mem_length;
+} __attribute__ ((packed));
+
+/* offsets to the hotplug slot resource table registers based on the above structure layout */
+enum slot_rt_offsets {
+	DEV_FUNC =		offsetof(struct slot_rt, dev_func),
+	PRIMARY_BUS = 		offsetof(struct slot_rt, primary_bus),
+	SECONDARY_BUS = 	offsetof(struct slot_rt, secondary_bus),
+	MAX_BUS = 		offsetof(struct slot_rt, max_bus),
+	IO_BASE = 		offsetof(struct slot_rt, io_base),
+	IO_LENGTH = 		offsetof(struct slot_rt, io_length),
+	MEM_BASE = 		offsetof(struct slot_rt, mem_base),
+	MEM_LENGTH = 		offsetof(struct slot_rt, mem_length),
+	PRE_MEM_BASE = 		offsetof(struct slot_rt, pre_mem_base),
+	PRE_MEM_LENGTH = 	offsetof(struct slot_rt, pre_mem_length),
+};
+
+struct pci_func {
+	struct pci_func *next;
+	u8 bus;
+	u8 device;
+	u8 function;
+	u8 is_a_board;
+	u16 status;
+	u8 configured;
+	u8 switch_save;
+	u8 presence_save;
+	u32 base_length[0x06];
+	u8 base_type[0x06];
+	u16 reserved2;
+	u32 config_space[0x20];
+	struct pci_resource *mem_head;
+	struct pci_resource *p_mem_head;
+	struct pci_resource *io_head;
+	struct pci_resource *bus_head;
+	struct timer_list *p_task_event;
+	struct pci_dev* pci_dev;
+};
+
+#define SLOT_MAGIC	0x67267321
+struct slot {
+	u32 magic;
+	struct slot *next;
+	u8 bus;
+	u8 device;
+	u8 number;
+	u8 is_a_board;
+	u8 configured;
+	u8 state;
+	u8 switch_save;
+	u8 presence_save;
+	u32 capabilities;
+	u16 reserved2;
+	struct timer_list task_event;
+	u8 hp_slot;
+	struct controller *ctrl;
+	void *p_sm_slot;
+	struct hotplug_slot *hotplug_slot;
+};
+
+struct pci_resource {
+	struct pci_resource * next;
+	u32 base;
+	u32 length;
+};
+
+struct event_info {
+	u32 event_type;
+	u8 hp_slot;
+};
+
+struct controller {
+	struct controller *next;
+	u32 ctrl_int_comp;
+	struct semaphore crit_sect;	/* critical section semaphore */
+	void *hpc_reg;			/* cookie for our pci controller location */
+	struct pci_resource *mem_head;
+	struct pci_resource *p_mem_head;
+	struct pci_resource *io_head;
+	struct pci_resource *bus_head;
+	struct pci_dev *pci_dev;
+	struct pci_bus *pci_bus;
+	struct event_info event_queue[10];
+	struct slot *slot;
+	u8 next_event;
+	u8 interrupt;
+	u8 cfgspc_irq;
+	u8 bus;				/* bus number for the pci hotplug controller */
+	u8 rev;
+	u8 slot_device_offset;
+	u8 first_slot;
+	u8 add_support;
+	u8 push_flag;
+	enum pci_bus_speed speed;
+	enum pci_bus_speed speed_capability;
+	u8 push_button;			/* 0 = no pushbutton, 1 = pushbutton present */
+	u8 slot_switch_type;		/* 0 = no switch, 1 = switch present */
+	u8 defeature_PHP;		/* 0 = PHP not supported, 1 = PHP supported */
+	u8 alternate_base_address;	/* 0 = not supported, 1 = supported */
+	u8 pci_config_space;		/* Index/data access to working registers 0 = not supported, 1 = supported */
+	u8 pcix_speed_capability;	/* PCI-X */
+	u8 pcix_support;		/* PCI-X */
+	u16 vendor_id;
+	struct work_struct int_task_event;
+	wait_queue_head_t queue;	/* sleep & wake process */
+};
+
+struct irq_mapping {
+	u8 barber_pole;
+	u8 valid_INT;
+	u8 interrupt[4];
+};
+
+struct resource_lists {
+	struct pci_resource *mem_head;
+	struct pci_resource *p_mem_head;
+	struct pci_resource *io_head;
+	struct pci_resource *bus_head;
+	struct irq_mapping *irqs;
+};
+
+#define ROM_PHY_ADDR			0x0F0000
+#define ROM_PHY_LEN			0x00ffff
+
+#define PCI_HPC_ID			0xA0F7
+#define PCI_SUB_HPC_ID			0xA2F7
+#define PCI_SUB_HPC_ID2			0xA2F8
+#define PCI_SUB_HPC_ID3			0xA2F9
+#define PCI_SUB_HPC_ID_INTC		0xA2FA
+#define PCI_SUB_HPC_ID4			0xA2FD
+
+#define INT_BUTTON_IGNORE		0
+#define INT_PRESENCE_ON			1
+#define INT_PRESENCE_OFF		2
+#define INT_SWITCH_CLOSE		3
+#define INT_SWITCH_OPEN			4
+#define INT_POWER_FAULT			5
+#define INT_POWER_FAULT_CLEAR		6
+#define INT_BUTTON_PRESS		7
+#define INT_BUTTON_RELEASE		8
+#define INT_BUTTON_CANCEL		9
+
+#define STATIC_STATE			0
+#define BLINKINGON_STATE		1
+#define BLINKINGOFF_STATE		2
+#define POWERON_STATE			3
+#define POWEROFF_STATE			4
+
+#define PCISLOT_INTERLOCK_CLOSED	0x00000001
+#define PCISLOT_ADAPTER_PRESENT		0x00000002
+#define PCISLOT_POWERED			0x00000004
+#define PCISLOT_66_MHZ_OPERATION	0x00000008
+#define PCISLOT_64_BIT_OPERATION	0x00000010
+#define PCISLOT_REPLACE_SUPPORTED	0x00000020
+#define PCISLOT_ADD_SUPPORTED		0x00000040
+#define PCISLOT_INTERLOCK_SUPPORTED	0x00000080
+#define PCISLOT_66_MHZ_SUPPORTED	0x00000100
+#define PCISLOT_64_BIT_SUPPORTED	0x00000200
+
+
+
+#define PCI_TO_PCI_BRIDGE_CLASS		0x00060400
+
+
+#define INTERLOCK_OPEN			0x00000002
+#define ADD_NOT_SUPPORTED		0x00000003
+#define CARD_FUNCTIONING		0x00000005
+#define ADAPTER_NOT_SAME		0x00000006
+#define NO_ADAPTER_PRESENT		0x00000009
+#define NOT_ENOUGH_RESOURCES		0x0000000B
+#define DEVICE_TYPE_NOT_SUPPORTED	0x0000000C
+#define POWER_FAILURE			0x0000000E
+
+#define REMOVE_NOT_SUPPORTED		0x00000003
+
+
+/*
+ * error Messages
+ */
+#define msg_initialization_err	"Initialization failure, error=%d\n"
+#define msg_HPC_rev_error	"Unsupported revision of the PCI hot plug controller found.\n"
+#define msg_HPC_non_compaq_or_intel	"The PCI hot plug controller is not supported by this driver.\n"
+#define msg_HPC_not_supported	"this system is not supported by this version of cpqphpd. Upgrade to a newer version of cpqphpd\n"
+#define msg_unable_to_save	"unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
+#define msg_button_on		"PCI slot #%d - powering on due to button press.\n"
+#define msg_button_off		"PCI slot #%d - powering off due to button press.\n"
+#define msg_button_cancel	"PCI slot #%d - action canceled due to button press.\n"
+#define msg_button_ignore	"PCI slot #%d - button press ignored.  (action in progress...)\n"
+
+
+/* sysfs functions for the hotplug controller info */
+extern void cpqhp_create_ctrl_files		(struct controller *ctrl);
+
+/* controller functions */
+extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
+extern irqreturn_t cpqhp_ctrl_intr		(int IRQ, void *data, struct pt_regs *regs);
+extern int	cpqhp_find_available_resources	(struct controller *ctrl, void *rom_start);
+extern int	cpqhp_event_start_thread	(void);
+extern void	cpqhp_event_stop_thread		(void);
+extern struct pci_func *cpqhp_slot_create	(unsigned char busnumber);
+extern struct pci_func *cpqhp_slot_find		(unsigned char bus, unsigned char device, unsigned char index);
+extern int	cpqhp_process_SI		(struct controller *ctrl, struct pci_func *func);
+extern int	cpqhp_process_SS		(struct controller *ctrl, struct pci_func *func);
+extern int	cpqhp_hardware_test		(struct controller *ctrl, int test_num);
+
+/* resource functions */
+extern int	cpqhp_resource_sort_and_combine	(struct pci_resource **head);
+
+/* pci functions */
+extern int	cpqhp_set_irq			(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
+extern int	cpqhp_get_bus_dev		(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot);
+extern int	cpqhp_save_config		(struct controller *ctrl, int busnumber, int is_hot_plug);
+extern int	cpqhp_save_base_addr_length	(struct controller *ctrl, struct pci_func * func);
+extern int	cpqhp_save_used_resources	(struct controller *ctrl, struct pci_func * func);
+extern int	cpqhp_configure_board		(struct controller *ctrl, struct pci_func * func);
+extern int	cpqhp_save_slot_config		(struct controller *ctrl, struct pci_func * new_slot);
+extern int	cpqhp_valid_replace		(struct controller *ctrl, struct pci_func * func);
+extern void	cpqhp_destroy_board_resources	(struct pci_func * func);
+extern int	cpqhp_return_board_resources	(struct pci_func * func, struct resource_lists * resources);
+extern void	cpqhp_destroy_resource_list	(struct resource_lists * resources);
+extern int	cpqhp_configure_device		(struct controller* ctrl, struct pci_func* func);
+extern int	cpqhp_unconfigure_device	(struct pci_func* func);
+extern struct slot *cpqhp_find_slot		(struct controller *ctrl, u8 device);
+
+/* Global variables */
+extern int cpqhp_debug;
+extern struct controller *cpqhp_ctrl_list;
+extern struct pci_func *cpqhp_slot_list[256];
+
+/* these can be gotten rid of, but for debugging they are purty */
+extern u8 cpqhp_nic_irq;
+extern u8 cpqhp_disk_irq;
+
+
+
+/* inline functions */
+
+
+/* Inline functions to check the sanity of a pointer that is passed to us */
+static inline int slot_paranoia_check (struct slot *slot, const char *function)
+{
+	if (!slot) {
+		dbg("%s - slot == NULL", function);
+		return -1;
+	}
+	if (slot->magic != SLOT_MAGIC) {
+		dbg("%s - bad magic number for slot", function);
+		return -1;
+	}
+	if (!slot->hotplug_slot) {
+		dbg("%s - slot->hotplug_slot == NULL!", function);
+		return -1;
+	}
+	return 0;
+}
+
+static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
+{ 
+	struct slot *slot;
+
+	if (!hotplug_slot) {
+		dbg("%s - hotplug_slot == NULL\n", function);
+		return NULL;
+	}
+
+	slot = (struct slot *)hotplug_slot->private;
+	if (slot_paranoia_check (slot, function))
+                return NULL;
+	return slot;
+}               
+
+/*
+ * return_resource
+ *
+ * Puts node back in the resource list pointed to by head
+ *
+ */
+static inline void return_resource (struct pci_resource **head, struct pci_resource *node)
+{
+	if (!node || !head)
+		return;
+	node->next = *head;
+	*head = node;
+}
+
+static inline void set_SOGO (struct controller *ctrl)
+{
+	u16 misc;
+	
+	misc = readw(ctrl->hpc_reg + MISC);
+	misc = (misc | 0x0001) & 0xFFFB;
+	writew(misc, ctrl->hpc_reg + MISC);
+}
+
+
+static inline void amber_LED_on (struct controller *ctrl, u8 slot)
+{
+	u32 led_control;
+	
+	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
+	led_control |= (0x01010000L << slot);
+	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
+}
+
+
+static inline void amber_LED_off (struct controller *ctrl, u8 slot)
+{
+	u32 led_control;
+	
+	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
+	led_control &= ~(0x01010000L << slot);
+	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
+}
+
+
+static inline int read_amber_LED (struct controller *ctrl, u8 slot)
+{
+	u32 led_control;
+
+	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
+	led_control &= (0x01010000L << slot);
+	
+	return led_control ? 1 : 0;
+}
+
+
+static inline void green_LED_on (struct controller *ctrl, u8 slot)
+{
+	u32 led_control;
+	
+	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
+	led_control |= 0x0101L << slot;
+	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
+}
+
+static inline void green_LED_off (struct controller *ctrl, u8 slot)
+{
+	u32 led_control;
+	
+	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
+	led_control &= ~(0x0101L << slot);
+	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
+}
+
+
+static inline void green_LED_blink (struct controller *ctrl, u8 slot)
+{
+	u32 led_control;
+	
+	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
+	led_control &= ~(0x0101L << slot);
+	led_control |= (0x0001L << slot);
+	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
+}
+
+
+static inline void slot_disable (struct controller *ctrl, u8 slot)
+{
+	u8 slot_enable;
+
+	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
+	slot_enable &= ~(0x01 << slot);
+	writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
+}
+
+
+static inline void slot_enable (struct controller *ctrl, u8 slot)
+{
+	u8 slot_enable;
+
+	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
+	slot_enable |= (0x01 << slot);
+	writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
+}
+
+
+static inline u8 is_slot_enabled (struct controller *ctrl, u8 slot)
+{
+	u8 slot_enable;
+
+	slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
+	slot_enable &= (0x01 << slot);
+	return slot_enable ? 1 : 0;
+}
+
+
+static inline u8 read_slot_enable (struct controller *ctrl)
+{
+	return readb(ctrl->hpc_reg + SLOT_ENABLE);
+}
+
+
+/*
+ * get_controller_speed - find the current frequency/mode of controller.
+ *
+ * @ctrl: controller to get frequency/mode for.
+ *
+ * Returns controller speed.
+ *
+ */
+static inline u8 get_controller_speed (struct controller *ctrl)
+{
+	u8 curr_freq;
+ 	u16 misc;
+ 	
+	if (ctrl->pcix_support) {
+		curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
+		if ((curr_freq & 0xB0) == 0xB0) 
+			return PCI_SPEED_133MHz_PCIX;
+		if ((curr_freq & 0xA0) == 0xA0)
+			return PCI_SPEED_100MHz_PCIX;
+		if ((curr_freq & 0x90) == 0x90)
+			return PCI_SPEED_66MHz_PCIX;
+		if (curr_freq & 0x10)
+			return PCI_SPEED_66MHz;
+
+		return PCI_SPEED_33MHz;
+	}
+
+ 	misc = readw(ctrl->hpc_reg + MISC);
+ 	return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
+}
+ 
+
+/*
+ * get_adapter_speed - find the max supported frequency/mode of adapter.
+ *
+ * @ctrl: hotplug controller.
+ * @hp_slot: hotplug slot where adapter is installed.
+ *
+ * Returns adapter speed.
+ *
+ */
+static inline u8 get_adapter_speed (struct controller *ctrl, u8 hp_slot)
+{
+	u32 temp_dword = readl(ctrl->hpc_reg + NON_INT_INPUT);
+	dbg("slot: %d, PCIXCAP: %8x\n", hp_slot, temp_dword);
+	if (ctrl->pcix_support) {
+		if (temp_dword & (0x10000 << hp_slot))
+			return PCI_SPEED_133MHz_PCIX;
+		if (temp_dword & (0x100 << hp_slot))
+			return PCI_SPEED_66MHz_PCIX;
+	}
+
+	if (temp_dword & (0x01 << hp_slot))
+		return PCI_SPEED_66MHz;
+
+	return PCI_SPEED_33MHz;
+}
+
+static inline void enable_slot_power (struct controller *ctrl, u8 slot)
+{
+	u8 slot_power;
+
+	slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
+	slot_power |= (0x01 << slot);
+	writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
+}
+
+static inline void disable_slot_power (struct controller *ctrl, u8 slot)
+{
+	u8 slot_power;
+
+	slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
+	slot_power &= ~(0x01 << slot);
+	writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
+}
+
+
+static inline int cpq_get_attention_status (struct controller *ctrl, struct slot *slot)
+{
+	u8 hp_slot;
+
+	if (slot == NULL)
+		return 1;
+
+	hp_slot = slot->device - ctrl->slot_device_offset;
+
+	return read_amber_LED (ctrl, hp_slot);
+}
+
+
+static inline int get_slot_enabled (struct controller *ctrl, struct slot *slot)
+{
+	u8 hp_slot;
+
+	if (slot == NULL)
+		return 1;
+
+	hp_slot = slot->device - ctrl->slot_device_offset;
+
+	return is_slot_enabled (ctrl, hp_slot);
+}
+
+
+static inline int cpq_get_latch_status (struct controller *ctrl, struct slot *slot)
+{
+	u32 status;
+	u8 hp_slot;
+
+	if (slot == NULL)
+		return 1;
+
+	hp_slot = slot->device - ctrl->slot_device_offset;
+	dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n",
+	    __FUNCTION__, slot->device, ctrl->slot_device_offset);
+
+	status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
+
+	return(status == 0) ? 1 : 0;
+}
+
+
+static inline int get_presence_status (struct controller *ctrl, struct slot *slot)
+{
+	int presence_save = 0;
+	u8 hp_slot;
+	u32 tempdword;
+
+	if (slot == NULL)
+		return 0;
+
+	hp_slot = slot->device - ctrl->slot_device_offset;
+
+	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
+	presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> hp_slot) & 0x02;
+
+	return presence_save;
+}
+
+#define SLOT_NAME_SIZE 10
+
+static inline void make_slot_name (char *buffer, int buffer_size, struct slot *slot)
+{
+	snprintf (buffer, buffer_size, "%d", slot->number);
+}
+
+
+static inline int wait_for_ctrl_irq (struct controller *ctrl)
+{
+        DECLARE_WAITQUEUE(wait, current);
+	int retval = 0;
+
+	dbg("%s - start\n", __FUNCTION__);
+	add_wait_queue(&ctrl->queue, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	/* Sleep for up to 1 second to wait for the LED to change. */
+	schedule_timeout(1*HZ);
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&ctrl->queue, &wait);
+	if (signal_pending(current))
+		retval =  -EINTR;
+
+	dbg("%s - end\n", __FUNCTION__);
+	return retval;
+}
+
+
+/**
+ * set_controller_speed - set the frequency and/or mode of a specific
+ * controller segment.
+ *
+ * @ctrl: controller to change frequency/mode for.
+ * @adapter_speed: the speed of the adapter we want to match.
+ * @hp_slot: the slot number where the adapter is installed.
+ *
+ * Returns 0 if we successfully change frequency and/or mode to match the
+ * adapter speed.
+ * 
+ */
+static inline u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)
+{
+	struct slot *slot;
+	u8 reg;
+	u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
+	u16 reg16;
+	u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
+	
+	if (ctrl->speed == adapter_speed)
+		return 0;
+	
+	/* We don't allow freq/mode changes if we find another adapter running
+	 * in another slot on this controller */
+	for(slot = ctrl->slot; slot; slot = slot->next) {
+		if (slot->device == (hp_slot + ctrl->slot_device_offset)) 
+			continue;
+		if (!slot->hotplug_slot && !slot->hotplug_slot->info) 
+			continue;
+		if (slot->hotplug_slot->info->adapter_status == 0) 
+			continue;
+		/* If another adapter is running on the same segment but at a
+		 * lower speed/mode, we allow the new adapter to function at
+		 * this rate if supported */
+		if (ctrl->speed < adapter_speed) 
+			return 0;
+
+		return 1;
+	}
+	
+	/* If the controller doesn't support freq/mode changes and the
+	 * controller is running at a higher mode, we bail */
+	if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
+		return 1;
+	
+	/* But we allow the adapter to run at a lower rate if possible */
+	if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
+		return 0;
+
+	/* We try to set the max speed supported by both the adapter and
+	 * controller */
+	if (ctrl->speed_capability < adapter_speed) {
+		if (ctrl->speed == ctrl->speed_capability)
+			return 0;
+		adapter_speed = ctrl->speed_capability;
+	}
+
+	writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
+	writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);
+	
+	set_SOGO(ctrl); 
+	wait_for_ctrl_irq(ctrl);
+	
+	if (adapter_speed != PCI_SPEED_133MHz_PCIX)
+		reg = 0xF5;
+	else
+		reg = 0xF4;	
+	pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
+	
+	reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);
+	reg16 &= ~0x000F;
+	switch(adapter_speed) {
+		case(PCI_SPEED_133MHz_PCIX): 
+			reg = 0x75;
+			reg16 |= 0xB; 
+			break;
+		case(PCI_SPEED_100MHz_PCIX):
+			reg = 0x74;
+			reg16 |= 0xA;
+			break;
+		case(PCI_SPEED_66MHz_PCIX):
+			reg = 0x73;
+			reg16 |= 0x9;
+			break;
+		case(PCI_SPEED_66MHz):
+			reg = 0x73;
+			reg16 |= 0x1;
+			break;
+		default: /* 33MHz PCI 2.2 */
+			reg = 0x71;
+			break;
+			
+	}
+	reg16 |= 0xB << 12;
+	writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);
+	
+	mdelay(5); 
+	
+	/* Reenable interrupts */
+	writel(0, ctrl->hpc_reg + INT_MASK);
+
+	pci_write_config_byte(ctrl->pci_dev, 0x41, reg); 
+	
+	/* Restart state machine */
+	reg = ~0xF;
+	pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);
+	pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
+	
+	/* Only if mode change...*/
+	if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
+		((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) 
+			set_SOGO(ctrl);
+	
+	wait_for_ctrl_irq(ctrl);
+	mdelay(1100);
+	
+	/* Restore LED/Slot state */
+	writel(leds, ctrl->hpc_reg + LED_CONTROL);
+	writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);
+	
+	set_SOGO(ctrl);
+	wait_for_ctrl_irq(ctrl);
+
+	ctrl->speed = adapter_speed;
+	slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+
+	info("Successfully changed frequency/mode for adapter in slot %d\n", 
+			slot->number);
+	return 0;
+}
+
+#endif
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_core.c linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_core.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_core.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_core.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,1541 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ * Jan 12, 2003 -	Added 66/100/133MHz PCI-X support,
+ * 			Torben Mathiasen <torben.mathiasen@hp.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/uaccess.h>
+
+#include "cpqphp.h"
+#include "cpqphp_nvram.h"
+#include "../../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
+
+
+/* Global variables */
+int cpqhp_debug;
+struct controller *cpqhp_ctrl_list;	/* = NULL */
+struct pci_func *cpqhp_slot_list[256];
+
+/* local variables */
+static void *smbios_table;
+static void *smbios_start;
+static void *cpqhp_rom_start;
+static u8 power_mode;
+static int debug;
+
+#define DRIVER_VERSION	"0.9.7"
+#define DRIVER_AUTHOR	"Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
+#define DRIVER_DESC	"Compaq Hot Plug PCI Controller Driver"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(power_mode, "b");
+MODULE_PARM_DESC(power_mode, "Power mode enabled or not");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+
+#define CPQHPC_MODULE_MINOR 208
+
+static int one_time_init (void);
+static int set_attention_status (struct hotplug_slot *slot, u8 value);
+static int process_SI		(struct hotplug_slot *slot);
+static int process_SS		(struct hotplug_slot *slot);
+static int hardware_test	(struct hotplug_slot *slot, u32 value);
+static int get_power_status	(struct hotplug_slot *slot, u8 *value);
+static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
+static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
+static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
+static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
+static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
+
+static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
+	.owner =		THIS_MODULE,
+	.set_attention_status =	set_attention_status,
+	.enable_slot =		process_SI,
+	.disable_slot =		process_SS,
+	.hardware_test =	hardware_test,
+	.get_power_status =	get_power_status,
+	.get_attention_status =	get_attention_status,
+	.get_latch_status =	get_latch_status,
+	.get_adapter_status =	get_adapter_status,
+  	.get_max_bus_speed =	get_max_bus_speed,
+  	.get_cur_bus_speed =	get_cur_bus_speed,
+};
+
+
+static inline int is_slot64bit (struct slot *slot)
+{
+	if (!slot || !slot->p_sm_slot)
+		return 0;
+
+	if (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06)
+		return 1;
+
+	return 0;
+}
+
+static inline int is_slot66mhz (struct slot *slot)
+{
+	if (!slot || !slot->p_sm_slot)
+		return 0;
+
+	if (readb(slot->p_sm_slot + SMBIOS_SLOT_TYPE) == 0x0E)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * detect_SMBIOS_pointer - find the system Management BIOS Table in the specified region of memory.
+ *
+ * @begin: begin pointer for region to be scanned.
+ * @end: end pointer for region to be scanned.
+ *
+ * Returns pointer to the head of the SMBIOS tables (or NULL)
+ *
+ */
+static void * detect_SMBIOS_pointer(void *begin, void *end)
+{
+	void *fp;
+	void *endp;
+	u8 temp1, temp2, temp3, temp4;
+	int status = 0;
+
+	endp = (end - sizeof(u32) + 1);
+
+	for (fp = begin; fp <= endp; fp += 16) {
+		temp1 = readb(fp);
+		temp2 = readb(fp+1);
+		temp3 = readb(fp+2);
+		temp4 = readb(fp+3);
+		if (temp1 == '_' &&
+		    temp2 == 'S' &&
+		    temp3 == 'M' &&
+		    temp4 == '_') {
+			status = 1;
+			break;
+		}
+	}
+	
+	if (!status)
+		fp = NULL;
+
+	dbg("Discovered SMBIOS Entry point at %p\n", fp);
+
+	return fp;
+}
+
+/**
+ * init_SERR - Initializes the per slot SERR generation.
+ *
+ * For unexpected switch opens
+ *
+ */
+static int init_SERR(struct controller * ctrl)
+{
+	u32 tempdword;
+	u32 number_of_slots;
+	u8 physical_slot;
+
+	if (!ctrl)
+		return 1;
+
+	tempdword = ctrl->first_slot;
+
+	number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
+	// Loop through slots
+	while (number_of_slots) {
+		physical_slot = tempdword;
+		writeb(0, ctrl->hpc_reg + SLOT_SERR);
+		tempdword++;
+		number_of_slots--;
+	}
+
+	return 0;
+}
+
+
+/* nice debugging output */
+static int pci_print_IRQ_route (void)
+{
+	struct irq_routing_table *routing_table;
+	int len;
+	int loop;
+
+	u8 tbus, tdevice, tslot;
+
+	routing_table = pcibios_get_irq_routing_table();
+	if (routing_table == NULL) {
+		err("No BIOS Routing Table??? Not good\n");
+		return -ENOMEM;
+	}
+
+	len = (routing_table->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
+	// Make sure I got at least one entry
+	if (len == 0) {
+		kfree(routing_table);
+		return -1;
+	}
+
+	dbg("bus dev func slot\n");
+
+	for (loop = 0; loop < len; ++loop) {
+		tbus = routing_table->slots[loop].bus;
+		tdevice = routing_table->slots[loop].devfn;
+		tslot = routing_table->slots[loop].slot;
+		dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
+
+	}
+	kfree(routing_table);
+	return 0;
+}
+
+
+/*
+ * get_subsequent_smbios_entry
+ *
+ * Gets the first entry if previous == NULL
+ * Otherwise, returns the next entry
+ * Uses global SMBIOS Table pointer
+ *
+ * @curr: %NULL or pointer to previously returned structure
+ *
+ * returns a pointer to an SMBIOS structure or NULL if none found
+ */
+static void * get_subsequent_smbios_entry(void *smbios_start, void *smbios_table, void *curr)
+{
+	u8 bail = 0;
+	u8 previous_byte = 1;
+	void *p_temp;
+	void *p_max;
+
+	if (!smbios_table || !curr)
+		return(NULL);
+
+	// set p_max to the end of the table
+	p_max = smbios_start + readw(smbios_table + ST_LENGTH);
+
+	p_temp = curr;
+	p_temp += readb(curr + SMBIOS_GENERIC_LENGTH);
+
+	while ((p_temp < p_max) && !bail) {
+		// Look for the double NULL terminator
+		// The first condition is the previous byte and the second is the curr
+		if (!previous_byte && !(readb(p_temp))) {
+			bail = 1;
+		}
+
+		previous_byte = readb(p_temp);
+		p_temp++;
+	}
+
+	if (p_temp < p_max) {
+		return p_temp;
+	} else {
+		return NULL;
+	}
+}
+
+
+/**
+ * get_SMBIOS_entry
+ *
+ * @type:SMBIOS structure type to be returned
+ * @previous: %NULL or pointer to previously returned structure
+ *
+ * Gets the first entry of the specified type if previous == NULL
+ * Otherwise, returns the next entry of the given type.
+ * Uses global SMBIOS Table pointer
+ * Uses get_subsequent_smbios_entry
+ *
+ * returns a pointer to an SMBIOS structure or %NULL if none found
+ */
+static void *get_SMBIOS_entry (void *smbios_start, void *smbios_table, u8 type, void * previous)
+{
+	if (!smbios_table)
+		return NULL;
+
+	if (!previous) {		  
+		previous = smbios_start;
+	} else {
+		previous = get_subsequent_smbios_entry(smbios_start, smbios_table, previous);
+	}
+
+	while (previous) {
+	       	if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
+			previous = get_subsequent_smbios_entry(smbios_start, smbios_table, previous);
+		} else {
+			break;
+		}
+	}
+
+	return previous;
+}
+
+
+static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void *smbios_table)
+{
+	struct slot *new_slot;
+	u8 number_of_slots;
+	u8 slot_device;
+	u8 slot_number;
+	u8 ctrl_slot;
+	u32 tempdword;
+	void *slot_entry= NULL;
+	int result;
+
+	dbg("%s\n", __FUNCTION__);
+
+	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
+
+	number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
+	slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
+	slot_number = ctrl->first_slot;
+
+	while (number_of_slots) {
+		new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL);
+		if (!new_slot)
+			return -ENOMEM;
+
+		memset(new_slot, 0, sizeof(struct slot));
+		new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
+		if (!new_slot->hotplug_slot) {
+			kfree (new_slot);
+			return -ENOMEM;
+		}
+		memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
+
+		new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+		if (!new_slot->hotplug_slot->info) {
+			kfree (new_slot->hotplug_slot);
+			kfree (new_slot);
+			return -ENOMEM;
+		}
+		memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
+		new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
+		if (!new_slot->hotplug_slot->name) {
+			kfree (new_slot->hotplug_slot->info);
+			kfree (new_slot->hotplug_slot);
+			kfree (new_slot);
+			return -ENOMEM;
+		}
+
+		new_slot->magic = SLOT_MAGIC;
+		new_slot->ctrl = ctrl;
+		new_slot->bus = ctrl->bus;
+		new_slot->device = slot_device;
+		new_slot->number = slot_number;
+		dbg("slot->number = %d\n",new_slot->number);
+
+		slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry);
+
+		while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) {
+			slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, slot_entry);
+		}
+
+		new_slot->p_sm_slot = slot_entry;
+
+		init_timer(&new_slot->task_event);
+		new_slot->task_event.expires = jiffies + 5 * HZ;
+		new_slot->task_event.function = cpqhp_pushbutton_thread;
+
+		//FIXME: these capabilities aren't used but if they are
+		//       they need to be correctly implemented
+		new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
+		new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
+
+		if (is_slot64bit(new_slot))
+			new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
+		if (is_slot66mhz(new_slot))
+			new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
+		if (ctrl->speed == PCI_SPEED_66MHz)
+			new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
+
+		ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
+
+		// Check presence
+		new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
+		// Check the switch state
+		new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
+		// Check the slot enable
+		new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
+
+		/* register this slot with the hotplug pci core */
+		new_slot->hotplug_slot->private = new_slot;
+		make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
+		new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
+		
+		new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot);
+		new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot);
+		new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot);
+		new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot);
+		
+		dbg ("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n", 
+		     new_slot->bus, new_slot->device, new_slot->number, ctrl->slot_device_offset, slot_number);
+		result = pci_hp_register (new_slot->hotplug_slot);
+		if (result) {
+			err ("pci_hp_register failed with error %d\n", result);
+			kfree (new_slot->hotplug_slot->info);
+			kfree (new_slot->hotplug_slot->name);
+			kfree (new_slot->hotplug_slot);
+			kfree (new_slot);
+			return result;
+		}
+		
+		new_slot->next = ctrl->slot;
+		ctrl->slot = new_slot;
+
+		number_of_slots--;
+		slot_device++;
+		slot_number++;
+	}
+
+	return(0);
+}
+
+
+static int ctrl_slot_cleanup (struct controller * ctrl)
+{
+	struct slot *old_slot, *next_slot;
+
+	old_slot = ctrl->slot;
+	ctrl->slot = NULL;
+
+	while (old_slot) {
+		next_slot = old_slot->next;
+		pci_hp_deregister (old_slot->hotplug_slot);
+		kfree(old_slot->hotplug_slot->info);
+		kfree(old_slot->hotplug_slot->name);
+		kfree(old_slot->hotplug_slot);
+		kfree(old_slot);
+		old_slot = next_slot;
+	}
+
+	//Free IRQ associated with hot plug device
+	free_irq(ctrl->interrupt, ctrl);
+	//Unmap the memory
+	iounmap(ctrl->hpc_reg);
+	//Finally reclaim PCI mem
+	release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
+			   pci_resource_len(ctrl->pci_dev, 0));
+
+	return(0);
+}
+
+
+//============================================================================
+// function:	get_slot_mapping
+//
+// Description: Attempts to determine a logical slot mapping for a PCI
+//		device.  Won't work for more than one PCI-PCI bridge
+//		in a slot.
+//
+// Input:	u8 bus_num - bus number of PCI device
+//		u8 dev_num - device number of PCI device
+//		u8 *slot - Pointer to u8 where slot number will
+//			be returned
+//
+// Output:	SUCCESS or FAILURE
+//=============================================================================
+static int get_slot_mapping (struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
+{
+	struct irq_routing_table *PCIIRQRoutingInfoLength;
+	u32 work;
+	long len;
+	long loop;
+
+	u8 tbus, tdevice, tslot, bridgeSlot;
+
+	dbg("%s: %p, %d, %d, %p\n", __FUNCTION__, bus, bus_num, dev_num, slot);
+
+	bridgeSlot = 0xFF;
+
+	PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
+	if (!PCIIRQRoutingInfoLength)
+		return -1;
+
+	len = (PCIIRQRoutingInfoLength->size -
+	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
+	// Make sure I got at least one entry
+	if (len == 0) {
+		if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
+		return -1;
+	}
+
+	for (loop = 0; loop < len; ++loop) {
+		tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
+		tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
+		tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
+
+		if ((tbus == bus_num) && (tdevice == dev_num)) {
+			*slot = tslot;
+
+			if (PCIIRQRoutingInfoLength != NULL)
+				kfree(PCIIRQRoutingInfoLength);
+			return 0;
+		} else {
+			// Didn't get a match on the target PCI device. Check if the
+			// current IRQ table entry is a PCI-to-PCI bridge device.  If so,
+			// and it's secondary bus matches the bus number for the target 
+			// device, I need to save the bridge's slot number.  If I can't 
+			// find an entry for the target device, I will have to assume it's 
+			// on the other side of the bridge, and assign it the bridge's slot.
+			bus->number = tbus;
+			pci_bus_read_config_dword (bus, PCI_DEVFN(tdevice, 0), PCI_REVISION_ID, &work);
+
+			if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
+				pci_bus_read_config_dword (bus, PCI_DEVFN(tdevice, 0), PCI_PRIMARY_BUS, &work);
+				// See if bridge's secondary bus matches target bus.
+				if (((work >> 8) & 0x000000FF) == (long) bus_num) {
+					bridgeSlot = tslot;
+				}
+			}
+		}
+
+	}
+
+	// If we got here, we didn't find an entry in the IRQ mapping table 
+	// for the target PCI device.  If we did determine that the target 
+	// device is on the other side of a PCI-to-PCI bridge, return the 
+	// slot number for the bridge.
+	if (bridgeSlot != 0xFF) {
+		*slot = bridgeSlot;
+		if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
+		return 0;
+	}
+	if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength );
+	// Couldn't find an entry in the routing table for this PCI device
+	return -1;
+}
+
+
+/**
+ * cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
+ *
+ */
+static int cpqhp_set_attention_status (struct controller *ctrl, struct pci_func *func, u32 status)
+{
+	u8 hp_slot;
+
+	hp_slot = func->device - ctrl->slot_device_offset;
+
+	if (func == NULL)
+		return(1);
+
+	// Wait for exclusive access to hardware
+	down(&ctrl->crit_sect);
+
+	if (status == 1) {
+		amber_LED_on (ctrl, hp_slot);
+	} else if (status == 0) {
+		amber_LED_off (ctrl, hp_slot);
+	} else {
+		// Done with exclusive hardware access
+		up(&ctrl->crit_sect);
+		return(1);
+	}
+
+	set_SOGO(ctrl);
+
+	// Wait for SOBS to be unset
+	wait_for_ctrl_irq (ctrl);
+
+	// Done with exclusive hardware access
+	up(&ctrl->crit_sect);
+
+	return(0);
+}
+
+
+/**
+ * set_attention_status - Turns the Amber LED for a slot on or off
+ *
+ */
+static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
+{
+	struct pci_func *slot_func;
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	u8 bus;
+	u8 devfn;
+	u8 device;
+	u8 function;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
+		return -ENODEV;
+
+	device = devfn >> 3;
+	function = devfn & 0x7;
+	dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
+
+	slot_func = cpqhp_slot_find(bus, device, function);
+	if (!slot_func) {
+		return -ENODEV;
+	}
+
+	return cpqhp_set_attention_status(ctrl, slot_func, status);
+}
+
+
+static int process_SI (struct hotplug_slot *hotplug_slot)
+{
+	struct pci_func *slot_func;
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	u8 bus;
+	u8 devfn;
+	u8 device;
+	u8 function;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
+		return -ENODEV;
+
+	device = devfn >> 3;
+	function = devfn & 0x7;
+	dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
+
+	slot_func = cpqhp_slot_find(bus, device, function);
+	if (!slot_func) {
+		return -ENODEV;
+	}
+
+	slot_func->bus = bus;
+	slot_func->device = device;
+	slot_func->function = function;
+	slot_func->configured = 0;
+	dbg("board_added(%p, %p)\n", slot_func, ctrl);
+	return cpqhp_process_SI(ctrl, slot_func);
+}
+
+
+static int process_SS (struct hotplug_slot *hotplug_slot)
+{
+	struct pci_func *slot_func;
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	u8 bus;
+	u8 devfn;
+	u8 device;
+	u8 function;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
+		return -ENODEV;
+
+	device = devfn >> 3;
+	function = devfn & 0x7;
+	dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
+
+	slot_func = cpqhp_slot_find(bus, device, function);
+	if (!slot_func) {
+		return -ENODEV;
+	}
+	
+	dbg("In power_down_board, slot_func = %p, ctrl = %p\n", slot_func, ctrl);
+	return cpqhp_process_SS(ctrl, slot_func);
+}
+
+
+static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+
+	return cpqhp_hardware_test (ctrl, value);	
+}
+
+
+static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	*value = get_slot_enabled(ctrl, slot);
+	return 0;
+}
+
+static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	*value = cpq_get_attention_status(ctrl, slot);
+	return 0;
+}
+
+static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	*value = cpq_get_latch_status (ctrl, slot);
+
+	return 0;
+}
+
+static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	*value = get_presence_status (ctrl, slot);
+
+	return 0;
+}
+
+static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	*value = ctrl->speed_capability;
+
+	return 0;
+}
+
+static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	*value = ctrl->speed;
+
+	return 0;
+}
+
+static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	u8 num_of_slots = 0;
+	u8 hp_slot = 0;
+	u8 device;
+	u8 rev;
+	u8 bus_cap;
+	u16 temp_word;
+	u16 vendor_id;
+	u16 subsystem_vid;
+	u16 subsystem_deviceid;
+	u32 rc;
+	struct controller *ctrl;
+	struct pci_func *func;
+
+	// Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
+	rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
+	if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
+		err(msg_HPC_non_compaq_or_intel);
+		return -ENODEV;
+	}
+	dbg("Vendor ID: %x\n", vendor_id);
+
+	rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
+	dbg("revision: %d\n", rev);
+	if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
+		err(msg_HPC_rev_error);
+		return -ENODEV;
+	}
+
+	/* Check for the proper subsytem ID's
+	 * Intel uses a different SSID programming model than Compaq.  
+	 * For Intel, each SSID bit identifies a PHP capability.
+	 * Also Intel HPC's may have RID=0.
+	 */
+	if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
+		// TODO: This code can be made to support non-Compaq or Intel subsystem IDs
+		rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
+		if (rc) {
+			err("%s : pci_read_config_word failed\n", __FUNCTION__);
+			return rc;
+		}
+		dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
+		if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
+			err(msg_HPC_non_compaq_or_intel);
+			return -ENODEV;
+		}
+
+		ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
+		if (!ctrl) {
+			err("%s : out of memory\n", __FUNCTION__);
+			return -ENOMEM;
+		}
+		memset(ctrl, 0, sizeof(struct controller));
+
+		rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
+		if (rc) {
+			err("%s : pci_read_config_word failed\n", __FUNCTION__);
+			goto err_free_ctrl;
+		}
+
+		info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
+
+		/* Set Vendor ID, so it can be accessed later from other functions */
+		ctrl->vendor_id = vendor_id;
+
+		switch (subsystem_vid) {
+			case PCI_VENDOR_ID_COMPAQ:
+				if (rev >= 0x13) { /* CIOBX */
+					ctrl->push_flag = 1;
+					ctrl->slot_switch_type = 1;		// Switch is present
+					ctrl->push_button = 1;			// Pushbutton is present
+					ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+					ctrl->defeature_PHP = 1;		// PHP is supported
+					ctrl->pcix_support = 1;			// PCI-X supported
+					ctrl->pcix_speed_capability = 1;
+					pci_read_config_byte(pdev, 0x41, &bus_cap);
+					if (bus_cap & 0x80) {
+						dbg("bus max supports 133MHz PCI-X\n");
+						ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
+						break;
+					}
+					if (bus_cap & 0x40) {
+						dbg("bus max supports 100MHz PCI-X\n");
+						ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+						break;
+					}
+					if (bus_cap & 20) {
+						dbg("bus max supports 66MHz PCI-X\n");
+						ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
+						break;
+					}
+					if (bus_cap & 10) {
+						dbg("bus max supports 66MHz PCI\n");
+						ctrl->speed_capability = PCI_SPEED_66MHz;
+						break;
+					}
+
+					break;
+				}
+
+				switch (subsystem_deviceid) {
+					case PCI_SUB_HPC_ID:
+						/* Original 6500/7000 implementation */
+						ctrl->slot_switch_type = 1;		// Switch is present
+						ctrl->speed_capability = PCI_SPEED_33MHz;
+						ctrl->push_button = 0;			// No pushbutton
+						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+						ctrl->defeature_PHP = 1;		// PHP is supported
+						ctrl->pcix_support = 0;			// PCI-X not supported
+						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
+						break;
+					case PCI_SUB_HPC_ID2:
+						/* First Pushbutton implementation */
+						ctrl->push_flag = 1;
+						ctrl->slot_switch_type = 1;		// Switch is present
+						ctrl->speed_capability = PCI_SPEED_33MHz;
+						ctrl->push_button = 1;			// Pushbutton is present
+						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+						ctrl->defeature_PHP = 1;		// PHP is supported
+						ctrl->pcix_support = 0;			// PCI-X not supported
+						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
+						break;
+					case PCI_SUB_HPC_ID_INTC:
+						/* Third party (6500/7000) */
+						ctrl->slot_switch_type = 1;		// Switch is present
+						ctrl->speed_capability = PCI_SPEED_33MHz;
+						ctrl->push_button = 0;			// No pushbutton
+						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+						ctrl->defeature_PHP = 1;			// PHP is supported
+						ctrl->pcix_support = 0;			// PCI-X not supported
+						ctrl->pcix_speed_capability = 0;		// N/A since PCI-X not supported
+						break;
+					case PCI_SUB_HPC_ID3:
+						/* First 66 Mhz implementation */
+						ctrl->push_flag = 1;
+						ctrl->slot_switch_type = 1;		// Switch is present
+						ctrl->speed_capability = PCI_SPEED_66MHz;
+						ctrl->push_button = 1;			// Pushbutton is present
+						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+						ctrl->defeature_PHP = 1;		// PHP is supported
+						ctrl->pcix_support = 0;			// PCI-X not supported
+						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
+						break;
+					case PCI_SUB_HPC_ID4:
+						/* First PCI-X implementation, 100MHz */
+						ctrl->push_flag = 1;
+						ctrl->slot_switch_type = 1;		// Switch is present
+						ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+						ctrl->push_button = 1;			// Pushbutton is present
+						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
+						ctrl->defeature_PHP = 1;		// PHP is supported
+						ctrl->pcix_support = 1;			// PCI-X supported
+						ctrl->pcix_speed_capability = 0;	
+						break;
+					default:
+						err(msg_HPC_not_supported);
+						rc = -ENODEV;
+						goto err_free_ctrl;
+				}
+				break;
+
+			case PCI_VENDOR_ID_INTEL:
+				/* Check for speed capability (0=33, 1=66) */
+				if (subsystem_deviceid & 0x0001) {
+					ctrl->speed_capability = PCI_SPEED_66MHz;
+				} else {
+					ctrl->speed_capability = PCI_SPEED_33MHz;
+				}
+
+				/* Check for push button */
+				if (subsystem_deviceid & 0x0002) {
+					/* no push button */
+					ctrl->push_button = 0;
+				} else {
+					/* push button supported */
+					ctrl->push_button = 1;
+				}
+
+				/* Check for slot switch type (0=mechanical, 1=not mechanical) */
+				if (subsystem_deviceid & 0x0004) {
+					/* no switch */
+					ctrl->slot_switch_type = 0;
+				} else {
+					/* switch */
+					ctrl->slot_switch_type = 1;
+				}
+
+				/* PHP Status (0=De-feature PHP, 1=Normal operation) */
+				if (subsystem_deviceid & 0x0008) {
+					ctrl->defeature_PHP = 1;	// PHP supported
+				} else {
+					ctrl->defeature_PHP = 0;	// PHP not supported
+				}
+
+				/* Alternate Base Address Register Interface (0=not supported, 1=supported) */
+				if (subsystem_deviceid & 0x0010) {
+					ctrl->alternate_base_address = 1;	// supported
+				} else {
+					ctrl->alternate_base_address = 0;	// not supported
+				}
+
+				/* PCI Config Space Index (0=not supported, 1=supported) */
+				if (subsystem_deviceid & 0x0020) {
+					ctrl->pci_config_space = 1;		// supported
+				} else {
+					ctrl->pci_config_space = 0;		// not supported
+				}
+
+				/* PCI-X support */
+				if (subsystem_deviceid & 0x0080) {
+					/* PCI-X capable */
+					ctrl->pcix_support = 1;
+					/* Frequency of operation in PCI-X mode */
+					if (subsystem_deviceid & 0x0040) {
+						/* 133MHz PCI-X if bit 7 is 1 */
+						ctrl->pcix_speed_capability = 1;
+					} else {
+						/* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
+						/* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
+						ctrl->pcix_speed_capability = 0;
+					}
+				} else {
+					/* Conventional PCI */
+					ctrl->pcix_support = 0;
+					ctrl->pcix_speed_capability = 0;
+				}
+				break;
+
+			default:
+				err(msg_HPC_not_supported);
+				rc = -ENODEV;
+				goto err_free_ctrl;
+		}
+
+	} else {
+		err(msg_HPC_not_supported);
+		return -ENODEV;
+	}
+
+	// Tell the user that we found one.
+	info("Initializing the PCI hot plug controller residing on PCI bus %d\n", pdev->bus->number);
+
+	dbg ("Hotplug controller capabilities:\n");
+	dbg ("    speed_capability       %d\n", ctrl->speed_capability);
+	dbg ("    slot_switch_type       %s\n", ctrl->slot_switch_type == 0 ? "no switch" : "switch present");
+	dbg ("    defeature_PHP          %s\n", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported");
+	dbg ("    alternate_base_address %s\n", ctrl->alternate_base_address == 0 ? "not supported" : "supported");
+	dbg ("    pci_config_space       %s\n", ctrl->pci_config_space == 0 ? "not supported" : "supported");
+	dbg ("    pcix_speed_capability  %s\n", ctrl->pcix_speed_capability == 0 ? "not supported" : "supported");
+	dbg ("    pcix_support           %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported");
+
+	ctrl->pci_dev = pdev;
+	pci_set_drvdata(pdev, ctrl);
+
+	/* make our own copy of the pci bus structure, as we like tweaking it a lot */
+	ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
+	if (!ctrl->pci_bus) {
+		err("out of memory\n");
+		rc = -ENOMEM;
+		goto err_free_ctrl;
+	}
+	memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
+
+	ctrl->bus = pdev->bus->number;
+	ctrl->rev = rev;
+	dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
+	     PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
+
+	init_MUTEX(&ctrl->crit_sect);
+	init_waitqueue_head(&ctrl->queue);
+
+	/* initialize our threads if they haven't already been started up */
+	rc = one_time_init();
+	if (rc) {
+		goto err_free_bus;
+	}
+	
+	dbg("pdev = %p\n", pdev);
+	dbg("pci resource start %lx\n", pci_resource_start(pdev, 0));
+	dbg("pci resource len %lx\n", pci_resource_len(pdev, 0));
+
+	if (!request_mem_region(pci_resource_start(pdev, 0),
+				pci_resource_len(pdev, 0), MY_NAME)) {
+		err("cannot reserve MMIO region\n");
+		rc = -ENOMEM;
+		goto err_free_bus;
+	}
+
+	ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+	if (!ctrl->hpc_reg) {
+		err("cannot remap MMIO region %lx @ %lx\n", pci_resource_len(pdev, 0), pci_resource_start(pdev, 0));
+		rc = -ENODEV;
+		goto err_free_mem_region;
+	}
+
+	// Check for 66Mhz operation
+	ctrl->speed = get_controller_speed(ctrl);
+
+
+	//**************************************************
+	//
+	//              Save configuration headers for this and
+	//              subordinate PCI buses
+	//
+	//**************************************************
+
+	// find the physical slot number of the first hot plug slot
+
+	// Get slot won't work for devices behind bridges, but
+	// in this case it will always be called for the "base"
+	// bus/dev/func of a slot.
+	// CS: this is leveraging the PCIIRQ routing code from the kernel (pci-pc.c: get_irq_routing_table)
+	rc = get_slot_mapping(ctrl->pci_bus, pdev->bus->number, (readb(ctrl->hpc_reg + SLOT_MASK) >> 4), &(ctrl->first_slot));
+	dbg("get_slot_mapping: first_slot = %d, returned = %d\n", ctrl->first_slot, rc);
+	if (rc) {
+		err(msg_initialization_err, rc);
+		goto err_iounmap;
+	}
+
+	// Store PCI Config Space for all devices on this bus
+	rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
+	if (rc) {
+		err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
+		goto err_iounmap;
+	}
+
+	/*
+	 * Get IO, memory, and IRQ resources for new devices
+	 */
+	// The next line is required for cpqhp_find_available_resources
+	ctrl->interrupt = pdev->irq;
+
+	ctrl->cfgspc_irq = 0;
+	pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ctrl->cfgspc_irq);
+
+	rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
+	ctrl->add_support = !rc;
+	if (rc) {
+		dbg("cpqhp_find_available_resources = 0x%x\n", rc);
+		err("unable to locate PCI configuration resources for hot plug add.\n");
+		goto err_iounmap;
+	}
+
+	/*
+	 * Finish setting up the hot plug ctrl device
+	 */
+	ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
+	dbg("NumSlots %d \n", ctrl->slot_device_offset);
+
+	ctrl->next_event = 0;
+
+	/* Setup the slot information structures */
+	rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
+	if (rc) {
+		err(msg_initialization_err, 6);
+		err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
+		goto err_iounmap;
+	}
+	
+	/* Mask all general input interrupts */
+	writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
+
+	/* set up the interrupt */
+	dbg("HPC interrupt = %d \n", ctrl->interrupt);
+	if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr,
+			SA_SHIRQ, MY_NAME, ctrl)) {
+		err("Can't get irq %d for the hotplug pci controller\n", ctrl->interrupt);
+		rc = -ENODEV;
+		goto err_iounmap;
+	}
+
+	/* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
+	temp_word = readw(ctrl->hpc_reg + MISC);
+	temp_word |= 0x4006;
+	writew(temp_word, ctrl->hpc_reg + MISC);
+
+	// Changed 05/05/97 to clear all interrupts at start
+	writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
+
+	ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
+
+	writel(0x0L, ctrl->hpc_reg + INT_MASK);
+
+	if (!cpqhp_ctrl_list) {
+		cpqhp_ctrl_list = ctrl;
+		ctrl->next = NULL;
+	} else {
+		ctrl->next = cpqhp_ctrl_list;
+		cpqhp_ctrl_list = ctrl;
+	}
+
+	// turn off empty slots here unless command line option "ON" set
+	// Wait for exclusive access to hardware
+	down(&ctrl->crit_sect);
+
+	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
+
+	// find first device number for the ctrl
+	device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
+
+	while (num_of_slots) {
+		dbg("num_of_slots: %d\n", num_of_slots);
+		func = cpqhp_slot_find(ctrl->bus, device, 0);
+		if (!func)
+			break;
+
+		hp_slot = func->device - ctrl->slot_device_offset;
+		dbg("hp_slot: %d\n", hp_slot);
+
+		// We have to save the presence info for these slots
+		temp_word = ctrl->ctrl_int_comp >> 16;
+		func->presence_save = (temp_word >> hp_slot) & 0x01;
+		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
+
+		if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
+			func->switch_save = 0;
+		} else {
+			func->switch_save = 0x10;
+		}
+
+		if (!power_mode) {
+			if (!func->is_a_board) {
+				green_LED_off (ctrl, hp_slot);
+				slot_disable (ctrl, hp_slot);
+			}
+		}
+
+		device++;
+		num_of_slots--;
+	}
+
+	if (!power_mode) {
+		set_SOGO(ctrl);
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
+	}
+
+	rc = init_SERR(ctrl);
+	if (rc) {
+		err("init_SERR failed\n");
+		up(&ctrl->crit_sect);
+		goto err_free_irq;
+	}
+
+	// Done with exclusive hardware access
+	up(&ctrl->crit_sect);
+
+	cpqhp_create_ctrl_files (ctrl);
+
+	return 0;
+
+err_free_irq:
+	free_irq(ctrl->interrupt, ctrl);
+err_iounmap:
+	iounmap(ctrl->hpc_reg);
+err_free_mem_region:
+	release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+err_free_bus:
+	kfree(ctrl->pci_bus);
+err_free_ctrl:
+	kfree(ctrl);
+	return rc;
+}
+
+
+static int one_time_init(void)
+{
+	int loop;
+	int retval = 0;
+	static int initialized = 0;
+
+	if (initialized)
+		return 0;
+
+	power_mode = 0;
+
+	retval = pci_print_IRQ_route();
+	if (retval)
+		goto error;
+
+	dbg("Initialize + Start the notification mechanism \n");
+
+	retval = cpqhp_event_start_thread();
+	if (retval)
+		goto error;
+
+	dbg("Initialize slot lists\n");
+	for (loop = 0; loop < 256; loop++) {
+		cpqhp_slot_list[loop] = NULL;
+	}
+
+	// FIXME: We also need to hook the NMI handler eventually.
+	// this also needs to be worked with Christoph
+	// register_NMI_handler();
+
+	// Map rom address
+	cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
+	if (!cpqhp_rom_start) {
+		err ("Could not ioremap memory region for ROM\n");
+		retval = -EIO;;
+		goto error;
+	}
+	
+	/* Now, map the int15 entry point if we are on compaq specific hardware */
+	compaq_nvram_init(cpqhp_rom_start);
+	
+	/* Map smbios table entry point structure */
+	smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start, cpqhp_rom_start + ROM_PHY_LEN);
+	if (!smbios_table) {
+		err ("Could not find the SMBIOS pointer in memory\n");
+		retval = -EIO;;
+		goto error;
+	}
+
+	smbios_start = ioremap(readl(smbios_table + ST_ADDRESS), readw(smbios_table + ST_LENGTH));
+	if (!smbios_start) {
+		err ("Could not ioremap memory region taken from SMBIOS values\n");
+		retval = -EIO;;
+		goto error;
+	}
+
+	initialized = 1;
+
+	return retval;
+
+error:
+	if (cpqhp_rom_start)
+		iounmap(cpqhp_rom_start);
+	if (smbios_start)
+		iounmap(smbios_start);
+	
+	return retval;
+}
+
+
+static void unload_cpqphpd(void)
+{
+	struct pci_func *next;
+	struct pci_func *TempSlot;
+	int loop;
+	u32 rc;
+	struct controller *ctrl;
+	struct controller *tctrl;
+	struct pci_resource *res;
+	struct pci_resource *tres;
+
+	rc = compaq_nvram_store(cpqhp_rom_start);
+
+	ctrl = cpqhp_ctrl_list;
+
+	while (ctrl) {
+		if (ctrl->hpc_reg) {
+			u16 misc;
+			rc = read_slot_enable (ctrl);
+			
+			writeb(0, ctrl->hpc_reg + SLOT_SERR);
+			writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
+			
+			misc = readw(ctrl->hpc_reg + MISC);
+			misc &= 0xFFFD;
+			writew(misc, ctrl->hpc_reg + MISC);
+		}
+
+		ctrl_slot_cleanup(ctrl);
+
+		res = ctrl->io_head;
+		while (res) {
+			tres = res;
+			res = res->next;
+			kfree(tres);
+		}
+
+		res = ctrl->mem_head;
+		while (res) {
+			tres = res;
+			res = res->next;
+			kfree(tres);
+		}
+
+		res = ctrl->p_mem_head;
+		while (res) {
+			tres = res;
+			res = res->next;
+			kfree(tres);
+		}
+
+		res = ctrl->bus_head;
+		while (res) {
+			tres = res;
+			res = res->next;
+			kfree(tres);
+		}
+
+		kfree (ctrl->pci_bus);
+
+		tctrl = ctrl;
+		ctrl = ctrl->next;
+		kfree(tctrl);
+	}
+
+	for (loop = 0; loop < 256; loop++) {
+		next = cpqhp_slot_list[loop];
+		while (next != NULL) {
+			res = next->io_head;
+			while (res) {
+				tres = res;
+				res = res->next;
+				kfree(tres);
+			}
+
+			res = next->mem_head;
+			while (res) {
+				tres = res;
+				res = res->next;
+				kfree(tres);
+			}
+
+			res = next->p_mem_head;
+			while (res) {
+				tres = res;
+				res = res->next;
+				kfree(tres);
+			}
+
+			res = next->bus_head;
+			while (res) {
+				tres = res;
+				res = res->next;
+				kfree(tres);
+			}
+
+			TempSlot = next;
+			next = next->next;
+			kfree(TempSlot);
+		}
+	}
+
+	// Stop the notification mechanism
+	cpqhp_event_stop_thread();
+
+	//unmap the rom address
+	if (cpqhp_rom_start)
+		iounmap(cpqhp_rom_start);
+	if (smbios_start)
+		iounmap(smbios_start);
+}
+
+
+
+static struct pci_device_id hpcd_pci_tbl[] __devinitdata = {
+	{
+	/* handle any PCI Hotplug controller */
+	.class =        ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
+	.class_mask =   ~0,
+	
+	/* no matter who makes it */
+	.vendor =       PCI_ANY_ID,
+	.device =       PCI_ANY_ID,
+	.subvendor =    PCI_ANY_ID,
+	.subdevice =    PCI_ANY_ID,
+	
+	}, { /* end: all zeroes */ }
+};
+
+MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
+
+
+
+static struct pci_driver cpqhpc_driver = {
+	.name =		"pci_hotplug",
+	.id_table =	hpcd_pci_tbl,
+	.probe =	cpqhpc_probe,
+	/* remove:	cpqhpc_remove_one, */
+};
+
+
+
+static int __init cpqhpc_init(void)
+{
+	int result;
+
+	cpqhp_debug = debug;
+
+	result = pci_module_init(&cpqhpc_driver);
+	dbg("pci_module_init = %d\n", result);
+	if (result)
+		return result;
+	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
+	return 0;
+}
+
+
+static void __exit cpqhpc_cleanup(void)
+{
+	dbg("unload_cpqphpd()\n");
+	unload_cpqphpd();
+
+	dbg("pci_unregister_driver\n");
+	pci_unregister_driver(&cpqhpc_driver);
+}
+
+
+module_init(cpqhpc_init);
+module_exit(cpqhpc_cleanup);
+
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_ctrl.c linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_ctrl.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_ctrl.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_ctrl.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,3084 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/smp_lock.h>
+#include <linux/pci.h>
+#include "cpqphp.h"
+
+static u32 configure_new_device(struct controller* ctrl, struct pci_func *func,u8 behind_bridge, struct resource_lists *resources);
+static int configure_new_function(struct controller* ctrl, struct pci_func *func,u8 behind_bridge, struct resource_lists *resources);
+static void interrupt_event_handler(struct controller *ctrl);
+
+static struct semaphore event_semaphore;	/* mutex for process loop (up if something to process) */
+static struct semaphore event_exit;		/* guard ensure thread has exited before calling it quits */
+static int event_finished;
+static unsigned long pushbutton_pending;	/* = 0 */
+
+/* things needed for the long_delay function */
+static struct semaphore		delay_sem;
+static wait_queue_head_t	delay_wait;
+
+/* delay is in jiffies to wait for */
+static void long_delay (int delay)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	
+	/* only allow 1 customer into the delay queue at once
+	 * yes this makes some people wait even longer, but who really cares?
+	 * this is for _huge_ delays to make the hardware happy as the 
+	 * signals bounce around
+	 */
+	down (&delay_sem);
+
+	init_waitqueue_head (&delay_wait);
+
+	add_wait_queue(&delay_wait, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(delay);
+	remove_wait_queue(&delay_wait, &wait);
+	set_current_state(TASK_RUNNING);
+	
+	up (&delay_sem);
+}
+
+
+//FIXME: The following line needs to be somewhere else...
+#define WRONG_BUS_FREQUENCY 0x07
+static u8 handle_switch_change(u8 change, struct controller * ctrl)
+{
+	int hp_slot;
+	u8 rc = 0;
+	u16 temp_word;
+	struct pci_func *func;
+	struct event_info *taskInfo;
+
+	if (!change)
+		return 0;
+
+	// Switch Change
+	dbg("cpqsbd:  Switch interrupt received.\n");
+
+	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
+		if (change & (0x1L << hp_slot)) {
+			//*********************************
+			// this one changed.
+			//*********************************
+			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
+
+			//this is the structure that tells the worker thread
+			//what to do
+			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
+			ctrl->next_event = (ctrl->next_event + 1) % 10;
+			taskInfo->hp_slot = hp_slot;
+
+			rc++;
+
+			temp_word = ctrl->ctrl_int_comp >> 16;
+			func->presence_save = (temp_word >> hp_slot) & 0x01;
+			func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
+
+			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
+				//*********************************
+				// Switch opened
+				//*********************************
+
+				func->switch_save = 0;
+
+				taskInfo->event_type = INT_SWITCH_OPEN;
+			} else {
+				//*********************************
+				// Switch closed
+				//*********************************
+
+				func->switch_save = 0x10;
+
+				taskInfo->event_type = INT_SWITCH_CLOSE;
+			}
+		}
+	}
+
+	return rc;
+}
+
+
+/*
+ * cpqhp_find_slot
+ */
+struct slot *cpqhp_find_slot (struct controller * ctrl, u8 device)
+{
+	struct slot *slot;
+
+	if (!ctrl)
+		return NULL;
+
+	slot = ctrl->slot;
+
+	while (slot && (slot->device != device)) {
+		slot = slot->next;
+	}
+
+	return slot;
+}
+
+
+static u8 handle_presence_change(u16 change, struct controller * ctrl)
+{
+	int hp_slot;
+	u8 rc = 0;
+	u8 temp_byte;
+	u16 temp_word;
+	struct pci_func *func;
+	struct event_info *taskInfo;
+	struct slot *p_slot;
+
+	if (!change)
+		return 0;
+
+	//*********************************
+	// Presence Change
+	//*********************************
+	dbg("cpqsbd:  Presence/Notify input change.\n");
+	dbg("         Changed bits are 0x%4.4x\n", change );
+
+	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
+		if (change & (0x0101 << hp_slot)) {
+			//*********************************
+			// this one changed.
+			//*********************************
+			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
+
+			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
+			ctrl->next_event = (ctrl->next_event + 1) % 10;
+			taskInfo->hp_slot = hp_slot;
+
+			rc++;
+
+			p_slot = cpqhp_find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));
+			if (!p_slot)
+				return 0;
+
+			// If the switch closed, must be a button
+			// If not in button mode, nevermind
+			if (func->switch_save && (ctrl->push_button == 1)) {
+				temp_word = ctrl->ctrl_int_comp >> 16;
+				temp_byte = (temp_word >> hp_slot) & 0x01;
+				temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
+
+				if (temp_byte != func->presence_save) {
+					//*********************************
+					// button Pressed (doesn't do anything)
+					//*********************************
+					dbg("hp_slot %d button pressed\n", hp_slot);
+					taskInfo->event_type = INT_BUTTON_PRESS;
+				} else {
+					//*********************************
+					// button Released - TAKE ACTION!!!!
+					//*********************************
+					dbg("hp_slot %d button released\n", hp_slot);
+					taskInfo->event_type = INT_BUTTON_RELEASE;
+
+					// Cancel if we are still blinking
+					if ((p_slot->state == BLINKINGON_STATE)
+					    || (p_slot->state == BLINKINGOFF_STATE)) {
+						taskInfo->event_type = INT_BUTTON_CANCEL;
+						dbg("hp_slot %d button cancel\n", hp_slot);
+					} else if ((p_slot->state == POWERON_STATE)
+						   || (p_slot->state == POWEROFF_STATE)) {
+						//info(msg_button_ignore, p_slot->number);
+						taskInfo->event_type = INT_BUTTON_IGNORE;
+						dbg("hp_slot %d button ignore\n", hp_slot);
+					}
+				}
+			} else {
+				// Switch is open, assume a presence change
+				// Save the presence state
+				temp_word = ctrl->ctrl_int_comp >> 16;
+				func->presence_save = (temp_word >> hp_slot) & 0x01;
+				func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
+
+				if ((!(ctrl->ctrl_int_comp & (0x010000 << hp_slot))) ||
+				    (!(ctrl->ctrl_int_comp & (0x01000000 << hp_slot)))) {
+					//*********************************
+					// Present
+					//*********************************
+					taskInfo->event_type = INT_PRESENCE_ON;
+				} else {
+					//*********************************
+					// Not Present
+					//*********************************
+					taskInfo->event_type = INT_PRESENCE_OFF;
+				}
+			}
+		}
+	}
+
+	return rc;
+}
+
+
+static u8 handle_power_fault(u8 change, struct controller * ctrl)
+{
+	int hp_slot;
+	u8 rc = 0;
+	struct pci_func *func;
+	struct event_info *taskInfo;
+
+	if (!change)
+		return 0;
+
+	//*********************************
+	// power fault
+	//*********************************
+
+	info("power fault interrupt\n");
+
+	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
+		if (change & (0x01 << hp_slot)) {
+			//*********************************
+			// this one changed.
+			//*********************************
+			func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
+
+			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
+			ctrl->next_event = (ctrl->next_event + 1) % 10;
+			taskInfo->hp_slot = hp_slot;
+
+			rc++;
+
+			if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
+				//*********************************
+				// power fault Cleared
+				//*********************************
+				func->status = 0x00;
+
+				taskInfo->event_type = INT_POWER_FAULT_CLEAR;
+			} else {
+				//*********************************
+				// power fault
+				//*********************************
+				taskInfo->event_type = INT_POWER_FAULT;
+
+				if (ctrl->rev < 4) {
+					amber_LED_on (ctrl, hp_slot);
+					green_LED_off (ctrl, hp_slot);
+					set_SOGO (ctrl);
+
+					// this is a fatal condition, we want to crash the
+					// machine to protect from data corruption
+					// simulated_NMI shouldn't ever return
+					//FIXME
+					//simulated_NMI(hp_slot, ctrl);
+
+					//The following code causes a software crash just in
+					//case simulated_NMI did return
+					//FIXME
+					//panic(msg_power_fault);
+				} else {
+					// set power fault status for this board
+					func->status = 0xFF;
+					info("power fault bit %x set\n", hp_slot);
+				}
+			}
+		}
+	}
+
+	return rc;
+}
+
+
+/*
+ * sort_by_size
+ *
+ * Sorts nodes on the list by their length.
+ * Smallest first.
+ *
+ */
+static int sort_by_size(struct pci_resource **head)
+{
+	struct pci_resource *current_res;
+	struct pci_resource *next_res;
+	int out_of_order = 1;
+
+	if (!(*head))
+		return(1);
+
+	if (!((*head)->next))
+		return(0);
+
+	while (out_of_order) {
+		out_of_order = 0;
+
+		// Special case for swapping list head
+		if (((*head)->next) &&
+		    ((*head)->length > (*head)->next->length)) {
+			out_of_order++;
+			current_res = *head;
+			*head = (*head)->next;
+			current_res->next = (*head)->next;
+			(*head)->next = current_res;
+		}
+
+		current_res = *head;
+
+		while (current_res->next && current_res->next->next) {
+			if (current_res->next->length > current_res->next->next->length) {
+				out_of_order++;
+				next_res = current_res->next;
+				current_res->next = current_res->next->next;
+				current_res = current_res->next;
+				next_res->next = current_res->next;
+				current_res->next = next_res;
+			} else
+				current_res = current_res->next;
+		}
+	}  // End of out_of_order loop
+
+	return(0);
+}
+
+
+/*
+ * sort_by_max_size
+ *
+ * Sorts nodes on the list by their length.
+ * Largest first.
+ *
+ */
+static int sort_by_max_size(struct pci_resource **head)
+{
+	struct pci_resource *current_res;
+	struct pci_resource *next_res;
+	int out_of_order = 1;
+
+	if (!(*head))
+		return(1);
+
+	if (!((*head)->next))
+		return(0);
+
+	while (out_of_order) {
+		out_of_order = 0;
+
+		// Special case for swapping list head
+		if (((*head)->next) &&
+		    ((*head)->length < (*head)->next->length)) {
+			out_of_order++;
+			current_res = *head;
+			*head = (*head)->next;
+			current_res->next = (*head)->next;
+			(*head)->next = current_res;
+		}
+
+		current_res = *head;
+
+		while (current_res->next && current_res->next->next) {
+			if (current_res->next->length < current_res->next->next->length) {
+				out_of_order++;
+				next_res = current_res->next;
+				current_res->next = current_res->next->next;
+				current_res = current_res->next;
+				next_res->next = current_res->next;
+				current_res->next = next_res;
+			} else
+				current_res = current_res->next;
+		}
+	}  // End of out_of_order loop
+
+	return(0);
+}
+
+
+/*
+ * do_pre_bridge_resource_split
+ *
+ *	Returns zero or one node of resources that aren't in use
+ *
+ */
+static struct pci_resource *do_pre_bridge_resource_split (struct pci_resource **head, struct pci_resource **orig_head, u32 alignment)
+{
+	struct pci_resource *prevnode = NULL;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u32 rc;
+	u32 temp_dword;
+	dbg("do_pre_bridge_resource_split\n");
+
+	if (!(*head) || !(*orig_head))
+		return(NULL);
+
+	rc = cpqhp_resource_sort_and_combine(head);
+
+	if (rc)
+		return(NULL);
+
+	if ((*head)->base != (*orig_head)->base)
+		return(NULL);
+
+	if ((*head)->length == (*orig_head)->length)
+		return(NULL);
+
+
+	// If we got here, there the bridge requires some of the resource, but
+	// we may be able to split some off of the front
+
+	node = *head;
+
+	if (node->length & (alignment -1)) {
+		// this one isn't an aligned length, so we'll make a new entry
+		// and split it up.
+		split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+		if (!split_node)
+			return(NULL);
+
+		temp_dword = (node->length | (alignment-1)) + 1 - alignment;
+
+		split_node->base = node->base;
+		split_node->length = temp_dword;
+
+		node->length -= temp_dword;
+		node->base += split_node->length;
+
+		// Put it in the list
+		*head = split_node;
+		split_node->next = node;
+	}
+
+	if (node->length < alignment) {
+		return(NULL);
+	}
+
+	// Now unlink it
+	if (*head == node) {
+		*head = node->next;
+		node->next = NULL;
+	} else {
+		prevnode = *head;
+		while (prevnode->next != node)
+			prevnode = prevnode->next;
+
+		prevnode->next = node->next;
+		node->next = NULL;
+	}
+
+	return(node);
+}
+
+
+/*
+ * do_bridge_resource_split
+ *
+ *	Returns zero or one node of resources that aren't in use
+ *
+ */
+static struct pci_resource *do_bridge_resource_split (struct pci_resource **head, u32 alignment)
+{
+	struct pci_resource *prevnode = NULL;
+	struct pci_resource *node;
+	u32 rc;
+	u32 temp_dword;
+
+	if (!(*head))
+		return(NULL);
+
+	rc = cpqhp_resource_sort_and_combine(head);
+
+	if (rc)
+		return(NULL);
+
+	node = *head;
+
+	while (node->next) {
+		prevnode = node;
+		node = node->next;
+		kfree(prevnode);
+	}
+
+	if (node->length < alignment) {
+		kfree(node);
+		return(NULL);
+	}
+
+	if (node->base & (alignment - 1)) {
+		// Short circuit if adjusted size is too small
+		temp_dword = (node->base | (alignment-1)) + 1;
+		if ((node->length - (temp_dword - node->base)) < alignment) {
+			kfree(node);
+			return(NULL);
+		}
+
+		node->length -= (temp_dword - node->base);
+		node->base = temp_dword;
+	}
+
+	if (node->length & (alignment - 1)) {
+		// There's stuff in use after this node
+		kfree(node);
+		return(NULL);
+	}
+
+	return(node);
+}
+
+
+/*
+ * get_io_resource
+ *
+ * this function sorts the resource list by size and then
+ * returns the first node of "size" length that is not in the
+ * ISA aliasing window.  If it finds a node larger than "size"
+ * it will split it up.
+ *
+ * size must be a power of two.
+ */
+static struct pci_resource *get_io_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *prevnode;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u32 temp_dword;
+
+	if (!(*head))
+		return(NULL);
+
+	if ( cpqhp_resource_sort_and_combine(head) )
+		return(NULL);
+
+	if ( sort_by_size(head) )
+		return(NULL);
+
+	for (node = *head; node; node = node->next) {
+		if (node->length < size)
+			continue;
+
+		if (node->base & (size - 1)) {
+			// this one isn't base aligned properly
+			// so we'll make a new entry and split it up
+			temp_dword = (node->base | (size-1)) + 1;
+
+			// Short circuit if adjusted size is too small
+			if ((node->length - (temp_dword - node->base)) < size)
+				continue;
+
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base;
+			split_node->length = temp_dword - node->base;
+			node->base = temp_dword;
+			node->length -= split_node->length;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		} // End of non-aligned base
+
+		// Don't need to check if too small since we already did
+		if (node->length > size) {
+			// this one is longer than we need
+			// so we'll make a new entry and split it up
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base + size;
+			split_node->length = node->length - size;
+			node->length = size;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		}  // End of too big on top end
+
+		// For IO make sure it's not in the ISA aliasing space
+		if (node->base & 0x300L)
+			continue;
+
+		// If we got here, then it is the right size
+		// Now take it out of the list
+		if (*head == node) {
+			*head = node->next;
+		} else {
+			prevnode = *head;
+			while (prevnode->next != node)
+				prevnode = prevnode->next;
+
+			prevnode->next = node->next;
+		}
+		node->next = NULL;
+		// Stop looping
+		break;
+	}
+
+	return(node);
+}
+
+
+/*
+ * get_max_resource
+ *
+ * Gets the largest node that is at least "size" big from the
+ * list pointed to by head.  It aligns the node on top and bottom
+ * to "size" alignment before returning it.
+ */
+static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *max;
+	struct pci_resource *temp;
+	struct pci_resource *split_node;
+	u32 temp_dword;
+
+	if (!(*head))
+		return(NULL);
+
+	if (cpqhp_resource_sort_and_combine(head))
+		return(NULL);
+
+	if (sort_by_max_size(head))
+		return(NULL);
+
+	for (max = *head;max; max = max->next) {
+
+		// If not big enough we could probably just bail, 
+		// instead we'll continue to the next.
+		if (max->length < size)
+			continue;
+
+		if (max->base & (size - 1)) {
+			// this one isn't base aligned properly
+			// so we'll make a new entry and split it up
+			temp_dword = (max->base | (size-1)) + 1;
+
+			// Short circuit if adjusted size is too small
+			if ((max->length - (temp_dword - max->base)) < size)
+				continue;
+
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = max->base;
+			split_node->length = temp_dword - max->base;
+			max->base = temp_dword;
+			max->length -= split_node->length;
+
+			// Put it next in the list
+			split_node->next = max->next;
+			max->next = split_node;
+		}
+
+		if ((max->base + max->length) & (size - 1)) {
+			// this one isn't end aligned properly at the top
+			// so we'll make a new entry and split it up
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+			temp_dword = ((max->base + max->length) & ~(size - 1));
+			split_node->base = temp_dword;
+			split_node->length = max->length + max->base
+					     - split_node->base;
+			max->length -= split_node->length;
+
+			// Put it in the list
+			split_node->next = max->next;
+			max->next = split_node;
+		}
+
+		// Make sure it didn't shrink too much when we aligned it
+		if (max->length < size)
+			continue;
+
+		// Now take it out of the list
+		temp = (struct pci_resource*) *head;
+		if (temp == max) {
+			*head = max->next;
+		} else {
+			while (temp && temp->next != max) {
+				temp = temp->next;
+			}
+
+			temp->next = max->next;
+		}
+
+		max->next = NULL;
+		return(max);
+	}
+
+	// If we get here, we couldn't find one
+	return(NULL);
+}
+
+
+/*
+ * get_resource
+ *
+ * this function sorts the resource list by size and then
+ * returns the first node of "size" length.  If it finds a node
+ * larger than "size" it will split it up.
+ *
+ * size must be a power of two.
+ */
+static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
+{
+	struct pci_resource *prevnode;
+	struct pci_resource *node;
+	struct pci_resource *split_node;
+	u32 temp_dword;
+
+	if (!(*head))
+		return(NULL);
+
+	if ( cpqhp_resource_sort_and_combine(head) )
+		return(NULL);
+
+	if ( sort_by_size(head) )
+		return(NULL);
+
+	for (node = *head; node; node = node->next) {
+		dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
+		    __FUNCTION__, size, node, node->base, node->length);
+		if (node->length < size)
+			continue;
+
+		if (node->base & (size - 1)) {
+			dbg("%s: not aligned\n", __FUNCTION__);
+			// this one isn't base aligned properly
+			// so we'll make a new entry and split it up
+			temp_dword = (node->base | (size-1)) + 1;
+
+			// Short circuit if adjusted size is too small
+			if ((node->length - (temp_dword - node->base)) < size)
+				continue;
+
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base;
+			split_node->length = temp_dword - node->base;
+			node->base = temp_dword;
+			node->length -= split_node->length;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		} // End of non-aligned base
+
+		// Don't need to check if too small since we already did
+		if (node->length > size) {
+			dbg("%s: too big\n", __FUNCTION__);
+			// this one is longer than we need
+			// so we'll make a new entry and split it up
+			split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!split_node)
+				return(NULL);
+
+			split_node->base = node->base + size;
+			split_node->length = node->length - size;
+			node->length = size;
+
+			// Put it in the list
+			split_node->next = node->next;
+			node->next = split_node;
+		}  // End of too big on top end
+
+		dbg("%s: got one!!!\n", __FUNCTION__);
+		// If we got here, then it is the right size
+		// Now take it out of the list
+		if (*head == node) {
+			*head = node->next;
+		} else {
+			prevnode = *head;
+			while (prevnode->next != node)
+				prevnode = prevnode->next;
+
+			prevnode->next = node->next;
+		}
+		node->next = NULL;
+		// Stop looping
+		break;
+	}
+	return(node);
+}
+
+
+/*
+ * cpqhp_resource_sort_and_combine
+ *
+ * Sorts all of the nodes in the list in ascending order by
+ * their base addresses.  Also does garbage collection by
+ * combining adjacent nodes.
+ *
+ * returns 0 if success
+ */
+int cpqhp_resource_sort_and_combine(struct pci_resource **head)
+{
+	struct pci_resource *node1;
+	struct pci_resource *node2;
+	int out_of_order = 1;
+
+	dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
+
+	if (!(*head))
+		return(1);
+
+	dbg("*head->next = %p\n",(*head)->next);
+
+	if (!(*head)->next)
+		return(0);	/* only one item on the list, already sorted! */
+
+	dbg("*head->base = 0x%x\n",(*head)->base);
+	dbg("*head->next->base = 0x%x\n",(*head)->next->base);
+	while (out_of_order) {
+		out_of_order = 0;
+
+		// Special case for swapping list head
+		if (((*head)->next) &&
+		    ((*head)->base > (*head)->next->base)) {
+			node1 = *head;
+			(*head) = (*head)->next;
+			node1->next = (*head)->next;
+			(*head)->next = node1;
+			out_of_order++;
+		}
+
+		node1 = (*head);
+
+		while (node1->next && node1->next->next) {
+			if (node1->next->base > node1->next->next->base) {
+				out_of_order++;
+				node2 = node1->next;
+				node1->next = node1->next->next;
+				node1 = node1->next;
+				node2->next = node1->next;
+				node1->next = node2;
+			} else
+				node1 = node1->next;
+		}
+	}  // End of out_of_order loop
+
+	node1 = *head;
+
+	while (node1 && node1->next) {
+		if ((node1->base + node1->length) == node1->next->base) {
+			// Combine
+			dbg("8..\n");
+			node1->length += node1->next->length;
+			node2 = node1->next;
+			node1->next = node1->next->next;
+			kfree(node2);
+		} else
+			node1 = node1->next;
+	}
+
+	return(0);
+}
+
+
+irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs)
+{
+	struct controller *ctrl = data;
+	u8 schedule_flag = 0;
+	u8 reset;
+	u16 misc;
+	u32 Diff;
+	u32 temp_dword;
+
+	
+	misc = readw(ctrl->hpc_reg + MISC);
+	//*********************************
+	// Check to see if it was our interrupt
+	//*********************************
+	if (!(misc & 0x000C)) {
+		return IRQ_NONE;
+	}
+
+	if (misc & 0x0004) {
+		//*********************************
+		// Serial Output interrupt Pending
+		//*********************************
+
+		// Clear the interrupt
+		misc |= 0x0004;
+		writew(misc, ctrl->hpc_reg + MISC);
+
+		// Read to clear posted writes
+		misc = readw(ctrl->hpc_reg + MISC);
+
+		dbg ("%s - waking up\n", __FUNCTION__);
+		wake_up_interruptible(&ctrl->queue);
+	}
+
+	if (misc & 0x0008) {
+		// General-interrupt-input interrupt Pending
+		Diff = readl(ctrl->hpc_reg + INT_INPUT_CLEAR) ^ ctrl->ctrl_int_comp;
+
+		ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
+
+		// Clear the interrupt
+		writel(Diff, ctrl->hpc_reg + INT_INPUT_CLEAR);
+
+		// Read it back to clear any posted writes
+		temp_dword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
+
+		if (!Diff) {
+			// Clear all interrupts
+			writel(0xFFFFFFFF, ctrl->hpc_reg + INT_INPUT_CLEAR);
+		}
+
+		schedule_flag += handle_switch_change((u8)(Diff & 0xFFL), ctrl);
+		schedule_flag += handle_presence_change((u16)((Diff & 0xFFFF0000L) >> 16), ctrl);
+		schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);
+	}
+
+	reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
+	if (reset & 0x40) {
+		/* Bus reset has completed */
+		reset &= 0xCF;
+		writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);
+		reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
+		wake_up_interruptible(&ctrl->queue);
+	}
+
+	if (schedule_flag) {
+		up(&event_semaphore);
+		dbg("Signal event_semaphore\n");
+	}
+	return IRQ_HANDLED;
+}
+
+
+/**
+ * cpqhp_slot_create - Creates a node and adds it to the proper bus.
+ * @busnumber - bus where new node is to be located
+ *
+ * Returns pointer to the new node or NULL if unsuccessful
+ */
+struct pci_func *cpqhp_slot_create(u8 busnumber)
+{
+	struct pci_func *new_slot;
+	struct pci_func *next;
+
+	new_slot = (struct pci_func *) kmalloc(sizeof(struct pci_func), GFP_KERNEL);
+
+	if (new_slot == NULL) {
+		// I'm not dead yet!
+		// You will be.
+		return(new_slot);
+	}
+
+	memset(new_slot, 0, sizeof(struct pci_func));
+
+	new_slot->next = NULL;
+	new_slot->configured = 1;
+
+	if (cpqhp_slot_list[busnumber] == NULL) {
+		cpqhp_slot_list[busnumber] = new_slot;
+	} else {
+		next = cpqhp_slot_list[busnumber];
+		while (next->next != NULL)
+			next = next->next;
+		next->next = new_slot;
+	}
+	return(new_slot);
+}
+
+
+/*
+ * slot_remove - Removes a node from the linked list of slots.
+ * @old_slot: slot to remove
+ *
+ * Returns 0 if successful, !0 otherwise.
+ */
+static int slot_remove(struct pci_func * old_slot)
+{
+	struct pci_func *next;
+
+	if (old_slot == NULL)
+		return(1);
+
+	next = cpqhp_slot_list[old_slot->bus];
+
+	if (next == NULL) {
+		return(1);
+	}
+
+	if (next == old_slot) {
+		cpqhp_slot_list[old_slot->bus] = old_slot->next;
+		cpqhp_destroy_board_resources(old_slot);
+		kfree(old_slot);
+		return(0);
+	}
+
+	while ((next->next != old_slot) && (next->next != NULL)) {
+		next = next->next;
+	}
+
+	if (next->next == old_slot) {
+		next->next = old_slot->next;
+		cpqhp_destroy_board_resources(old_slot);
+		kfree(old_slot);
+		return(0);
+	} else
+		return(2);
+}
+
+
+/**
+ * bridge_slot_remove - Removes a node from the linked list of slots.
+ * @bridge: bridge to remove
+ *
+ * Returns 0 if successful, !0 otherwise.
+ */
+static int bridge_slot_remove(struct pci_func *bridge)
+{
+	u8 subordinateBus, secondaryBus;
+	u8 tempBus;
+	struct pci_func *next;
+
+	if (bridge == NULL)
+		return(1);
+
+	secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
+	subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
+
+	for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
+		next = cpqhp_slot_list[tempBus];
+
+		while (!slot_remove(next)) {
+			next = cpqhp_slot_list[tempBus];
+		}
+	}
+
+	next = cpqhp_slot_list[bridge->bus];
+
+	if (next == NULL) {
+		return(1);
+	}
+
+	if (next == bridge) {
+		cpqhp_slot_list[bridge->bus] = bridge->next;
+		kfree(bridge);
+		return(0);
+	}
+
+	while ((next->next != bridge) && (next->next != NULL)) {
+		next = next->next;
+	}
+
+	if (next->next == bridge) {
+		next->next = bridge->next;
+		kfree(bridge);
+		return(0);
+	} else
+		return(2);
+}
+
+
+/**
+ * cpqhp_slot_find - Looks for a node by bus, and device, multiple functions accessed
+ * @bus: bus to find
+ * @device: device to find
+ * @index: is 0 for first function found, 1 for the second...
+ *
+ * Returns pointer to the node if successful, %NULL otherwise.
+ */
+struct pci_func *cpqhp_slot_find(u8 bus, u8 device, u8 index)
+{
+	int found = -1;
+	struct pci_func *func;
+
+	func = cpqhp_slot_list[bus];
+
+	if ((func == NULL) || ((func->device == device) && (index == 0)))
+		return(func);
+
+	if (func->device == device)
+		found++;
+
+	while (func->next != NULL) {
+		func = func->next;
+
+		if (func->device == device)
+			found++;
+
+		if (found == index)
+			return(func);
+	}
+
+	return(NULL);
+}
+
+
+// DJZ: I don't think is_bridge will work as is.
+//FIXME
+static int is_bridge(struct pci_func * func)
+{
+	// Check the header type
+	if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
+		return 1;
+	else
+		return 0;
+}
+
+
+/* the following routines constitute the bulk of the 
+   hotplug controller logic
+ */
+
+
+/**
+ * board_replaced - Called after a board has been replaced in the system.
+ *
+ * This is only used if we don't have resources for hot add
+ * Turns power on for the board
+ * Checks to see if board is the same
+ * If board is same, reconfigures it
+ * If board isn't same, turns it back off.
+ *
+ */
+static u32 board_replaced(struct pci_func * func, struct controller * ctrl)
+{
+	u8 hp_slot;
+	u8 temp_byte;
+	u8 adapter_speed;
+	u32 index;
+	u32 rc = 0;
+	u32 src = 8;
+
+	hp_slot = func->device - ctrl->slot_device_offset;
+
+	if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {
+		//*********************************
+		// The switch is open.
+		//*********************************
+		rc = INTERLOCK_OPEN;
+	} else if (is_slot_enabled (ctrl, hp_slot)) {
+		//*********************************
+		// The board is already on
+		//*********************************
+		rc = CARD_FUNCTIONING;
+	} else {
+		// Wait for exclusive access to hardware
+		down(&ctrl->crit_sect);
+
+		// turn on board without attaching to the bus
+		enable_slot_power (ctrl, hp_slot);
+
+		set_SOGO(ctrl);
+
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
+
+		// Change bits in slot power register to force another shift out
+		// NOTE: this is to work around the timer bug
+		temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
+		writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
+		writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
+
+		set_SOGO(ctrl);
+
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
+		
+		adapter_speed = get_adapter_speed(ctrl, hp_slot);
+		if (ctrl->speed != adapter_speed)
+			if (set_controller_speed(ctrl, adapter_speed, hp_slot))
+				rc = WRONG_BUS_FREQUENCY;
+
+		// turn off board without attaching to the bus
+		disable_slot_power (ctrl, hp_slot);
+
+		set_SOGO(ctrl);
+
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
+
+		// Done with exclusive hardware access
+		up(&ctrl->crit_sect);
+
+		if (rc)
+			return(rc);
+
+		// Wait for exclusive access to hardware
+		down(&ctrl->crit_sect);
+
+		slot_enable (ctrl, hp_slot);
+		green_LED_blink (ctrl, hp_slot);
+
+		amber_LED_off (ctrl, hp_slot);
+
+		set_SOGO(ctrl);
+
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
+
+		// Done with exclusive hardware access
+		up(&ctrl->crit_sect);
+
+		// Wait for ~1 second because of hot plug spec
+		long_delay(1*HZ);
+
+		// Check for a power fault
+		if (func->status == 0xFF) {
+			// power fault occurred, but it was benign
+			rc = POWER_FAILURE;
+			func->status = 0;
+		} else
+			rc = cpqhp_valid_replace(ctrl, func);
+
+		if (!rc) {
+			// It must be the same board
+
+			rc = cpqhp_configure_board(ctrl, func);
+
+			if (rc || src) {
+				// If configuration fails, turn it off
+				// Get slot won't work for devices behind bridges, but
+				// in this case it will always be called for the "base"
+				// bus/dev/func of an adapter.
+
+				// Wait for exclusive access to hardware
+				down(&ctrl->crit_sect);
+
+				amber_LED_on (ctrl, hp_slot);
+				green_LED_off (ctrl, hp_slot);
+				slot_disable (ctrl, hp_slot);
+
+				set_SOGO(ctrl);
+
+				// Wait for SOBS to be unset
+				wait_for_ctrl_irq (ctrl);
+
+				// Done with exclusive hardware access
+				up(&ctrl->crit_sect);
+
+				if (rc)
+					return(rc);
+				else
+					return(1);
+			}
+
+			func->status = 0;
+			func->switch_save = 0x10;
+
+			index = 1;
+			while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
+				rc |= cpqhp_configure_board(ctrl, func);
+				index++;
+			}
+
+			if (rc) {
+				// If configuration fails, turn it off
+				// Get slot won't work for devices behind bridges, but
+				// in this case it will always be called for the "base"
+				// bus/dev/func of an adapter.
+
+				// Wait for exclusive access to hardware
+				down(&ctrl->crit_sect);
+
+				amber_LED_on (ctrl, hp_slot);
+				green_LED_off (ctrl, hp_slot);
+				slot_disable (ctrl, hp_slot);
+
+				set_SOGO(ctrl);
+
+				// Wait for SOBS to be unset
+				wait_for_ctrl_irq (ctrl);
+
+				// Done with exclusive hardware access
+				up(&ctrl->crit_sect);
+
+				return(rc);
+			}
+			// Done configuring so turn LED on full time
+
+			// Wait for exclusive access to hardware
+			down(&ctrl->crit_sect);
+
+			green_LED_on (ctrl, hp_slot);
+
+			set_SOGO(ctrl);
+
+			// Wait for SOBS to be unset
+			wait_for_ctrl_irq (ctrl);
+
+			// Done with exclusive hardware access
+			up(&ctrl->crit_sect);
+			rc = 0;
+		} else {
+			// Something is wrong
+
+			// Get slot won't work for devices behind bridges, but
+			// in this case it will always be called for the "base"
+			// bus/dev/func of an adapter.
+
+			// Wait for exclusive access to hardware
+			down(&ctrl->crit_sect);
+
+			amber_LED_on (ctrl, hp_slot);
+			green_LED_off (ctrl, hp_slot);
+			slot_disable (ctrl, hp_slot);
+
+			set_SOGO(ctrl);
+
+			// Wait for SOBS to be unset
+			wait_for_ctrl_irq (ctrl);
+
+			// Done with exclusive hardware access
+			up(&ctrl->crit_sect);
+		}
+
+	}
+	return(rc);
+
+}
+
+
+/**
+ * board_added - Called after a board has been added to the system.
+ *
+ * Turns power on for the board
+ * Configures board
+ *
+ */
+static u32 board_added(struct pci_func * func, struct controller * ctrl)
+{
+	u8 hp_slot;
+	u8 temp_byte;
+	u8 adapter_speed;
+	int index;
+	u32 temp_register = 0xFFFFFFFF;
+	u32 rc = 0;
+	struct pci_func *new_slot = NULL;
+	struct slot *p_slot;
+	struct resource_lists res_lists;
+
+	hp_slot = func->device - ctrl->slot_device_offset;
+	dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
+	    __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
+
+	// Wait for exclusive access to hardware
+	down(&ctrl->crit_sect);
+
+	// turn on board without attaching to the bus
+	enable_slot_power (ctrl, hp_slot);
+
+	set_SOGO(ctrl);
+
+	// Wait for SOBS to be unset
+	wait_for_ctrl_irq (ctrl);
+
+	// Change bits in slot power register to force another shift out
+	// NOTE: this is to work around the timer bug
+	temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
+	writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
+	writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
+
+	set_SOGO(ctrl);
+
+	// Wait for SOBS to be unset
+	wait_for_ctrl_irq (ctrl);
+	
+	adapter_speed = get_adapter_speed(ctrl, hp_slot);
+	if (ctrl->speed != adapter_speed)
+		if (set_controller_speed(ctrl, adapter_speed, hp_slot))
+			rc = WRONG_BUS_FREQUENCY;
+	
+	// turn off board without attaching to the bus
+	disable_slot_power (ctrl, hp_slot);
+
+	set_SOGO(ctrl);
+
+	// Wait for SOBS to be unset
+	wait_for_ctrl_irq (ctrl);
+
+	// Done with exclusive hardware access
+	up(&ctrl->crit_sect);
+
+	if (rc)
+		return(rc);
+	
+	p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+
+	// turn on board and blink green LED
+
+	// Wait for exclusive access to hardware
+	dbg("%s: before down\n", __FUNCTION__);
+	down(&ctrl->crit_sect);
+	dbg("%s: after down\n", __FUNCTION__);
+
+	dbg("%s: before slot_enable\n", __FUNCTION__);
+	slot_enable (ctrl, hp_slot);
+
+	dbg("%s: before green_LED_blink\n", __FUNCTION__);
+	green_LED_blink (ctrl, hp_slot);
+
+	dbg("%s: before amber_LED_blink\n", __FUNCTION__);
+	amber_LED_off (ctrl, hp_slot);
+
+	dbg("%s: before set_SOGO\n", __FUNCTION__);
+	set_SOGO(ctrl);
+
+	// Wait for SOBS to be unset
+	dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__);
+	wait_for_ctrl_irq (ctrl);
+	dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
+
+	// Done with exclusive hardware access
+	dbg("%s: before up\n", __FUNCTION__);
+	up(&ctrl->crit_sect);
+	dbg("%s: after up\n", __FUNCTION__);
+
+	// Wait for ~1 second because of hot plug spec
+	dbg("%s: before long_delay\n", __FUNCTION__);
+	long_delay(1*HZ);
+	dbg("%s: after long_delay\n", __FUNCTION__);
+
+	dbg("%s: func status = %x\n", __FUNCTION__, func->status);
+	// Check for a power fault
+	if (func->status == 0xFF) {
+		// power fault occurred, but it was benign
+		temp_register = 0xFFFFFFFF;
+		dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
+		rc = POWER_FAILURE;
+		func->status = 0;
+	} else {
+		// Get vendor/device ID u32
+		ctrl->pci_bus->number = func->bus;
+		rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
+		dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc);
+		dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
+
+		if (rc != 0) {
+			// Something's wrong here
+			temp_register = 0xFFFFFFFF;
+			dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
+		}
+		// Preset return code.  It will be changed later if things go okay.
+		rc = NO_ADAPTER_PRESENT;
+	}
+
+	// All F's is an empty slot or an invalid board
+	if (temp_register != 0xFFFFFFFF) {	  // Check for a board in the slot
+		res_lists.io_head = ctrl->io_head;
+		res_lists.mem_head = ctrl->mem_head;
+		res_lists.p_mem_head = ctrl->p_mem_head;
+		res_lists.bus_head = ctrl->bus_head;
+		res_lists.irqs = NULL;
+
+		rc = configure_new_device(ctrl, func, 0, &res_lists);
+
+		dbg("%s: back from configure_new_device\n", __FUNCTION__);
+		ctrl->io_head = res_lists.io_head;
+		ctrl->mem_head = res_lists.mem_head;
+		ctrl->p_mem_head = res_lists.p_mem_head;
+		ctrl->bus_head = res_lists.bus_head;
+
+		cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
+		cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
+		cpqhp_resource_sort_and_combine(&(ctrl->io_head));
+		cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
+
+		if (rc) {
+			// Wait for exclusive access to hardware
+			down(&ctrl->crit_sect);
+
+			amber_LED_on (ctrl, hp_slot);
+			green_LED_off (ctrl, hp_slot);
+			slot_disable (ctrl, hp_slot);
+
+			set_SOGO(ctrl);
+
+			// Wait for SOBS to be unset
+			wait_for_ctrl_irq (ctrl);
+
+			// Done with exclusive hardware access
+			up(&ctrl->crit_sect);
+			return(rc);
+		} else {
+			cpqhp_save_slot_config(ctrl, func);
+		}
+
+
+		func->status = 0;
+		func->switch_save = 0x10;
+		func->is_a_board = 0x01;
+
+		//next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present)
+		dbg("%s: configure linux pci_dev structure\n", __FUNCTION__);
+		index = 0;
+		do {
+			new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
+			if (new_slot && !new_slot->pci_dev) {
+				cpqhp_configure_device(ctrl, new_slot);
+			}
+		} while (new_slot);
+
+		// Wait for exclusive access to hardware
+		down(&ctrl->crit_sect);
+
+		green_LED_on (ctrl, hp_slot);
+
+		set_SOGO(ctrl);
+
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
+
+		// Done with exclusive hardware access
+		up(&ctrl->crit_sect);
+	} else {
+		// Wait for exclusive access to hardware
+		down(&ctrl->crit_sect);
+
+		amber_LED_on (ctrl, hp_slot);
+		green_LED_off (ctrl, hp_slot);
+		slot_disable (ctrl, hp_slot);
+
+		set_SOGO(ctrl);
+
+		// Wait for SOBS to be unset
+		wait_for_ctrl_irq (ctrl);
+
+		// Done with exclusive hardware access
+		up(&ctrl->crit_sect);
+
+		return(rc);
+	}
+	return 0;
+}
+
+
+/**
+ * remove_board - Turns off slot and LED's
+ *
+ */
+static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl)
+{
+	int index;
+	u8 skip = 0;
+	u8 device;
+	u8 hp_slot;
+	u8 temp_byte;
+	u32 rc;
+	struct resource_lists res_lists;
+	struct pci_func *temp_func;
+
+	if (func == NULL)
+		return(1);
+
+	if (cpqhp_unconfigure_device(func))
+		return(1);
+
+	device = func->device;
+
+	hp_slot = func->device - ctrl->slot_device_offset;
+	dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
+
+	// When we get here, it is safe to change base Address Registers.
+	// We will attempt to save the base Address Register Lengths
+	if (replace_flag || !ctrl->add_support)
+		rc = cpqhp_save_base_addr_length(ctrl, func);
+	else if (!func->bus_head && !func->mem_head &&
+		 !func->p_mem_head && !func->io_head) {
+		// Here we check to see if we've saved any of the board's
+		// resources already.  If so, we'll skip the attempt to
+		// determine what's being used.
+		index = 0;
+		temp_func = cpqhp_slot_find(func->bus, func->device, index++);
+		while (temp_func) {
+			if (temp_func->bus_head || temp_func->mem_head
+			    || temp_func->p_mem_head || temp_func->io_head) {
+				skip = 1;
+				break;
+			}
+			temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++);
+		}
+
+		if (!skip)
+			rc = cpqhp_save_used_resources(ctrl, func);
+	}
+	// Change status to shutdown
+	if (func->is_a_board)
+		func->status = 0x01;
+	func->configured = 0;
+
+	// Wait for exclusive access to hardware
+	down(&ctrl->crit_sect);
+
+	green_LED_off (ctrl, hp_slot);
+	slot_disable (ctrl, hp_slot);
+
+	set_SOGO(ctrl);
+
+	// turn off SERR for slot
+	temp_byte = readb(ctrl->hpc_reg + SLOT_SERR);
+	temp_byte &= ~(0x01 << hp_slot);
+	writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);
+
+	// Wait for SOBS to be unset
+	wait_for_ctrl_irq (ctrl);
+
+	// Done with exclusive hardware access
+	up(&ctrl->crit_sect);
+
+	if (!replace_flag && ctrl->add_support) {
+		while (func) {
+			res_lists.io_head = ctrl->io_head;
+			res_lists.mem_head = ctrl->mem_head;
+			res_lists.p_mem_head = ctrl->p_mem_head;
+			res_lists.bus_head = ctrl->bus_head;
+
+			cpqhp_return_board_resources(func, &res_lists);
+
+			ctrl->io_head = res_lists.io_head;
+			ctrl->mem_head = res_lists.mem_head;
+			ctrl->p_mem_head = res_lists.p_mem_head;
+			ctrl->bus_head = res_lists.bus_head;
+
+			cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
+			cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
+			cpqhp_resource_sort_and_combine(&(ctrl->io_head));
+			cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
+
+			if (is_bridge(func)) {
+				bridge_slot_remove(func);
+			} else
+				slot_remove(func);
+
+			func = cpqhp_slot_find(ctrl->bus, device, 0);
+		}
+
+		// Setup slot structure with entry for empty slot
+		func = cpqhp_slot_create(ctrl->bus);
+
+		if (func == NULL) {
+			// Out of memory
+			return(1);
+		}
+
+		func->bus = ctrl->bus;
+		func->device = device;
+		func->function = 0;
+		func->configured = 0;
+		func->switch_save = 0x10;
+		func->is_a_board = 0;
+		func->p_task_event = NULL;
+	}
+
+	return 0;
+}
+
+
+static void pushbutton_helper_thread (unsigned long data)
+{
+	pushbutton_pending = data;
+	up(&event_semaphore);
+}
+
+
+// this is the main worker thread
+static int event_thread(void* data)
+{
+	struct controller *ctrl;
+	lock_kernel();
+	daemonize("phpd_event");
+	
+	unlock_kernel();
+
+	while (1) {
+		dbg("!!!!event_thread sleeping\n");
+		down_interruptible (&event_semaphore);
+		dbg("event_thread woken finished = %d\n", event_finished);
+		if (event_finished) break;
+		/* Do stuff here */
+		if (pushbutton_pending)
+			cpqhp_pushbutton_thread(pushbutton_pending);
+		else
+			for (ctrl = cpqhp_ctrl_list; ctrl; ctrl=ctrl->next)
+				interrupt_event_handler(ctrl);
+	}
+	dbg("event_thread signals exit\n");
+	up(&event_exit);
+	return 0;
+}
+
+
+int cpqhp_event_start_thread (void)
+{
+	int pid;
+
+	/* initialize our semaphores */
+	init_MUTEX(&delay_sem);
+	init_MUTEX_LOCKED(&event_semaphore);
+	init_MUTEX_LOCKED(&event_exit);
+	event_finished=0;
+
+	pid = kernel_thread(event_thread, 0, 0);
+	if (pid < 0) {
+		err ("Can't start up our event thread\n");
+		return -1;
+	}
+	dbg("Our event thread pid = %d\n", pid);
+	return 0;
+}
+
+
+void cpqhp_event_stop_thread (void)
+{
+	event_finished = 1;
+	dbg("event_thread finish command given\n");
+	up(&event_semaphore);
+	dbg("wait for event_thread to exit\n");
+	down(&event_exit);
+}
+
+
+static int update_slot_info (struct controller *ctrl, struct slot *slot)
+{
+	struct hotplug_slot_info *info;
+	int result;
+
+	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->power_status = get_slot_enabled(ctrl, slot);
+	info->attention_status = cpq_get_attention_status(ctrl, slot);
+	info->latch_status = cpq_get_latch_status(ctrl, slot);
+	info->adapter_status = get_presence_status(ctrl, slot);
+	result = pci_hp_change_slot_info(slot->hotplug_slot, info);
+	kfree (info);
+	return result;
+}
+
+static void interrupt_event_handler(struct controller *ctrl)
+{
+	int loop = 0;
+	int change = 1;
+	struct pci_func *func;
+	u8 hp_slot;
+	struct slot *p_slot;
+
+	while (change) {
+		change = 0;
+
+		for (loop = 0; loop < 10; loop++) {
+			//dbg("loop %d\n", loop);
+			if (ctrl->event_queue[loop].event_type != 0) {
+				hp_slot = ctrl->event_queue[loop].hp_slot;
+
+				func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
+				if (!func)
+					return;
+
+				p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+				if (!p_slot)
+					return;
+
+				dbg("hp_slot %d, func %p, p_slot %p\n",
+				    hp_slot, func, p_slot);
+
+				if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
+					dbg("button pressed\n");
+				} else if (ctrl->event_queue[loop].event_type == 
+					   INT_BUTTON_CANCEL) {
+					dbg("button cancel\n");
+					del_timer(&p_slot->task_event);
+
+					// Wait for exclusive access to hardware
+					down(&ctrl->crit_sect);
+
+					if (p_slot->state == BLINKINGOFF_STATE) {
+						// slot is on
+						// turn on green LED
+						dbg("turn on green LED\n");
+						green_LED_on (ctrl, hp_slot);
+					} else if (p_slot->state == BLINKINGON_STATE) {
+						// slot is off
+						// turn off green LED
+						dbg("turn off green LED\n");
+						green_LED_off (ctrl, hp_slot);
+					}
+
+					info(msg_button_cancel, p_slot->number);
+
+					p_slot->state = STATIC_STATE;
+
+					amber_LED_off (ctrl, hp_slot);
+
+					set_SOGO(ctrl);
+
+					// Wait for SOBS to be unset
+					wait_for_ctrl_irq (ctrl);
+
+					// Done with exclusive hardware access
+					up(&ctrl->crit_sect);
+				}
+				// ***********button Released (No action on press...)
+				else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
+					dbg("button release\n");
+
+					if (is_slot_enabled (ctrl, hp_slot)) {
+						// slot is on
+						dbg("slot is on\n");
+						p_slot->state = BLINKINGOFF_STATE;
+						info(msg_button_off, p_slot->number);
+					} else {
+						// slot is off
+						dbg("slot is off\n");
+						p_slot->state = BLINKINGON_STATE;
+						info(msg_button_on, p_slot->number);
+					}
+					// Wait for exclusive access to hardware
+					down(&ctrl->crit_sect);
+					
+					dbg("blink green LED and turn off amber\n");
+					
+					amber_LED_off (ctrl, hp_slot);
+					green_LED_blink (ctrl, hp_slot);
+					
+					set_SOGO(ctrl);
+
+					// Wait for SOBS to be unset
+					wait_for_ctrl_irq (ctrl);
+
+					// Done with exclusive hardware access
+					up(&ctrl->crit_sect);
+					init_timer(&p_slot->task_event);
+					p_slot->hp_slot = hp_slot;
+					p_slot->ctrl = ctrl;
+//					p_slot->physical_slot = physical_slot;
+					p_slot->task_event.expires = jiffies + 5 * HZ;   // 5 second delay
+					p_slot->task_event.function = pushbutton_helper_thread;
+					p_slot->task_event.data = (u32) p_slot;
+
+					dbg("add_timer p_slot = %p\n", p_slot);
+					add_timer(&p_slot->task_event);
+				}
+				// ***********POWER FAULT
+				else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
+					dbg("power fault\n");
+				} else {
+					/* refresh notification */
+					if (p_slot)
+						update_slot_info(ctrl, p_slot);
+				}
+
+				ctrl->event_queue[loop].event_type = 0;
+
+				change = 1;
+			}
+		}		// End of FOR loop
+	}
+
+	return;
+}
+
+
+/**
+ * cpqhp_pushbutton_thread
+ *
+ * Scheduled procedure to handle blocking stuff for the pushbuttons
+ * Handles all pending events and exits.
+ *
+ */
+void cpqhp_pushbutton_thread (unsigned long slot)
+{
+	u8 hp_slot;
+	u8 device;
+	struct pci_func *func;
+	struct slot *p_slot = (struct slot *) slot;
+	struct controller *ctrl = (struct controller *) p_slot->ctrl;
+
+	pushbutton_pending = 0;
+	hp_slot = p_slot->hp_slot;
+
+	device = p_slot->device;
+
+	if (is_slot_enabled (ctrl, hp_slot)) {
+		p_slot->state = POWEROFF_STATE;
+		// power Down board
+		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
+		dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
+		if (!func) {
+			dbg("Error! func NULL in %s\n", __FUNCTION__);
+			return ;
+		}
+
+		if (func != NULL && ctrl != NULL) {
+			if (cpqhp_process_SS(ctrl, func) != 0) {
+				amber_LED_on (ctrl, hp_slot);
+				green_LED_on (ctrl, hp_slot);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOBS to be unset
+				wait_for_ctrl_irq (ctrl);
+			}
+		}
+
+		p_slot->state = STATIC_STATE;
+	} else {
+		p_slot->state = POWERON_STATE;
+		// slot is off
+
+		func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
+		dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
+		if (!func) {
+			dbg("Error! func NULL in %s\n", __FUNCTION__);
+			return ;
+		}
+
+		if (func != NULL && ctrl != NULL) {
+			if (cpqhp_process_SI(ctrl, func) != 0) {
+				amber_LED_on (ctrl, hp_slot);
+				green_LED_off (ctrl, hp_slot);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOBS to be unset
+				wait_for_ctrl_irq (ctrl);
+			}
+		}
+
+		p_slot->state = STATIC_STATE;
+	}
+
+	return;
+}
+
+
+int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
+{
+	u8 device, hp_slot;
+	u16 temp_word;
+	u32 tempdword;
+	int rc;
+	struct slot* p_slot;
+	int physical_slot = 0;
+
+	if (!ctrl)
+		return(1);
+
+	tempdword = 0;
+
+	device = func->device;
+	hp_slot = device - ctrl->slot_device_offset;
+	p_slot = cpqhp_find_slot(ctrl, device);
+	if (p_slot) {
+		physical_slot = p_slot->number;
+	}
+
+	// Check to see if the interlock is closed
+	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
+
+	if (tempdword & (0x01 << hp_slot)) {
+		return(1);
+	}
+
+	if (func->is_a_board) {
+		rc = board_replaced(func, ctrl);
+	} else {
+		// add board
+		slot_remove(func);
+
+		func = cpqhp_slot_create(ctrl->bus);
+		if (func == NULL) {
+			return(1);
+		}
+
+		func->bus = ctrl->bus;
+		func->device = device;
+		func->function = 0;
+		func->configured = 0;
+		func->is_a_board = 1;
+
+		// We have to save the presence info for these slots
+		temp_word = ctrl->ctrl_int_comp >> 16;
+		func->presence_save = (temp_word >> hp_slot) & 0x01;
+		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
+
+		if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
+			func->switch_save = 0;
+		} else {
+			func->switch_save = 0x10;
+		}
+
+		rc = board_added(func, ctrl);
+		if (rc) {
+			if (is_bridge(func)) {
+				bridge_slot_remove(func);
+			} else
+				slot_remove(func);
+
+			// Setup slot structure with entry for empty slot
+			func = cpqhp_slot_create(ctrl->bus);
+
+			if (func == NULL) {
+				// Out of memory
+				return(1);
+			}
+
+			func->bus = ctrl->bus;
+			func->device = device;
+			func->function = 0;
+			func->configured = 0;
+			func->is_a_board = 0;
+
+			// We have to save the presence info for these slots
+			temp_word = ctrl->ctrl_int_comp >> 16;
+			func->presence_save = (temp_word >> hp_slot) & 0x01;
+			func->presence_save |=
+			(temp_word >> (hp_slot + 7)) & 0x02;
+
+			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
+				func->switch_save = 0;
+			} else {
+				func->switch_save = 0x10;
+			}
+		}
+	}
+
+	if (rc) {
+		dbg("%s: rc = %d\n", __FUNCTION__, rc);
+	}
+
+	if (p_slot)
+		update_slot_info(ctrl, p_slot);
+
+	return rc;
+}
+
+
+int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
+{
+	u8 device, class_code, header_type, BCR;
+	u8 index = 0;
+	u8 replace_flag;
+	u32 rc = 0;
+	unsigned int devfn;
+	struct slot* p_slot;
+	struct pci_bus *pci_bus = ctrl->pci_bus;
+	int physical_slot=0;
+
+	device = func->device; 
+	func = cpqhp_slot_find(ctrl->bus, device, index++);
+	p_slot = cpqhp_find_slot(ctrl, device);
+	if (p_slot) {
+		physical_slot = p_slot->number;
+	}
+
+	// Make sure there are no video controllers here
+	while (func && !rc) {
+		pci_bus->number = func->bus;
+		devfn = PCI_DEVFN(func->device, func->function);
+
+		// Check the Class Code
+		rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+		if (rc)
+			return rc;
+
+		if (class_code == PCI_BASE_CLASS_DISPLAY) {
+			/* Display/Video adapter (not supported) */
+			rc = REMOVE_NOT_SUPPORTED;
+		} else {
+			// See if it's a bridge
+			rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+			if (rc)
+				return rc;
+
+			// If it's a bridge, check the VGA Enable bit
+			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+				rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
+				if (rc)
+					return rc;
+
+				// If the VGA Enable bit is set, remove isn't supported
+				if (BCR & PCI_BRIDGE_CTL_VGA) {
+					rc = REMOVE_NOT_SUPPORTED;
+				}
+			}
+		}
+
+		func = cpqhp_slot_find(ctrl->bus, device, index++);
+	}
+
+	func = cpqhp_slot_find(ctrl->bus, device, 0);
+	if ((func != NULL) && !rc) {
+		//FIXME: Replace flag should be passed into process_SS
+		replace_flag = !(ctrl->add_support);
+		rc = remove_board(func, replace_flag, ctrl);
+	} else if (!rc) {
+		rc = 1;
+	}
+
+	if (p_slot)
+		update_slot_info(ctrl, p_slot);
+
+	return(rc);
+}
+
+
+
+/**
+ * hardware_test - runs hardware tests
+ *
+ * For hot plug ctrl folks to play with.
+ * test_num is the number entered in the GUI
+ *
+ */
+int cpqhp_hardware_test(struct controller *ctrl, int test_num)
+{
+	u32 save_LED;
+	u32 work_LED;
+	int loop;
+	int num_of_slots;
+
+	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
+
+	switch (test_num) {
+		case 1:
+			// Do stuff here!
+
+			// Do that funky LED thing
+			save_LED = readl(ctrl->hpc_reg + LED_CONTROL);	// so we can restore them later
+			work_LED = 0x01010101;
+			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+			for (loop = 0; loop < num_of_slots; loop++) {
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				work_LED = work_LED << 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				long_delay((2*HZ)/10);
+			}
+			for (loop = 0; loop < num_of_slots; loop++) {
+				work_LED = work_LED >> 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				long_delay((2*HZ)/10);
+			}
+			for (loop = 0; loop < num_of_slots; loop++) {
+				work_LED = work_LED << 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				long_delay((2*HZ)/10);
+			}
+			for (loop = 0; loop < num_of_slots; loop++) {
+				work_LED = work_LED >> 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				long_delay((2*HZ)/10);
+			}
+
+			work_LED = 0x01010000;
+			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+			for (loop = 0; loop < num_of_slots; loop++) {
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				work_LED = work_LED << 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				long_delay((2*HZ)/10);
+			}
+			for (loop = 0; loop < num_of_slots; loop++) {
+				work_LED = work_LED >> 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				long_delay((2*HZ)/10);
+			}
+			work_LED = 0x00000101;
+			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+			for (loop = 0; loop < num_of_slots; loop++) {
+				work_LED = work_LED << 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				long_delay((2*HZ)/10);
+			}
+			for (loop = 0; loop < num_of_slots; loop++) {
+				work_LED = work_LED >> 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				long_delay((2*HZ)/10);
+			}
+
+
+			work_LED = 0x01010000;
+			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+			for (loop = 0; loop < num_of_slots; loop++) {
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				long_delay((3*HZ)/10);
+				work_LED = work_LED >> 16;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				
+				set_SOGO(ctrl);
+
+				// Wait for SOGO interrupt
+				wait_for_ctrl_irq (ctrl);
+
+				// Get ready for next iteration
+				long_delay((3*HZ)/10);
+				work_LED = work_LED << 16;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+				work_LED = work_LED << 1;
+				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+			}
+
+			writel (save_LED, ctrl->hpc_reg + LED_CONTROL);	// put it back the way it was
+
+			set_SOGO(ctrl);
+
+			// Wait for SOBS to be unset
+			wait_for_ctrl_irq (ctrl);
+			break;
+		case 2:
+			// Do other stuff here!
+			break;
+		case 3:
+			// and more...
+			break;
+	}
+	return 0;
+}
+
+
+/**
+ * configure_new_device - Configures the PCI header information of one board.
+ *
+ * @ctrl: pointer to controller structure
+ * @func: pointer to function structure
+ * @behind_bridge: 1 if this is a recursive call, 0 if not
+ * @resources: pointer to set of resource lists
+ *
+ * Returns 0 if success
+ *
+ */
+static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
+				 u8 behind_bridge, struct resource_lists * resources)
+{
+	u8 temp_byte, function, max_functions, stop_it;
+	int rc;
+	u32 ID;
+	struct pci_func *new_slot;
+	int index;
+
+	new_slot = func;
+
+	dbg("%s\n", __FUNCTION__);
+	// Check for Multi-function device
+	ctrl->pci_bus->number = func->bus;
+	rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
+	if (rc) {
+		dbg("%s: rc = %d\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	if (temp_byte & 0x80)	// Multi-function device
+		max_functions = 8;
+	else
+		max_functions = 1;
+
+	function = 0;
+
+	do {
+		rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);
+
+		if (rc) {
+			dbg("configure_new_function failed %d\n",rc);
+			index = 0;
+
+			while (new_slot) {
+				new_slot = cpqhp_slot_find(new_slot->bus, new_slot->device, index++);
+
+				if (new_slot)
+					cpqhp_return_board_resources(new_slot, resources);
+			}
+
+			return(rc);
+		}
+
+		function++;
+
+		stop_it = 0;
+
+		//  The following loop skips to the next present function
+		//  and creates a board structure
+
+		while ((function < max_functions) && (!stop_it)) {
+			pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
+
+			if (ID == 0xFFFFFFFF) {	  // There's nothing there. 
+				function++;
+			} else {  // There's something there
+				// Setup slot structure.
+				new_slot = cpqhp_slot_create(func->bus);
+
+				if (new_slot == NULL) {
+					// Out of memory
+					return(1);
+				}
+
+				new_slot->bus = func->bus;
+				new_slot->device = func->device;
+				new_slot->function = function;
+				new_slot->is_a_board = 1;
+				new_slot->status = 0;
+
+				stop_it++;
+			}
+		}
+
+	} while (function < max_functions);
+	dbg("returning from configure_new_device\n");
+
+	return 0;
+}
+
+
+/*
+  Configuration logic that involves the hotplug data structures and 
+  their bookkeeping
+ */
+
+
+/**
+ * configure_new_function - Configures the PCI header information of one device
+ *
+ * @ctrl: pointer to controller structure
+ * @func: pointer to function structure
+ * @behind_bridge: 1 if this is a recursive call, 0 if not
+ * @resources: pointer to set of resource lists
+ *
+ * Calls itself recursively for bridged devices.
+ * Returns 0 if success
+ *
+ */
+static int configure_new_function (struct controller * ctrl, struct pci_func * func,
+				   u8 behind_bridge, struct resource_lists * resources)
+{
+	int cloop;
+	u8 IRQ;
+	u8 temp_byte;
+	u8 device;
+	u8 class_code;
+	u16 command;
+	u16 temp_word;
+	u32 temp_dword;
+	u32 rc;
+	u32 temp_register;
+	u32 base;
+	u32 ID;
+	unsigned int devfn;
+	struct pci_resource *mem_node;
+	struct pci_resource *p_mem_node;
+	struct pci_resource *io_node;
+	struct pci_resource *bus_node;
+	struct pci_resource *hold_mem_node;
+	struct pci_resource *hold_p_mem_node;
+	struct pci_resource *hold_IO_node;
+	struct pci_resource *hold_bus_node;
+	struct irq_mapping irqs;
+	struct pci_func *new_slot;
+	struct pci_bus *pci_bus;
+	struct resource_lists temp_resources;
+
+	pci_bus = ctrl->pci_bus;
+	pci_bus->number = func->bus;
+	devfn = PCI_DEVFN(func->device, func->function);
+
+	// Check for Bridge
+	rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
+	if (rc)
+		return rc;
+
+	if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
+		// set Primary bus
+		dbg("set Primary bus = %d\n", func->bus);
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
+		if (rc)
+			return rc;
+
+		// find range of busses to use
+		dbg("find ranges of buses to use\n");
+		bus_node = get_max_resource(&resources->bus_head, 1);
+
+		// If we don't have any busses to allocate, we can't continue
+		if (!bus_node)
+			return -ENOMEM;
+
+		// set Secondary bus
+		temp_byte = bus_node->base;
+		dbg("set Secondary bus = %d\n", bus_node->base);
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
+		if (rc)
+			return rc;
+
+		// set subordinate bus
+		temp_byte = bus_node->base + bus_node->length - 1;
+		dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
+		if (rc)
+			return rc;
+
+		// set subordinate Latency Timer and base Latency Timer
+		temp_byte = 0x40;
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
+		if (rc)
+			return rc;
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
+		if (rc)
+			return rc;
+
+		// set Cache Line size
+		temp_byte = 0x08;
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
+		if (rc)
+			return rc;
+
+		// Setup the IO, memory, and prefetchable windows
+
+		io_node = get_max_resource(&(resources->io_head), 0x1000);
+		if (!io_node)
+			return -ENOMEM;
+		mem_node = get_max_resource(&(resources->mem_head), 0x100000);
+		if (!mem_node)
+			return -ENOMEM;
+		p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);
+		if (!p_mem_node)
+			return -ENOMEM;
+		dbg("Setup the IO, memory, and prefetchable windows\n");
+		dbg("io_node\n");
+		dbg("(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
+		dbg("mem_node\n");
+		dbg("(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
+		dbg("p_mem_node\n");
+		dbg("(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
+
+		// set up the IRQ info
+		if (!resources->irqs) {
+			irqs.barber_pole = 0;
+			irqs.interrupt[0] = 0;
+			irqs.interrupt[1] = 0;
+			irqs.interrupt[2] = 0;
+			irqs.interrupt[3] = 0;
+			irqs.valid_INT = 0;
+		} else {
+			irqs.barber_pole = resources->irqs->barber_pole;
+			irqs.interrupt[0] = resources->irqs->interrupt[0];
+			irqs.interrupt[1] = resources->irqs->interrupt[1];
+			irqs.interrupt[2] = resources->irqs->interrupt[2];
+			irqs.interrupt[3] = resources->irqs->interrupt[3];
+			irqs.valid_INT = resources->irqs->valid_INT;
+		}
+
+		// set up resource lists that are now aligned on top and bottom
+		// for anything behind the bridge.
+		temp_resources.bus_head = bus_node;
+		temp_resources.io_head = io_node;
+		temp_resources.mem_head = mem_node;
+		temp_resources.p_mem_head = p_mem_node;
+		temp_resources.irqs = &irqs;
+
+		// Make copies of the nodes we are going to pass down so that
+		// if there is a problem,we can just use these to free resources
+		hold_bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+		hold_IO_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+		hold_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+		hold_p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+		if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
+			if (hold_bus_node)
+				kfree(hold_bus_node);
+			if (hold_IO_node)
+				kfree(hold_IO_node);
+			if (hold_mem_node)
+				kfree(hold_mem_node);
+			if (hold_p_mem_node)
+				kfree(hold_p_mem_node);
+
+			return(1);
+		}
+
+		memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
+
+		bus_node->base += 1;
+		bus_node->length -= 1;
+		bus_node->next = NULL;
+
+		// If we have IO resources copy them and fill in the bridge's
+		// IO range registers
+		if (io_node) {
+			memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
+			io_node->next = NULL;
+
+			// set IO base and Limit registers
+			temp_byte = io_node->base >> 8;
+			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
+
+			temp_byte = (io_node->base + io_node->length - 1) >> 8;
+			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
+		} else {
+			kfree(hold_IO_node);
+			hold_IO_node = NULL;
+		}
+
+		// If we have memory resources copy them and fill in the bridge's
+		// memory range registers.  Otherwise, fill in the range
+		// registers with values that disable them.
+		if (mem_node) {
+			memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
+			mem_node->next = NULL;
+
+			// set Mem base and Limit registers
+			temp_word = mem_node->base >> 16;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+
+			temp_word = (mem_node->base + mem_node->length - 1) >> 16;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+		} else {
+			temp_word = 0xFFFF;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+
+			temp_word = 0x0000;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+
+			kfree(hold_mem_node);
+			hold_mem_node = NULL;
+		}
+
+		// If we have prefetchable memory resources copy them and 
+		// fill in the bridge's memory range registers.  Otherwise,
+		// fill in the range registers with values that disable them.
+		if (p_mem_node) {
+			memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
+			p_mem_node->next = NULL;
+
+			// set Pre Mem base and Limit registers
+			temp_word = p_mem_node->base >> 16;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+
+			temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+		} else {
+			temp_word = 0xFFFF;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+
+			temp_word = 0x0000;
+			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+
+			kfree(hold_p_mem_node);
+			hold_p_mem_node = NULL;
+		}
+
+		// Adjust this to compensate for extra adjustment in first loop
+		irqs.barber_pole--;
+
+		rc = 0;
+
+		// Here we actually find the devices and configure them
+		for (device = 0; (device <= 0x1F) && !rc; device++) {
+			irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
+
+			ID = 0xFFFFFFFF;
+			pci_bus->number = hold_bus_node->base;
+			pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
+			pci_bus->number = func->bus;
+
+			if (ID != 0xFFFFFFFF) {	  //  device Present
+				// Setup slot structure.
+				new_slot = cpqhp_slot_create(hold_bus_node->base);
+
+				if (new_slot == NULL) {
+					// Out of memory
+					rc = -ENOMEM;
+					continue;
+				}
+
+				new_slot->bus = hold_bus_node->base;
+				new_slot->device = device;
+				new_slot->function = 0;
+				new_slot->is_a_board = 1;
+				new_slot->status = 0;
+
+				rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);
+				dbg("configure_new_device rc=0x%x\n",rc);
+			}	// End of IF (device in slot?)
+		}		// End of FOR loop
+
+		if (rc) {
+			cpqhp_destroy_resource_list(&temp_resources);
+
+			return_resource(&(resources->bus_head), hold_bus_node);
+			return_resource(&(resources->io_head), hold_IO_node);
+			return_resource(&(resources->mem_head), hold_mem_node);
+			return_resource(&(resources->p_mem_head), hold_p_mem_node);
+			return(rc);
+		}
+		// save the interrupt routing information
+		if (resources->irqs) {
+			resources->irqs->interrupt[0] = irqs.interrupt[0];
+			resources->irqs->interrupt[1] = irqs.interrupt[1];
+			resources->irqs->interrupt[2] = irqs.interrupt[2];
+			resources->irqs->interrupt[3] = irqs.interrupt[3];
+			resources->irqs->valid_INT = irqs.valid_INT;
+		} else if (!behind_bridge) {
+			// We need to hook up the interrupts here
+			for (cloop = 0; cloop < 4; cloop++) {
+				if (irqs.valid_INT & (0x01 << cloop)) {
+					rc = cpqhp_set_irq(func->bus, func->device,
+							   0x0A + cloop, irqs.interrupt[cloop]);
+					if (rc) {
+						cpqhp_destroy_resource_list (&temp_resources);
+
+						return_resource(&(resources-> bus_head), hold_bus_node);
+						return_resource(&(resources-> io_head), hold_IO_node);
+						return_resource(&(resources-> mem_head), hold_mem_node);
+						return_resource(&(resources-> p_mem_head), hold_p_mem_node);
+						return rc;
+					}
+				}
+			}	// end of for loop
+		}
+		// Return unused bus resources
+		// First use the temporary node to store information for the board
+		if (hold_bus_node && bus_node && temp_resources.bus_head) {
+			hold_bus_node->length = bus_node->base - hold_bus_node->base;
+
+			hold_bus_node->next = func->bus_head;
+			func->bus_head = hold_bus_node;
+
+			temp_byte = temp_resources.bus_head->base - 1;
+
+			// set subordinate bus
+			rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
+
+			if (temp_resources.bus_head->length == 0) {
+				kfree(temp_resources.bus_head);
+				temp_resources.bus_head = NULL;
+			} else {
+				return_resource(&(resources->bus_head), temp_resources.bus_head);
+			}
+		}
+
+		// If we have IO space available and there is some left,
+		// return the unused portion
+		if (hold_IO_node && temp_resources.io_head) {
+			io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
+							       &hold_IO_node, 0x1000);
+
+			// Check if we were able to split something off
+			if (io_node) {
+				hold_IO_node->base = io_node->base + io_node->length;
+
+				temp_byte = (hold_IO_node->base) >> 8;
+				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_BASE, temp_byte);
+
+				return_resource(&(resources->io_head), io_node);
+			}
+
+			io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
+
+			// Check if we were able to split something off
+			if (io_node) {
+				// First use the temporary node to store information for the board
+				hold_IO_node->length = io_node->base - hold_IO_node->base;
+
+				// If we used any, add it to the board's list
+				if (hold_IO_node->length) {
+					hold_IO_node->next = func->io_head;
+					func->io_head = hold_IO_node;
+
+					temp_byte = (io_node->base - 1) >> 8;
+					rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
+
+					return_resource(&(resources->io_head), io_node);
+				} else {
+					// it doesn't need any IO
+					temp_word = 0x0000;
+					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_LIMIT, temp_word);
+
+					return_resource(&(resources->io_head), io_node);
+					kfree(hold_IO_node);
+				}
+			} else {
+				// it used most of the range
+				hold_IO_node->next = func->io_head;
+				func->io_head = hold_IO_node;
+			}
+		} else if (hold_IO_node) {
+			// it used the whole range
+			hold_IO_node->next = func->io_head;
+			func->io_head = hold_IO_node;
+		}
+		// If we have memory space available and there is some left,
+		// return the unused portion
+		if (hold_mem_node && temp_resources.mem_head) {
+			mem_node = do_pre_bridge_resource_split(&(temp_resources.  mem_head),
+								&hold_mem_node, 0x100000);
+
+			// Check if we were able to split something off
+			if (mem_node) {
+				hold_mem_node->base = mem_node->base + mem_node->length;
+
+				temp_word = (hold_mem_node->base) >> 16;
+				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+
+				return_resource(&(resources->mem_head), mem_node);
+			}
+
+			mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000);
+
+			// Check if we were able to split something off
+			if (mem_node) {
+				// First use the temporary node to store information for the board
+				hold_mem_node->length = mem_node->base - hold_mem_node->base;
+
+				if (hold_mem_node->length) {
+					hold_mem_node->next = func->mem_head;
+					func->mem_head = hold_mem_node;
+
+					// configure end address
+					temp_word = (mem_node->base - 1) >> 16;
+					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+
+					// Return unused resources to the pool
+					return_resource(&(resources->mem_head), mem_node);
+				} else {
+					// it doesn't need any Mem
+					temp_word = 0x0000;
+					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+
+					return_resource(&(resources->mem_head), mem_node);
+					kfree(hold_mem_node);
+				}
+			} else {
+				// it used most of the range
+				hold_mem_node->next = func->mem_head;
+				func->mem_head = hold_mem_node;
+			}
+		} else if (hold_mem_node) {
+			// it used the whole range
+			hold_mem_node->next = func->mem_head;
+			func->mem_head = hold_mem_node;
+		}
+		// If we have prefetchable memory space available and there is some 
+		// left at the end, return the unused portion
+		if (hold_p_mem_node && temp_resources.p_mem_head) {
+			p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
+								  &hold_p_mem_node, 0x100000);
+
+			// Check if we were able to split something off
+			if (p_mem_node) {
+				hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
+
+				temp_word = (hold_p_mem_node->base) >> 16;
+				rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+
+				return_resource(&(resources->p_mem_head), p_mem_node);
+			}
+
+			p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000);
+
+			// Check if we were able to split something off
+			if (p_mem_node) {
+				// First use the temporary node to store information for the board
+				hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
+
+				// If we used any, add it to the board's list
+				if (hold_p_mem_node->length) {
+					hold_p_mem_node->next = func->p_mem_head;
+					func->p_mem_head = hold_p_mem_node;
+
+					temp_word = (p_mem_node->base - 1) >> 16;
+					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+
+					return_resource(&(resources->p_mem_head), p_mem_node);
+				} else {
+					// it doesn't need any PMem
+					temp_word = 0x0000;
+					rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+
+					return_resource(&(resources->p_mem_head), p_mem_node);
+					kfree(hold_p_mem_node);
+				}
+			} else {
+				// it used the most of the range
+				hold_p_mem_node->next = func->p_mem_head;
+				func->p_mem_head = hold_p_mem_node;
+			}
+		} else if (hold_p_mem_node) {
+			// it used the whole range
+			hold_p_mem_node->next = func->p_mem_head;
+			func->p_mem_head = hold_p_mem_node;
+		}
+		// We should be configuring an IRQ and the bridge's base address
+		// registers if it needs them.  Although we have never seen such
+		// a device
+
+		// enable card
+		command = 0x0157;	// = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
+		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
+
+		// set Bridge Control Register
+		command = 0x07;		// = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA
+		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
+	} else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
+		// Standard device
+		rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+
+		if (class_code == PCI_BASE_CLASS_DISPLAY) {
+			// Display (video) adapter (not supported)
+			return(DEVICE_TYPE_NOT_SUPPORTED);
+		}
+		// Figure out IO and memory needs
+		for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
+			temp_register = 0xFFFFFFFF;
+
+			dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
+			rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+
+			rc = pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
+			dbg("CND: base = 0x%x\n", temp_register);
+
+			if (temp_register) {	  // If this register is implemented
+				if ((temp_register & 0x03L) == 0x01) {
+					// Map IO
+
+					// set base = amount of IO space
+					base = temp_register & 0xFFFFFFFC;
+					base = ~base + 1;
+
+					dbg("CND:      length = 0x%x\n", base);
+					io_node = get_io_resource(&(resources->io_head), base);
+					dbg("Got io_node start = %8.8x, length = %8.8x next (%p)\n",
+					    io_node->base, io_node->length, io_node->next);
+					dbg("func (%p) io_head (%p)\n", func, func->io_head);
+
+					// allocate the resource to the board
+					if (io_node) {
+						base = io_node->base;
+
+						io_node->next = func->io_head;
+						func->io_head = io_node;
+					} else
+						return -ENOMEM;
+				} else if ((temp_register & 0x0BL) == 0x08) {
+					// Map prefetchable memory
+					base = temp_register & 0xFFFFFFF0;
+					base = ~base + 1;
+
+					dbg("CND:      length = 0x%x\n", base);
+					p_mem_node = get_resource(&(resources->p_mem_head), base);
+
+					// allocate the resource to the board
+					if (p_mem_node) {
+						base = p_mem_node->base;
+
+						p_mem_node->next = func->p_mem_head;
+						func->p_mem_head = p_mem_node;
+					} else
+						return -ENOMEM;
+				} else if ((temp_register & 0x0BL) == 0x00) {
+					// Map memory
+					base = temp_register & 0xFFFFFFF0;
+					base = ~base + 1;
+
+					dbg("CND:      length = 0x%x\n", base);
+					mem_node = get_resource(&(resources->mem_head), base);
+
+					// allocate the resource to the board
+					if (mem_node) {
+						base = mem_node->base;
+
+						mem_node->next = func->mem_head;
+						func->mem_head = mem_node;
+					} else
+						return -ENOMEM;
+				} else if ((temp_register & 0x0BL) == 0x04) {
+					// Map memory
+					base = temp_register & 0xFFFFFFF0;
+					base = ~base + 1;
+
+					dbg("CND:      length = 0x%x\n", base);
+					mem_node = get_resource(&(resources->mem_head), base);
+
+					// allocate the resource to the board
+					if (mem_node) {
+						base = mem_node->base;
+
+						mem_node->next = func->mem_head;
+						func->mem_head = mem_node;
+					} else
+						return -ENOMEM;
+				} else if ((temp_register & 0x0BL) == 0x06) {
+					// Those bits are reserved, we can't handle this
+					return(1);
+				} else {
+					// Requesting space below 1M
+					return(NOT_ENOUGH_RESOURCES);
+				}
+
+				rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
+
+				// Check for 64-bit base
+				if ((temp_register & 0x07L) == 0x04) {
+					cloop += 4;
+
+					// Upper 32 bits of address always zero on today's systems
+					// FIXME this is probably not true on Alpha and ia64???
+					base = 0;
+					rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
+				}
+			}
+		}		// End of base register loop
+
+		// Figure out which interrupt pin this function uses
+		rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
+
+		// If this function needs an interrupt and we are behind a bridge
+		// and the pin is tied to something that's alread mapped,
+		// set this one the same
+		if (temp_byte && resources->irqs && 
+		    (resources->irqs->valid_INT & 
+		     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
+			// We have to share with something already set up
+			IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
+		} else {
+			// Program IRQ based on card type
+			rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
+
+			if (class_code == PCI_BASE_CLASS_STORAGE) {
+				IRQ = cpqhp_disk_irq;
+			} else {
+				IRQ = cpqhp_nic_irq;
+			}
+		}
+
+		// IRQ Line
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
+
+		if (!behind_bridge) {
+			rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
+			if (rc)
+				return(1);
+		} else {
+			//TBD - this code may also belong in the other clause of this If statement
+			resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
+			resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
+		}
+
+		// Latency Timer
+		temp_byte = 0x40;
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
+
+		// Cache Line size
+		temp_byte = 0x08;
+		rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
+
+		// disable ROM base Address
+		temp_dword = 0x00L;
+		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_dword);
+
+		// enable card
+		temp_word = 0x0157;	// = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
+		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, temp_word);
+	}			// End of Not-A-Bridge else
+	else {
+		// It's some strange type of PCI adapter (Cardbus?)
+		return(DEVICE_TYPE_NOT_SUPPORTED);
+	}
+
+	func->configured = 1;
+
+	return 0;
+}
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_nvram.c linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_nvram.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_nvram.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_nvram.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,667 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include "cpqphp.h"
+#include "cpqphp_nvram.h"
+
+
+#define ROM_INT15_PHY_ADDR		0x0FF859
+#define READ_EV				0xD8A4
+#define WRITE_EV			0xD8A5
+
+struct register_foo {
+	union {
+		unsigned long lword;		/* eax */
+		unsigned short word;		/* ax */
+
+		struct {
+			unsigned char low;	/* al */
+			unsigned char high;	/* ah */
+		} byte;
+	} data;
+
+	unsigned char opcode;	/* see below */
+	unsigned long length;	/* if the reg. is a pointer, how much data */
+} __attribute__ ((packed));
+
+struct all_reg {
+	struct register_foo eax_reg;
+	struct register_foo ebx_reg;
+	struct register_foo ecx_reg;
+	struct register_foo edx_reg;
+	struct register_foo edi_reg;
+	struct register_foo esi_reg;
+	struct register_foo eflags_reg;
+} __attribute__ ((packed));
+
+
+struct ev_hrt_header {
+	u8 Version;
+	u8 num_of_ctrl;
+	u8 next;
+};
+
+struct ev_hrt_ctrl {
+	u8 bus;
+	u8 device;
+	u8 function;
+	u8 mem_avail;
+	u8 p_mem_avail;
+	u8 io_avail;
+	u8 bus_avail;
+	u8 next;
+};
+
+
+static u8 evbuffer_init;
+static u8 evbuffer_length;
+static u8 evbuffer[1024];
+
+static void *compaq_int15_entry_point;
+
+static spinlock_t int15_lock;		/* lock for ordering int15_bios_call() */
+
+
+/* This is a series of function that deals with
+   setting & getting the hotplug resource table in some environment variable.
+*/
+
+/*
+ * We really shouldn't be doing this unless there is a _very_ good reason to!!!
+ * greg k-h
+ */
+
+
+static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail)
+{
+	u8 **tByte;
+
+	if ((*used + 1) > *avail)
+		return(1);
+	
+	*((u8*)*p_buffer) = value;
+	tByte = (u8**)p_buffer;
+	(*tByte)++;
+	*used+=1;
+	return(0);
+}
+
+
+static u32 add_dword( u32 **p_buffer, u32 value, u32 *used, u32 *avail)
+{
+	if ((*used + 4) > *avail)
+		return(1);
+
+	**p_buffer = value;
+	(*p_buffer)++;
+	*used+=4;
+	return(0);
+}
+
+
+/*
+ * check_for_compaq_ROM
+ *
+ * this routine verifies that the ROM OEM string is 'COMPAQ'
+ *
+ * returns 0 for non-Compaq ROM, 1 for Compaq ROM
+ */
+static int check_for_compaq_ROM (void *rom_start)
+{
+	u8 temp1, temp2, temp3, temp4, temp5, temp6;
+	int result = 0;
+
+	temp1 = readb(rom_start + 0xffea + 0);
+	temp2 = readb(rom_start + 0xffea + 1);
+	temp3 = readb(rom_start + 0xffea + 2);
+	temp4 = readb(rom_start + 0xffea + 3);
+	temp5 = readb(rom_start + 0xffea + 4);
+	temp6 = readb(rom_start + 0xffea + 5);
+	if ((temp1 == 'C') &&
+	    (temp2 == 'O') &&
+	    (temp3 == 'M') &&
+	    (temp4 == 'P') &&
+	    (temp5 == 'A') &&
+	    (temp6 == 'Q')) {
+		result = 1;
+	}
+	dbg ("%s - returned %d\n", __FUNCTION__, result);
+	return result;
+}
+
+
+static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
+{
+	unsigned long flags;
+	int op = operation;
+	int ret_val;
+	
+	if (!compaq_int15_entry_point)
+		return -ENODEV;
+	
+	spin_lock_irqsave(&int15_lock, flags);
+	__asm__ (
+		"xorl   %%ebx,%%ebx\n" \
+		"xorl    %%edx,%%edx\n" \
+		"pushf\n" \
+		"push %%cs\n" \
+		"cli\n" \
+		"call *%6\n"
+		: "=c" (*buf_size), "=a" (ret_val)
+		: "a" (op), "c" (*buf_size), "S" (ev_name),
+		"D" (buffer), "m" (compaq_int15_entry_point)
+		: "%ebx", "%edx");
+	spin_unlock_irqrestore(&int15_lock, flags);
+	
+	return((ret_val & 0xFF00) >> 8);
+}
+
+
+/*
+ * load_HRT
+ *
+ * Read the hot plug Resource Table from NVRAM
+ */
+static int load_HRT (void *rom_start)
+{
+	u32 available;
+	u32 temp_dword;
+	u8 temp_byte = 0xFF;
+	u32 rc;
+
+	if (!check_for_compaq_ROM(rom_start)) {
+		return -ENODEV;
+	}
+
+	available = 1024;
+
+	// Now load the EV
+	temp_dword = available;
+
+	rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);
+
+	evbuffer_length = temp_dword;
+
+	// We're maintaining the resource lists so write FF to invalidate old info
+	temp_dword = 1;
+
+	rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);
+
+	return rc;
+}
+
+
+/*
+ * store_HRT
+ *
+ * Save the hot plug Resource Table in NVRAM
+ */
+static u32 store_HRT (void *rom_start)
+{
+	u32 *buffer;
+	u32 *pFill;
+	u32 usedbytes;
+	u32 available;
+	u32 temp_dword;
+	u32 rc;
+	u8 loop;
+	u8 numCtrl = 0;
+	struct controller *ctrl;
+	struct pci_resource *resNode;
+	struct ev_hrt_header *p_EV_header;
+	struct ev_hrt_ctrl *p_ev_ctrl;
+
+	available = 1024;
+
+	if (!check_for_compaq_ROM(rom_start)) {
+		return(1);
+	}
+
+	buffer = (u32*) evbuffer;
+
+	if (!buffer)
+		return(1);
+
+	pFill = buffer;
+	usedbytes = 0;
+
+	p_EV_header = (struct ev_hrt_header *) pFill;
+
+	ctrl = cpqhp_ctrl_list;
+	
+	// The revision of this structure
+	rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available);
+	if (rc)
+		return(rc);
+
+	// The number of controllers
+	rc = add_byte( &pFill, 1, &usedbytes, &available);
+	if (rc)
+		return(rc);
+
+	while (ctrl) {
+		p_ev_ctrl = (struct ev_hrt_ctrl *) pFill;
+
+		numCtrl++;
+
+		// The bus number
+		rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available);
+		if (rc)
+			return(rc);
+
+		// The device Number
+		rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
+		if (rc)
+			return(rc);
+
+		// The function Number
+		rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
+		if (rc)
+			return(rc);
+
+		// Skip the number of available entries
+		rc = add_dword( &pFill, 0, &usedbytes, &available);
+		if (rc)
+			return(rc);
+
+		// Figure out memory Available
+
+		resNode = ctrl->mem_head;
+
+		loop = 0;
+
+		while (resNode) {
+			loop ++;
+
+			// base
+			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
+			if (rc)
+				return(rc);
+
+			// length
+			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
+			if (rc)
+				return(rc);
+
+			resNode = resNode->next;
+		}
+
+		// Fill in the number of entries
+		p_ev_ctrl->mem_avail = loop;
+
+		// Figure out prefetchable memory Available
+
+		resNode = ctrl->p_mem_head;
+
+		loop = 0;
+
+		while (resNode) {
+			loop ++;
+
+			// base
+			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
+			if (rc)
+				return(rc);
+
+			// length
+			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
+			if (rc)
+				return(rc);
+
+			resNode = resNode->next;
+		}
+
+		// Fill in the number of entries
+		p_ev_ctrl->p_mem_avail = loop;
+
+		// Figure out IO Available
+
+		resNode = ctrl->io_head;
+
+		loop = 0;
+
+		while (resNode) {
+			loop ++;
+
+			// base
+			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
+			if (rc)
+				return(rc);
+
+			// length
+			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
+			if (rc)
+				return(rc);
+
+			resNode = resNode->next;
+		}
+
+		// Fill in the number of entries
+		p_ev_ctrl->io_avail = loop;
+
+		// Figure out bus Available
+
+		resNode = ctrl->bus_head;
+
+		loop = 0;
+
+		while (resNode) {
+			loop ++;
+
+			// base
+			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
+			if (rc)
+				return(rc);
+
+			// length
+			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
+			if (rc)
+				return(rc);
+
+			resNode = resNode->next;
+		}
+
+		// Fill in the number of entries
+		p_ev_ctrl->bus_avail = loop;
+
+		ctrl = ctrl->next;
+	}
+	
+	p_EV_header->num_of_ctrl = numCtrl;
+
+	// Now store the EV
+
+	temp_dword = usedbytes;
+
+	rc = access_EV(WRITE_EV, "CQTHPS", (u8*) buffer, &temp_dword);
+
+	dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword);
+
+	evbuffer_length = temp_dword;
+
+	if (rc) {
+		err(msg_unable_to_save);
+		return(1);
+	}
+
+	return(0);
+}
+
+
+void compaq_nvram_init (void *rom_start)
+{
+	if (rom_start) {
+		compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
+	}
+	dbg("int15 entry  = %p\n", compaq_int15_entry_point);
+
+	/* initialize our int15 lock */
+	spin_lock_init(&int15_lock);
+}
+
+
+int compaq_nvram_load (void *rom_start, struct controller *ctrl)
+{
+	u8 bus, device, function;
+	u8 nummem, numpmem, numio, numbus;
+	u32 rc;
+	u8 *p_byte;
+	struct pci_resource *mem_node;
+	struct pci_resource *p_mem_node;
+	struct pci_resource *io_node;
+	struct pci_resource *bus_node;
+	struct ev_hrt_ctrl *p_ev_ctrl;
+	struct ev_hrt_header *p_EV_header;
+
+	if (!evbuffer_init) {
+		// Read the resource list information in from NVRAM
+		if (load_HRT(rom_start))
+			memset (evbuffer, 0, 1024);
+
+		evbuffer_init = 1;
+	}
+
+	// If we saved information in NVRAM, use it now
+	p_EV_header = (struct ev_hrt_header *) evbuffer;
+
+	// The following code is for systems where version 1.0 of this
+	// driver has been loaded, but doesn't support the hardware.
+	// In that case, the driver would incorrectly store something
+	// in NVRAM.
+	if ((p_EV_header->Version == 2) ||
+	    ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
+		p_byte = &(p_EV_header->next);
+
+		p_ev_ctrl = (struct ev_hrt_ctrl *) &(p_EV_header->next);
+
+		p_byte += 3;
+
+		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+			return 2;
+
+		bus = p_ev_ctrl->bus;
+		device = p_ev_ctrl->device;
+		function = p_ev_ctrl->function;
+
+		while ((bus != ctrl->bus) ||
+		       (device != PCI_SLOT(ctrl->pci_dev->devfn)) || 
+		       (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
+			nummem = p_ev_ctrl->mem_avail;
+			numpmem = p_ev_ctrl->p_mem_avail;
+			numio = p_ev_ctrl->io_avail;
+			numbus = p_ev_ctrl->bus_avail;
+
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+				return 2;
+
+			// Skip forward to the next entry
+			p_byte += (nummem + numpmem + numio + numbus) * 8;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+				return 2;
+
+			p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;
+
+			p_byte += 3;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+				return 2;
+
+			bus = p_ev_ctrl->bus;
+			device = p_ev_ctrl->device;
+			function = p_ev_ctrl->function;
+		}
+
+		nummem = p_ev_ctrl->mem_avail;
+		numpmem = p_ev_ctrl->p_mem_avail;
+		numio = p_ev_ctrl->io_avail;
+		numbus = p_ev_ctrl->bus_avail;
+
+		p_byte += 4;
+
+		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
+			return 2;
+
+		while (nummem--) {
+			mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!mem_node)
+				break;
+
+			mem_node->base = *(u32*)p_byte;
+			dbg("mem base = %8.8x\n",mem_node->base);
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(mem_node);
+				return 2;
+			}
+
+			mem_node->length = *(u32*)p_byte;
+			dbg("mem length = %8.8x\n",mem_node->length);
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(mem_node);
+				return 2;
+			}
+
+			mem_node->next = ctrl->mem_head;
+			ctrl->mem_head = mem_node;
+		}
+
+		while (numpmem--) {
+			p_mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!p_mem_node)
+				break;
+
+			p_mem_node->base = *(u32*)p_byte;
+			dbg("pre-mem base = %8.8x\n",p_mem_node->base);
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(p_mem_node);
+				return 2;
+			}
+
+			p_mem_node->length = *(u32*)p_byte;
+			dbg("pre-mem length = %8.8x\n",p_mem_node->length);
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(p_mem_node);
+				return 2;
+			}
+
+			p_mem_node->next = ctrl->p_mem_head;
+			ctrl->p_mem_head = p_mem_node;
+		}
+
+		while (numio--) {
+			io_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!io_node)
+				break;
+
+			io_node->base = *(u32*)p_byte;
+			dbg("io base = %8.8x\n",io_node->base);
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(io_node);
+				return 2;
+			}
+
+			io_node->length = *(u32*)p_byte;
+			dbg("io length = %8.8x\n",io_node->length);
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(io_node);
+				return 2;
+			}
+
+			io_node->next = ctrl->io_head;
+			ctrl->io_head = io_node;
+		}
+
+		while (numbus--) {
+			bus_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+
+			if (!bus_node)
+				break;
+
+			bus_node->base = *(u32*)p_byte;
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(bus_node);
+				return 2;
+			}
+
+			bus_node->length = *(u32*)p_byte;
+			p_byte += 4;
+
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(bus_node);
+				return 2;
+			}
+
+			bus_node->next = ctrl->bus_head;
+			ctrl->bus_head = bus_node;
+		}
+
+		// If all of the following fail, we don't have any resources for
+		// hot plug add
+		rc = 1;
+		rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
+		rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
+		rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
+		rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
+
+		if (rc)
+			return(rc);
+	} else {
+		if ((evbuffer[0] != 0) && (!ctrl->push_flag)) 
+			return 1;
+	}
+
+	return 0;
+}
+
+	
+int compaq_nvram_store (void *rom_start)
+{
+	int rc = 1;
+
+	if (rom_start == NULL)
+		return -ENODEV;
+
+	if (evbuffer_init) {
+		rc = store_HRT(rom_start);
+		if (rc) {
+			err(msg_unable_to_save);
+		}
+	}
+	return rc;
+}
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_nvram.h linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_nvram.h
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_nvram.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_nvram.h	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,57 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+
+#ifndef _CPQPHP_NVRAM_H
+#define _CPQPHP_NVRAM_H
+
+#ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
+
+static inline void compaq_nvram_init (void *rom_start)
+{
+	return;
+}
+
+static inline int compaq_nvram_load (void *rom_start, struct controller *ctrl)
+{
+	return 0;
+}
+
+static inline int compaq_nvram_store (void *rom_start)
+{
+	return 0;
+}
+
+#else
+
+extern void compaq_nvram_init	(void *rom_start);
+extern int compaq_nvram_load	(void *rom_start, struct controller *ctrl);
+extern int compaq_nvram_store	(void *rom_start);
+
+#endif
+
+#endif
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_pci.c linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_pci.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_pci.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_pci.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,1549 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+#include "../pci.h"
+#include "cpqphp.h"
+#include "cpqphp_nvram.h"
+#include "../../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
+
+
+u8 cpqhp_nic_irq;
+u8 cpqhp_disk_irq;
+
+static u16 unused_IRQ;
+
+/*
+ * detect_HRT_floating_pointer
+ *
+ * find the Hot Plug Resource Table in the specified region of memory.
+ *
+ */
+static void *detect_HRT_floating_pointer(void *begin, void *end)
+{
+	void *fp;
+	void *endp;
+	u8 temp1, temp2, temp3, temp4;
+	int status = 0;
+
+	endp = (end - sizeof(struct hrt) + 1);
+
+	for (fp = begin; fp <= endp; fp += 16) {
+		temp1 = readb(fp + SIG0);
+		temp2 = readb(fp + SIG1);
+		temp3 = readb(fp + SIG2);
+		temp4 = readb(fp + SIG3);
+		if (temp1 == '$' &&
+		    temp2 == 'H' &&
+		    temp3 == 'R' &&
+		    temp4 == 'T') {
+			status = 1;
+			break;
+		}
+	}
+
+	if (!status)
+		fp = NULL;
+
+	dbg("Discovered Hotplug Resource Table at %p\n", fp);
+	return fp;
+}
+
+
+int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  
+{
+	unsigned char bus;
+	struct pci_bus *child;
+	int num;
+
+	if (func->pci_dev == NULL)
+		func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
+
+	/* No pci device, we need to create it then */
+	if (func->pci_dev == NULL) {
+		dbg("INFO: pci_dev still null\n");
+
+		num = pci_scan_slot(ctrl->pci_dev->bus, PCI_DEVFN(func->device, func->function));
+		if (num)
+			pci_bus_add_devices(ctrl->pci_dev->bus);
+
+		func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
+		if (func->pci_dev == NULL) {
+			dbg("ERROR: pci_dev still null\n");
+			return 0;
+		}
+	}
+
+	if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+		pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
+		child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
+		pci_do_scan_bus(child);
+	}
+
+	return 0;
+}
+
+
+int cpqhp_unconfigure_device(struct pci_func* func) 
+{
+	int j;
+	
+	dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
+
+	for (j=0; j<8 ; j++) {
+		struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
+		if (temp)
+			pci_remove_bus_device(temp);
+	}
+	return 0;
+}
+
+static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
+{
+	u32 vendID = 0;
+
+	if (pci_bus_read_config_dword (bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
+		return -1;
+	if (vendID == 0xffffffff)
+		return -1;
+	return pci_bus_read_config_dword (bus, devfn, offset, value);
+}
+
+
+/*
+ * cpqhp_set_irq
+ *
+ * @bus_num: bus number of PCI device
+ * @dev_num: device number of PCI device
+ * @slot: pointer to u8 where slot number will be returned
+ */
+int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
+{
+	int rc;
+	u16 temp_word;
+	struct pci_dev fakedev;
+	struct pci_bus fakebus;
+
+	fakedev.devfn = dev_num << 3;
+	fakedev.bus = &fakebus;
+	fakebus.number = bus_num;
+	dbg("%s: dev %d, bus %d, pin %d, num %d\n",
+	    __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
+	rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
+	dbg("%s: rc %d\n", __FUNCTION__, rc);
+	if (!rc)
+		return !rc;
+
+	// set the Edge Level Control Register (ELCR)
+	temp_word = inb(0x4d0);
+	temp_word |= inb(0x4d1) << 8;
+
+	temp_word |= 0x01 << irq_num;
+
+	// This should only be for x86 as it sets the Edge Level Control Register
+	outb((u8) (temp_word & 0xFF), 0x4d0);
+	outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
+
+	return 0;
+}
+
+
+/*
+ * WTF??? This function isn't in the code, yet a function calls it, but the 
+ * compiler optimizes it away?  strange.  Here as a placeholder to keep the 
+ * compiler happy.
+ */
+static int PCI_ScanBusNonBridge (u8 bus, u8 device)
+{
+	return 0;
+}
+
+static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
+{
+	u8 tdevice;
+	u32 work;
+	u8 tbus;
+
+	ctrl->pci_bus->number = bus_num;
+
+	for (tdevice = 0; tdevice < 0x100; tdevice++) {
+		//Scan for access first
+		if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
+			continue;
+		dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
+		//Yep we got one. Not a bridge ?
+		if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
+			*dev_num = tdevice;
+			dbg("found it !\n");
+			return 0;
+		}
+	}
+	for (tdevice = 0; tdevice < 0x100; tdevice++) {
+		//Scan for access first
+		if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
+			continue;
+		dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
+		//Yep we got one. bridge ?
+		if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
+			pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
+			dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
+			if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
+				return 0;
+		}
+	}
+
+	return -1;
+}
+
+
+static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
+{
+	struct irq_routing_table *PCIIRQRoutingInfoLength;
+	long len;
+	long loop;
+	u32 work;
+
+	u8 tbus, tdevice, tslot;
+
+	PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
+	if (!PCIIRQRoutingInfoLength)
+		return -1;
+
+	len = (PCIIRQRoutingInfoLength->size -
+	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
+	// Make sure I got at least one entry
+	if (len == 0) {
+		if (PCIIRQRoutingInfoLength != NULL)
+			kfree(PCIIRQRoutingInfoLength );
+		return -1;
+	}
+
+	for (loop = 0; loop < len; ++loop) {
+		tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
+		tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn;
+		tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
+
+		if (tslot == slot) {
+			*bus_num = tbus;
+			*dev_num = tdevice;
+			ctrl->pci_bus->number = tbus;
+			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
+			if (!nobridge || (work == 0xffffffff)) {
+				if (PCIIRQRoutingInfoLength != NULL)
+					kfree(PCIIRQRoutingInfoLength );
+				return 0;
+			}
+
+			dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
+			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
+			dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);
+
+			if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
+				pci_bus_read_config_byte (ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
+				dbg("Scan bus for Non Bridge: bus %d\n", tbus);
+				if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
+					*bus_num = tbus;
+					if (PCIIRQRoutingInfoLength != NULL)
+						kfree(PCIIRQRoutingInfoLength );
+					return 0;
+				}
+			} else {
+				if (PCIIRQRoutingInfoLength != NULL)
+					kfree(PCIIRQRoutingInfoLength );
+				return 0;
+			}
+
+		}
+	}
+	if (PCIIRQRoutingInfoLength != NULL)
+		kfree(PCIIRQRoutingInfoLength );
+	return -1;
+}
+
+
+int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot)
+{
+	return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0);	//plain (bridges allowed)
+}
+
+
+/* More PCI configuration routines; this time centered around hotplug controller */
+
+
+/*
+ * cpqhp_save_config
+ *
+ * Reads configuration for all slots in a PCI bus and saves info.
+ *
+ * Note:  For non-hot plug busses, the slot # saved is the device #
+ *
+ * returns 0 if success
+ */
+int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
+{
+	long rc;
+	u8 class_code;
+	u8 header_type;
+	u32 ID;
+	u8 secondary_bus;
+	struct pci_func *new_slot;
+	int sub_bus;
+	int FirstSupported;
+	int LastSupported;
+	int max_functions;
+	int function;
+	u8 DevError;
+	int device = 0;
+	int cloop = 0;
+	int stop_it;
+	int index;
+
+	//              Decide which slots are supported
+
+	if (is_hot_plug) {
+		//*********************************
+		// is_hot_plug is the slot mask
+		//*********************************
+		FirstSupported = is_hot_plug >> 4;
+		LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
+	} else {
+		FirstSupported = 0;
+		LastSupported = 0x1F;
+	}
+
+	//     Save PCI configuration space for all devices in supported slots
+	ctrl->pci_bus->number = busnumber;
+	for (device = FirstSupported; device <= LastSupported; device++) {
+		ID = 0xFFFFFFFF;
+		rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
+
+		if (ID != 0xFFFFFFFF) {	  //  device in slot
+			rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
+			if (rc)
+				return rc;
+
+			rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
+			if (rc)
+				return rc;
+
+			// If multi-function device, set max_functions to 8
+			if (header_type & 0x80)
+				max_functions = 8;
+			else
+				max_functions = 1;
+
+			function = 0;
+
+			do {
+				DevError = 0;
+
+				if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {   // P-P Bridge
+					//  Recurse the subordinate bus
+					//  get the subordinate bus number
+					rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
+					if (rc) {
+						return rc;
+					} else {
+						sub_bus = (int) secondary_bus;
+
+						// Save secondary bus cfg spc
+						// with this recursive call.
+						rc = cpqhp_save_config(ctrl, sub_bus, 0);
+						if (rc)
+							return rc;
+						ctrl->pci_bus->number = busnumber;
+					}
+				}
+
+				index = 0;
+				new_slot = cpqhp_slot_find(busnumber, device, index++);
+				while (new_slot && 
+				       (new_slot->function != (u8) function))
+					new_slot = cpqhp_slot_find(busnumber, device, index++);
+
+				if (!new_slot) {
+					// Setup slot structure.
+					new_slot = cpqhp_slot_create(busnumber);
+
+					if (new_slot == NULL)
+						return(1);
+				}
+
+				new_slot->bus = (u8) busnumber;
+				new_slot->device = (u8) device;
+				new_slot->function = (u8) function;
+				new_slot->is_a_board = 1;
+				new_slot->switch_save = 0x10;
+				// In case of unsupported board
+				new_slot->status = DevError;
+				new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
+
+				for (cloop = 0; cloop < 0x20; cloop++) {
+					rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
+					if (rc)
+						return rc;
+				}
+
+				function++;
+
+				stop_it = 0;
+
+				//  this loop skips to the next present function
+				//  reading in Class Code and Header type.
+
+				while ((function < max_functions)&&(!stop_it)) {
+					rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
+					if (ID == 0xFFFFFFFF) {	 // nothing there.
+						function++;
+					} else {  // Something there
+						rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
+						if (rc)
+							return rc;
+
+						rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
+						if (rc)
+							return rc;
+
+						stop_it++;
+					}
+				}
+
+			} while (function < max_functions);
+		}		// End of IF (device in slot?)
+		else if (is_hot_plug) {
+			// Setup slot structure with entry for empty slot
+			new_slot = cpqhp_slot_create(busnumber);
+
+			if (new_slot == NULL) {
+				return(1);
+			}
+
+			new_slot->bus = (u8) busnumber;
+			new_slot->device = (u8) device;
+			new_slot->function = 0;
+			new_slot->is_a_board = 0;
+			new_slot->presence_save = 0;
+			new_slot->switch_save = 0;
+		}
+	}			// End of FOR loop
+
+	return(0);
+}
+
+
+/*
+ * cpqhp_save_slot_config
+ *
+ * Saves configuration info for all PCI devices in a given slot
+ * including subordinate busses.
+ *
+ * returns 0 if success
+ */
+int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
+{
+	long rc;
+	u8 class_code;
+	u8 header_type;
+	u32 ID;
+	u8 secondary_bus;
+	int sub_bus;
+	int max_functions;
+	int function;
+	int cloop = 0;
+	int stop_it;
+
+	ID = 0xFFFFFFFF;
+
+	ctrl->pci_bus->number = new_slot->bus;
+	pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
+
+	if (ID != 0xFFFFFFFF) {	  //  device in slot
+		pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
+		pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
+
+		if (header_type & 0x80)	// Multi-function device
+			max_functions = 8;
+		else
+			max_functions = 1;
+
+		function = 0;
+
+		do {
+			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
+				//  Recurse the subordinate bus
+				pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
+
+				sub_bus = (int) secondary_bus;
+
+				// Save the config headers for the secondary bus.
+				rc = cpqhp_save_config(ctrl, sub_bus, 0);
+				if (rc)
+					return(rc);
+				ctrl->pci_bus->number = new_slot->bus;
+
+			}	// End of IF
+
+			new_slot->status = 0;
+
+			for (cloop = 0; cloop < 0x20; cloop++) {
+				pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
+			}
+
+			function++;
+
+			stop_it = 0;
+
+			//  this loop skips to the next present function
+			//  reading in the Class Code and the Header type.
+
+			while ((function < max_functions) && (!stop_it)) {
+				pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
+
+				if (ID == 0xFFFFFFFF) {	 // nothing there.
+					function++;
+				} else {  // Something there
+					pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
+
+					pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
+
+					stop_it++;
+				}
+			}
+
+		} while (function < max_functions);
+	}			// End of IF (device in slot?)
+	else {
+		return(2);
+	}
+
+	return(0);
+}
+
+
+/*
+ * cpqhp_save_base_addr_length
+ *
+ * Saves the length of all base address registers for the
+ * specified slot.  this is for hot plug REPLACE
+ *
+ * returns 0 if success
+ */
+int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
+{
+	u8 cloop;
+	u8 header_type;
+	u8 secondary_bus;
+	u8 type;
+	int sub_bus;
+	u32 temp_register;
+	u32 base;
+	u32 rc;
+	struct pci_func *next;
+	int index = 0;
+	struct pci_bus *pci_bus = ctrl->pci_bus;
+	unsigned int devfn;
+
+	func = cpqhp_slot_find(func->bus, func->device, index++);
+
+	while (func != NULL) {
+		pci_bus->number = func->bus;
+		devfn = PCI_DEVFN(func->device, func->function);
+
+		// Check for Bridge
+		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+
+		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+			// PCI-PCI Bridge
+			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
+
+			sub_bus = (int) secondary_bus;
+
+			next = cpqhp_slot_list[sub_bus];
+
+			while (next != NULL) {
+				rc = cpqhp_save_base_addr_length(ctrl, next);
+
+				if (rc)
+					return(rc);
+
+				next = next->next;
+			}
+			pci_bus->number = func->bus;
+
+			//FIXME: this loop is duplicated in the non-bridge case.  The two could be rolled together
+			// Figure out IO and memory base lengths
+			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
+				temp_register = 0xFFFFFFFF;
+				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
+
+				if (base) {  // If this register is implemented
+					if (base & 0x01L) {
+						// IO base
+						// set base = amount of IO space requested
+						base = base & 0xFFFFFFFE;
+						base = (~base) + 1;
+
+						type = 1;
+					} else {
+						// memory base
+						base = base & 0xFFFFFFF0;
+						base = (~base) + 1;
+
+						type = 0;
+					}
+				} else {
+					base = 0x0L;
+					type = 0;
+				}
+
+				// Save information in slot structure
+				func->base_length[(cloop - 0x10) >> 2] =
+				base;
+				func->base_type[(cloop - 0x10) >> 2] = type;
+
+			}	// End of base register loop
+
+
+		} else if ((header_type & 0x7F) == 0x00) {	  // PCI-PCI Bridge
+			// Figure out IO and memory base lengths
+			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
+				temp_register = 0xFFFFFFFF;
+				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
+
+				if (base) {  // If this register is implemented
+					if (base & 0x01L) {
+						// IO base
+						// base = amount of IO space requested
+						base = base & 0xFFFFFFFE;
+						base = (~base) + 1;
+
+						type = 1;
+					} else {
+						// memory base
+						// base = amount of memory space requested
+						base = base & 0xFFFFFFF0;
+						base = (~base) + 1;
+
+						type = 0;
+					}
+				} else {
+					base = 0x0L;
+					type = 0;
+				}
+
+				// Save information in slot structure
+				func->base_length[(cloop - 0x10) >> 2] = base;
+				func->base_type[(cloop - 0x10) >> 2] = type;
+
+			}	// End of base register loop
+
+		} else {	  // Some other unknown header type
+		}
+
+		// find the next device in this slot
+		func = cpqhp_slot_find(func->bus, func->device, index++);
+	}
+
+	return(0);
+}
+
+
+/*
+ * cpqhp_save_used_resources
+ *
+ * Stores used resource information for existing boards.  this is
+ * for boards that were in the system when this driver was loaded.
+ * this function is for hot plug ADD
+ *
+ * returns 0 if success
+ */
+int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
+{
+	u8 cloop;
+	u8 header_type;
+	u8 secondary_bus;
+	u8 temp_byte;
+	u8 b_base;
+	u8 b_length;
+	u16 command;
+	u16 save_command;
+	u16 w_base;
+	u16 w_length;
+	u32 temp_register;
+	u32 save_base;
+	u32 base;
+	int index = 0;
+	struct pci_resource *mem_node;
+	struct pci_resource *p_mem_node;
+	struct pci_resource *io_node;
+	struct pci_resource *bus_node;
+	struct pci_bus *pci_bus = ctrl->pci_bus;
+	unsigned int devfn;
+
+	func = cpqhp_slot_find(func->bus, func->device, index++);
+
+	while ((func != NULL) && func->is_a_board) {
+		pci_bus->number = func->bus;
+		devfn = PCI_DEVFN(func->device, func->function);
+
+		// Save the command register
+		pci_bus_read_config_word (pci_bus, devfn, PCI_COMMAND, &save_command);
+
+		// disable card
+		command = 0x00;
+		pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
+
+		// Check for Bridge
+		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+
+		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
+			// Clear Bridge Control Register
+			command = 0x00;
+			pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
+			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
+			pci_bus_read_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
+
+			bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+			if (!bus_node)
+				return -ENOMEM;
+
+			bus_node->base = secondary_bus;
+			bus_node->length = temp_byte - secondary_bus + 1;
+
+			bus_node->next = func->bus_head;
+			func->bus_head = bus_node;
+
+			// Save IO base and Limit registers
+			pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_BASE, &b_base);
+			pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_LIMIT, &b_length);
+
+			if ((b_base <= b_length) && (save_command & 0x01)) {
+				io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+				if (!io_node)
+					return -ENOMEM;
+
+				io_node->base = (b_base & 0xF0) << 8;
+				io_node->length = (b_length - b_base + 0x10) << 8;
+
+				io_node->next = func->io_head;
+				func->io_head = io_node;
+			}
+
+			// Save memory base and Limit registers
+			pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
+			pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
+
+			if ((w_base <= w_length) && (save_command & 0x02)) {
+				mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+				if (!mem_node)
+					return -ENOMEM;
+
+				mem_node->base = w_base << 16;
+				mem_node->length = (w_length - w_base + 0x10) << 16;
+
+				mem_node->next = func->mem_head;
+				func->mem_head = mem_node;
+			}
+
+			// Save prefetchable memory base and Limit registers
+			pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
+			pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
+
+			if ((w_base <= w_length) && (save_command & 0x02)) {
+				p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+				if (!p_mem_node)
+					return -ENOMEM;
+
+				p_mem_node->base = w_base << 16;
+				p_mem_node->length = (w_length - w_base + 0x10) << 16;
+
+				p_mem_node->next = func->p_mem_head;
+				func->p_mem_head = p_mem_node;
+			}
+			// Figure out IO and memory base lengths
+			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
+				pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
+
+				temp_register = 0xFFFFFFFF;
+				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
+
+				temp_register = base;
+
+				if (base) {  // If this register is implemented
+					if (((base & 0x03L) == 0x01)
+					    && (save_command & 0x01)) {
+						// IO base
+						// set temp_register = amount of IO space requested
+						temp_register = base & 0xFFFFFFFE;
+						temp_register = (~temp_register) + 1;
+
+						io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+						if (!io_node)
+							return -ENOMEM;
+
+						io_node->base =
+						save_base & (~0x03L);
+						io_node->length = temp_register;
+
+						io_node->next = func->io_head;
+						func->io_head = io_node;
+					} else
+						if (((base & 0x0BL) == 0x08)
+						    && (save_command & 0x02)) {
+						// prefetchable memory base
+						temp_register = base & 0xFFFFFFF0;
+						temp_register = (~temp_register) + 1;
+
+						p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+						if (!p_mem_node)
+							return -ENOMEM;
+
+						p_mem_node->base = save_base & (~0x0FL);
+						p_mem_node->length = temp_register;
+
+						p_mem_node->next = func->p_mem_head;
+						func->p_mem_head = p_mem_node;
+					} else
+						if (((base & 0x0BL) == 0x00)
+						    && (save_command & 0x02)) {
+						// prefetchable memory base
+						temp_register = base & 0xFFFFFFF0;
+						temp_register = (~temp_register) + 1;
+
+						mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+						if (!mem_node)
+							return -ENOMEM;
+
+						mem_node->base = save_base & (~0x0FL);
+						mem_node->length = temp_register;
+
+						mem_node->next = func->mem_head;
+						func->mem_head = mem_node;
+					} else
+						return(1);
+				}
+			}	// End of base register loop
+		} else if ((header_type & 0x7F) == 0x00) {	  // Standard header
+			// Figure out IO and memory base lengths
+			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
+				pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
+
+				temp_register = 0xFFFFFFFF;
+				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
+
+				temp_register = base;
+
+				if (base) {	  // If this register is implemented
+					if (((base & 0x03L) == 0x01)
+					    && (save_command & 0x01)) {
+						// IO base
+						// set temp_register = amount of IO space requested
+						temp_register = base & 0xFFFFFFFE;
+						temp_register = (~temp_register) + 1;
+
+						io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+						if (!io_node)
+							return -ENOMEM;
+
+						io_node->base = save_base & (~0x01L);
+						io_node->length = temp_register;
+
+						io_node->next = func->io_head;
+						func->io_head = io_node;
+					} else
+						if (((base & 0x0BL) == 0x08)
+						    && (save_command & 0x02)) {
+						// prefetchable memory base
+						temp_register = base & 0xFFFFFFF0;
+						temp_register = (~temp_register) + 1;
+
+						p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+						if (!p_mem_node)
+							return -ENOMEM;
+
+						p_mem_node->base = save_base & (~0x0FL);
+						p_mem_node->length = temp_register;
+
+						p_mem_node->next = func->p_mem_head;
+						func->p_mem_head = p_mem_node;
+					} else
+						if (((base & 0x0BL) == 0x00)
+						    && (save_command & 0x02)) {
+						// prefetchable memory base
+						temp_register = base & 0xFFFFFFF0;
+						temp_register = (~temp_register) + 1;
+
+						mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+						if (!mem_node)
+							return -ENOMEM;
+
+						mem_node->base = save_base & (~0x0FL);
+						mem_node->length = temp_register;
+
+						mem_node->next = func->mem_head;
+						func->mem_head = mem_node;
+					} else
+						return(1);
+				}
+			}	// End of base register loop
+		} else {	  // Some other unknown header type
+		}
+
+		// find the next device in this slot
+		func = cpqhp_slot_find(func->bus, func->device, index++);
+	}
+
+	return(0);
+}
+
+
+/*
+ * cpqhp_configure_board
+ *
+ * Copies saved configuration information to one slot.
+ * this is called recursively for bridge devices.
+ * this is for hot plug REPLACE!
+ *
+ * returns 0 if success
+ */
+int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
+{
+	int cloop;
+	u8 header_type;
+	u8 secondary_bus;
+	int sub_bus;
+	struct pci_func *next;
+	u32 temp;
+	u32 rc;
+	int index = 0;
+	struct pci_bus *pci_bus = ctrl->pci_bus;
+	unsigned int devfn;
+
+	func = cpqhp_slot_find(func->bus, func->device, index++);
+
+	while (func != NULL) {
+		pci_bus->number = func->bus;
+		devfn = PCI_DEVFN(func->device, func->function);
+
+		// Start at the top of config space so that the control
+		// registers are programmed last
+		for (cloop = 0x3C; cloop > 0; cloop -= 4) {
+			pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
+		}
+
+		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+
+		// If this is a bridge device, restore subordinate devices
+		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
+			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
+
+			sub_bus = (int) secondary_bus;
+
+			next = cpqhp_slot_list[sub_bus];
+
+			while (next != NULL) {
+				rc = cpqhp_configure_board(ctrl, next);
+
+				if (rc)
+					return rc;
+
+				next = next->next;
+			}
+		} else {
+
+			// Check all the base Address Registers to make sure
+			// they are the same.  If not, the board is different.
+
+			for (cloop = 16; cloop < 40; cloop += 4) {
+				pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
+
+				if (temp != func->config_space[cloop >> 2]) {
+					dbg("Config space compare failure!!! offset = %x\n", cloop);
+					dbg("bus = %x, device = %x, function = %x\n", func->bus, func->device, func->function);
+					dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop >> 2]);
+					return 1;
+				}
+			}
+		}
+
+		func->configured = 1;
+
+		func = cpqhp_slot_find(func->bus, func->device, index++);
+	}
+
+	return 0;
+}
+
+
+/*
+ * cpqhp_valid_replace
+ *
+ * this function checks to see if a board is the same as the
+ * one it is replacing.  this check will detect if the device's
+ * vendor or device id's are the same
+ *
+ * returns 0 if the board is the same nonzero otherwise
+ */
+int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
+{
+	u8 cloop;
+	u8 header_type;
+	u8 secondary_bus;
+	u8 type;
+	u32 temp_register = 0;
+	u32 base;
+	u32 rc;
+	struct pci_func *next;
+	int index = 0;
+	struct pci_bus *pci_bus = ctrl->pci_bus;
+	unsigned int devfn;
+
+	if (!func->is_a_board)
+		return(ADD_NOT_SUPPORTED);
+
+	func = cpqhp_slot_find(func->bus, func->device, index++);
+
+	while (func != NULL) {
+		pci_bus->number = func->bus;
+		devfn = PCI_DEVFN(func->device, func->function);
+
+		pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
+
+		// No adapter present
+		if (temp_register == 0xFFFFFFFF)
+			return(NO_ADAPTER_PRESENT);
+
+		if (temp_register != func->config_space[0])
+			return(ADAPTER_NOT_SAME);
+
+		// Check for same revision number and class code
+		pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
+
+		// Adapter not the same
+		if (temp_register != func->config_space[0x08 >> 2])
+			return(ADAPTER_NOT_SAME);
+
+		// Check for Bridge
+		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
+
+		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
+			// In order to continue checking, we must program the
+			// bus registers in the bridge to respond to accesses
+			// for it's subordinate bus(es)
+
+			temp_register = func->config_space[0x18 >> 2];
+			pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
+
+			secondary_bus = (temp_register >> 8) & 0xFF;
+
+			next = cpqhp_slot_list[secondary_bus];
+
+			while (next != NULL) {
+				rc = cpqhp_valid_replace(ctrl, next);
+
+				if (rc)
+					return(rc);
+
+				next = next->next;
+			}
+
+		}
+		// Check to see if it is a standard config header
+		else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
+			// Check subsystem vendor and ID
+			pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
+
+			if (temp_register != func->config_space[0x2C >> 2]) {
+				// If it's a SMART-2 and the register isn't filled
+				// in, ignore the difference because
+				// they just have an old rev of the firmware
+
+				if (!((func->config_space[0] == 0xAE100E11)
+				      && (temp_register == 0x00L)))
+					return(ADAPTER_NOT_SAME);
+			}
+			// Figure out IO and memory base lengths
+			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
+				temp_register = 0xFFFFFFFF;
+				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
+				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
+				if (base) {	  // If this register is implemented
+					if (base & 0x01L) {
+						// IO base
+						// set base = amount of IO space requested
+						base = base & 0xFFFFFFFE;
+						base = (~base) + 1;
+
+						type = 1;
+					} else {
+						// memory base
+						base = base & 0xFFFFFFF0;
+						base = (~base) + 1;
+
+						type = 0;
+					}
+				} else {
+					base = 0x0L;
+					type = 0;
+				}
+
+				// Check information in slot structure
+				if (func->base_length[(cloop - 0x10) >> 2] != base)
+					return(ADAPTER_NOT_SAME);
+
+				if (func->base_type[(cloop - 0x10) >> 2] != type)
+					return(ADAPTER_NOT_SAME);
+
+			}	// End of base register loop
+
+		}		// End of (type 0 config space) else
+		else {
+			// this is not a type 0 or 1 config space header so
+			// we don't know how to do it
+			return(DEVICE_TYPE_NOT_SUPPORTED);
+		}
+
+		// Get the next function
+		func = cpqhp_slot_find(func->bus, func->device, index++);
+	}
+
+
+	return(0);
+}
+
+
+/*
+ * cpqhp_find_available_resources
+ *
+ * Finds available memory, IO, and IRQ resources for programming
+ * devices which may be added to the system
+ * this function is for hot plug ADD!
+ *
+ * returns 0 if success
+ */  
+int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
+{
+	u8 temp;
+	u8 populated_slot;
+	u8 bridged_slot;
+	void *one_slot;
+	struct pci_func *func = NULL;
+	int i = 10, index;
+	u32 temp_dword, rc;
+	struct pci_resource *mem_node;
+	struct pci_resource *p_mem_node;
+	struct pci_resource *io_node;
+	struct pci_resource *bus_node;
+	void *rom_resource_table;
+
+	rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
+	dbg("rom_resource_table = %p\n", rom_resource_table);
+
+	if (rom_resource_table == NULL) {
+		return -ENODEV;
+	}
+	// Sum all resources and setup resource maps
+	unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
+	dbg("unused_IRQ = %x\n", unused_IRQ);
+
+	temp = 0;
+	while (unused_IRQ) {
+		if (unused_IRQ & 1) {
+			cpqhp_disk_irq = temp;
+			break;
+		}
+		unused_IRQ = unused_IRQ >> 1;
+		temp++;
+	}
+
+	dbg("cpqhp_disk_irq= %d\n", cpqhp_disk_irq);
+	unused_IRQ = unused_IRQ >> 1;
+	temp++;
+
+	while (unused_IRQ) {
+		if (unused_IRQ & 1) {
+			cpqhp_nic_irq = temp;
+			break;
+		}
+		unused_IRQ = unused_IRQ >> 1;
+		temp++;
+	}
+
+	dbg("cpqhp_nic_irq= %d\n", cpqhp_nic_irq);
+	unused_IRQ = readl(rom_resource_table + PCIIRQ);
+
+	temp = 0;
+
+	if (!cpqhp_nic_irq) {
+		cpqhp_nic_irq = ctrl->cfgspc_irq;
+	}
+
+	if (!cpqhp_disk_irq) {
+		cpqhp_disk_irq = ctrl->cfgspc_irq;
+	}
+
+	dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
+
+	rc = compaq_nvram_load(rom_start, ctrl);
+	if (rc)
+		return rc;
+
+	one_slot = rom_resource_table + sizeof (struct hrt);
+
+	i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
+	dbg("number_of_entries = %d\n", i);
+
+	if (!readb(one_slot + SECONDARY_BUS)) {
+		return(1);
+	}
+
+	dbg("dev|IO base|length|Mem base|length|Pre base|length|PB SB MB\n");
+
+	while (i && readb(one_slot + SECONDARY_BUS)) {
+		u8 dev_func = readb(one_slot + DEV_FUNC);
+		u8 primary_bus = readb(one_slot + PRIMARY_BUS);
+		u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
+		u8 max_bus = readb(one_slot + MAX_BUS);
+		u16 io_base = readw(one_slot + IO_BASE);
+		u16 io_length = readw(one_slot + IO_LENGTH);
+		u16 mem_base = readw(one_slot + MEM_BASE);
+		u16 mem_length = readw(one_slot + MEM_LENGTH);
+		u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
+		u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
+
+		dbg("%2.2x | %4.4x  | %4.4x | %4.4x   | %4.4x | %4.4x   | %4.4x |%2.2x %2.2x %2.2x\n",
+		    dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
+		    primary_bus, secondary_bus, max_bus);
+
+		// If this entry isn't for our controller's bus, ignore it
+		if (primary_bus != ctrl->bus) {
+			i--;
+			one_slot += sizeof (struct slot_rt);
+			continue;
+		}
+		// find out if this entry is for an occupied slot
+		ctrl->pci_bus->number = primary_bus;
+		pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
+		dbg("temp_D_word = %x\n", temp_dword);
+
+		if (temp_dword != 0xFFFFFFFF) {
+			index = 0;
+			func = cpqhp_slot_find(primary_bus, dev_func >> 3, 0);
+
+			while (func && (func->function != (dev_func & 0x07))) {
+				dbg("func = %p (bus, dev, fun) = (%d, %d, %d)\n", func, primary_bus, dev_func >> 3, index);
+				func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
+			}
+
+			// If we can't find a match, skip this table entry
+			if (!func) {
+				i--;
+				one_slot += sizeof (struct slot_rt);
+				continue;
+			}
+			// this may not work and shouldn't be used
+			if (secondary_bus != primary_bus)
+				bridged_slot = 1;
+			else
+				bridged_slot = 0;
+
+			populated_slot = 1;
+		} else {
+			populated_slot = 0;
+			bridged_slot = 0;
+		}
+
+
+		// If we've got a valid IO base, use it
+
+		temp_dword = io_base + io_length;
+
+		if ((io_base) && (temp_dword < 0x10000)) {
+			io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+			if (!io_node)
+				return -ENOMEM;
+
+			io_node->base = io_base;
+			io_node->length = io_length;
+
+			dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length);
+			dbg("populated slot =%d \n", populated_slot);
+			if (!populated_slot) {
+				io_node->next = ctrl->io_head;
+				ctrl->io_head = io_node;
+			} else {
+				io_node->next = func->io_head;
+				func->io_head = io_node;
+			}
+		}
+
+		// If we've got a valid memory base, use it
+		temp_dword = mem_base + mem_length;
+		if ((mem_base) && (temp_dword < 0x10000)) {
+			mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+			if (!mem_node)
+				return -ENOMEM;
+
+			mem_node->base = mem_base << 16;
+
+			mem_node->length = mem_length << 16;
+
+			dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length);
+			dbg("populated slot =%d \n", populated_slot);
+			if (!populated_slot) {
+				mem_node->next = ctrl->mem_head;
+				ctrl->mem_head = mem_node;
+			} else {
+				mem_node->next = func->mem_head;
+				func->mem_head = mem_node;
+			}
+		}
+
+		// If we've got a valid prefetchable memory base, and
+		// the base + length isn't greater than 0xFFFF
+		temp_dword = pre_mem_base + pre_mem_length;
+		if ((pre_mem_base) && (temp_dword < 0x10000)) {
+			p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+			if (!p_mem_node)
+				return -ENOMEM;
+
+			p_mem_node->base = pre_mem_base << 16;
+
+			p_mem_node->length = pre_mem_length << 16;
+			dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length);
+			dbg("populated slot =%d \n", populated_slot);
+
+			if (!populated_slot) {
+				p_mem_node->next = ctrl->p_mem_head;
+				ctrl->p_mem_head = p_mem_node;
+			} else {
+				p_mem_node->next = func->p_mem_head;
+				func->p_mem_head = p_mem_node;
+			}
+		}
+
+		// If we've got a valid bus number, use it
+		// The second condition is to ignore bus numbers on
+		// populated slots that don't have PCI-PCI bridges
+		if (secondary_bus && (secondary_bus != primary_bus)) {
+			bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+			if (!bus_node)
+				return -ENOMEM;
+
+			bus_node->base = secondary_bus;
+			bus_node->length = max_bus - secondary_bus + 1;
+			dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length);
+			dbg("populated slot =%d \n", populated_slot);
+			if (!populated_slot) {
+				bus_node->next = ctrl->bus_head;
+				ctrl->bus_head = bus_node;
+			} else {
+				bus_node->next = func->bus_head;
+				func->bus_head = bus_node;
+			}
+		}
+
+		i--;
+		one_slot += sizeof (struct slot_rt);
+	}
+
+	// If all of the following fail, we don't have any resources for
+	// hot plug add
+	rc = 1;
+	rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
+	rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
+	rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
+	rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
+
+	return(rc);
+}
+
+
+/*
+ * cpqhp_return_board_resources
+ *
+ * this routine returns all resources allocated to a board to
+ * the available pool.
+ *
+ * returns 0 if success
+ */
+int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * resources)
+{
+	int rc = 0;
+	struct pci_resource *node;
+	struct pci_resource *t_node;
+	dbg("%s\n", __FUNCTION__);
+
+	if (!func)
+		return(1);
+
+	node = func->io_head;
+	func->io_head = NULL;
+	while (node) {
+		t_node = node->next;
+		return_resource(&(resources->io_head), node);
+		node = t_node;
+	}
+
+	node = func->mem_head;
+	func->mem_head = NULL;
+	while (node) {
+		t_node = node->next;
+		return_resource(&(resources->mem_head), node);
+		node = t_node;
+	}
+
+	node = func->p_mem_head;
+	func->p_mem_head = NULL;
+	while (node) {
+		t_node = node->next;
+		return_resource(&(resources->p_mem_head), node);
+		node = t_node;
+	}
+
+	node = func->bus_head;
+	func->bus_head = NULL;
+	while (node) {
+		t_node = node->next;
+		return_resource(&(resources->bus_head), node);
+		node = t_node;
+	}
+
+	rc |= cpqhp_resource_sort_and_combine(&(resources->mem_head));
+	rc |= cpqhp_resource_sort_and_combine(&(resources->p_mem_head));
+	rc |= cpqhp_resource_sort_and_combine(&(resources->io_head));
+	rc |= cpqhp_resource_sort_and_combine(&(resources->bus_head));
+
+	return(rc);
+}
+
+
+/*
+ * cpqhp_destroy_resource_list
+ *
+ * Puts node back in the resource list pointed to by head
+ */
+void cpqhp_destroy_resource_list (struct resource_lists * resources)
+{
+	struct pci_resource *res, *tres;
+
+	res = resources->io_head;
+	resources->io_head = NULL;
+
+	while (res) {
+		tres = res;
+		res = res->next;
+		kfree(tres);
+	}
+
+	res = resources->mem_head;
+	resources->mem_head = NULL;
+
+	while (res) {
+		tres = res;
+		res = res->next;
+		kfree(tres);
+	}
+
+	res = resources->p_mem_head;
+	resources->p_mem_head = NULL;
+
+	while (res) {
+		tres = res;
+		res = res->next;
+		kfree(tres);
+	}
+
+	res = resources->bus_head;
+	resources->bus_head = NULL;
+
+	while (res) {
+		tres = res;
+		res = res->next;
+		kfree(tres);
+	}
+}
+
+
+/*
+ * cpqhp_destroy_board_resources
+ *
+ * Puts node back in the resource list pointed to by head
+ */
+void cpqhp_destroy_board_resources (struct pci_func * func)
+{
+	struct pci_resource *res, *tres;
+
+	res = func->io_head;
+	func->io_head = NULL;
+
+	while (res) {
+		tres = res;
+		res = res->next;
+		kfree(tres);
+	}
+
+	res = func->mem_head;
+	func->mem_head = NULL;
+
+	while (res) {
+		tres = res;
+		res = res->next;
+		kfree(tres);
+	}
+
+	res = func->p_mem_head;
+	func->p_mem_head = NULL;
+
+	while (res) {
+		tres = res;
+		res = res->next;
+		kfree(tres);
+	}
+
+	res = func->bus_head;
+	func->bus_head = NULL;
+
+	while (res) {
+		tres = res;
+		res = res->next;
+		kfree(tres);
+	}
+}
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_sysfs.c linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_sysfs.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/cpqphp_sysfs.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/cpqphp_sysfs.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,143 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include "cpqphp.h"
+
+
+/* A few routines that create sysfs entries for the hot plug controller */
+
+static int show_ctrl (struct device *dev, char *buf)
+{
+	struct pci_dev *pci_dev;
+	struct controller *ctrl;
+	char * out = buf;
+	int index;
+	struct pci_resource *res;
+
+	pci_dev = container_of (dev, struct pci_dev, dev);
+	ctrl = pci_get_drvdata(pci_dev);
+
+	out += sprintf(buf, "Free resources: memory\n");
+	index = 11;
+	res = ctrl->mem_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: prefetchable memory\n");
+	index = 11;
+	res = ctrl->p_mem_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: IO\n");
+	index = 11;
+	res = ctrl->io_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: bus numbers\n");
+	index = 11;
+	res = ctrl->bus_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+
+	return out - buf;
+}
+static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
+
+static int show_dev (struct device *dev, char *buf)
+{
+	struct pci_dev *pci_dev;
+	struct controller *ctrl;
+	char * out = buf;
+	int index;
+	struct pci_resource *res;
+	struct pci_func *new_slot;
+	struct slot *slot;
+
+	pci_dev = container_of (dev, struct pci_dev, dev);
+	ctrl = pci_get_drvdata(pci_dev);
+
+	slot=ctrl->slot;
+
+	while (slot) {
+		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
+		if (!new_slot)
+			break;
+		out += sprintf(out, "assigned resources: memory\n");
+		index = 11;
+		res = new_slot->mem_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: prefetchable memory\n");
+		index = 11;
+		res = new_slot->p_mem_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: IO\n");
+		index = 11;
+		res = new_slot->io_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: bus numbers\n");
+		index = 11;
+		res = new_slot->bus_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		slot=slot->next;
+	}
+
+	return out - buf;
+}
+static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
+
+void cpqhp_create_ctrl_files (struct controller *ctrl)
+{
+	device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
+	device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
+}
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp.h linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp.h
--- linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp.h	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,772 @@
+#ifndef __IBMPHP_H
+#define __IBMPHP_H
+
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include "pci_hotplug.h"
+
+extern int ibmphp_debug;
+
+#if !defined(CONFIG_HOTPLUG_PCI_IBM_MODULE)
+	#define MY_NAME "ibmphpd"
+#else
+	#define MY_NAME THIS_MODULE->name
+#endif
+#define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
+#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+
+
+/* EBDA stuff */
+
+/***********************************************************
+* SLOT CAPABILITY                                          *
+***********************************************************/
+
+#define EBDA_SLOT_133_MAX		0x20
+#define EBDA_SLOT_100_MAX		0x10
+#define EBDA_SLOT_66_MAX		0x02
+#define EBDA_SLOT_PCIX_CAP		0x08
+
+
+/************************************************************
+*  RESOURE TYPE                                             *
+************************************************************/
+
+#define EBDA_RSRC_TYPE_MASK		0x03
+#define EBDA_IO_RSRC_TYPE		0x00
+#define EBDA_MEM_RSRC_TYPE		0x01
+#define EBDA_PFM_RSRC_TYPE		0x03
+#define EBDA_RES_RSRC_TYPE		0x02
+
+
+/*************************************************************
+*  IO RESTRICTION TYPE                                       *
+*************************************************************/
+
+#define EBDA_IO_RESTRI_MASK		0x0c
+#define EBDA_NO_RESTRI			0x00
+#define EBDA_AVO_VGA_ADDR		0x04
+#define EBDA_AVO_VGA_ADDR_AND_ALIA	0x08
+#define EBDA_AVO_ISA_ADDR		0x0c
+
+
+/**************************************************************
+*  DEVICE TYPE DEF                                            *
+**************************************************************/
+
+#define EBDA_DEV_TYPE_MASK		0x10
+#define EBDA_PCI_DEV			0x10
+#define EBDA_NON_PCI_DEV		0x00
+
+
+/***************************************************************
+*  PRIMARY DEF DEFINITION                                      *
+***************************************************************/
+
+#define EBDA_PRI_DEF_MASK		0x20
+#define EBDA_PRI_PCI_BUS_INFO		0x20
+#define EBDA_NORM_DEV_RSRC_INFO		0x00
+
+
+//--------------------------------------------------------------
+// RIO TABLE DATA STRUCTURE
+//--------------------------------------------------------------
+
+struct rio_table_hdr {
+	u8 ver_num; 
+	u8 scal_count;
+	u8 riodev_count;
+	u16 offset;
+};
+
+//-------------------------------------------------------------
+// SCALABILITY DETAIL
+//-------------------------------------------------------------
+
+struct scal_detail {
+	u8 node_id;
+	u32 cbar;
+	u8 port0_node_connect;
+	u8 port0_port_connect;
+	u8 port1_node_connect;
+	u8 port1_port_connect;
+	u8 port2_node_connect;
+	u8 port2_port_connect;
+	u8 chassis_num;
+//	struct list_head scal_detail_list;
+};
+
+//--------------------------------------------------------------
+// RIO DETAIL 
+//--------------------------------------------------------------
+
+struct rio_detail {
+	u8 rio_node_id;
+	u32 bbar;
+	u8 rio_type;
+	u8 owner_id;
+	u8 port0_node_connect;
+	u8 port0_port_connect;
+	u8 port1_node_connect;
+	u8 port1_port_connect;
+	u8 first_slot_num;
+	u8 status;
+	u8 wpindex;
+	u8 chassis_num;
+	struct list_head rio_detail_list;
+};
+
+struct opt_rio {
+	u8 rio_type;
+	u8 chassis_num;
+	u8 first_slot_num;
+	u8 middle_num;
+	struct list_head opt_rio_list;
+};	
+
+struct opt_rio_lo {
+	u8 rio_type;
+	u8 chassis_num;
+	u8 first_slot_num;
+	u8 middle_num;
+	u8 pack_count;
+	struct list_head opt_rio_lo_list;
+};	
+
+/****************************************************************
+*  HPC DESCRIPTOR NODE                                          *
+****************************************************************/
+
+struct ebda_hpc_list {
+	u8 format;
+	u16 num_ctlrs;
+	short phys_addr;
+//      struct list_head ebda_hpc_list;
+};
+/*****************************************************************
+*   IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS           *
+*   STRUCTURE                                                    *
+*****************************************************************/
+
+struct ebda_hpc_slot {
+	u8 slot_num;
+	u32 slot_bus_num;
+	u8 ctl_index;
+	u8 slot_cap;
+};
+
+struct ebda_hpc_bus {
+	u32 bus_num;
+	u8 slots_at_33_conv;
+	u8 slots_at_66_conv;
+	u8 slots_at_66_pcix;
+	u8 slots_at_100_pcix;
+	u8 slots_at_133_pcix;
+};
+
+
+/********************************************************************
+*   THREE TYPE OF HOT PLUG CONTROLER                                *
+********************************************************************/
+
+struct isa_ctlr_access {
+	u16 io_start;
+	u16 io_end;
+};
+
+struct pci_ctlr_access {
+	u8 bus;
+	u8 dev_fun;
+};
+
+struct wpeg_i2c_ctlr_access {
+	ulong wpegbbar;
+	u8 i2c_addr;
+};
+
+#define HPC_DEVICE_ID		0x0246
+#define HPC_SUBSYSTEM_ID	0x0247
+#define HPC_PCI_OFFSET		0x40
+/*************************************************************************
+*   RSTC DESCRIPTOR NODE                                                 *
+*************************************************************************/
+
+struct ebda_rsrc_list {
+	u8 format;
+	u16 num_entries;
+	u16 phys_addr;
+	struct ebda_rsrc_list *next;
+};
+
+
+/***************************************************************************
+*   PCI RSRC NODE                                                          *
+***************************************************************************/
+
+struct ebda_pci_rsrc {
+	u8 rsrc_type;
+	u8 bus_num;
+	u8 dev_fun;
+	u32 start_addr;
+	u32 end_addr;
+	u8 marked;	/* for NVRAM */
+	struct list_head ebda_pci_rsrc_list;
+};
+
+
+/***********************************************************
+* BUS_INFO DATE STRUCTURE                                  *
+***********************************************************/
+
+struct bus_info {
+	u8 slot_min;
+	u8 slot_max;
+	u8 slot_count;
+	u8 busno;
+	u8 controller_id;
+	u8 current_speed;
+	u8 current_bus_mode;
+	u8 index;
+	u8 slots_at_33_conv;
+	u8 slots_at_66_conv;
+	u8 slots_at_66_pcix;
+	u8 slots_at_100_pcix;
+	u8 slots_at_133_pcix;
+	struct list_head bus_info_list;
+};
+
+
+/***********************************************************
+* GLOBAL VARIABLES                                         *
+***********************************************************/
+extern struct list_head ibmphp_ebda_pci_rsrc_head;
+extern struct list_head ibmphp_slot_head;
+extern struct list_head ibmphp_res_head;
+/***********************************************************
+* FUNCTION PROTOTYPES                                      *
+***********************************************************/
+
+extern void ibmphp_free_ebda_hpc_queue (void);
+extern int ibmphp_access_ebda (void);
+extern struct slot *ibmphp_get_slot_from_physical_num (u8);
+extern int ibmphp_get_total_hp_slots (void);
+extern void ibmphp_free_ibm_slot (struct slot *);
+extern void ibmphp_free_bus_info_queue (void);
+extern void ibmphp_free_ebda_pci_rsrc_queue (void);
+extern struct bus_info *ibmphp_find_same_bus_num (u32);
+extern int ibmphp_get_bus_index (u8);
+extern u16 ibmphp_get_total_controllers (void);
+extern int ibmphp_register_pci (void);
+
+/* passed parameters */
+#define MEM		0
+#define IO		1
+#define PFMEM		2
+
+/* bit masks */
+#define RESTYPE		0x03
+#define IOMASK		0x00	/* will need to take its complement */
+#define MMASK		0x01
+#define PFMASK		0x03
+#define PCIDEVMASK	0x10	/* we should always have PCI devices */
+#define PRIMARYBUSMASK	0x20
+
+/* pci specific defines */
+#define PCI_VENDOR_ID_NOTVALID		0xFFFF
+#define PCI_HEADER_TYPE_MULTIDEVICE	0x80
+#define PCI_HEADER_TYPE_MULTIBRIDGE	0x81
+
+#define LATENCY		0x64
+#define CACHE		64
+#define DEVICEENABLE	0x015F		/* CPQ has 0x0157 */
+
+#define IOBRIDGE	0x1000		/* 4k */
+#define MEMBRIDGE	0x100000	/* 1M */
+
+/* irqs */
+#define SCSI_IRQ	0x09
+#define LAN_IRQ		0x0A
+#define OTHER_IRQ	0x0B
+
+/* Data Structures */
+
+/* type is of the form x x xx xx
+ *                     | |  |  |_ 00 - I/O, 01 - Memory, 11 - PFMemory
+ *                     | |  - 00 - No Restrictions, 01 - Avoid VGA, 10 - Avoid
+ *                     | |    VGA and their aliases, 11 - Avoid ISA
+ *                     | - 1 - PCI device, 0 - non pci device
+ *                     - 1 - Primary PCI Bus Information (0 if Normal device)
+ * the IO restrictions [2:3] are only for primary buses
+ */
+
+
+/* we need this struct because there could be several resource blocks
+ * allocated per primary bus in the EBDA
+ */
+struct range_node {
+	int rangeno;
+	u32 start;
+	u32 end;
+	struct range_node *next;
+};
+
+struct bus_node {
+	u8 busno;
+	int noIORanges;
+	struct range_node *rangeIO;
+	int noMemRanges;
+	struct range_node *rangeMem;
+	int noPFMemRanges;
+	struct range_node *rangePFMem;
+	int needIOUpdate;
+	int needMemUpdate;
+	int needPFMemUpdate;
+	struct resource_node *firstIO;	/* first IO resource on the Bus */
+	struct resource_node *firstMem;	/* first memory resource on the Bus */
+	struct resource_node *firstPFMem;	/* first prefetchable memory resource on the Bus */
+	struct resource_node *firstPFMemFromMem;	/* when run out of pfmem available, taking from Mem */
+	struct list_head bus_list;
+};
+
+struct resource_node {
+	int rangeno;
+	u8 busno;
+	u8 devfunc;
+	u32 start;
+	u32 end;
+	u32 len;
+	int type;		/* MEM, IO, PFMEM */
+	u8 fromMem;		/* this is to indicate that the range is from
+				 * from the Memory bucket rather than from PFMem */
+	struct resource_node *next;
+	struct resource_node *nextRange;	/* for the other mem range on bus */
+};
+
+struct res_needed {
+	u32 mem;
+	u32 pfmem;
+	u32 io;
+	u8 not_correct;		/* needed for return */
+	int devices[32];	/* for device numbers behind this bridge */
+};
+
+/* functions */
+
+extern int ibmphp_rsrc_init (void);
+extern int ibmphp_add_resource (struct resource_node *);
+extern int ibmphp_remove_resource (struct resource_node *);
+extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int);
+extern int ibmphp_check_resource (struct resource_node *, u8);
+extern int ibmphp_remove_bus (struct bus_node *, u8);
+extern void ibmphp_free_resources (void);
+extern int ibmphp_add_pfmem_from_mem (struct resource_node *);
+extern struct bus_node *ibmphp_find_res_bus (u8);
+extern void ibmphp_print_test (void);	/* for debugging purposes */
+
+extern void ibmphp_hpc_initvars (void);
+extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *);
+extern int ibmphp_hpc_writeslot (struct slot *, u8);
+extern void ibmphp_lock_operations (void);
+extern void ibmphp_unlock_operations (void);
+extern int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *);
+extern int ibmphp_hpc_start_poll_thread (void);
+extern void ibmphp_hpc_stop_poll_thread (void);
+
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+// HPC return codes
+//----------------------------------------------------------------------------
+#define FALSE				0x00
+#define TRUE				0x01
+#define HPC_ERROR			0xFF
+
+//-----------------------------------------------------------------------------
+// BUS INFO
+//-----------------------------------------------------------------------------
+#define BUS_SPEED			0x30
+#define BUS_MODE			0x40
+#define BUS_MODE_PCIX			0x01
+#define BUS_MODE_PCI			0x00
+#define BUS_SPEED_2			0x20
+#define BUS_SPEED_1			0x10
+#define BUS_SPEED_33			0x00
+#define BUS_SPEED_66			0x01
+#define BUS_SPEED_100			0x02
+#define BUS_SPEED_133			0x03
+#define BUS_SPEED_66PCIX		0x04
+#define BUS_SPEED_66UNKNOWN		0x05
+#define BUS_STATUS_AVAILABLE		0x01
+#define BUS_CONTROL_AVAILABLE		0x02
+#define SLOT_LATCH_REGS_SUPPORTED	0x10
+
+#define PRGM_MODEL_REV_LEVEL		0xF0
+#define MAX_ADAPTER_NONE		0x09
+
+//----------------------------------------------------------------------------
+// HPC 'write' operations/commands
+//----------------------------------------------------------------------------
+//	Command			Code	State	Write to reg
+//					Machine	at index
+//-------------------------	----	-------	------------
+#define HPC_CTLR_ENABLEIRQ	0x00	// N	15
+#define HPC_CTLR_DISABLEIRQ	0x01	// N	15
+#define HPC_SLOT_OFF		0x02	// Y	0-14
+#define HPC_SLOT_ON		0x03	// Y	0-14
+#define HPC_SLOT_ATTNOFF	0x04	// N	0-14
+#define HPC_SLOT_ATTNON		0x05	// N	0-14
+#define HPC_CTLR_CLEARIRQ	0x06	// N	15
+#define HPC_CTLR_RESET		0x07	// Y	15
+#define HPC_CTLR_IRQSTEER	0x08	// N	15
+#define HPC_BUS_33CONVMODE	0x09	// Y	31-34
+#define HPC_BUS_66CONVMODE	0x0A	// Y	31-34
+#define HPC_BUS_66PCIXMODE	0x0B	// Y	31-34
+#define HPC_BUS_100PCIXMODE	0x0C	// Y	31-34
+#define HPC_BUS_133PCIXMODE	0x0D	// Y	31-34
+#define HPC_ALLSLOT_OFF		0x11	// Y	15
+#define HPC_ALLSLOT_ON		0x12	// Y	15
+#define HPC_SLOT_BLINKLED	0x13	// N	0-14
+
+//----------------------------------------------------------------------------
+// read commands
+//----------------------------------------------------------------------------
+#define READ_SLOTSTATUS		0x01
+#define READ_EXTSLOTSTATUS	0x02
+#define READ_BUSSTATUS		0x03
+#define READ_CTLRSTATUS		0x04
+#define READ_ALLSTAT		0x05
+#define READ_ALLSLOT		0x06
+#define READ_SLOTLATCHLOWREG	0x07
+#define READ_REVLEVEL		0x08
+#define READ_HPCOPTIONS		0x09
+//----------------------------------------------------------------------------
+// slot status
+//----------------------------------------------------------------------------
+#define HPC_SLOT_POWER		0x01
+#define HPC_SLOT_CONNECT	0x02
+#define HPC_SLOT_ATTN		0x04
+#define HPC_SLOT_PRSNT2		0x08
+#define HPC_SLOT_PRSNT1		0x10
+#define HPC_SLOT_PWRGD		0x20
+#define HPC_SLOT_BUS_SPEED	0x40
+#define HPC_SLOT_LATCH		0x80
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_POWER status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_POWER_OFF	0x00
+#define HPC_SLOT_POWER_ON	0x01
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_CONNECT status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_CONNECTED	0x00
+#define HPC_SLOT_DISCONNECTED	0x01
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_ATTN status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_ATTN_OFF	0x00
+#define HPC_SLOT_ATTN_ON	0x01
+#define HPC_SLOT_ATTN_BLINK	0x02
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_PRSNT status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_EMPTY		0x00
+#define HPC_SLOT_PRSNT_7	0x01
+#define HPC_SLOT_PRSNT_15	0x02
+#define HPC_SLOT_PRSNT_25	0x03
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_PWRGD status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_PWRGD_FAULT_NONE	0x00
+#define HPC_SLOT_PWRGD_GOOD		0x01
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_BUS_SPEED status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_BUS_SPEED_OK	0x00
+#define HPC_SLOT_BUS_SPEED_MISM	0x01
+
+//----------------------------------------------------------------------------
+// HPC_SLOT_LATCH status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_LATCH_OPEN	0x01	// NOTE : in PCI spec bit off = open
+#define HPC_SLOT_LATCH_CLOSED	0x00	// NOTE : in PCI spec bit on  = closed
+
+
+//----------------------------------------------------------------------------
+// extended slot status
+//----------------------------------------------------------------------------
+#define HPC_SLOT_PCIX		0x01
+#define HPC_SLOT_SPEED1		0x02
+#define HPC_SLOT_SPEED2		0x04
+#define HPC_SLOT_BLINK_ATTN	0x08
+#define HPC_SLOT_RSRVD1		0x10
+#define HPC_SLOT_RSRVD2		0x20
+#define HPC_SLOT_BUS_MODE	0x40
+#define HPC_SLOT_RSRVD3		0x80
+
+//----------------------------------------------------------------------------
+// HPC_XSLOT_PCIX_CAP status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_PCIX_NO	0x00
+#define HPC_SLOT_PCIX_YES	0x01
+
+//----------------------------------------------------------------------------
+// HPC_XSLOT_SPEED status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_SPEED_33	0x00
+#define HPC_SLOT_SPEED_66	0x01
+#define HPC_SLOT_SPEED_133	0x02
+
+//----------------------------------------------------------------------------
+// HPC_XSLOT_ATTN_BLINK status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_ATTN_BLINK_OFF	0x00
+#define HPC_SLOT_ATTN_BLINK_ON	0x01
+
+//----------------------------------------------------------------------------
+// HPC_XSLOT_BUS_MODE status return codes
+//----------------------------------------------------------------------------
+#define HPC_SLOT_BUS_MODE_OK	0x00
+#define HPC_SLOT_BUS_MODE_MISM	0x01
+
+//----------------------------------------------------------------------------
+// Controller status
+//----------------------------------------------------------------------------
+#define HPC_CTLR_WORKING	0x01
+#define HPC_CTLR_FINISHED	0x02
+#define HPC_CTLR_RESULT0	0x04
+#define HPC_CTLR_RESULT1	0x08
+#define HPC_CTLR_RESULE2	0x10
+#define HPC_CTLR_RESULT3	0x20
+#define HPC_CTLR_IRQ_ROUTG	0x40
+#define HPC_CTLR_IRQ_PENDG	0x80
+
+//----------------------------------------------------------------------------
+// HPC_CTLR_WROKING status return codes
+//----------------------------------------------------------------------------
+#define HPC_CTLR_WORKING_NO	0x00
+#define HPC_CTLR_WORKING_YES	0x01
+
+//----------------------------------------------------------------------------
+// HPC_CTLR_FINISHED status return codes
+//----------------------------------------------------------------------------
+#define HPC_CTLR_FINISHED_NO	0x00
+#define HPC_CTLR_FINISHED_YES	0x01
+
+//----------------------------------------------------------------------------
+// HPC_CTLR_RESULT status return codes
+//----------------------------------------------------------------------------
+#define HPC_CTLR_RESULT_SUCCESS	0x00
+#define HPC_CTLR_RESULT_FAILED	0x01
+#define HPC_CTLR_RESULT_RSVD	0x02
+#define HPC_CTLR_RESULT_NORESP	0x03
+
+
+//----------------------------------------------------------------------------
+// macro for slot info
+//----------------------------------------------------------------------------
+#define SLOT_POWER(s)	((u8) ((s & HPC_SLOT_POWER) \
+	? HPC_SLOT_POWER_ON : HPC_SLOT_POWER_OFF))
+
+#define SLOT_CONNECT(s)	((u8) ((s & HPC_SLOT_CONNECT) \
+	? HPC_SLOT_DISCONNECTED : HPC_SLOT_CONNECTED))
+
+#define SLOT_ATTN(s,es)	((u8) ((es & HPC_SLOT_BLINK_ATTN) \
+	? HPC_SLOT_ATTN_BLINK \
+	: ((s & HPC_SLOT_ATTN) ? HPC_SLOT_ATTN_ON : HPC_SLOT_ATTN_OFF)))
+
+#define SLOT_PRESENT(s)	((u8) ((s & HPC_SLOT_PRSNT1) \
+	? ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_EMPTY : HPC_SLOT_PRSNT_15) \
+	: ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_PRSNT_25 : HPC_SLOT_PRSNT_7)))
+
+#define SLOT_PWRGD(s)	((u8) ((s & HPC_SLOT_PWRGD) \
+	? HPC_SLOT_PWRGD_GOOD : HPC_SLOT_PWRGD_FAULT_NONE))
+
+#define SLOT_BUS_SPEED(s)	((u8) ((s & HPC_SLOT_BUS_SPEED) \
+	? HPC_SLOT_BUS_SPEED_MISM : HPC_SLOT_BUS_SPEED_OK))
+
+#define SLOT_LATCH(s)	((u8) ((s & HPC_SLOT_LATCH) \
+	? HPC_SLOT_LATCH_CLOSED : HPC_SLOT_LATCH_OPEN))
+
+#define SLOT_PCIX(es)	((u8) ((es & HPC_SLOT_PCIX) \
+	? HPC_SLOT_PCIX_YES : HPC_SLOT_PCIX_NO))
+
+#define SLOT_SPEED(es)	((u8) ((es & HPC_SLOT_SPEED2) \
+	? ((es & HPC_SLOT_SPEED1) ? HPC_SLOT_SPEED_133   \
+				: HPC_SLOT_SPEED_66)   \
+	: HPC_SLOT_SPEED_33))
+
+#define SLOT_BUS_MODE(es)	((u8) ((es & HPC_SLOT_BUS_MODE) \
+	? HPC_SLOT_BUS_MODE_MISM : HPC_SLOT_BUS_MODE_OK))
+
+//--------------------------------------------------------------------------
+// macro for bus info
+//---------------------------------------------------------------------------
+#define CURRENT_BUS_SPEED(s)	((u8) (s & BUS_SPEED_2) \
+	? ((s & BUS_SPEED_1) ? BUS_SPEED_133 : BUS_SPEED_100) \
+	: ((s & BUS_SPEED_1) ? BUS_SPEED_66 : BUS_SPEED_33))
+
+#define CURRENT_BUS_MODE(s)	((u8) (s & BUS_MODE) ? BUS_MODE_PCIX : BUS_MODE_PCI)
+
+#define READ_BUS_STATUS(s)	((u8) (s->options & BUS_STATUS_AVAILABLE))
+
+#define READ_BUS_MODE(s)	((s->revision & PRGM_MODEL_REV_LEVEL) >= 0x20)
+
+#define SET_BUS_STATUS(s)	((u8) (s->options & BUS_CONTROL_AVAILABLE))
+
+#define READ_SLOT_LATCH(s)	((u8) (s->options & SLOT_LATCH_REGS_SUPPORTED))
+
+//----------------------------------------------------------------------------
+// macro for controller info
+//----------------------------------------------------------------------------
+#define CTLR_WORKING(c) ((u8) ((c & HPC_CTLR_WORKING) \
+	? HPC_CTLR_WORKING_YES : HPC_CTLR_WORKING_NO))
+#define CTLR_FINISHED(c) ((u8) ((c & HPC_CTLR_FINISHED) \
+	? HPC_CTLR_FINISHED_YES : HPC_CTLR_FINISHED_NO))
+#define CTLR_RESULT(c) ((u8) ((c & HPC_CTLR_RESULT1)  \
+	? ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_NORESP \
+				: HPC_CTLR_RESULT_RSVD)  \
+	: ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_FAILED \
+				: HPC_CTLR_RESULT_SUCCESS)))
+
+// command that affect the state machine of HPC
+#define NEEDTOCHECK_CMDSTATUS(c) ((c == HPC_SLOT_OFF)        || \
+				  (c == HPC_SLOT_ON)         || \
+				  (c == HPC_CTLR_RESET)      || \
+				  (c == HPC_BUS_33CONVMODE)  || \
+				  (c == HPC_BUS_66CONVMODE)  || \
+				  (c == HPC_BUS_66PCIXMODE)  || \
+				  (c == HPC_BUS_100PCIXMODE) || \
+				  (c == HPC_BUS_133PCIXMODE) || \
+				  (c == HPC_ALLSLOT_OFF)     || \
+				  (c == HPC_ALLSLOT_ON))
+
+
+/* Core part of the driver */
+
+#define ENABLE		1
+#define DISABLE		0
+
+#define CARD_INFO	0x07
+#define PCIX133		0x07
+#define PCIX66		0x05
+#define PCI66		0x04
+
+extern struct pci_bus *ibmphp_pci_bus;
+
+/* Variables */
+
+struct pci_func {
+	struct pci_dev *dev;	/* from the OS */
+	u8 busno;
+	u8 device;
+	u8 function;
+	struct resource_node *io[6];
+	struct resource_node *mem[6];
+	struct resource_node *pfmem[6];
+	struct pci_func *next;
+	int devices[32];	/* for bridge config */
+	u8 irq[4];		/* for interrupt config */
+	u8 bus;			/* flag for unconfiguring, to say if PPB */
+};
+
+struct slot {
+	u8 bus;
+	u8 device;
+	u8 number;
+	u8 real_physical_slot_num;
+	char name[100];
+	u32 capabilities;
+	u8 supported_speed;
+	u8 supported_bus_mode;
+	struct hotplug_slot *hotplug_slot;
+	struct controller *ctrl;
+	struct pci_func *func;
+	u8 irq[4];
+	u8 flag;		/* this is for disable slot and polling */
+	int bit_mode;		/* 0 = 32, 1 = 64 */
+	u8 ctlr_index;
+	struct bus_info *bus_on;
+	struct list_head ibm_slot_list;
+	u8 status;
+	u8 ext_status;
+	u8 busstatus;
+};
+
+struct controller {
+	struct ebda_hpc_slot *slots;
+	struct ebda_hpc_bus *buses;
+	struct pci_dev *ctrl_dev; /* in case where controller is PCI */
+	u8 starting_slot_num;	/* starting and ending slot #'s this ctrl controls*/
+	u8 ending_slot_num;
+	u8 revision;
+	u8 options;		/* which options HPC supports */
+	u8 status;
+	u8 ctlr_id;
+	u8 slot_count;
+	u8 bus_count;
+	u8 ctlr_relative_id;
+	u32 irq;
+	union {
+		struct isa_ctlr_access isa_ctlr;
+		struct pci_ctlr_access pci_ctlr;
+		struct wpeg_i2c_ctlr_access wpeg_ctlr;
+	} u;
+	u8 ctlr_type;
+	struct list_head ebda_hpc_list;
+};
+
+/* Functions */
+
+extern int ibmphp_init_devno (struct slot **);	/* This function is called from EBDA, so we need it not be static */
+extern int ibmphp_disable_slot (struct hotplug_slot *);	/* This function is called from HPC, so we need it to not be static */
+extern int ibmphp_do_disable_slot (struct slot *slot_cur);
+extern int ibmphp_update_slot_info (struct slot *);	/* This function is called from HPC, so we need it to not be be static */
+extern int ibmphp_configure_card (struct pci_func *, u8);
+extern int ibmphp_unconfigure_card (struct slot **, int);
+extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops;
+
+static inline void long_delay (int delay)
+{
+	set_current_state (TASK_INTERRUPTIBLE);
+	schedule_timeout (delay);
+}
+
+#endif				//__IBMPHP_H
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_core.c linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_core.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_core.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_core.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,1416 @@
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/smp_lock.h>
+#include "../pci.h"
+#include "../../../arch/i386/pci/pci.h"	/* for struct irq_routing_table */
+#include "ibmphp.h"
+
+#define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
+#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
+#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
+#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
+#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
+
+#define DRIVER_VERSION	"0.6"
+#define DRIVER_DESC	"IBM Hot Plug PCI Controller Driver"
+
+int ibmphp_debug;
+
+static int debug;
+MODULE_PARM (debug, "i");
+MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
+MODULE_LICENSE ("GPL");
+MODULE_DESCRIPTION (DRIVER_DESC);
+
+struct pci_bus *ibmphp_pci_bus;
+static int max_slots;
+
+static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */
+
+static int init_flag;
+
+/*
+static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
+
+static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
+{
+	return get_max_adapter_speed_1 (hs, value, 1);
+}
+*/
+static inline int get_cur_bus_info (struct slot **sl) 
+{
+	int rc = 1;
+	struct slot * slot_cur = *sl;
+
+	debug ("options = %x\n", slot_cur->ctrl->options);
+	debug ("revision = %x\n", slot_cur->ctrl->revision);	
+
+	if (READ_BUS_STATUS (slot_cur->ctrl)) 
+		rc = ibmphp_hpc_readslot (slot_cur, READ_BUSSTATUS, NULL);
+	
+	if (rc) 
+		return rc;
+	  
+	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus);
+	if (READ_BUS_MODE (slot_cur->ctrl))
+		slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus);
+	else
+		slot_cur->bus_on->current_bus_mode = 0xFF;
+
+	debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode);
+	
+	*sl = slot_cur;
+	return 0;
+}
+
+static inline int slot_update (struct slot **sl)
+{
+	int rc;
+ 	rc = ibmphp_hpc_readslot (*sl, READ_ALLSTAT, NULL);
+	if (rc) 
+		return rc;
+	if (!init_flag)
+		return get_cur_bus_info (sl);
+	return rc;
+}
+
+static int __init get_max_slots (void)
+{
+	struct slot * slot_cur;
+	struct list_head * tmp;
+	u8 slot_count = 0;
+
+	list_for_each (tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+		/* sometimes the hot-pluggable slots start with 4 (not always from 1 */
+		slot_count = max (slot_count, slot_cur->number);
+	}
+	return slot_count;
+}
+
+/* This routine will put the correct slot->device information per slot.  It's
+ * called from initialization of the slot structures. It will also assign
+ * interrupt numbers per each slot.
+ * Parameters: struct slot
+ * Returns 0 or errors
+ */
+int ibmphp_init_devno (struct slot **cur_slot)
+{
+	struct irq_routing_table *rtable;
+	int len;
+	int loop;
+	int i;
+
+	rtable = pcibios_get_irq_routing_table ();
+	if (!rtable) {
+		err ("no BIOS routing table...\n");
+		return -ENOMEM;
+	}
+
+	len = (rtable->size - sizeof (struct irq_routing_table)) / sizeof (struct irq_info);
+
+	if (!len)
+		return -1;
+	for (loop = 0; loop < len; loop++) {
+		if ((*cur_slot)->number == rtable->slots[loop].slot) {
+		if ((*cur_slot)->bus == rtable->slots[loop].bus) {
+			(*cur_slot)->device = PCI_SLOT (rtable->slots[loop].devfn);
+			for (i = 0; i < 4; i++)
+				(*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector ((int) (*cur_slot)->bus, (int) (*cur_slot)->device, i);
+
+				debug ("(*cur_slot)->irq[0] = %x\n", (*cur_slot)->irq[0]);
+				debug ("(*cur_slot)->irq[1] = %x\n", (*cur_slot)->irq[1]);
+				debug ("(*cur_slot)->irq[2] = %x\n", (*cur_slot)->irq[2]);
+				debug ("(*cur_slot)->irq[3] = %x\n", (*cur_slot)->irq[3]);
+
+				debug ("rtable->exlusive_irqs = %x\n", rtable->exclusive_irqs);
+				debug ("rtable->slots[loop].irq[0].bitmap = %x\n", rtable->slots[loop].irq[0].bitmap);
+				debug ("rtable->slots[loop].irq[1].bitmap = %x\n", rtable->slots[loop].irq[1].bitmap);
+				debug ("rtable->slots[loop].irq[2].bitmap = %x\n", rtable->slots[loop].irq[2].bitmap);
+				debug ("rtable->slots[loop].irq[3].bitmap = %x\n", rtable->slots[loop].irq[3].bitmap);
+
+				debug ("rtable->slots[loop].irq[0].link= %x\n", rtable->slots[loop].irq[0].link);
+				debug ("rtable->slots[loop].irq[1].link = %x\n", rtable->slots[loop].irq[1].link);
+				debug ("rtable->slots[loop].irq[2].link = %x\n", rtable->slots[loop].irq[2].link);
+				debug ("rtable->slots[loop].irq[3].link = %x\n", rtable->slots[loop].irq[3].link);
+				debug ("end of init_devno\n");
+				return 0;
+			}
+		}
+	}
+
+	return -1;
+}
+
+static inline int power_on (struct slot *slot_cur)
+{
+	u8 cmd = HPC_SLOT_ON;
+	int retval;
+
+	retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+	if (retval) {
+		err ("power on failed\n");
+		return retval;
+	}
+	if (CTLR_RESULT (slot_cur->ctrl->status)) {
+		err ("command not completed successfully in power_on \n");
+		return -EIO;
+	}
+	long_delay (3 * HZ); /* For ServeRAID cards, and some 66 PCI */
+	return 0;
+}
+
+static inline int power_off (struct slot *slot_cur)
+{
+	u8 cmd = HPC_SLOT_OFF;
+	int retval;
+
+	retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+	if (retval) {
+		err ("power off failed \n");
+		return retval;
+	}
+	if (CTLR_RESULT (slot_cur->ctrl->status)) {
+		err ("command not completed successfully in power_off \n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 value)
+{
+	int rc = 0;
+	struct slot *pslot;
+	u8 cmd;
+	int hpcrc = 0;
+
+	debug ("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n", (ulong) hotplug_slot, value);
+	ibmphp_lock_operations ();
+	cmd = 0x00;     // avoid compiler warning
+
+	if (hotplug_slot) {
+		switch (value) {
+		case HPC_SLOT_ATTN_OFF:
+			cmd = HPC_SLOT_ATTNOFF;
+			break;
+		case HPC_SLOT_ATTN_ON:
+			cmd = HPC_SLOT_ATTNON;
+			break;
+		case HPC_SLOT_ATTN_BLINK:
+			cmd = HPC_SLOT_BLINKLED;
+			break;
+		default:
+			rc = -ENODEV;
+			err ("set_attention_status - Error : invalid input [%x]\n", value);
+			break;
+		}
+		if (rc == 0) {
+			pslot = (struct slot *) hotplug_slot->private;
+			if (pslot)
+				hpcrc = ibmphp_hpc_writeslot (pslot, cmd);
+			else
+				rc = -ENODEV;
+		}
+	} else	
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+
+	debug ("set_attention_status - Exit rc[%d]\n", rc);
+	return rc;
+}
+
+static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+        
+	ibmphp_lock_operations ();
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+			if (!hpcrc)
+				hpcrc = ibmphp_hpc_readslot (pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
+			if (!hpcrc) {
+				*value = SLOT_ATTN (myslot.status, myslot.ext_status);
+				rc = 0;
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+	debug ("get_attention_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations ();
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+			if (!hpcrc) {
+				*value = SLOT_LATCH (myslot.status);
+				rc = 0;
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+	debug ("get_latch_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+
+static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations ();
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+			if (!hpcrc) {
+				*value = SLOT_PWRGD (myslot.status);
+				rc = 0;
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+	debug ("get_power_status - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+static int get_adapter_present (struct hotplug_slot *hotplug_slot, u8 * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	u8 present;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong) hotplug_slot, (ulong) value);
+	ibmphp_lock_operations ();
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+			if (!hpcrc) {
+				present = SLOT_PRESENT (myslot.status);
+				if (present == HPC_SLOT_EMPTY)
+					*value = 0;
+				else
+					*value = 1;
+				rc = 0;
+			}
+		}
+	} else
+		rc = -ENODEV;
+	if (hpcrc)
+		rc = hpcrc;
+
+	ibmphp_unlock_operations ();
+	debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	u8 mode = 0;
+
+	debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
+		hotplug_slot, value);
+
+	ibmphp_lock_operations ();
+
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			rc = 0;
+			mode = pslot->supported_bus_mode;
+			*value = pslot->supported_speed; 
+			switch (*value) {
+			case BUS_SPEED_33:
+				break;
+			case BUS_SPEED_66:
+				if (mode == BUS_MODE_PCIX) 
+					*value += 0x01;
+				break;
+			case BUS_SPEED_100:
+			case BUS_SPEED_133:
+				*value = pslot->supported_speed + 0x01;
+				break;
+			default:
+				/* Note (will need to change): there would be soon 256, 512 also */
+				rc = -ENODEV;
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	ibmphp_unlock_operations ();
+	debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
+	return rc;
+}
+
+static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	u8 mode = 0;
+
+	debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
+		hotplug_slot, value);
+
+	ibmphp_lock_operations ();
+
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			rc = get_cur_bus_info (&pslot);
+			if (!rc) {
+				mode = pslot->bus_on->current_bus_mode;
+				*value = pslot->bus_on->current_speed;
+				switch (*value) {
+				case BUS_SPEED_33:
+					break;
+				case BUS_SPEED_66:
+					if (mode == BUS_MODE_PCIX) 
+						*value += 0x01;
+					else if (mode == BUS_MODE_PCI)
+						;
+					else
+						*value = PCI_SPEED_UNKNOWN;
+					break;
+				case BUS_SPEED_100:
+				case BUS_SPEED_133:
+					*value += 0x01;
+					break;
+				default:
+					/* Note of change: there would also be 256, 512 soon */
+					rc = -ENODEV;
+				}
+			}
+		}
+	} else
+		rc = -ENODEV;
+
+	ibmphp_unlock_operations ();
+	debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
+	return rc;
+}
+/*
+static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
+{
+	int rc = -ENODEV;
+	struct slot *pslot;
+	int hpcrc = 0;
+	struct slot myslot;
+
+	debug ("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
+
+	if (flag)
+		ibmphp_lock_operations ();
+
+	if (hotplug_slot && value) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
+
+			if (!(SLOT_LATCH (myslot.status)) && (SLOT_PRESENT (myslot.status))) {
+				hpcrc = ibmphp_hpc_readslot (pslot, READ_EXTSLOTSTATUS, &(myslot.ext_status));
+				if (!hpcrc) {
+					*value = SLOT_SPEED (myslot.ext_status);
+					rc = 0;
+				}
+			} else {
+				*value = MAX_ADAPTER_NONE;
+				rc = 0;
+			}
+                }
+        } else
+		rc = -ENODEV;
+
+	if (hpcrc)
+		rc = hpcrc;
+
+	if (flag)
+		ibmphp_unlock_operations ();
+
+	debug ("get_max_adapter_speed_1 - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	return rc;
+}
+
+static int get_bus_name (struct hotplug_slot *hotplug_slot, char * value)
+{
+	int rc = -ENODEV;
+	struct slot *pslot = NULL;
+
+	debug ("get_bus_name - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot);
+
+	ibmphp_lock_operations ();
+
+	if (hotplug_slot) {
+		pslot = (struct slot *) hotplug_slot->private;
+		if (pslot) {
+			rc = 0;
+			snprintf (value, 100, "Bus %x", pslot->bus);
+		}
+	} else
+		rc = -ENODEV;
+
+	ibmphp_unlock_operations ();
+	debug ("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
+	return rc;
+}
+*/
+
+/*******************************************************************************
+ * This routine will initialize the ops data structure used in the validate
+ * function. It will also power off empty slots that are powered on since BIOS
+ * leaves those on, albeit disconnected
+ ******************************************************************************/
+static int __init init_ops (void)
+{
+	struct slot *slot_cur;
+	struct list_head *tmp;
+	int retval;
+	int rc;
+
+	list_for_each (tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+
+		if (!slot_cur)
+			return -ENODEV;
+
+		debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);
+		if (slot_cur->ctrl->revision == 0xFF) 
+			if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
+				return -1;
+
+		if (slot_cur->bus_on->current_speed == 0xFF) 
+			if (get_cur_bus_info (&slot_cur)) 
+				return -1;
+
+		if (slot_cur->ctrl->options == 0xFF)
+			if (get_hpc_options (slot_cur, &slot_cur->ctrl->options))
+				return -1;
+
+		retval = slot_update (&slot_cur);
+		if (retval)
+			return retval;
+
+		debug ("status = %x\n", slot_cur->status);
+		debug ("ext_status = %x\n", slot_cur->ext_status);
+		debug ("SLOT_POWER = %x\n", SLOT_POWER (slot_cur->status));
+		debug ("SLOT_PRESENT = %x\n", SLOT_PRESENT (slot_cur->status));
+		debug ("SLOT_LATCH = %x\n", SLOT_LATCH (slot_cur->status));
+
+		if ((SLOT_PWRGD (slot_cur->status)) && 
+		    !(SLOT_PRESENT (slot_cur->status)) && 
+		    !(SLOT_LATCH (slot_cur->status))) {
+			debug ("BEFORE POWER OFF COMMAND\n");
+				rc = power_off (slot_cur);
+				if (rc)
+					return rc;
+
+	/*		retval = slot_update (&slot_cur);
+	 *		if (retval)
+	 *			return retval;
+	 *		ibmphp_update_slot_info (slot_cur);
+	 */
+		}
+	}
+	init_flag = 0;
+	return 0;
+}
+
+/* This operation will check whether the slot is within the bounds and
+ * the operation is valid to perform on that slot
+ * Parameters: slot, operation
+ * Returns: 0 or error codes
+ */
+static int validate (struct slot *slot_cur, int opn)
+{
+	int number;
+	int retval;
+
+	if (!slot_cur)
+		return -ENODEV;
+	number = slot_cur->number;
+	if ((number > max_slots) || (number < 0))
+		return -EBADSLT;
+	debug ("slot_number in validate is %d\n", slot_cur->number);
+
+	retval = slot_update (&slot_cur);
+	if (retval)
+		return retval;
+
+	switch (opn) {
+		case ENABLE:
+			if (!(SLOT_PWRGD (slot_cur->status)) && 
+			     (SLOT_PRESENT (slot_cur->status)) && 
+			     !(SLOT_LATCH (slot_cur->status)))
+				return 0;
+			break;
+		case DISABLE:
+			if ((SLOT_PWRGD (slot_cur->status)) && 
+			    (SLOT_PRESENT (slot_cur->status)) &&
+			    !(SLOT_LATCH (slot_cur->status)))
+				return 0;
+			break;
+		default:
+			break;
+	}
+	err ("validate failed....\n");
+	return -EINVAL;
+}
+
+/********************************************************************************
+ * This routine is for updating the data structures in the hotplug core
+ * Parameters: struct slot
+ * Returns: 0 or error
+ *******************************************************************************/
+int ibmphp_update_slot_info (struct slot *slot_cur)
+{
+	struct hotplug_slot_info *info;
+	int rc;
+	u8 bus_speed;
+	u8 mode;
+
+	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+	if (!info) {
+		err ("out of system memory \n");
+		return -ENOMEM;
+	}
+        
+	info->power_status = SLOT_PWRGD (slot_cur->status);
+	info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
+	info->latch_status = SLOT_LATCH (slot_cur->status);
+        if (!SLOT_PRESENT (slot_cur->status)) {
+                info->adapter_status = 0;
+//		info->max_adapter_speed_status = MAX_ADAPTER_NONE;
+	} else {
+                info->adapter_status = 1;
+//		get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
+	}
+
+	bus_speed = slot_cur->bus_on->current_speed;
+	mode = slot_cur->bus_on->current_bus_mode;
+
+	switch (bus_speed) {
+	case BUS_SPEED_33:
+		break;
+	case BUS_SPEED_66:
+		if (mode == BUS_MODE_PCIX) 
+			bus_speed += 0x01;
+		else if (mode == BUS_MODE_PCI)
+			;
+		else
+			bus_speed = PCI_SPEED_UNKNOWN;
+		break;
+	case BUS_SPEED_100:
+	case BUS_SPEED_133:
+		bus_speed += 0x01;
+		break;
+	default:
+		bus_speed = PCI_SPEED_UNKNOWN;
+	}
+
+	info->cur_bus_speed = bus_speed;
+	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
+	// To do: bus_names 
+	
+	rc = pci_hp_change_slot_info (slot_cur->hotplug_slot, info);
+	kfree (info);
+	return rc;
+}
+
+
+/******************************************************************************
+ * This function will return the pci_func, given bus and devfunc, or NULL.  It
+ * is called from visit routines
+ ******************************************************************************/
+
+static struct pci_func *ibm_slot_find (u8 busno, u8 device, u8 function)
+{
+	struct pci_func *func_cur;
+	struct slot *slot_cur;
+	struct list_head * tmp;
+	list_for_each (tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+		if (slot_cur->func) {
+			func_cur = slot_cur->func;
+			while (func_cur) {
+				if ((func_cur->busno == busno) && (func_cur->device == device) && (func_cur->function == function))
+					return func_cur;
+				func_cur = func_cur->next;
+			}
+		}
+	}
+	return NULL;
+}
+
+/*************************************************************
+ * This routine frees up memory used by struct slot, including
+ * the pointers to pci_func, bus, hotplug_slot, controller,
+ * and deregistering from the hotplug core
+ *************************************************************/
+static void free_slots (void)
+{
+	struct slot *slot_cur;
+	struct list_head * tmp;
+	struct list_head * next;
+
+	debug ("%s -- enter\n", __FUNCTION__);
+
+	list_for_each_safe (tmp, next, &ibmphp_slot_head) {
+	
+		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+
+		pci_hp_deregister (slot_cur->hotplug_slot);
+
+		if (slot_cur->hotplug_slot) {
+			kfree (slot_cur->hotplug_slot);
+			slot_cur->hotplug_slot = NULL;
+		}
+
+		if (slot_cur->ctrl) 
+			slot_cur->ctrl = NULL;
+		
+		if (slot_cur->bus_on) 
+			slot_cur->bus_on = NULL;
+
+		ibmphp_unconfigure_card (&slot_cur, -1);  /* we don't want to actually remove the resources, since free_resources will do just that */
+
+		kfree (slot_cur);
+		slot_cur = NULL;
+	}
+	debug ("%s -- exit\n", __FUNCTION__);
+}
+
+static int ibm_unconfigure_device (struct pci_func *func)
+{
+	struct pci_dev *temp;
+	u8 j;
+
+	debug ("inside %s\n", __FUNCTION__);
+	debug ("func->device = %x, func->function = %x\n", func->device, func->function);
+	debug ("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
+
+	for (j = 0; j < 0x08; j++) {
+		temp = pci_find_slot (func->busno, (func->device << 3) | j);
+		if (temp)
+			pci_remove_bus_device(temp);
+	}
+	return 0;
+}
+
+/*
+ * The following function is to fix kernel bug regarding 
+ * getting bus entries, here we manually add those primary 
+ * bus entries to kernel bus structure whenever apply
+ */
+
+static u8 bus_structure_fixup (u8 busno)
+{
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+	u16 l;
+
+	if (pci_find_bus(busno) || !(ibmphp_find_same_bus_num (busno)))
+		return 1;
+
+	bus = kmalloc (sizeof (*bus), GFP_KERNEL);
+	if (!bus) {
+		err ("%s - out of memory\n", __FUNCTION__);
+		return 1;
+	}
+	dev = kmalloc (sizeof (*dev), GFP_KERNEL);
+	if (!dev) {
+		kfree (bus);
+		err ("%s - out of memory\n", __FUNCTION__);
+		return 1;
+	}
+
+	bus->number = busno;
+	bus->ops = ibmphp_pci_bus->ops;
+	dev->bus = bus;
+	for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
+		if (!pci_read_config_word (dev, PCI_VENDOR_ID, &l) &&  l != 0x0000 && l != 0xffff) {
+			debug ("%s - Inside bus_struture_fixup() \n", __FUNCTION__);
+			pci_scan_bus (busno, ibmphp_pci_bus->ops, NULL);
+			break;
+		}
+	}
+
+	kfree (dev);
+	kfree (bus);
+
+	return 0;
+}
+
+static int ibm_configure_device (struct pci_func *func)
+{
+	unsigned char bus;
+	struct pci_bus *child;
+	int num;
+	int flag = 0;	/* this is to make sure we don't double scan the bus, for bridged devices primarily */
+
+	if (!(bus_structure_fixup (func->busno)))
+		flag = 1;
+	if (func->dev == NULL)
+		func->dev = pci_find_slot (func->busno, PCI_DEVFN(func->device, func->function));
+
+	if (func->dev == NULL) {
+		struct pci_bus *bus = pci_find_bus(func->busno);
+		if (!bus)
+			return 0;
+
+		num = pci_scan_slot(bus, PCI_DEVFN(func->device, func->function));
+		if (num)
+			pci_bus_add_devices(bus);
+
+		func->dev = pci_find_slot(func->busno, PCI_DEVFN(func->device, func->function));
+		if (func->dev == NULL) {
+			err ("ERROR... : pci_dev still NULL \n");
+			return 0;
+		}
+	}
+	if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
+		pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);
+		child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
+		pci_do_scan_bus (child);
+	}
+
+	return 0;
+}
+
+/*******************************************************
+ * Returns whether the bus is empty or not 
+ *******************************************************/
+static int is_bus_empty (struct slot * slot_cur)
+{
+	int rc;
+	struct slot * tmp_slot;
+	u8 i = slot_cur->bus_on->slot_min;
+
+	while (i <= slot_cur->bus_on->slot_max) {
+		if (i == slot_cur->number) {
+			i++;
+			continue;
+		}
+		tmp_slot = ibmphp_get_slot_from_physical_num (i);
+		if (!tmp_slot)
+			return 0;
+		rc = slot_update (&tmp_slot);
+		if (rc)
+			return 0;
+		if (SLOT_PRESENT (tmp_slot->status) && SLOT_PWRGD (tmp_slot->status))
+			return 0;
+		i++;
+	}
+	return 1;
+}
+
+/***********************************************************
+ * If the HPC permits and the bus currently empty, tries to set the 
+ * bus speed and mode at the maximum card and bus capability
+ * Parameters: slot
+ * Returns: bus is set (0) or error code
+ ***********************************************************/
+static int set_bus (struct slot * slot_cur)
+{
+	int rc;
+	u8 speed;
+	u8 cmd = 0x0;
+	struct pci_dev *dev = NULL;
+	int retval;
+
+	debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number);
+	if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
+		rc = slot_update (&slot_cur);
+		if (rc)
+			return rc;
+		speed = SLOT_SPEED (slot_cur->ext_status);
+		debug ("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
+		switch (speed) {
+		case HPC_SLOT_SPEED_33:
+			cmd = HPC_BUS_33CONVMODE;
+			break;
+		case HPC_SLOT_SPEED_66:
+			if (SLOT_PCIX (slot_cur->ext_status)) {
+				if ((slot_cur->supported_speed >= BUS_SPEED_66) && (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
+					cmd = HPC_BUS_66PCIXMODE;
+				else if (!SLOT_BUS_MODE (slot_cur->ext_status))
+					/* if max slot/bus capability is 66 pci
+					and there's no bus mode mismatch, then
+					the adapter supports 66 pci */ 
+					cmd = HPC_BUS_66CONVMODE;
+				else
+					cmd = HPC_BUS_33CONVMODE;
+			} else {
+				if (slot_cur->supported_speed >= BUS_SPEED_66)
+					cmd = HPC_BUS_66CONVMODE;
+				else
+					cmd = HPC_BUS_33CONVMODE;
+			}
+			break;
+		case HPC_SLOT_SPEED_133:
+			switch (slot_cur->supported_speed) {
+			case BUS_SPEED_33:
+				cmd = HPC_BUS_33CONVMODE;
+				break;
+			case BUS_SPEED_66:
+				if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
+					cmd = HPC_BUS_66PCIXMODE;
+				else
+					cmd = HPC_BUS_66CONVMODE;
+				break;
+			case BUS_SPEED_100:
+				cmd = HPC_BUS_100PCIXMODE;
+				break;
+			case BUS_SPEED_133:
+				/* This is to take care of the bug in CIOBX chip */
+				while ((dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,
+							      0x0101, dev)) != NULL)
+					ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
+				cmd = HPC_BUS_133PCIXMODE;
+				break;
+			default:
+				err ("Wrong bus speed \n");
+				return -ENODEV;
+			}
+			break;
+		default:
+			err ("wrong slot speed \n");
+			return -ENODEV;
+		}
+		debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd);
+		retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+		if (retval) {
+			err ("setting bus speed failed\n");
+			return retval;
+		}
+		if (CTLR_RESULT (slot_cur->ctrl->status)) {
+			err ("command not completed successfully in set_bus \n");
+			return -EIO;
+		}
+	}
+	/* This is for x440, once Brandon fixes the firmware, 
+	will not need this delay */
+	long_delay (1 * HZ);
+	debug ("%s -Exit \n", __FUNCTION__);
+	return 0;
+}
+
+/* This routine checks the bus limitations that the slot is on from the BIOS.
+ * This is used in deciding whether or not to power up the slot.  
+ * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
+ * same bus) 
+ * Parameters: slot
+ * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
+ */
+static int check_limitations (struct slot *slot_cur)
+{
+	u8 i;
+	struct slot * tmp_slot;
+	u8 count = 0;
+	u8 limitation = 0;
+
+	for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
+		tmp_slot = ibmphp_get_slot_from_physical_num (i);
+		if (!tmp_slot)
+			return -ENODEV;
+		if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) 
+			count++;
+	}
+	get_cur_bus_info (&slot_cur);
+	switch (slot_cur->bus_on->current_speed) {
+	case BUS_SPEED_33:
+		limitation = slot_cur->bus_on->slots_at_33_conv;
+		break;
+	case BUS_SPEED_66:
+		if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
+			limitation = slot_cur->bus_on->slots_at_66_pcix;
+		else
+			limitation = slot_cur->bus_on->slots_at_66_conv;
+		break;
+	case BUS_SPEED_100:
+		limitation = slot_cur->bus_on->slots_at_100_pcix;
+		break;
+	case BUS_SPEED_133:
+		limitation = slot_cur->bus_on->slots_at_133_pcix;
+		break;
+	}
+
+	if ((count + 1) > limitation)
+		return -EINVAL;
+	return 0;
+}
+
+static inline void print_card_capability (struct slot *slot_cur)
+{
+	info ("capability of the card is ");
+	if ((slot_cur->ext_status & CARD_INFO) == PCIX133) 
+		info ("   133 MHz PCI-X \n");
+	else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
+		info ("    66 MHz PCI-X \n");
+	else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
+		info ("    66 MHz PCI \n");
+	else
+		info ("    33 MHz PCI \n");
+
+}
+
+/* This routine will power on the slot, configure the device(s) and find the
+ * drivers for them.
+ * Parameters: hotplug_slot
+ * Returns: 0 or failure codes
+ */
+static int enable_slot (struct hotplug_slot *hs)
+{
+	int rc, i, rcpr;
+	struct slot *slot_cur;
+	u8 function;
+	struct pci_func *tmp_func;
+
+	ibmphp_lock_operations ();
+
+	debug ("ENABLING SLOT........ \n");
+	slot_cur = (struct slot *) hs->private;
+
+	if ((rc = validate (slot_cur, ENABLE))) {
+		err ("validate function failed \n");
+		goto error_nopower;
+	}
+
+	attn_LED_blink (slot_cur);
+	
+	rc = set_bus (slot_cur);
+	if (rc) {
+		err ("was not able to set the bus \n");
+		goto error_nopower;
+	}
+
+	/*-----------------debugging------------------------------*/
+	get_cur_bus_info (&slot_cur);
+	debug ("the current bus speed right after set_bus = %x \n", slot_cur->bus_on->current_speed); 
+	/*----------------------------------------------------------*/
+
+	rc = check_limitations (slot_cur);
+	if (rc) {
+		err ("Adding this card exceeds the limitations of this bus.\n");
+		err ("(i.e., >1 133MHz cards running on same bus, or "
+		     ">2 66 PCI cards running on same bus\n.");
+		err ("Try hot-adding into another bus \n");
+		rc = -EINVAL;
+		goto error_nopower;
+	}
+
+	rc = power_on (slot_cur);
+
+	if (rc) {
+		err ("something wrong when powering up... please see below for details\n");
+		/* need to turn off before on, otherwise, blinking overwrites */
+		attn_off(slot_cur);
+		attn_on (slot_cur);
+		if (slot_update (&slot_cur)) {
+			attn_off (slot_cur);
+			attn_on (slot_cur);
+			rc = -ENODEV;
+			goto exit;
+		}
+		/* Check to see the error of why it failed */
+		if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PWRGD (slot_cur->status)))
+			err ("power fault occurred trying to power up \n");
+		else if (SLOT_BUS_SPEED (slot_cur->status)) {
+			err ("bus speed mismatch occurred.  please check current bus speed and card capability \n");
+			print_card_capability (slot_cur);
+		} else if (SLOT_BUS_MODE (slot_cur->ext_status)) {
+			err ("bus mode mismatch occurred.  please check current bus mode and card capability \n");
+			print_card_capability (slot_cur);
+		}
+		ibmphp_update_slot_info (slot_cur);
+		goto exit;
+	}
+	debug ("after power_on\n");
+	/*-----------------------debugging---------------------------*/
+	get_cur_bus_info (&slot_cur);
+	debug ("the current bus speed right after power_on = %x \n", slot_cur->bus_on->current_speed);
+	/*----------------------------------------------------------*/
+
+	rc = slot_update (&slot_cur);
+	if (rc)
+		goto error_power;
+	
+	rc = -EINVAL;
+	if (SLOT_POWER (slot_cur->status) && !(SLOT_PWRGD (slot_cur->status))) {
+		err ("power fault occurred trying to power up... \n");
+		goto error_power;
+	}
+	if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
+		err ("bus speed mismatch occurred.  please check current bus speed and card capability \n");
+		print_card_capability (slot_cur);
+		goto error_power;
+	} 
+	/* Don't think this case will happen after above checks... but just in case, for paranoia sake */
+	if (!(SLOT_POWER (slot_cur->status))) {
+		err ("power on failed... \n");
+		goto error_power;
+	}
+
+	slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+	if (!slot_cur->func) {
+		/* We cannot do update_slot_info here, since no memory for
+		 * kmalloc n.e.ways, and update_slot_info allocates some */
+		err ("out of system memory \n");
+		rc = -ENOMEM;
+		goto error_power;
+	}
+	memset (slot_cur->func, 0, sizeof (struct pci_func));
+	slot_cur->func->busno = slot_cur->bus;
+	slot_cur->func->device = slot_cur->device;
+	for (i = 0; i < 4; i++)
+		slot_cur->func->irq[i] = slot_cur->irq[i];
+
+	debug ("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n", slot_cur->bus, slot_cur->device);
+
+	if (ibmphp_configure_card (slot_cur->func, slot_cur->number)) {
+		err ("configure_card was unsuccessful... \n");
+		ibmphp_unconfigure_card (&slot_cur, 1); /* true because don't need to actually deallocate resources, just remove references */
+		debug ("after unconfigure_card\n");
+		slot_cur->func = NULL;
+		rc = -ENOMEM;
+		goto error_power;
+	}
+
+	function = 0x00;
+	do {
+		tmp_func = ibm_slot_find (slot_cur->bus, slot_cur->func->device, function++);
+		if (tmp_func && !(tmp_func->dev))
+			ibm_configure_device (tmp_func);
+	} while (tmp_func);
+
+	attn_off (slot_cur);
+	if (slot_update (&slot_cur)) {
+		rc = -EFAULT;
+		goto exit;
+	}
+	ibmphp_print_test ();
+	rc = ibmphp_update_slot_info (slot_cur);
+exit:
+	ibmphp_unlock_operations(); 
+	return rc;
+
+error_nopower:
+	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
+	attn_on (slot_cur);
+error_cont:
+	rcpr = slot_update (&slot_cur);
+	if (rcpr) {
+		rc = rcpr;
+		goto exit;
+	}
+	ibmphp_update_slot_info (slot_cur);
+	goto exit;
+
+error_power:
+	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
+	attn_on (slot_cur);
+	rcpr = power_off (slot_cur);
+	if (rcpr) {
+		rc = rcpr;
+		goto exit;
+	}
+	goto error_cont;
+}
+
+/**************************************************************
+* HOT REMOVING ADAPTER CARD                                   *
+* INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE                *
+* OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE         *
+          DISABLE POWER ,                                    *
+**************************************************************/
+int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = hotplug_slot->private;
+	int rc;
+	
+	ibmphp_lock_operations();
+	rc = ibmphp_do_disable_slot(slot);
+	ibmphp_unlock_operations();
+	return rc;
+}
+
+int ibmphp_do_disable_slot (struct slot *slot_cur)
+{
+	int rc;
+	u8 flag;
+	int parm = 0;
+
+	debug ("DISABLING SLOT... \n"); 
+		
+	if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
+		return -ENODEV;
+	}
+	
+	flag = slot_cur->flag;
+	slot_cur->flag = TRUE;
+
+	if (flag == TRUE) {
+		rc = validate (slot_cur, DISABLE);	/* checking if powered off already & valid slot # */
+		if (rc)
+			goto error;
+	}
+	attn_LED_blink (slot_cur);
+
+	if (slot_cur->func == NULL) {
+		/* We need this for fncs's that were there on bootup */
+		slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+		if (!slot_cur->func) {
+			err ("out of system memory \n");
+			rc = -ENOMEM;
+			goto error;
+		}
+		memset (slot_cur->func, 0, sizeof (struct pci_func));
+		slot_cur->func->busno = slot_cur->bus;
+		slot_cur->func->device = slot_cur->device;
+	}
+
+	if ((rc = ibm_unconfigure_device (slot_cur->func))) {
+		err ("removing from kernel failed... \n");
+		err ("Please check to see if it was statically linked or is "
+		     "in use otherwise. (perhaps the driver is not 'hot-removable')\n");
+		goto error;
+	}
+        
+	/* If we got here from latch suddenly opening on operating card or 
+	a power fault, there's no power to the card, so cannot
+	read from it to determine what resources it occupied.  This operation
+	is forbidden anyhow.  The best we can do is remove it from kernel
+	lists at least */
+
+	if (!flag) {
+		attn_off (slot_cur);
+		return 0;
+	}
+
+	rc = ibmphp_unconfigure_card (&slot_cur, parm);
+	slot_cur->func = NULL;
+	debug ("in disable_slot. after unconfigure_card\n");
+	if (rc) {
+		err ("could not unconfigure card.\n");
+		goto error;
+	}
+
+	rc = ibmphp_hpc_writeslot (slot_cur, HPC_SLOT_OFF);
+	if (rc)
+		goto error;
+
+	attn_off (slot_cur);
+	rc = slot_update (&slot_cur);
+	if (rc)
+		goto exit;
+
+	rc = ibmphp_update_slot_info (slot_cur);
+	ibmphp_print_test ();
+exit:
+	return rc;
+
+error:
+	/*  Need to turn off if was blinking b4 */
+	attn_off (slot_cur);
+	attn_on (slot_cur);
+	if (slot_update (&slot_cur)) {
+		rc = -EFAULT;
+		goto exit;
+	}
+	if (flag)		
+		ibmphp_update_slot_info (slot_cur);
+	goto exit;
+}
+
+struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
+	.owner =			THIS_MODULE,
+	.set_attention_status =		set_attention_status,
+	.enable_slot =			enable_slot,
+	.disable_slot =			ibmphp_disable_slot,
+	.hardware_test =		NULL,
+	.get_power_status =		get_power_status,
+	.get_attention_status =		get_attention_status,
+	.get_latch_status =		get_latch_status,
+	.get_adapter_status =		get_adapter_present,
+	.get_max_bus_speed =		get_max_bus_speed,
+	.get_cur_bus_speed =		get_cur_bus_speed,
+/*	.get_max_adapter_speed =	get_max_adapter_speed,
+	.get_bus_name_status =		get_bus_name,
+*/
+};
+
+static void ibmphp_unload (void)
+{
+	free_slots ();
+	debug ("after slots \n");
+	ibmphp_free_resources ();
+	debug ("after resources \n");
+	ibmphp_free_bus_info_queue ();
+	debug ("after bus info \n");
+	ibmphp_free_ebda_hpc_queue ();
+	debug ("after ebda hpc \n");
+	ibmphp_free_ebda_pci_rsrc_queue ();
+	debug ("after ebda pci rsrc \n");
+	kfree (ibmphp_pci_bus);
+}
+
+static int __init ibmphp_init (void)
+{
+	struct pci_bus *bus;
+	int i = 0;
+	int rc = 0;
+
+	init_flag = 1;
+
+	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
+
+	ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL);
+	if (!ibmphp_pci_bus) {
+		err ("out of memory\n");
+		rc = -ENOMEM;
+		goto exit;
+	}
+
+	bus = pci_find_bus(0);
+	if (!bus) {
+		err ("Can't find the root pci bus, can not continue\n");
+		rc = -ENODEV;
+		goto error;
+	}
+	memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
+
+	ibmphp_debug = debug;
+
+	ibmphp_hpc_initvars ();
+
+	for (i = 0; i < 16; i++)
+		irqs[i] = 0;
+
+	if ((rc = ibmphp_access_ebda ()))
+		goto error;
+	debug ("after ibmphp_access_ebda ()\n");
+
+	if ((rc = ibmphp_rsrc_init ()))
+		goto error;
+	debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
+
+	max_slots = get_max_slots ();
+	
+	if ((rc = ibmphp_register_pci ()))
+		goto error;
+
+	if (init_ops ()) {
+		rc = -ENODEV;
+		goto error;
+	}
+
+	ibmphp_print_test ();
+	if ((rc = ibmphp_hpc_start_poll_thread ())) {
+		goto error;
+	}
+
+	/* lock ourselves into memory with a module 
+	 * count of -1 so that no one can unload us. */
+	module_put(THIS_MODULE);
+
+exit:
+	return rc;
+
+error:
+	ibmphp_unload ();
+	goto exit;
+}
+
+static void __exit ibmphp_exit (void)
+{
+	ibmphp_hpc_stop_poll_thread ();
+	debug ("after polling\n");
+	ibmphp_unload ();
+	debug ("done\n");
+}
+
+module_init (ibmphp_init);
+module_exit (ibmphp_exit);
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_ebda.c linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_ebda.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_ebda.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_ebda.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,1228 @@
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Tong Yu, IBM Corporation
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include "ibmphp.h"
+
+/*
+ * POST builds data blocks(in this data block definition, a char-1
+ * byte, short(or word)-2 byte, long(dword)-4 byte) in the Extended
+ * BIOS Data Area which describe the configuration of the hot-plug
+ * controllers and resources used by the PCI Hot-Plug devices.
+ *
+ * This file walks EBDA, maps data block from physical addr,
+ * reconstruct linked lists about all system resource(MEM, PFM, IO)
+ * already assigned by POST, as well as linked lists about hot plug
+ * controllers (ctlr#, slot#, bus&slot features...)
+ */
+
+/* Global lists */
+LIST_HEAD (ibmphp_ebda_pci_rsrc_head);
+LIST_HEAD (ibmphp_slot_head);
+
+/* Local variables */
+static struct ebda_hpc_list *hpc_list_ptr;
+static struct ebda_rsrc_list *rsrc_list_ptr;
+static struct rio_table_hdr *rio_table_ptr = NULL;
+static LIST_HEAD (ebda_hpc_head);
+static LIST_HEAD (bus_info_head);
+static LIST_HEAD (rio_vg_head);
+static LIST_HEAD (rio_lo_head);
+static LIST_HEAD (opt_vg_head);
+static LIST_HEAD (opt_lo_head);
+static void *io_mem;
+
+/* Local functions */
+static int ebda_rsrc_controller (void);
+static int ebda_rsrc_rsrc (void);
+static int ebda_rio_table (void);
+
+static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
+{
+	struct ebda_hpc_list *list;
+
+	list = kmalloc (sizeof (struct ebda_hpc_list), GFP_KERNEL);
+	if (!list)
+		return NULL;
+	memset (list, 0, sizeof (*list));
+	return list;
+}
+
+static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
+{
+	struct controller *controller;
+	struct ebda_hpc_slot *slots;
+	struct ebda_hpc_bus *buses;
+
+	controller = kmalloc (sizeof (struct controller), GFP_KERNEL);
+	if (!controller)
+		return NULL;
+	memset (controller, 0, sizeof (*controller));
+
+	slots = kmalloc (sizeof (struct ebda_hpc_slot) * slot_count, GFP_KERNEL);
+	if (!slots) {
+		kfree (controller);
+		return NULL;
+	}
+	memset (slots, 0, sizeof (*slots) * slot_count);
+	controller->slots = slots;
+
+	buses = kmalloc (sizeof (struct ebda_hpc_bus) * bus_count, GFP_KERNEL);
+	if (!buses) {
+		kfree (controller->slots);
+		kfree (controller);
+		return NULL;
+	}
+	memset (buses, 0, sizeof (*buses) * bus_count);
+	controller->buses = buses;
+
+	return controller;
+}
+
+static void free_ebda_hpc (struct controller *controller)
+{
+	kfree (controller->slots);
+	controller->slots = NULL;
+	kfree (controller->buses);
+	controller->buses = NULL;
+	controller->ctrl_dev = NULL;
+	kfree (controller);
+}
+
+static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void)
+{
+	struct ebda_rsrc_list *list;
+
+	list = kmalloc (sizeof (struct ebda_rsrc_list), GFP_KERNEL);
+	if (!list)
+		return NULL;
+	memset (list, 0, sizeof (*list));
+	return list;
+}
+
+static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
+{
+	struct ebda_pci_rsrc *resource;
+
+	resource = kmalloc (sizeof (struct ebda_pci_rsrc), GFP_KERNEL);
+	if (!resource)
+		return NULL;
+	memset (resource, 0, sizeof (*resource));
+	return resource;
+}
+
+static void __init print_bus_info (void)
+{
+	struct bus_info *ptr;
+	struct list_head *ptr1;
+	
+	list_for_each (ptr1, &bus_info_head) {
+		ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+		debug ("%s - slot_min = %x\n", __FUNCTION__, ptr->slot_min);
+		debug ("%s - slot_max = %x\n", __FUNCTION__, ptr->slot_max);
+		debug ("%s - slot_count = %x\n", __FUNCTION__, ptr->slot_count);
+		debug ("%s - bus# = %x\n", __FUNCTION__, ptr->busno);
+		debug ("%s - current_speed = %x\n", __FUNCTION__, ptr->current_speed);
+		debug ("%s - controller_id = %x\n", __FUNCTION__, ptr->controller_id);
+		
+		debug ("%s - slots_at_33_conv = %x\n", __FUNCTION__, ptr->slots_at_33_conv);
+		debug ("%s - slots_at_66_conv = %x\n", __FUNCTION__, ptr->slots_at_66_conv);
+		debug ("%s - slots_at_66_pcix = %x\n", __FUNCTION__, ptr->slots_at_66_pcix);
+		debug ("%s - slots_at_100_pcix = %x\n", __FUNCTION__, ptr->slots_at_100_pcix);
+		debug ("%s - slots_at_133_pcix = %x\n", __FUNCTION__, ptr->slots_at_133_pcix);
+
+	}
+}
+
+static void print_lo_info (void)
+{
+	struct rio_detail *ptr;
+	struct list_head *ptr1;
+	debug ("print_lo_info ---- \n");	
+	list_for_each (ptr1, &rio_lo_head) {
+		ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
+		debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
+		debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
+		debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
+		debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
+		debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
+		debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
+
+	}
+}
+
+static void print_vg_info (void)
+{
+	struct rio_detail *ptr;
+	struct list_head *ptr1;
+	debug ("%s --- \n", __FUNCTION__);
+	list_for_each (ptr1, &rio_vg_head) {
+		ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
+		debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
+		debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
+		debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
+		debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
+		debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
+		debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
+
+	}
+}
+
+static void __init print_ebda_pci_rsrc (void)
+{
+	struct ebda_pci_rsrc *ptr;
+	struct list_head *ptr1;
+
+	list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
+		ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+		debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", 
+			__FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
+	}
+}
+
+static void __init print_ibm_slot (void)
+{
+	struct slot *ptr;
+	struct list_head *ptr1;
+
+	list_for_each (ptr1, &ibmphp_slot_head) {
+		ptr = list_entry (ptr1, struct slot, ibm_slot_list);
+		debug ("%s - slot_number: %x \n", __FUNCTION__, ptr->number); 
+	}
+}
+
+static void __init print_opt_vg (void)
+{
+	struct opt_rio *ptr;
+	struct list_head *ptr1;
+	debug ("%s --- \n", __FUNCTION__);
+	list_for_each (ptr1, &opt_vg_head) {
+		ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
+		debug ("%s - rio_type %x \n", __FUNCTION__, ptr->rio_type); 
+		debug ("%s - chassis_num: %x \n", __FUNCTION__, ptr->chassis_num); 
+		debug ("%s - first_slot_num: %x \n", __FUNCTION__, ptr->first_slot_num); 
+		debug ("%s - middle_num: %x \n", __FUNCTION__, ptr->middle_num); 
+	}
+}
+
+static void __init print_ebda_hpc (void)
+{
+	struct controller *hpc_ptr;
+	struct list_head *ptr1;
+	u16 index;
+
+	list_for_each (ptr1, &ebda_hpc_head) {
+
+		hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list); 
+
+		for (index = 0; index < hpc_ptr->slot_count; index++) {
+			debug ("%s - physical slot#: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_num);
+			debug ("%s - pci bus# of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_bus_num);
+			debug ("%s - index into ctlr addr: %x\n", __FUNCTION__, hpc_ptr->slots[index].ctl_index);
+			debug ("%s - cap of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_cap);
+		}
+
+		for (index = 0; index < hpc_ptr->bus_count; index++) {
+			debug ("%s - bus# of each bus controlled by this ctlr: %x\n", __FUNCTION__, hpc_ptr->buses[index].bus_num);
+		}
+
+		debug ("%s - type of hpc: %x\n", __FUNCTION__, hpc_ptr->ctlr_type);
+		switch (hpc_ptr->ctlr_type) {
+		case 1:
+			debug ("%s - bus: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.bus);
+			debug ("%s - dev_fun: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.dev_fun);
+			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
+			break;
+
+		case 0:
+			debug ("%s - io_start: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_start);
+			debug ("%s - io_end: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_end);
+			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
+			break;
+
+		case 2:
+		case 4:
+			debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
+			debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
+			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
+			break;
+		}
+	}
+}
+
+int __init ibmphp_access_ebda (void)
+{
+	u8 format, num_ctlrs, rio_complete, hs_complete;
+	u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, rc, re, rc_id, re_id, base;
+
+
+	rio_complete = 0;
+	hs_complete = 0;
+
+	io_mem = ioremap ((0x40 << 4) + 0x0e, 2);
+	if (!io_mem )
+		return -ENOMEM;
+	ebda_seg = readw (io_mem);
+	iounmap (io_mem);
+	debug ("returned ebda segment: %x\n", ebda_seg);
+	
+	io_mem = ioremap (ebda_seg<<4, 65000);
+	if (!io_mem )
+		return -ENOMEM;
+	next_offset = 0x180;
+
+	for (;;) {
+		offset = next_offset;
+		next_offset = readw (io_mem + offset);	/* offset of next blk */
+
+		offset += 2;
+		if (next_offset == 0)	/* 0 indicate it's last blk */
+			break;
+		blk_id = readw (io_mem + offset);	/* this blk id */
+
+		offset += 2;
+		/* check if it is hot swap block or rio block */
+		if (blk_id != 0x4853 && blk_id != 0x4752)
+			continue;
+		/* found hs table */
+		if (blk_id == 0x4853) {
+			debug ("now enter hot swap block---\n");
+			debug ("hot blk id: %x\n", blk_id);
+			format = readb (io_mem + offset);
+
+			offset += 1;
+			if (format != 4) {
+				iounmap (io_mem);
+				return -ENODEV;
+			}
+			debug ("hot blk format: %x\n", format);
+			/* hot swap sub blk */
+			base = offset;
+
+			sub_addr = base;
+			re = readw (io_mem + sub_addr);	/* next sub blk */
+
+			sub_addr += 2;
+			rc_id = readw (io_mem + sub_addr); 	/* sub blk id */
+
+			sub_addr += 2;
+			if (rc_id != 0x5243) {
+				iounmap (io_mem);
+				return -ENODEV;
+			}
+			/* rc sub blk signature  */
+			num_ctlrs = readb (io_mem + sub_addr);
+
+			sub_addr += 1;
+			hpc_list_ptr = alloc_ebda_hpc_list ();
+			if (!hpc_list_ptr) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			hpc_list_ptr->format = format;
+			hpc_list_ptr->num_ctlrs = num_ctlrs;
+			hpc_list_ptr->phys_addr = sub_addr;	/*  offset of RSRC_CONTROLLER blk */
+			debug ("info about hpc descriptor---\n");
+			debug ("hot blk format: %x\n", format);
+			debug ("num of controller: %x\n", num_ctlrs);
+			debug ("offset of hpc data structure enteries: %x\n ", sub_addr);
+
+			sub_addr = base + re;	/* re sub blk */
+			rc = readw (io_mem + sub_addr);	/* next sub blk */
+
+			sub_addr += 2;
+			re_id = readw (io_mem + sub_addr);	/* sub blk id */
+
+			sub_addr += 2;
+			if (re_id != 0x5245) {
+				iounmap (io_mem);
+				return -ENODEV;
+			}
+
+			/* signature of re */
+			num_entries = readw (io_mem + sub_addr);
+
+			sub_addr += 2;	/* offset of RSRC_ENTRIES blk */
+			rsrc_list_ptr = alloc_ebda_rsrc_list ();
+			if (!rsrc_list_ptr ) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			rsrc_list_ptr->format = format;
+			rsrc_list_ptr->num_entries = num_entries;
+			rsrc_list_ptr->phys_addr = sub_addr;
+
+			debug ("info about rsrc descriptor---\n");
+			debug ("format: %x\n", format);
+			debug ("num of rsrc: %x\n", num_entries);
+			debug ("offset of rsrc data structure enteries: %x\n ", sub_addr);
+
+			hs_complete = 1;
+		}
+		/* found rio table */
+		else if (blk_id == 0x4752) {
+			debug ("now enter io table ---\n");
+			debug ("rio blk id: %x\n", blk_id);
+
+			rio_table_ptr = kmalloc (sizeof (struct rio_table_hdr), GFP_KERNEL);
+			if (!rio_table_ptr)
+				return -ENOMEM; 
+			memset (rio_table_ptr, 0, sizeof (struct rio_table_hdr) );
+			rio_table_ptr->ver_num = readb (io_mem + offset);
+			rio_table_ptr->scal_count = readb (io_mem + offset + 1);
+			rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
+			rio_table_ptr->offset = offset +3 ;
+			
+			debug ("info about rio table hdr ---\n");
+			debug ("ver_num: %x\nscal_count: %x\nriodev_count: %x\noffset of rio table: %x\n ", rio_table_ptr->ver_num, rio_table_ptr->scal_count, rio_table_ptr->riodev_count, rio_table_ptr->offset);
+
+			rio_complete = 1;
+		}
+	}
+
+	if (!hs_complete && !rio_complete) {
+		iounmap (io_mem);
+		return -ENODEV;
+	}
+
+	if (rio_table_ptr) {
+		if (rio_complete == 1 && rio_table_ptr->ver_num == 3) {
+			rc = ebda_rio_table ();
+			if (rc) {
+				iounmap (io_mem);
+				return rc;
+			}
+		}
+	}
+	rc = ebda_rsrc_controller ();
+	if (rc) {
+		iounmap (io_mem);
+		return rc;
+	}
+
+	rc = ebda_rsrc_rsrc ();
+	if (rc) {
+		iounmap (io_mem);
+		return rc;
+	}
+
+	iounmap (io_mem);
+	return 0;
+}
+
+/*
+ * map info of scalability details and rio details from physical address
+ */
+static int __init ebda_rio_table (void)
+{
+	u16 offset;
+	u8 i;
+	struct rio_detail *rio_detail_ptr;
+
+	offset = rio_table_ptr->offset;
+	offset += 12 * rio_table_ptr->scal_count;
+
+	// we do concern about rio details
+	for (i = 0; i < rio_table_ptr->riodev_count; i++) {
+		rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
+		if (!rio_detail_ptr)
+			return -ENOMEM;
+		memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
+		rio_detail_ptr->rio_node_id = readb (io_mem + offset);
+		rio_detail_ptr->bbar = readl (io_mem + offset + 1);
+		rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
+		rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
+		rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
+		rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
+		rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
+		rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
+		rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
+		rio_detail_ptr->status = readb (io_mem + offset + 12);
+		rio_detail_ptr->wpindex = readb (io_mem + offset + 13);
+		rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);
+//		debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
+		//create linked list of chassis
+		if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5) 
+			list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head);
+		//create linked list of expansion box				
+		else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7) 
+			list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head);
+		else 
+			// not in my concern
+			kfree (rio_detail_ptr);
+		offset += 15;
+	}
+	print_lo_info ();
+	print_vg_info ();
+	return 0;
+}
+
+/*
+ * reorganizing linked list of chassis	 
+ */
+static struct opt_rio *search_opt_vg (u8 chassis_num)
+{
+	struct opt_rio *ptr;
+	struct list_head *ptr1;
+	list_for_each (ptr1, &opt_vg_head) {
+		ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
+		if (ptr->chassis_num == chassis_num)
+			return ptr;
+	}		
+	return NULL;
+}
+
+static int __init combine_wpg_for_chassis (void)
+{
+	struct opt_rio *opt_rio_ptr = NULL;
+	struct rio_detail *rio_detail_ptr = NULL;
+	struct list_head *list_head_ptr = NULL;
+	
+	list_for_each (list_head_ptr, &rio_vg_head) {
+		rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
+		opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
+		if (!opt_rio_ptr) {
+			opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
+			if (!opt_rio_ptr)
+				return -ENOMEM;
+			memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
+			opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
+			opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
+			opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
+			opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
+			list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head);
+		} else {	
+			opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
+			opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
+		}	
+	}
+	print_opt_vg ();
+	return 0;	
+}	
+
+/*
+ * reorgnizing linked list of expansion box	 
+ */
+static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
+{
+	struct opt_rio_lo *ptr;
+	struct list_head *ptr1;
+	list_for_each (ptr1, &opt_lo_head) {
+		ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
+		if (ptr->chassis_num == chassis_num)
+			return ptr;
+	}		
+	return NULL;
+}
+
+static int combine_wpg_for_expansion (void)
+{
+	struct opt_rio_lo *opt_rio_lo_ptr = NULL;
+	struct rio_detail *rio_detail_ptr = NULL;
+	struct list_head *list_head_ptr = NULL;
+	
+	list_for_each (list_head_ptr, &rio_lo_head) {
+		rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
+		opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
+		if (!opt_rio_lo_ptr) {
+			opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
+			if (!opt_rio_lo_ptr)
+				return -ENOMEM;
+			memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
+			opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
+			opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
+			opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
+			opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
+			opt_rio_lo_ptr->pack_count = 1;
+			
+			list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
+		} else {	
+			opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
+			opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
+			opt_rio_lo_ptr->pack_count = 2;
+		}	
+	}
+	return 0;	
+}
+	
+
+/* Since we don't know the max slot number per each chassis, hence go
+ * through the list of all chassis to find out the range
+ * Arguments: slot_num, 1st slot number of the chassis we think we are on, 
+ * var (0 = chassis, 1 = expansion box) 
+ */
+static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
+{
+	struct opt_rio *opt_vg_ptr = NULL;
+	struct opt_rio_lo *opt_lo_ptr = NULL;
+	struct list_head *ptr = NULL;
+	int rc = 0;
+
+	if (!var) {
+		list_for_each (ptr, &opt_vg_head) {
+			opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
+			if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) { 
+				rc = -ENODEV;
+				break;
+			}
+		}
+	} else {
+		list_for_each (ptr, &opt_lo_head) {
+			opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
+			if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
+				rc = -ENODEV;
+				break;
+			}
+		}
+	}
+	return rc;
+}
+
+static struct opt_rio_lo * find_rxe_num (u8 slot_num)
+{
+	struct opt_rio_lo *opt_lo_ptr;
+	struct list_head *ptr;
+
+	list_for_each (ptr, &opt_lo_head) {
+		opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
+		//check to see if this slot_num belongs to expansion box
+		if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1))) 
+			return opt_lo_ptr;
+	}
+	return NULL;
+}
+
+static struct opt_rio * find_chassis_num (u8 slot_num)
+{
+	struct opt_rio *opt_vg_ptr;
+	struct list_head *ptr;
+
+	list_for_each (ptr, &opt_vg_head) {
+		opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
+		//check to see if this slot_num belongs to chassis 
+		if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0))) 
+			return opt_vg_ptr;
+	}
+	return NULL;
+}
+
+/* This routine will find out how many slots are in the chassis, so that
+ * the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
+ */
+static u8 calculate_first_slot (u8 slot_num)
+{
+	u8 first_slot = 1;
+	struct list_head * list;
+	struct slot * slot_cur;
+	
+	list_for_each (list, &ibmphp_slot_head) {
+		slot_cur = list_entry (list, struct slot, ibm_slot_list);
+		if (slot_cur->ctrl) {
+			if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num)) 
+				first_slot = slot_cur->ctrl->ending_slot_num;
+		}
+	}			
+	return first_slot + 1;
+
+}
+static char *create_file_name (struct slot * slot_cur)
+{
+	struct opt_rio *opt_vg_ptr = NULL;
+	struct opt_rio_lo *opt_lo_ptr = NULL;
+	static char str[30];
+	int which = 0; /* rxe = 1, chassis = 0 */
+	u8 number = 1; /* either chassis or rxe # */
+	u8 first_slot = 1;
+	u8 slot_num;
+	u8 flag = 0;
+
+	if (!slot_cur) {
+		err ("Structure passed is empty \n");
+		return NULL;
+	}
+	
+	slot_num = slot_cur->number;
+
+	memset (str, 0, sizeof(str));
+	
+	if (rio_table_ptr) {
+		if (rio_table_ptr->ver_num == 3) {
+			opt_vg_ptr = find_chassis_num (slot_num);
+			opt_lo_ptr = find_rxe_num (slot_num);
+		}
+	}
+	if (opt_vg_ptr) {
+		if (opt_lo_ptr) {
+			if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) {
+				number = opt_lo_ptr->chassis_num;
+				first_slot = opt_lo_ptr->first_slot_num;
+				which = 1; /* it is RXE */
+			} else {
+				first_slot = opt_vg_ptr->first_slot_num;
+				number = opt_vg_ptr->chassis_num;
+				which = 0;
+			}
+		} else {
+			first_slot = opt_vg_ptr->first_slot_num;
+			number = opt_vg_ptr->chassis_num;
+			which = 0;
+		}
+		++flag;
+	} else if (opt_lo_ptr) {
+		number = opt_lo_ptr->chassis_num;
+		first_slot = opt_lo_ptr->first_slot_num;
+		which = 1;
+		++flag;
+	} else if (rio_table_ptr) {
+		if (rio_table_ptr->ver_num == 3) {
+			/* if both NULL and we DO have correct RIO table in BIOS */
+			return NULL;
+		}
+	} 
+	if (!flag) {
+		if (slot_cur->ctrl->ctlr_type == 4) {
+			first_slot = calculate_first_slot (slot_num);
+			which = 1;
+		} else {
+			which = 0;
+		}
+	}
+
+	sprintf(str, "%s%dslot%d",
+		which == 0 ? "chassis" : "rxe",
+		number, slot_num - first_slot + 1);
+	return str;
+}
+
+static struct pci_driver ibmphp_driver;
+
+/*
+ * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
+ * each hpc from physical address to a list of hot plug controllers based on
+ * hpc descriptors.
+ */
+static int __init ebda_rsrc_controller (void)
+{
+	u16 addr, addr_slot, addr_bus;
+	u8 ctlr_id, temp, bus_index;
+	u16 ctlr, slot, bus;
+	u16 slot_num, bus_num, index;
+	struct hotplug_slot *hp_slot_ptr;
+	struct controller *hpc_ptr;
+	struct ebda_hpc_bus *bus_ptr;
+	struct ebda_hpc_slot *slot_ptr;
+	struct bus_info *bus_info_ptr1, *bus_info_ptr2;
+	int rc;
+	struct slot *tmp_slot;
+	struct list_head *list;
+
+	addr = hpc_list_ptr->phys_addr;
+	for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
+		bus_index = 1;
+		ctlr_id = readb (io_mem + addr);
+		addr += 1;
+		slot_num = readb (io_mem + addr);
+
+		addr += 1;
+		addr_slot = addr;	/* offset of slot structure */
+		addr += (slot_num * 4);
+
+		bus_num = readb (io_mem + addr);
+
+		addr += 1;
+		addr_bus = addr;	/* offset of bus */
+		addr += (bus_num * 9);	/* offset of ctlr_type */
+		temp = readb (io_mem + addr);
+
+		addr += 1;
+		/* init hpc structure */
+		hpc_ptr = alloc_ebda_hpc (slot_num, bus_num);
+		if (!hpc_ptr ) {
+			rc = -ENOMEM;
+			goto error_no_hpc;
+		}
+		hpc_ptr->ctlr_id = ctlr_id;
+		hpc_ptr->ctlr_relative_id = ctlr;
+		hpc_ptr->slot_count = slot_num;
+		hpc_ptr->bus_count = bus_num;
+		debug ("now enter ctlr data struture ---\n");
+		debug ("ctlr id: %x\n", ctlr_id);
+		debug ("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
+		debug ("count of slots controlled by this ctlr: %x\n", slot_num);
+		debug ("count of buses controlled by this ctlr: %x\n", bus_num);
+
+		/* init slot structure, fetch slot, bus, cap... */
+		slot_ptr = hpc_ptr->slots;
+		for (slot = 0; slot < slot_num; slot++) {
+			slot_ptr->slot_num = readb (io_mem + addr_slot);
+			slot_ptr->slot_bus_num = readb (io_mem + addr_slot + slot_num);
+			slot_ptr->ctl_index = readb (io_mem + addr_slot + 2*slot_num);
+			slot_ptr->slot_cap = readb (io_mem + addr_slot + 3*slot_num);
+
+			// create bus_info lined list --- if only one slot per bus: slot_min = slot_max 
+
+			bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);
+			if (!bus_info_ptr2) {
+				bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL);
+				if (!bus_info_ptr1) {
+					rc = -ENOMEM;
+					goto error_no_hp_slot;
+				}
+				memset (bus_info_ptr1, 0, sizeof (struct bus_info));
+				bus_info_ptr1->slot_min = slot_ptr->slot_num;
+				bus_info_ptr1->slot_max = slot_ptr->slot_num;
+				bus_info_ptr1->slot_count += 1;
+				bus_info_ptr1->busno = slot_ptr->slot_bus_num;
+				bus_info_ptr1->index = bus_index++;
+				bus_info_ptr1->current_speed = 0xff;
+				bus_info_ptr1->current_bus_mode = 0xff;
+				
+				bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;
+				
+				list_add_tail (&bus_info_ptr1->bus_info_list, &bus_info_head);
+
+			} else {
+				bus_info_ptr2->slot_min = min (bus_info_ptr2->slot_min, slot_ptr->slot_num);
+				bus_info_ptr2->slot_max = max (bus_info_ptr2->slot_max, slot_ptr->slot_num);
+				bus_info_ptr2->slot_count += 1;
+
+			}
+
+			// end of creating the bus_info linked list
+
+			slot_ptr++;
+			addr_slot += 1;
+		}
+
+		/* init bus structure */
+		bus_ptr = hpc_ptr->buses;
+		for (bus = 0; bus < bus_num; bus++) {
+			bus_ptr->bus_num = readb (io_mem + addr_bus + bus);
+			bus_ptr->slots_at_33_conv = readb (io_mem + addr_bus + bus_num + 8 * bus);
+			bus_ptr->slots_at_66_conv = readb (io_mem + addr_bus + bus_num + 8 * bus + 1);
+
+			bus_ptr->slots_at_66_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 2);
+
+			bus_ptr->slots_at_100_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 3);
+
+			bus_ptr->slots_at_133_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 4);
+
+			bus_info_ptr2 = ibmphp_find_same_bus_num (bus_ptr->bus_num);
+			if (bus_info_ptr2) {
+				bus_info_ptr2->slots_at_33_conv = bus_ptr->slots_at_33_conv;
+				bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv;
+				bus_info_ptr2->slots_at_66_pcix = bus_ptr->slots_at_66_pcix;
+				bus_info_ptr2->slots_at_100_pcix = bus_ptr->slots_at_100_pcix;
+				bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix; 
+			}
+			bus_ptr++;
+		}
+
+		hpc_ptr->ctlr_type = temp;
+
+		switch (hpc_ptr->ctlr_type) {
+			case 1:
+				hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
+				hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
+				hpc_ptr->irq = readb (io_mem + addr + 2);
+				addr += 3;
+				debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", 
+					hpc_ptr->u.pci_ctlr.bus,
+					hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
+				break;
+
+			case 0:
+				hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
+				hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
+				if (!request_region (hpc_ptr->u.isa_ctlr.io_start,
+						     (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
+						     "ibmphp")) {
+					rc = -ENODEV;
+					goto error_no_hp_slot;
+				}
+				hpc_ptr->irq = readb (io_mem + addr + 4);
+				addr += 5;
+				break;
+
+			case 2:
+			case 4:
+				hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
+				hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
+				hpc_ptr->irq = readb (io_mem + addr + 5);
+				addr += 6;
+				break;
+			default:
+				rc = -ENODEV;
+				goto error_no_hp_slot;
+		}
+
+		//reorganize chassis' linked list
+		combine_wpg_for_chassis ();
+		combine_wpg_for_expansion ();
+		hpc_ptr->revision = 0xff;
+		hpc_ptr->options = 0xff;
+		hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
+		hpc_ptr->ending_slot_num = hpc_ptr->slots[slot_num-1].slot_num;
+
+		// register slots with hpc core as well as create linked list of ibm slot
+		for (index = 0; index < hpc_ptr->slot_count; index++) {
+
+			hp_slot_ptr = (struct hotplug_slot *) kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
+			if (!hp_slot_ptr) {
+				rc = -ENOMEM;
+				goto error_no_hp_slot;
+			}
+			memset (hp_slot_ptr, 0, sizeof (struct hotplug_slot));
+
+			hp_slot_ptr->info = (struct hotplug_slot_info *) kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+			if (!hp_slot_ptr->info) {
+				rc = -ENOMEM;
+				goto error_no_hp_info;
+			}
+			memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info));
+
+			hp_slot_ptr->name = (char *) kmalloc (30, GFP_KERNEL);
+			if (!hp_slot_ptr->name) {
+				rc = -ENOMEM;
+				goto error_no_hp_name;
+			}
+
+			tmp_slot = kmalloc (sizeof (struct slot), GFP_KERNEL);
+			if (!tmp_slot) {
+				rc = -ENOMEM;
+				goto error_no_slot;
+			}
+			memset (tmp_slot, 0, sizeof (*tmp_slot));
+
+			tmp_slot->flag = TRUE;
+
+			tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
+			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
+				tmp_slot->supported_speed =  3;
+			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX)
+				tmp_slot->supported_speed =  2;
+			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX)
+				tmp_slot->supported_speed =  1;
+				
+			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP)
+				tmp_slot->supported_bus_mode = 1;
+			else
+				tmp_slot->supported_bus_mode = 0;
+
+
+			tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num;
+
+			bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num);
+			if (!bus_info_ptr1) {
+				rc = -ENODEV;
+				goto error;
+			}
+			tmp_slot->bus_on = bus_info_ptr1;
+			bus_info_ptr1 = NULL;
+			tmp_slot->ctrl = hpc_ptr;
+
+			tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index;
+			tmp_slot->number = hpc_ptr->slots[index].slot_num;
+			tmp_slot->hotplug_slot = hp_slot_ptr;
+
+			hp_slot_ptr->private = tmp_slot;
+
+			rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr);
+			if (rc)
+				goto error;
+
+			rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private);
+			if (rc)
+				goto error;
+			hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
+
+			// end of registering ibm slot with hotplug core
+
+			list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
+		}
+
+		print_bus_info ();
+		list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
+
+	}			/* each hpc  */
+
+	list_for_each (list, &ibmphp_slot_head) {
+		tmp_slot = list_entry (list, struct slot, ibm_slot_list);
+
+		snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
+		pci_hp_register (tmp_slot->hotplug_slot);
+	}
+
+	print_ebda_hpc ();
+	print_ibm_slot ();
+	return 0;
+
+error:
+	kfree (hp_slot_ptr->private);
+error_no_slot:
+	kfree (hp_slot_ptr->name);
+error_no_hp_name:
+	kfree (hp_slot_ptr->info);
+error_no_hp_info:
+	kfree (hp_slot_ptr);
+error_no_hp_slot:
+	free_ebda_hpc (hpc_ptr);
+error_no_hpc:
+	iounmap (io_mem);
+	return rc;
+}
+
+/* 
+ * map info (bus, devfun, start addr, end addr..) of i/o, memory,
+ * pfm from the physical addr to a list of resource.
+ */
+static int __init ebda_rsrc_rsrc (void)
+{
+	u16 addr;
+	short rsrc;
+	u8 type, rsrc_type;
+	struct ebda_pci_rsrc *rsrc_ptr;
+
+	addr = rsrc_list_ptr->phys_addr;
+	debug ("now entering rsrc land\n");
+	debug ("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr);
+
+	for (rsrc = 0; rsrc < rsrc_list_ptr->num_entries; rsrc++) {
+		type = readb (io_mem + addr);
+
+		addr += 1;
+		rsrc_type = type & EBDA_RSRC_TYPE_MASK;
+
+		if (rsrc_type == EBDA_IO_RSRC_TYPE) {
+			rsrc_ptr = alloc_ebda_pci_rsrc ();
+			if (!rsrc_ptr) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			rsrc_ptr->rsrc_type = type;
+
+			rsrc_ptr->bus_num = readb (io_mem + addr);
+			rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
+			rsrc_ptr->start_addr = readw (io_mem + addr + 2);
+			rsrc_ptr->end_addr = readw (io_mem + addr + 4);
+			addr += 6;
+
+			debug ("rsrc from io type ----\n");
+			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
+				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
+
+			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
+		}
+
+		if (rsrc_type == EBDA_MEM_RSRC_TYPE || rsrc_type == EBDA_PFM_RSRC_TYPE) {
+			rsrc_ptr = alloc_ebda_pci_rsrc ();
+			if (!rsrc_ptr ) {
+				iounmap (io_mem);
+				return -ENOMEM;
+			}
+			rsrc_ptr->rsrc_type = type;
+
+			rsrc_ptr->bus_num = readb (io_mem + addr);
+			rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
+			rsrc_ptr->start_addr = readl (io_mem + addr + 2);
+			rsrc_ptr->end_addr = readl (io_mem + addr + 6);
+			addr += 10;
+
+			debug ("rsrc from mem or pfm ---\n");
+			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", 
+				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
+
+			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
+		}
+	}
+	kfree (rsrc_list_ptr);
+	rsrc_list_ptr = NULL;
+	print_ebda_pci_rsrc ();
+	return 0;
+}
+
+u16 ibmphp_get_total_controllers (void)
+{
+	return hpc_list_ptr->num_ctlrs;
+}
+
+struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
+{
+	struct slot *slot;
+	struct list_head *list;
+
+	list_for_each (list, &ibmphp_slot_head) {
+		slot = list_entry (list, struct slot, ibm_slot_list);
+		if (slot->number == physical_num)
+			return slot;
+	}
+	return NULL;
+}
+
+/* To find:
+ *	- the smallest slot number
+ *	- the largest slot number
+ *	- the total number of the slots based on each bus
+ *	  (if only one slot per bus slot_min = slot_max )
+ */
+struct bus_info *ibmphp_find_same_bus_num (u32 num)
+{
+	struct bus_info *ptr;
+	struct list_head  *ptr1;
+
+	list_for_each (ptr1, &bus_info_head) {
+		ptr = list_entry (ptr1, struct bus_info, bus_info_list); 
+		if (ptr->busno == num) 
+			 return ptr;
+	}
+	return NULL;
+}
+
+/*  Finding relative bus number, in order to map corresponding
+ *  bus register
+ */
+int ibmphp_get_bus_index (u8 num)
+{
+	struct bus_info *ptr;
+	struct list_head  *ptr1;
+
+	list_for_each (ptr1, &bus_info_head) {
+		ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+		if (ptr->busno == num)  
+			return ptr->index;
+	}
+	return -ENODEV;
+}
+
+void ibmphp_free_bus_info_queue (void)
+{
+	struct bus_info *bus_info;
+	struct list_head *list;
+	struct list_head *next;
+
+	list_for_each_safe (list, next, &bus_info_head ) {
+		bus_info = list_entry (list, struct bus_info, bus_info_list);
+		kfree (bus_info);
+	}
+}
+
+void ibmphp_free_ebda_hpc_queue (void)
+{
+	struct controller *controller = NULL;
+	struct list_head *list;
+	struct list_head *next;
+	int pci_flag = 0;
+
+	list_for_each_safe (list, next, &ebda_hpc_head) {
+		controller = list_entry (list, struct controller, ebda_hpc_list);
+		if (controller->ctlr_type == 0)
+			release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
+		else if ((controller->ctlr_type == 1) && (!pci_flag)) {
+			++pci_flag;
+			pci_unregister_driver (&ibmphp_driver);
+		}
+		free_ebda_hpc (controller);
+	}
+}
+
+void ibmphp_free_ebda_pci_rsrc_queue (void)
+{
+	struct ebda_pci_rsrc *resource;
+	struct list_head *list;
+	struct list_head *next;
+
+	list_for_each_safe (list, next, &ibmphp_ebda_pci_rsrc_head) {
+		resource = list_entry (list, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+		kfree (resource);
+		resource = NULL;
+	}
+}
+
+static struct pci_device_id id_table[] __devinitdata = {
+	{
+		.vendor		= PCI_VENDOR_ID_IBM,
+		.device		= HPC_DEVICE_ID,
+		.subvendor	= PCI_VENDOR_ID_IBM,
+		.subdevice	= HPC_SUBSYSTEM_ID,
+		.class		= ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
+	}, {}
+};		
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
+static struct pci_driver ibmphp_driver = {
+	.name		= "ibmphp",
+	.id_table	= id_table,
+	.probe		= ibmphp_probe,
+};
+
+int ibmphp_register_pci (void)
+{
+	struct controller *ctrl;
+	struct list_head *tmp;
+	int rc = 0;
+
+	list_for_each (tmp, &ebda_hpc_head) {
+		ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
+		if (ctrl->ctlr_type == 1) {
+			rc = pci_module_init (&ibmphp_driver);
+			break;
+		}
+	}
+	return rc;
+}
+static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
+{
+	struct controller *ctrl;
+	struct list_head *tmp;
+
+	debug ("inside ibmphp_probe \n");
+	
+	list_for_each (tmp, &ebda_hpc_head) {
+		ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
+		if (ctrl->ctlr_type == 1) {
+			if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
+				ctrl->ctrl_dev = dev;
+				debug ("found device!!! \n");
+				debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
+				return 0;
+			}
+		}
+	}
+	return -ENODEV;
+}
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_hpc.c linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_hpc.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_hpc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_hpc.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,1228 @@
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Jyoti Shah, IBM Corporation
+ *
+ * Copyright (c) 2001-2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *                  <jshah@us.ibm.com>
+ *
+ */
+
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include "ibmphp.h"
+
+static int to_debug = FALSE;
+#define debug_polling(fmt, arg...)	do { if (to_debug) debug (fmt, arg); } while (0)
+
+//----------------------------------------------------------------------------
+// timeout values
+//----------------------------------------------------------------------------
+#define CMD_COMPLETE_TOUT_SEC	60	// give HPC 60 sec to finish cmd
+#define HPC_CTLR_WORKING_TOUT	60	// give HPC 60 sec to finish cmd
+#define HPC_GETACCESS_TIMEOUT	60	// seconds
+#define POLL_INTERVAL_SEC	2	// poll HPC every 2 seconds
+#define POLL_LATCH_CNT		5	// poll latch 5 times, then poll slots
+
+//----------------------------------------------------------------------------
+// Winnipeg Architected Register Offsets
+//----------------------------------------------------------------------------
+#define WPG_I2CMBUFL_OFFSET	0x08	// I2C Message Buffer Low
+#define WPG_I2CMOSUP_OFFSET	0x10	// I2C Master Operation Setup Reg
+#define WPG_I2CMCNTL_OFFSET	0x20	// I2C Master Control Register
+#define WPG_I2CPARM_OFFSET	0x40	// I2C Parameter Register
+#define WPG_I2CSTAT_OFFSET	0x70	// I2C Status Register
+
+//----------------------------------------------------------------------------
+// Winnipeg Store Type commands (Add this commands to the register offset)
+//----------------------------------------------------------------------------
+#define WPG_I2C_AND		0x1000	// I2C AND operation
+#define WPG_I2C_OR		0x2000	// I2C OR operation
+
+//----------------------------------------------------------------------------
+// Command set for I2C Master Operation Setup Regisetr
+//----------------------------------------------------------------------------
+#define WPG_READATADDR_MASK	0x00010000	// read,bytes,I2C shifted,index
+#define WPG_WRITEATADDR_MASK	0x40010000	// write,bytes,I2C shifted,index
+#define WPG_READDIRECT_MASK	0x10010000
+#define WPG_WRITEDIRECT_MASK	0x60010000
+
+
+//----------------------------------------------------------------------------
+// bit masks for I2C Master Control Register
+//----------------------------------------------------------------------------
+#define WPG_I2CMCNTL_STARTOP_MASK	0x00000002	// Start the Operation
+
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+#define WPG_I2C_IOREMAP_SIZE	0x2044	// size of linear address interval
+
+//----------------------------------------------------------------------------
+// command index
+//----------------------------------------------------------------------------
+#define WPG_1ST_SLOT_INDEX	0x01	// index - 1st slot for ctlr
+#define WPG_CTLR_INDEX		0x0F	// index - ctlr
+#define WPG_1ST_EXTSLOT_INDEX	0x10	// index - 1st ext slot for ctlr
+#define WPG_1ST_BUS_INDEX	0x1F	// index - 1st bus for ctlr
+
+//----------------------------------------------------------------------------
+// macro utilities
+//----------------------------------------------------------------------------
+// if bits 20,22,25,26,27,29,30 are OFF return TRUE
+#define HPC_I2CSTATUS_CHECK(s)	((u8)((s & 0x00000A76) ? FALSE : TRUE))
+
+//----------------------------------------------------------------------------
+// global variables
+//----------------------------------------------------------------------------
+static int ibmphp_shutdown;
+static int tid_poll;
+static struct semaphore sem_hpcaccess;	// lock access to HPC
+static struct semaphore semOperations;	// lock all operations and
+					// access to data structures
+static struct semaphore sem_exit;	// make sure polling thread goes away
+//----------------------------------------------------------------------------
+// local function prototypes
+//----------------------------------------------------------------------------
+static u8 i2c_ctrl_read (struct controller *, void *, u8);
+static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
+static u8 hpc_writecmdtoindex (u8, u8);
+static u8 hpc_readcmdtoindex (u8, u8);
+static void get_hpc_access (void);
+static void free_hpc_access (void);
+static void poll_hpc (void);
+static int update_slot (struct slot *, u8);
+static int process_changeinstatus (struct slot *, struct slot *);
+static int process_changeinlatch (u8, u8, struct controller *);
+static int hpc_poll_thread (void *);
+static int hpc_wait_ctlr_notworking (int, struct controller *, void *, u8 *);
+//----------------------------------------------------------------------------
+
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_hpc_initvars
+*
+* Action:  initialize semaphores and variables
+*---------------------------------------------------------------------*/
+void __init ibmphp_hpc_initvars (void)
+{
+	debug ("%s - Entry\n", __FUNCTION__);
+
+	init_MUTEX (&sem_hpcaccess);
+	init_MUTEX (&semOperations);
+	init_MUTEX_LOCKED (&sem_exit);
+	to_debug = FALSE;
+	ibmphp_shutdown = FALSE;
+	tid_poll = 0;
+
+	debug ("%s - Exit\n", __FUNCTION__);
+}
+
+/*----------------------------------------------------------------------
+* Name:    i2c_ctrl_read
+*
+* Action:  read from HPC over I2C
+*
+*---------------------------------------------------------------------*/
+static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
+{
+	u8 status;
+	int i;
+	void *wpg_addr;		// base addr + offset
+	ulong wpg_data,		// data to/from WPG LOHI format
+	ultemp, data;		// actual data HILO format
+
+
+	debug_polling ("%s - Entry WPGBbar[%lx] index[%x] \n", __FUNCTION__, (ulong) WPGBbar, index);
+
+	//--------------------------------------------------------------------
+	// READ - step 1
+	// read at address, byte length, I2C address (shifted), index
+	// or read direct, byte length, index
+	if (ctlr_ptr->ctlr_type == 0x02) {
+		data = WPG_READATADDR_MASK;
+		// fill in I2C address
+		ultemp = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr;
+		ultemp = ultemp >> 1;
+		data |= (ultemp << 8);
+
+		// fill in index
+		data |= (ulong) index;
+	} else if (ctlr_ptr->ctlr_type == 0x04) {
+		data = WPG_READDIRECT_MASK;
+
+		// fill in index
+		ultemp = (ulong) index;
+		ultemp = ultemp << 8;
+		data |= ultemp;
+	} else {
+		err ("this controller type is not supported \n");
+		return HPC_ERROR;
+	}
+
+	wpg_data = swab32 (data);	// swap data before writing
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// READ - step 2 : clear the message buffer
+	data = 0x00000000;
+	wpg_data = swab32 (data);
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// READ - step 3 : issue start operation, I2C master control bit 30:ON
+	//                 2020 : [20] OR operation at [20] offset 0x20
+	data = WPG_I2CMCNTL_STARTOP_MASK;
+	wpg_data = swab32 (data);
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) WPG_I2C_OR;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// READ - step 4 : wait until start operation bit clears
+	i = CMD_COMPLETE_TOUT_SEC;
+	while (i) {
+		long_delay (1 * HZ / 100);
+		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET;
+		wpg_data = readl (wpg_addr);
+		data = swab32 (wpg_data);
+		if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
+			break;
+		i--;
+	}
+	if (i == 0) {
+		debug ("%s - Error : WPG timeout\n", __FUNCTION__);
+		return HPC_ERROR;
+	}
+	//--------------------------------------------------------------------
+	// READ - step 5 : read I2C status register
+	i = CMD_COMPLETE_TOUT_SEC;
+	while (i) {
+		long_delay (1 * HZ / 100);
+		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CSTAT_OFFSET;
+		wpg_data = readl (wpg_addr);
+		data = swab32 (wpg_data);
+		if (HPC_I2CSTATUS_CHECK (data))
+			break;
+		i--;
+	}
+	if (i == 0) {
+		debug ("ctrl_read - Exit Error:I2C timeout\n");
+		return HPC_ERROR;
+	}
+
+	//--------------------------------------------------------------------
+	// READ - step 6 : get DATA
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
+	wpg_data = readl (wpg_addr);
+	data = swab32 (wpg_data);
+
+	status = (u8) data;
+
+	debug_polling ("%s - Exit index[%x] status[%x]\n", __FUNCTION__, index, status);
+
+	return (status);
+}
+
+/*----------------------------------------------------------------------
+* Name:    i2c_ctrl_write
+*
+* Action:  write to HPC over I2C
+*
+* Return   0 or error codes
+*---------------------------------------------------------------------*/
+static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
+{
+	u8 rc;
+	void *wpg_addr;		// base addr + offset
+	ulong wpg_data,		// data to/from WPG LOHI format 
+	ultemp, data;		// actual data HILO format
+	int i;
+
+
+	debug_polling ("%s - Entry WPGBbar[%lx] index[%x] cmd[%x]\n", __FUNCTION__, (ulong) WPGBbar, index, cmd);
+
+	rc = 0;
+	//--------------------------------------------------------------------
+	// WRITE - step 1
+	// write at address, byte length, I2C address (shifted), index
+	// or write direct, byte length, index
+	data = 0x00000000;
+
+	if (ctlr_ptr->ctlr_type == 0x02) {
+		data = WPG_WRITEATADDR_MASK;
+		// fill in I2C address
+		ultemp = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr;
+		ultemp = ultemp >> 1;
+		data |= (ultemp << 8);
+
+		// fill in index
+		data |= (ulong) index;
+	} else if (ctlr_ptr->ctlr_type == 0x04) {
+		data = WPG_WRITEDIRECT_MASK;
+
+		// fill in index
+		ultemp = (ulong) index;
+		ultemp = ultemp << 8;
+		data |= ultemp;
+	} else {
+		err ("this controller type is not supported \n");
+		return HPC_ERROR;
+	}
+
+	wpg_data = swab32 (data);	// swap data before writing
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// WRITE - step 2 : clear the message buffer
+	data = 0x00000000 | (ulong) cmd;
+	wpg_data = swab32 (data);
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// WRITE - step 3 : issue start operation,I2C master control bit 30:ON
+	//                 2020 : [20] OR operation at [20] offset 0x20
+	data = WPG_I2CMCNTL_STARTOP_MASK;
+	wpg_data = swab32 (data);
+	(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) WPG_I2C_OR;
+	writel (wpg_data, wpg_addr);
+
+	//--------------------------------------------------------------------
+	// WRITE - step 4 : wait until start operation bit clears
+	i = CMD_COMPLETE_TOUT_SEC;
+	while (i) {
+		long_delay (1 * HZ / 100);
+		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET;
+		wpg_data = readl (wpg_addr);
+		data = swab32 (wpg_data);
+		if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
+			break;
+		i--;
+	}
+	if (i == 0) {
+		debug ("%s - Exit Error:WPG timeout\n", __FUNCTION__);
+		rc = HPC_ERROR;
+	}
+
+	//--------------------------------------------------------------------
+	// WRITE - step 5 : read I2C status register
+	i = CMD_COMPLETE_TOUT_SEC;
+	while (i) {
+		long_delay (1 * HZ / 100);
+		(ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CSTAT_OFFSET;
+		wpg_data = readl (wpg_addr);
+		data = swab32 (wpg_data);
+		if (HPC_I2CSTATUS_CHECK (data))
+			break;
+		i--;
+	}
+	if (i == 0) {
+		debug ("ctrl_read - Error : I2C timeout\n");
+		rc = HPC_ERROR;
+	}
+
+	debug_polling ("%s Exit rc[%x]\n", __FUNCTION__, rc);
+	return (rc);
+}
+
+//------------------------------------------------------------
+//  Read from ISA type HPC 
+//------------------------------------------------------------
+static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
+{
+	u16 start_address;
+	u16 end_address;
+	u8 data;
+
+	start_address = ctlr_ptr->u.isa_ctlr.io_start;
+	end_address = ctlr_ptr->u.isa_ctlr.io_end;
+	data = inb (start_address + offset);
+	return data;
+}
+
+//--------------------------------------------------------------
+// Write to ISA type HPC
+//--------------------------------------------------------------
+static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
+{
+	u16 start_address;
+	u16 port_address;
+	
+	start_address = ctlr_ptr->u.isa_ctlr.io_start;
+	port_address = start_address + (u16) offset;
+	outb (data, port_address);
+}
+
+static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
+{
+	u8 data = 0x00;
+	debug ("inside pci_ctrl_read\n");
+	if (ctrl->ctrl_dev)
+		pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
+	return data;
+}
+
+static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
+{
+	u8 rc = -ENODEV;
+	debug ("inside pci_ctrl_write\n");
+	if (ctrl->ctrl_dev) {
+		pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
+		rc = 0;
+	}
+	return rc;
+}
+
+static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset)
+{
+	u8 rc;
+	switch (ctlr->ctlr_type) {
+	case 0:
+		rc = isa_ctrl_read (ctlr, offset);
+		break;
+	case 1:
+		rc = pci_ctrl_read (ctlr, offset);
+		break;
+	case 2:
+	case 4:
+		rc = i2c_ctrl_read (ctlr, base, offset);
+		break;
+	default:
+		return -ENODEV;
+	}
+	return rc;
+}
+
+static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data)
+{
+	u8 rc = 0;
+	switch (ctlr->ctlr_type) {
+	case 0:
+		isa_ctrl_write(ctlr, offset, data);
+		break;
+	case 1:
+		rc = pci_ctrl_write (ctlr, offset, data);
+		break;
+	case 2:
+	case 4:
+		rc = i2c_ctrl_write(ctlr, base, offset, data);
+		break;
+	default:
+		return -ENODEV;
+	}
+	return rc;
+}
+/*----------------------------------------------------------------------
+* Name:    hpc_writecmdtoindex()
+*
+* Action:  convert a write command to proper index within a controller
+*
+* Return   index, HPC_ERROR
+*---------------------------------------------------------------------*/
+static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
+{
+	u8 rc;
+
+	switch (cmd) {
+	case HPC_CTLR_ENABLEIRQ:	// 0x00.N.15
+	case HPC_CTLR_CLEARIRQ:	// 0x06.N.15
+	case HPC_CTLR_RESET:	// 0x07.N.15
+	case HPC_CTLR_IRQSTEER:	// 0x08.N.15
+	case HPC_CTLR_DISABLEIRQ:	// 0x01.N.15
+	case HPC_ALLSLOT_ON:	// 0x11.N.15
+	case HPC_ALLSLOT_OFF:	// 0x12.N.15
+		rc = 0x0F;
+		break;
+
+	case HPC_SLOT_OFF:	// 0x02.Y.0-14
+	case HPC_SLOT_ON:	// 0x03.Y.0-14
+	case HPC_SLOT_ATTNOFF:	// 0x04.N.0-14
+	case HPC_SLOT_ATTNON:	// 0x05.N.0-14
+	case HPC_SLOT_BLINKLED:	// 0x13.N.0-14
+		rc = index;
+		break;
+
+	case HPC_BUS_33CONVMODE:
+	case HPC_BUS_66CONVMODE:
+	case HPC_BUS_66PCIXMODE:
+	case HPC_BUS_100PCIXMODE:
+	case HPC_BUS_133PCIXMODE:
+		rc = index + WPG_1ST_BUS_INDEX - 1;
+		break;
+
+	default:
+		err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
+		rc = HPC_ERROR;
+	}
+
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    hpc_readcmdtoindex()
+*
+* Action:  convert a read command to proper index within a controller
+*
+* Return   index, HPC_ERROR
+*---------------------------------------------------------------------*/
+static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
+{
+	u8 rc;
+
+	switch (cmd) {
+	case READ_CTLRSTATUS:
+		rc = 0x0F;
+		break;
+	case READ_SLOTSTATUS:
+	case READ_ALLSTAT:
+		rc = index;
+		break;
+	case READ_EXTSLOTSTATUS:
+		rc = index + WPG_1ST_EXTSLOT_INDEX;
+		break;
+	case READ_BUSSTATUS:
+		rc = index + WPG_1ST_BUS_INDEX - 1;
+		break;
+	case READ_SLOTLATCHLOWREG:
+		rc = 0x28;
+		break;
+	case READ_REVLEVEL:
+		rc = 0x25;
+		break;
+	case READ_HPCOPTIONS:
+		rc = 0x27;
+		break;
+	default:
+		rc = HPC_ERROR;
+	}
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    HPCreadslot()
+*
+* Action:  issue a READ command to HPC
+*
+* Input:   pslot   - can not be NULL for READ_ALLSTAT
+*          pstatus - can be NULL for READ_ALLSTAT
+*
+* Return   0 or error codes
+*---------------------------------------------------------------------*/
+int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
+{
+	void *wpg_bbar = NULL;
+	struct controller *ctlr_ptr;
+	struct list_head *pslotlist;
+	u8 index, status;
+	int rc = 0;
+	int busindex;
+
+	debug_polling ("%s - Entry pslot[%lx] cmd[%x] pstatus[%lx]\n", __FUNCTION__, (ulong) pslot, cmd, (ulong) pstatus);
+
+	if ((pslot == NULL)
+	    || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
+		rc = -EINVAL;
+		err ("%s - Error invalid pointer, rc[%d]\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	if (cmd == READ_BUSSTATUS) {
+		busindex = ibmphp_get_bus_index (pslot->bus);
+		if (busindex < 0) {
+			rc = -EINVAL;
+			err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
+			return rc;
+		} else
+			index = (u8) busindex;
+	} else
+		index = pslot->ctlr_index;
+
+	index = hpc_readcmdtoindex (cmd, index);
+
+	if (index == HPC_ERROR) {
+		rc = -EINVAL;
+		err ("%s - Exit Error:invalid index, rc[%d]\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	ctlr_ptr = pslot->ctrl;
+
+	get_hpc_access ();
+
+	//--------------------------------------------------------------------
+	// map physical address to logical address
+	//--------------------------------------------------------------------
+	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
+		wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+
+	//--------------------------------------------------------------------
+	// check controller status before reading
+	//--------------------------------------------------------------------
+	rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
+	if (!rc) {
+		switch (cmd) {
+		case READ_ALLSTAT:
+			// update the slot structure
+			pslot->ctrl->status = status;
+			pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
+						       &status);
+			if (!rc)
+				pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
+
+			break;
+
+		case READ_SLOTSTATUS:
+			// DO NOT update the slot structure
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+
+		case READ_EXTSLOTSTATUS:
+			// DO NOT update the slot structure
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+
+		case READ_CTLRSTATUS:
+			// DO NOT update the slot structure
+			*pstatus = status;
+			break;
+
+		case READ_BUSSTATUS:
+			pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+		case READ_REVLEVEL:
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+		case READ_HPCOPTIONS:
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+		case READ_SLOTLATCHLOWREG:
+			// DO NOT update the slot structure
+			*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
+			break;
+
+			// Not used
+		case READ_ALLSLOT:
+			list_for_each (pslotlist, &ibmphp_slot_head) {
+				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+				index = pslot->ctlr_index;
+				rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr,
+								wpg_bbar, &status);
+				if (!rc) {
+					pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
+					rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT,
+									ctlr_ptr, wpg_bbar, &status);
+					if (!rc)
+						pslot->ext_status =
+						    ctrl_read (ctlr_ptr, wpg_bbar,
+								index + WPG_1ST_EXTSLOT_INDEX);
+				} else {
+					err ("%s - Error ctrl_read failed\n", __FUNCTION__);
+					rc = -EINVAL;
+					break;
+				}
+			}
+			break;
+		default:
+			rc = -EINVAL;
+			break;
+		}
+	}
+	//--------------------------------------------------------------------
+	// cleanup
+	//--------------------------------------------------------------------
+	
+	// remove physical to logical address mapping
+	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
+		iounmap (wpg_bbar);	
+	
+	free_hpc_access ();
+
+	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_hpc_writeslot()
+*
+* Action: issue a WRITE command to HPC
+*---------------------------------------------------------------------*/
+int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
+{
+	void *wpg_bbar = NULL;
+	struct controller *ctlr_ptr;
+	u8 index, status;
+	int busindex;
+	u8 done;
+	int rc = 0;
+	int timeout;
+
+	debug_polling ("%s - Entry pslot[%lx] cmd[%x]\n", __FUNCTION__, (ulong) pslot, cmd);
+	if (pslot == NULL) {
+		rc = -EINVAL;
+		err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
+		(cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
+		(cmd == HPC_BUS_133PCIXMODE)) {
+		busindex = ibmphp_get_bus_index (pslot->bus);
+		if (busindex < 0) {
+			rc = -EINVAL;
+			err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
+			return rc;
+		} else
+			index = (u8) busindex;
+	} else
+		index = pslot->ctlr_index;
+
+	index = hpc_writecmdtoindex (cmd, index);
+
+	if (index == HPC_ERROR) {
+		rc = -EINVAL;
+		err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
+		return rc;
+	}
+
+	ctlr_ptr = pslot->ctrl;
+
+	get_hpc_access ();
+
+	//--------------------------------------------------------------------
+	// map physical address to logical address
+	//--------------------------------------------------------------------
+	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
+		wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+
+		debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
+		ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
+		ctlr_ptr->u.wpeg_ctlr.i2c_addr);
+	}
+	//--------------------------------------------------------------------
+	// check controller status before writing
+	//--------------------------------------------------------------------
+	rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
+	if (!rc) {
+
+		ctrl_write (ctlr_ptr, wpg_bbar, index, cmd);
+
+		//--------------------------------------------------------------------
+		// check controller is still not working on the command
+		//--------------------------------------------------------------------
+		timeout = CMD_COMPLETE_TOUT_SEC;
+		done = FALSE;
+		while (!done) {
+			rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
+							&status);
+			if (!rc) {
+				if (NEEDTOCHECK_CMDSTATUS (cmd)) {
+					if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
+						done = TRUE;
+				} else
+					done = TRUE;
+			}
+			if (!done) {
+				long_delay (1 * HZ);
+				if (timeout < 1) {
+					done = TRUE;
+					err ("%s - Error command complete timeout\n", __FUNCTION__);
+					rc = -EFAULT;
+				} else
+					timeout--;
+			}
+		}
+		ctlr_ptr->status = status;
+	}
+	// cleanup
+
+	// remove physical to logical address mapping
+	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
+		iounmap (wpg_bbar);	
+	free_hpc_access ();
+
+	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    get_hpc_access()
+*
+* Action: make sure only one process can access HPC at one time
+*---------------------------------------------------------------------*/
+static void get_hpc_access (void)
+{
+	down (&sem_hpcaccess);
+}
+
+/*----------------------------------------------------------------------
+* Name:    free_hpc_access()
+*---------------------------------------------------------------------*/
+void free_hpc_access (void)
+{
+	up (&sem_hpcaccess);
+}
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_lock_operations()
+*
+* Action: make sure only one process can change the data structure
+*---------------------------------------------------------------------*/
+void ibmphp_lock_operations (void)
+{
+	down (&semOperations);
+	to_debug = TRUE;
+}
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_unlock_operations()
+*---------------------------------------------------------------------*/
+void ibmphp_unlock_operations (void)
+{
+	debug ("%s - Entry\n", __FUNCTION__);
+	up (&semOperations);
+	to_debug = FALSE;
+	debug ("%s - Exit\n", __FUNCTION__);
+}
+
+/*----------------------------------------------------------------------
+* Name:    poll_hpc()
+*---------------------------------------------------------------------*/
+#define POLL_LATCH_REGISTER	0
+#define POLL_SLOTS		1
+#define POLL_SLEEP		2
+static void poll_hpc (void)
+{
+	struct slot myslot;
+	struct slot *pslot = NULL;
+	struct list_head *pslotlist;
+	int rc;
+	int poll_state = POLL_LATCH_REGISTER;
+	u8 oldlatchlow = 0x00;
+	u8 curlatchlow = 0x00;
+	int poll_count = 0;
+	u8 ctrl_count = 0x00;
+
+	debug ("%s - Entry\n", __FUNCTION__);
+
+	while (!ibmphp_shutdown) {
+		if (ibmphp_shutdown) 
+			break;
+		
+		/* try to get the lock to do some kind of harware access */
+		down (&semOperations);
+
+		switch (poll_state) {
+		case POLL_LATCH_REGISTER: 
+			oldlatchlow = curlatchlow;
+			ctrl_count = 0x00;
+			list_for_each (pslotlist, &ibmphp_slot_head) {
+				if (ctrl_count >= ibmphp_get_total_controllers())
+					break;
+				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+					ctrl_count++;
+					if (READ_SLOT_LATCH (pslot->ctrl)) {
+						rc = ibmphp_hpc_readslot (pslot,
+									  READ_SLOTLATCHLOWREG,
+									  &curlatchlow);
+						if (oldlatchlow != curlatchlow)
+							process_changeinlatch (oldlatchlow,
+									       curlatchlow,
+									       pslot->ctrl);
+					}
+				}
+			}
+			++poll_count;
+			poll_state = POLL_SLEEP;
+			break;
+		case POLL_SLOTS:
+			list_for_each (pslotlist, &ibmphp_slot_head) {
+				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+				// make a copy of the old status
+				memcpy ((void *) &myslot, (void *) pslot,
+					sizeof (struct slot));
+				rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+				if ((myslot.status != pslot->status)
+				    || (myslot.ext_status != pslot->ext_status))
+					process_changeinstatus (pslot, &myslot);
+			}
+			ctrl_count = 0x00;
+			list_for_each (pslotlist, &ibmphp_slot_head) {
+				if (ctrl_count >= ibmphp_get_total_controllers())
+					break;
+				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+					ctrl_count++;
+					if (READ_SLOT_LATCH (pslot->ctrl))
+						rc = ibmphp_hpc_readslot (pslot,
+									  READ_SLOTLATCHLOWREG,
+									  &curlatchlow);
+				}
+			}
+			++poll_count;
+			poll_state = POLL_SLEEP;
+			break;
+		case POLL_SLEEP:
+			/* don't sleep with a lock on the hardware */
+			up (&semOperations);
+			long_delay (POLL_INTERVAL_SEC * HZ);
+
+			if (ibmphp_shutdown) 
+				break;
+			
+			down (&semOperations);
+			
+			if (poll_count >= POLL_LATCH_CNT) {
+				poll_count = 0;
+				poll_state = POLL_SLOTS;
+			} else
+				poll_state = POLL_LATCH_REGISTER;
+			break;
+		}	
+		/* give up the harware semaphore */
+		up (&semOperations);
+		/* sleep for a short time just for good measure */
+		set_current_state (TASK_INTERRUPTIBLE);
+		schedule_timeout (HZ/10);
+	}
+	up (&sem_exit);
+	debug ("%s - Exit\n", __FUNCTION__);
+}
+
+
+/* ----------------------------------------------------------------------
+ *  Name:    ibmphp_hpc_fillhpslotinfo(hotplug_slot * phpslot)
+ *
+ *  Action:  fill out the hotplug_slot info
+ *
+ *  Input:   pointer to hotplug_slot
+ *
+ *  Return
+ *  Value:   0 or error codes
+ *-----------------------------------------------------------------------*/
+int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *phpslot)
+{
+	int rc = 0;
+	struct slot *pslot;
+
+	if (phpslot && phpslot->private) {
+		pslot = (struct slot *) phpslot->private;
+		rc = update_slot (pslot, (u8) TRUE);
+		if (!rc) {
+
+			// power - enabled:1  not:0
+			phpslot->info->power_status = SLOT_POWER (pslot->status);
+
+			// attention - off:0, on:1, blinking:2
+			phpslot->info->attention_status = SLOT_ATTN (pslot->status, pslot->ext_status);
+
+			// latch - open:1 closed:0
+			phpslot->info->latch_status = SLOT_LATCH (pslot->status);
+
+			// pci board - present:1 not:0
+			if (SLOT_PRESENT (pslot->status))
+				phpslot->info->adapter_status = 1;
+			else
+				phpslot->info->adapter_status = 0;
+/*
+			if (pslot->bus_on->supported_bus_mode
+				&& (pslot->bus_on->supported_speed == BUS_SPEED_66))
+				phpslot->info->max_bus_speed_status = BUS_SPEED_66PCIX;
+			else
+				phpslot->info->max_bus_speed_status = pslot->bus_on->supported_speed;
+*/		} else
+			rc = -EINVAL;
+	} else
+		rc = -EINVAL;
+
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    update_slot
+*
+* Action:  fill out slot status and extended status, controller status
+*
+* Input:   pointer to slot struct
+*---------------------------------------------------------------------*/
+static int update_slot (struct slot *pslot, u8 update)
+{
+	int rc = 0;
+
+	debug ("%s - Entry pslot[%lx]\n", __FUNCTION__, (ulong) pslot);
+	rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+	debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    process_changeinstatus
+*
+* Action:  compare old and new slot status, process the change in status
+*
+* Input:   pointer to slot struct, old slot struct
+*
+* Return   0 or error codes
+* Value:
+*
+* Side
+* Effects: None.
+*
+* Notes:
+*---------------------------------------------------------------------*/
+static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
+{
+	u8 status;
+	int rc = 0;
+	u8 disable = FALSE;
+	u8 update = FALSE;
+
+	debug ("process_changeinstatus - Entry pslot[%lx], poldslot[%lx]\n", (ulong) pslot,
+	       (ulong) poldslot);
+
+	// bit 0 - HPC_SLOT_POWER
+	if ((pslot->status & 0x01) != (poldslot->status & 0x01))
+		update = TRUE;
+
+	// bit 1 - HPC_SLOT_CONNECT
+	// ignore
+
+	// bit 2 - HPC_SLOT_ATTN
+	if ((pslot->status & 0x04) != (poldslot->status & 0x04))
+		update = TRUE;
+
+	// bit 3 - HPC_SLOT_PRSNT2
+	// bit 4 - HPC_SLOT_PRSNT1
+	if (((pslot->status & 0x08) != (poldslot->status & 0x08))
+		|| ((pslot->status & 0x10) != (poldslot->status & 0x10)))
+		update = TRUE;
+
+	// bit 5 - HPC_SLOT_PWRGD
+	if ((pslot->status & 0x20) != (poldslot->status & 0x20))
+		// OFF -> ON: ignore, ON -> OFF: disable slot
+		if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) 
+			disable = TRUE;
+
+	// bit 6 - HPC_SLOT_BUS_SPEED
+	// ignore
+
+	// bit 7 - HPC_SLOT_LATCH
+	if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
+		update = TRUE;
+		// OPEN -> CLOSE
+		if (pslot->status & 0x80) {
+			if (SLOT_PWRGD (pslot->status)) {
+				// power goes on and off after closing latch
+				// check again to make sure power is still ON
+				long_delay (1 * HZ);
+				rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
+				if (SLOT_PWRGD (status))
+					update = TRUE;
+				else	// overwrite power in pslot to OFF
+					pslot->status &= ~HPC_SLOT_POWER;
+			}
+		}
+		// CLOSE -> OPEN 
+		else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
+			&& (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
+			disable = TRUE;
+		}
+		// else - ignore
+	}
+	// bit 4 - HPC_SLOT_BLINK_ATTN
+	if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
+		update = TRUE;
+
+	if (disable) {
+		debug ("process_changeinstatus - disable slot\n");
+		pslot->flag = FALSE;
+		rc = ibmphp_do_disable_slot (pslot);
+	}
+
+	if (update || disable) {
+		ibmphp_update_slot_info (pslot);
+	}
+
+	debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __FUNCTION__, rc, disable, update);
+
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    process_changeinlatch
+*
+* Action:  compare old and new latch reg status, process the change
+*
+* Input:   old and current latch register status
+*
+* Return   0 or error codes
+* Value:
+*---------------------------------------------------------------------*/
+static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl)
+{
+	struct slot myslot, *pslot;
+	u8 i;
+	u8 mask;
+	int rc = 0;
+
+	debug ("%s - Entry old[%x], new[%x]\n", __FUNCTION__, old, new);
+	// bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
+
+	for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
+		mask = 0x01 << i;
+		if ((mask & old) != (mask & new)) {
+			pslot = ibmphp_get_slot_from_physical_num (i);
+			if (pslot) {
+				memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
+				rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+				debug ("%s - call process_changeinstatus for slot[%d]\n", __FUNCTION__, i);
+				process_changeinstatus (pslot, &myslot);
+			} else {
+				rc = -EINVAL;
+				err ("%s - Error bad pointer for slot[%d]\n", __FUNCTION__, i);
+			}
+		}
+	}
+	debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    hpc_poll_thread
+*
+* Action:  polling
+*
+* Return   0
+* Value:
+*---------------------------------------------------------------------*/
+static int hpc_poll_thread (void *data)
+{
+	debug ("%s - Entry\n", __FUNCTION__);
+
+	daemonize("hpc_poll");
+	allow_signal(SIGKILL);
+
+	poll_hpc ();
+
+	tid_poll = 0;
+	debug ("%s - Exit\n", __FUNCTION__);
+	return 0;
+}
+
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_hpc_start_poll_thread
+*
+* Action:  start polling thread
+*---------------------------------------------------------------------*/
+int __init ibmphp_hpc_start_poll_thread (void)
+{
+	int rc = 0;
+
+	debug ("%s - Entry\n", __FUNCTION__);
+
+	tid_poll = kernel_thread (hpc_poll_thread, 0, 0);
+	if (tid_poll < 0) {
+		err ("%s - Error, thread not started\n", __FUNCTION__);
+		rc = -1;
+	}
+
+	debug ("%s - Exit tid_poll[%d] rc[%d]\n", __FUNCTION__, tid_poll, rc);
+	return rc;
+}
+
+/*----------------------------------------------------------------------
+* Name:    ibmphp_hpc_stop_poll_thread
+*
+* Action:  stop polling thread and cleanup
+*---------------------------------------------------------------------*/
+void __exit ibmphp_hpc_stop_poll_thread (void)
+{
+	debug ("%s - Entry\n", __FUNCTION__);
+
+	ibmphp_shutdown = TRUE;
+	debug ("before locking operations \n");
+	ibmphp_lock_operations ();
+	debug ("after locking operations \n");
+	
+	// wait for poll thread to exit
+	debug ("before sem_exit down \n");
+	down (&sem_exit);
+	debug ("after sem_exit down \n");
+
+	// cleanup
+	debug ("before free_hpc_access \n");
+	free_hpc_access ();
+	debug ("after free_hpc_access \n");
+	ibmphp_unlock_operations ();
+	debug ("after unlock operations \n");
+	up (&sem_exit);
+	debug ("after sem exit up\n");
+
+	debug ("%s - Exit\n", __FUNCTION__);
+}
+
+/*----------------------------------------------------------------------
+* Name:    hpc_wait_ctlr_notworking
+*
+* Action:  wait until the controller is in a not working state
+*
+* Return   0, HPC_ERROR
+* Value:
+*---------------------------------------------------------------------*/
+static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void *wpg_bbar,
+				    u8 * pstatus)
+{
+	int rc = 0;
+	u8 done = FALSE;
+
+	debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
+
+	while (!done) {
+		*pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
+		if (*pstatus == HPC_ERROR) {
+			rc = HPC_ERROR;
+			done = TRUE;
+		}
+		if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
+			done = TRUE;
+		if (!done) {
+			long_delay (1 * HZ);
+			if (timeout < 1) {
+				done = TRUE;
+				err ("HPCreadslot - Error ctlr timeout\n");
+				rc = HPC_ERROR;
+			} else
+				timeout--;
+		}
+	}
+	debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
+	return rc;
+}
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_pci.c linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_pci.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_pci.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_pci.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,1758 @@
+/*
+ * IBM Hot Plug Controller Driver
+ * 
+ * Written By: Irene Zubarev, IBM Corporation
+ * 
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include "ibmphp.h"
+
+
+static int configure_device(struct pci_func *);
+static int configure_bridge(struct pci_func **, u8);
+static struct res_needed *scan_behind_bridge(struct pci_func *, u8);
+static int add_new_bus (struct bus_node *, struct resource_node *, struct resource_node *, struct resource_node *, u8);
+static u8 find_sec_number (u8 primary_busno, u8 slotno);
+
+/*
+ * NOTE..... If BIOS doesn't provide default routing, we assign:
+ * 9 for SCSI, 10 for LAN adapters, and 11 for everything else. 
+ * If adapter is bridged, then we assign 11 to it and devices behind it.
+ * We also assign the same irq numbers for multi function devices.
+ * These are PIC mode, so shouldn't matter n.e.ways (hopefully)
+ */
+static void assign_alt_irq (struct pci_func * cur_func, u8 class_code)
+{
+	int j = 0;
+	for (j = 0; j < 4; j++) {
+		if (cur_func->irq[j] == 0xff) {
+			switch (class_code) {
+				case PCI_BASE_CLASS_STORAGE:
+					cur_func->irq[j] = SCSI_IRQ;
+					break;
+				case PCI_BASE_CLASS_NETWORK:
+					cur_func->irq[j] = LAN_IRQ;
+					break;
+				default:
+					cur_func->irq[j] = OTHER_IRQ;
+					break;
+			}
+		}
+	}
+}
+
+/*
+ * Configures the device to be added (will allocate needed resources if it
+ * can), the device can be a bridge or a regular pci device, can also be
+ * multi-functional
+ * 
+ * Input: function to be added
+ * 
+ * TO DO:  The error case with Multifunction device or multi function bridge,
+ * if there is an error, will need to go through all previous functions and 
+ * unconfigure....or can add some code into unconfigure_card....
+ */
+int ibmphp_configure_card (struct pci_func *func, u8 slotno)
+{
+	u16 vendor_id;
+	u32 class;
+	u8 class_code;
+	u8 hdr_type, device, sec_number;
+	u8 function;
+	struct pci_func *newfunc;	/* for multi devices */
+	struct pci_func *cur_func, *prev_func;
+	int rc, i, j;
+	int cleanup_count;
+	u8 flag;
+	u8 valid_device = 0x00; /* to see if we are able to read from card any device info at all */
+
+	debug ("inside configure_card, func->busno = %x \n", func->busno);
+
+	device = func->device;
+	cur_func = func;
+
+	/* We only get bus and device from IRQ routing table.  So at this point,
+	 * func->busno is correct, and func->device contains only device (at the 5 
+	 * highest bits)
+	 */
+
+	/* For every function on the card */
+	for (function = 0x00; function < 0x08; function++) {
+		unsigned int devfn = PCI_DEVFN(device, function);
+		ibmphp_pci_bus->number = cur_func->busno;
+
+		cur_func->function = function;
+
+		debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n",
+			cur_func->busno, cur_func->device, cur_func->function);
+
+		pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
+
+		debug ("vendor_id is %x\n", vendor_id);
+		if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
+			/* found correct device!!! */
+			debug ("found valid device, vendor_id = %x\n", vendor_id);
+
+			++valid_device;
+
+			/* header: x x x x x x x x
+			 *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
+			 *         |_=> 0 = single function device, 1 = multi-function device
+			 */
+
+			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+			pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
+
+			class_code = class >> 24;
+			debug ("hrd_type = %x, class = %x, class_code %x \n", hdr_type, class, class_code);
+			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
+			if (class == PCI_CLASS_NOT_DEFINED_VGA) {
+				err ("The device %x is VGA compatible and as is not supported for hot plugging. "
+				     "Please choose another device.\n", cur_func->device);
+				return -ENODEV;
+			} else if (class == PCI_CLASS_DISPLAY_VGA) {
+				err ("The device %x is not supported for hot plugging. "
+				     "Please choose another device.\n", cur_func->device);
+				return -ENODEV;
+			}
+			switch (hdr_type) {
+				case PCI_HEADER_TYPE_NORMAL:
+					debug ("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class);
+					assign_alt_irq (cur_func, class_code);
+					if ((rc = configure_device (cur_func)) < 0) {
+						/* We need to do this in case some other BARs were properly inserted */
+						err ("was not able to configure devfunc %x on bus %x. \n",
+						     cur_func->device, cur_func->busno);
+						cleanup_count = 6;
+						goto error;
+					}	
+					cur_func->next = NULL;
+					function = 0x8;
+					break;
+				case PCI_HEADER_TYPE_MULTIDEVICE:
+					assign_alt_irq (cur_func, class_code);
+					if ((rc = configure_device (cur_func)) < 0) {
+						/* We need to do this in case some other BARs were properly inserted */
+						err ("was not able to configure devfunc %x on bus %x...bailing out\n",
+						     cur_func->device, cur_func->busno);
+						cleanup_count = 6;
+						goto error;
+					}
+					newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+					if (!newfunc) {
+						err ("out of system memory \n");
+						return -ENOMEM;
+					}
+					memset (newfunc, 0, sizeof (struct pci_func));
+					newfunc->busno = cur_func->busno;
+					newfunc->device = device;
+					cur_func->next = newfunc;
+					cur_func = newfunc;
+					for (j = 0; j < 4; j++)
+						newfunc->irq[j] = cur_func->irq[j];
+					break;
+				case PCI_HEADER_TYPE_MULTIBRIDGE:
+					class >>= 8;
+					if (class != PCI_CLASS_BRIDGE_PCI) {
+						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
+						     "Please insert another card.\n", cur_func->device);
+						return -ENODEV;
+					}
+					assign_alt_irq (cur_func, class_code);
+					rc = configure_bridge (&cur_func, slotno);
+					if (rc == -ENODEV) {
+						err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
+						err ("Bus %x, devfunc %x \n", cur_func->busno, cur_func->device);
+						return rc;
+					}
+					if (rc) {
+						/* We need to do this in case some other BARs were properly inserted */
+						err ("was not able to hot-add PPB properly.\n");
+						func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
+						cleanup_count = 2;
+						goto error;
+					}
+
+					pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+					flag = FALSE;
+					for (i = 0; i < 32; i++) {
+						if (func->devices[i]) {
+							newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+							if (!newfunc) {
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (newfunc, 0, sizeof (struct pci_func));
+							newfunc->busno = sec_number;
+							newfunc->device = (u8) i;
+							for (j = 0; j < 4; j++)
+								newfunc->irq[j] = cur_func->irq[j];
+
+							if (flag) {
+								for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
+								prev_func->next = newfunc;
+							} else
+								cur_func->next = newfunc;
+
+							rc = ibmphp_configure_card (newfunc, slotno);
+							/* This could only happen if kmalloc failed */
+							if (rc) {
+								/* We need to do this in case bridge itself got configured properly, but devices behind it failed */
+								func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
+								cleanup_count = 2;
+								goto error;
+							}
+							flag = TRUE;
+						}
+					}
+
+					newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+					if (!newfunc) {
+						err ("out of system memory \n");
+						return -ENOMEM;
+					}
+					memset (newfunc, 0, sizeof (struct pci_func));
+					newfunc->busno = cur_func->busno;
+					newfunc->device = device;
+					for (j = 0; j < 4; j++)
+						newfunc->irq[j] = cur_func->irq[j];
+					for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
+					prev_func->next = newfunc;
+					cur_func = newfunc;
+					break;
+				case PCI_HEADER_TYPE_BRIDGE:
+					class >>= 8;
+					debug ("class now is %x\n", class);
+					if (class != PCI_CLASS_BRIDGE_PCI) {
+						err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
+						     "Please insert another card.\n", cur_func->device);
+						return -ENODEV;
+					}
+
+					assign_alt_irq (cur_func, class_code);
+
+					debug ("cur_func->busno b4 configure_bridge is %x\n", cur_func->busno);
+					rc = configure_bridge (&cur_func, slotno);
+					if (rc == -ENODEV) {
+						err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
+						err ("Bus %x, devfunc %x \n", cur_func->busno, cur_func->device);
+						return rc;
+					}
+					if (rc) {
+						/* We need to do this in case some other BARs were properly inserted */
+						func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
+						err ("was not able to hot-add PPB properly.\n");
+						cleanup_count = 2;
+						goto error;
+					}
+					debug ("cur_func->busno = %x, device = %x, function = %x\n",
+						cur_func->busno, device, function);
+					pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+					debug ("after configuring bridge..., sec_number = %x\n", sec_number);
+					flag = FALSE;
+					for (i = 0; i < 32; i++) {
+						if (func->devices[i]) {
+							debug ("inside for loop, device is %x\n", i);
+							newfunc = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
+							if (!newfunc) {
+								err (" out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (newfunc, 0, sizeof (struct pci_func));
+							newfunc->busno = sec_number;
+							newfunc->device = (u8) i;
+							for (j = 0; j < 4; j++)
+								newfunc->irq[j] = cur_func->irq[j];
+
+							if (flag) {
+								for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
+								prev_func->next = newfunc;
+							} else
+								cur_func->next = newfunc;
+
+							rc = ibmphp_configure_card (newfunc, slotno);
+
+							/* Again, this case should not happen... For complete paranoia, will need to call remove_bus */
+							if (rc) {
+								/* We need to do this in case some other BARs were properly inserted */
+								func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
+								cleanup_count = 2;
+								goto error;
+							}
+							flag = TRUE;
+						}
+					}
+
+					function = 0x8;
+					break;
+				default:
+					err ("MAJOR PROBLEM!!!!, header type not supported? %x\n", hdr_type);
+					return -ENXIO;
+					break;
+			}	/* end of switch */
+		}	/* end of valid device */
+	}	/* end of for */
+
+	if (!valid_device) {
+		err ("Cannot find any valid devices on the card.  Or unable to read from card.\n");
+		return -ENODEV;
+	}
+
+	return 0;
+
+error:
+	for (i = 0; i < cleanup_count; i++) {
+		if (cur_func->io[i]) {
+			ibmphp_remove_resource (cur_func->io[i]);
+			cur_func->io[i] = NULL;
+		} else if (cur_func->pfmem[i]) {
+			ibmphp_remove_resource (cur_func->pfmem[i]);
+			cur_func->pfmem[i] = NULL;
+		} else if (cur_func->mem[i]) {
+			ibmphp_remove_resource (cur_func->mem[i]);
+			cur_func->mem[i] = NULL;
+		}
+	}
+	return rc;
+}
+
+/*
+ * This function configures the pci BARs of a single device.  
+ * Input: pointer to the pci_func
+ * Output: configured PCI, 0, or error
+ */
+static int configure_device (struct pci_func *func)
+{
+	u32 bar[6];
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	u8 irq;
+	int count;
+	int len[6];
+	struct resource_node *io[6];
+	struct resource_node *mem[6];
+	struct resource_node *mem_tmp;
+	struct resource_node *pfmem[6];
+	unsigned int devfn;
+
+	debug ("%s - inside\n", __FUNCTION__);
+
+	devfn = PCI_DEVFN(func->device, func->function);
+	ibmphp_pci_bus->number = func->busno;
+
+	for (count = 0; address[count]; count++) {	/* for 6 BARs */
+
+		/* not sure if i need this.  per scott, said maybe need smth like this
+		   if devices don't adhere 100% to the spec, so don't want to write
+		   to the reserved bits
+
+		pcibios_read_config_byte(cur_func->busno, cur_func->device, 
+		PCI_BASE_ADDRESS_0 + 4 * count, &tmp);
+		if (tmp & 0x01) // IO
+			pcibios_write_config_dword(cur_func->busno, cur_func->device, 
+			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFD);
+		else  // Memory
+			pcibios_write_config_dword(cur_func->busno, cur_func->device, 
+			PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
+		 */
+		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+
+		if (!bar[count])	/* This BAR is not implemented */
+			continue;
+
+		debug ("Device %x BAR %d wants %x\n", func->device, count, bar[count]);
+
+		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			debug ("inside IO SPACE\n");
+
+			len[count] = bar[count] & 0xFFFFFFFC;
+			len[count] = ~len[count] + 1;
+
+			debug ("len[count] in IO %x, count %d\n", len[count], count);
+
+			io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+
+			if (!io[count]) {
+				err ("out of system memory \n");
+				return -ENOMEM;
+			}
+			memset (io[count], 0, sizeof (struct resource_node));
+			io[count]->type = IO;
+			io[count]->busno = func->busno;
+			io[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+			io[count]->len = len[count];
+			if (ibmphp_check_resource(io[count], 0) == 0) {
+				ibmphp_add_resource (io[count]);
+				func->io[count] = io[count];
+			} else {
+				err ("cannot allocate requested io for bus %x device %x function %x len %x\n",
+				     func->busno, func->device, func->function, len[count]);
+				kfree (io[count]);
+				return -EIO;
+			}
+			pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
+	
+			/* _______________This is for debugging purposes only_____________________ */ 
+			debug ("b4 writing, the IO address is %x\n", func->io[count]->start);
+			pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+			debug ("after writing.... the start address is %x\n", bar[count]);
+			/* _________________________________________________________________________*/
+
+		} else {
+			/* This is Memory */
+			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+				debug ("PFMEM SPACE\n");
+
+				len[count] = bar[count] & 0xFFFFFFF0;
+				len[count] = ~len[count] + 1;
+
+				debug ("len[count] in PFMEM %x, count %d\n", len[count], count);
+
+				pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+				if (!pfmem[count]) {
+					err ("out of system memory \n");
+					return -ENOMEM;
+				}
+				memset (pfmem[count], 0, sizeof (struct resource_node));
+				pfmem[count]->type = PFMEM;
+				pfmem[count]->busno = func->busno;
+				pfmem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				pfmem[count]->len = len[count];
+				pfmem[count]->fromMem = FALSE;
+				if (ibmphp_check_resource (pfmem[count], 0) == 0) {
+					ibmphp_add_resource (pfmem[count]);
+					func->pfmem[count] = pfmem[count];
+				} else {
+					mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+					if (!mem_tmp) {
+						err ("out of system memory \n");
+						kfree (pfmem[count]);
+						return -ENOMEM;
+					}
+					memset (mem_tmp, 0, sizeof (struct resource_node));
+					mem_tmp->type = MEM;
+					mem_tmp->busno = pfmem[count]->busno;
+					mem_tmp->devfunc = pfmem[count]->devfunc;
+					mem_tmp->len = pfmem[count]->len;
+					debug ("there's no pfmem... going into mem.\n");
+					if (ibmphp_check_resource (mem_tmp, 0) == 0) {
+						ibmphp_add_resource (mem_tmp);
+						pfmem[count]->fromMem = TRUE;
+						pfmem[count]->rangeno = mem_tmp->rangeno;
+						pfmem[count]->start = mem_tmp->start;
+						pfmem[count]->end = mem_tmp->end;
+						ibmphp_add_pfmem_from_mem (pfmem[count]);
+						func->pfmem[count] = pfmem[count];
+					} else {
+						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
+						     func->busno, func->device, len[count]);
+						kfree (mem_tmp);
+						kfree (pfmem[count]);
+						return -EIO;
+					}
+				}
+
+				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
+
+				/*_______________This is for debugging purposes only______________________________*/				
+				debug ("b4 writing, start address is %x\n", func->pfmem[count]->start);
+				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+				debug ("after writing, start address is %x\n", bar[count]);
+				/*_________________________________________________________________________________*/
+
+				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
+					debug ("inside the mem 64 case, count %d\n", count);
+					count += 1;
+					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
+					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
+				}
+			} else {
+				/* regular memory */
+				debug ("REGULAR MEM SPACE\n");
+
+				len[count] = bar[count] & 0xFFFFFFF0;
+				len[count] = ~len[count] + 1;
+
+				debug ("len[count] in Mem %x, count %d\n", len[count], count);
+
+				mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+				if (!mem[count]) {
+					err ("out of system memory \n");
+					return -ENOMEM;
+				}
+				memset (mem[count], 0, sizeof (struct resource_node));
+				mem[count]->type = MEM;
+				mem[count]->busno = func->busno;
+				mem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				mem[count]->len = len[count];
+				if (ibmphp_check_resource (mem[count], 0) == 0) {
+					ibmphp_add_resource (mem[count]);
+					func->mem[count] = mem[count];
+				} else {
+					err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
+					     func->busno, func->device, len[count]);
+					kfree (mem[count]);
+					return -EIO;
+				}
+				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
+				/* _______________________This is for debugging purposes only _______________________*/
+				debug ("b4 writing, start address is %x\n", func->mem[count]->start);
+				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+				debug ("after writing, the address is %x\n", bar[count]);
+				/* __________________________________________________________________________________*/
+
+				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					debug ("inside mem 64 case, reg. mem, count %d\n", count);
+					count += 1;
+					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
+					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
+				}
+			}
+		}		/* end of mem */
+	}			/* end of for */
+
+	func->bus = 0;		/* To indicate that this is not a PPB */
+	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
+	if ((irq > 0x00) && (irq < 0x05))
+		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
+
+	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
+	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
+
+	pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
+	pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
+
+	return 0;
+}
+
+/******************************************************************************
+ * This routine configures a PCI-2-PCI bridge and the functions behind it
+ * Parameters: pci_func
+ * Returns: 
+ ******************************************************************************/
+static int configure_bridge (struct pci_func **func_passed, u8 slotno)
+{
+	int count;
+	int i;
+	int rc;
+	u8 sec_number;
+	u8 io_base;
+	u16 pfmem_base;
+	u32 bar[2];
+	u32 len[2];
+	u8 flag_io = FALSE;
+	u8 flag_mem = FALSE;
+	u8 flag_pfmem = FALSE;
+	u8 need_io_upper = FALSE;
+	u8 need_pfmem_upper = FALSE;
+	struct res_needed *amount_needed = NULL;
+	struct resource_node *io = NULL;
+	struct resource_node *bus_io[2] = {NULL, NULL};
+	struct resource_node *mem = NULL;
+	struct resource_node *bus_mem[2] = {NULL, NULL};
+	struct resource_node *mem_tmp = NULL;
+	struct resource_node *pfmem = NULL;
+	struct resource_node *bus_pfmem[2] = {NULL, NULL};
+	struct bus_node *bus;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		0
+	};
+	struct pci_func *func = *func_passed;
+	unsigned int devfn;
+	u8 irq;
+	int retval;
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	devfn = PCI_DEVFN(func->function, func->device);
+	ibmphp_pci_bus->number = func->busno;
+
+	/* Configuring necessary info for the bridge so that we could see the devices
+	 * behind it
+	 */
+
+	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
+
+	/* _____________________For debugging purposes only __________________________
+	pci_bus_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
+	debug ("primary # written into the bridge is %x\n", pri_number);
+	 ___________________________________________________________________________*/
+
+	/* in EBDA, only get allocated 1 additional bus # per slot */
+	sec_number = find_sec_number (func->busno, slotno);
+	if (sec_number == 0xff) {
+		err ("cannot allocate secondary bus number for the bridged device \n");
+		return -EINVAL;
+	}
+
+	debug ("after find_sec_number, the number we got is %x\n", sec_number);
+	debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
+
+	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
+	
+	/* __________________For debugging purposes only __________________________________
+	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+	debug ("sec_number after write/read is %x\n", sec_number);
+	 ________________________________________________________________________________*/
+
+	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
+
+	/* __________________For debugging purposes only ____________________________________
+	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
+	debug ("subordinate number after write/read is %x\n", sec_number);
+	 __________________________________________________________________________________*/
+
+	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
+	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
+	pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
+
+	debug ("func->busno is %x\n", func->busno);
+	debug ("sec_number after writing is %x\n", sec_number);
+
+
+	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	   !!!!!!!!!!!!!!!NEED TO ADD!!!  FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!! 
+	   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+
+
+	/* First we need to allocate mem/io for the bridge itself in case it needs it */
+	for (count = 0; address[count]; count++) {	/* for 2 BARs */
+		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+
+		if (!bar[count]) {
+			/* This BAR is not implemented */
+			debug ("so we come here then, eh?, count = %d\n", count);
+			continue;
+		}
+		//  tmp_bar = bar[count];
+
+		debug ("Bar %d wants %x\n", count, bar[count]);
+
+		if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			len[count] = bar[count] & 0xFFFFFFFC;
+			len[count] = ~len[count] + 1;
+
+			debug ("len[count] in IO = %x\n", len[count]);
+
+			bus_io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		
+			if (!bus_io[count]) {
+				err ("out of system memory \n");
+				retval = -ENOMEM;
+				goto error;
+			}
+			memset (bus_io[count], 0, sizeof (struct resource_node));
+			bus_io[count]->type = IO;
+			bus_io[count]->busno = func->busno;
+			bus_io[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+			bus_io[count]->len = len[count];
+			if (ibmphp_check_resource (bus_io[count], 0) == 0) {
+				ibmphp_add_resource (bus_io[count]);
+				func->io[count] = bus_io[count];
+			} else {
+				err ("cannot allocate requested io for bus %x, device %x, len %x\n",
+				     func->busno, func->device, len[count]);
+				kfree (bus_io[count]);
+				return -EIO;
+			}
+
+			pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
+
+		} else {
+			/* This is Memory */
+			if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+				len[count] = bar[count] & 0xFFFFFFF0;
+				len[count] = ~len[count] + 1;
+
+				debug ("len[count] in PFMEM = %x\n", len[count]);
+
+				bus_pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+				if (!bus_pfmem[count]) {
+					err ("out of system memory \n");
+					retval = -ENOMEM;
+					goto error;
+				}
+				memset (bus_pfmem[count], 0, sizeof (struct resource_node));
+				bus_pfmem[count]->type = PFMEM;
+				bus_pfmem[count]->busno = func->busno;
+				bus_pfmem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				bus_pfmem[count]->len = len[count];
+				bus_pfmem[count]->fromMem = FALSE;
+				if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {
+					ibmphp_add_resource (bus_pfmem[count]);
+					func->pfmem[count] = bus_pfmem[count];
+				} else {
+					mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+					if (!mem_tmp) {
+						err ("out of system memory \n");
+						retval = -ENOMEM;
+						goto error;
+					}
+					memset (mem_tmp, 0, sizeof (struct resource_node));
+					mem_tmp->type = MEM;
+					mem_tmp->busno = bus_pfmem[count]->busno;
+					mem_tmp->devfunc = bus_pfmem[count]->devfunc;
+					mem_tmp->len = bus_pfmem[count]->len;
+					if (ibmphp_check_resource (mem_tmp, 0) == 0) {
+						ibmphp_add_resource (mem_tmp);
+						bus_pfmem[count]->fromMem = TRUE;
+						bus_pfmem[count]->rangeno = mem_tmp->rangeno;
+						ibmphp_add_pfmem_from_mem (bus_pfmem[count]);
+						func->pfmem[count] = bus_pfmem[count];
+					} else {
+						err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n", 
+						     func->busno, func->device, len[count]);
+						kfree (mem_tmp);
+						kfree (bus_pfmem[count]);
+						return -EIO;
+					}
+				}
+
+				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
+
+				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
+					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
+
+				}
+			} else {
+				/* regular memory */
+				len[count] = bar[count] & 0xFFFFFFF0;
+				len[count] = ~len[count] + 1;
+
+				debug ("len[count] in Memory is %x\n", len[count]);
+
+				bus_mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+				if (!bus_mem[count]) {
+					err ("out of system memory \n");
+					retval = -ENOMEM;
+					goto error;
+				}
+				memset (bus_mem[count], 0, sizeof (struct resource_node));
+				bus_mem[count]->type = MEM;
+				bus_mem[count]->busno = func->busno;
+				bus_mem[count]->devfunc = ((func->device << 3) | (func->function & 0x7));
+				bus_mem[count]->len = len[count];
+				if (ibmphp_check_resource (bus_mem[count], 0) == 0) {
+					ibmphp_add_resource (bus_mem[count]);
+					func->mem[count] = bus_mem[count];
+				} else {
+					err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
+					     func->busno, func->device, len[count]);
+					kfree (bus_mem[count]);
+					return -EIO;
+				}
+
+				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
+
+				if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+					/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
+					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
+
+				}
+			}
+		}		/* end of mem */
+	}			/* end of for  */
+
+	/* Now need to see how much space the devices behind the bridge needed */
+	amount_needed = scan_behind_bridge (func, sec_number);
+	if (amount_needed == NULL)
+		return -ENOMEM;
+
+	ibmphp_pci_bus->number = func->busno;
+	debug ("after coming back from scan_behind_bridge\n");
+	debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
+	debug ("amount_needed->io = %x\n", amount_needed->io);
+	debug ("amount_needed->mem = %x\n", amount_needed->mem);
+	debug ("amount_needed->pfmem =  %x\n", amount_needed->pfmem);
+
+	if (amount_needed->not_correct) {		
+		debug ("amount_needed is not correct \n");
+		for (count = 0; address[count]; count++) {
+			/* for 2 BARs */
+			if (bus_io[count]) {
+				ibmphp_remove_resource (bus_io[count]);
+				func->io[count] = NULL;
+			} else if (bus_pfmem[count]) {
+				ibmphp_remove_resource (bus_pfmem[count]);
+				func->pfmem[count] = NULL;
+			} else if (bus_mem[count]) {
+				ibmphp_remove_resource (bus_mem[count]);
+				func->mem[count] = NULL;
+			}
+		}
+		kfree (amount_needed);
+		return -ENODEV;
+	}
+
+	if (!amount_needed->io) {
+		debug ("it doesn't want IO?\n");
+		flag_io = TRUE;
+	} else {
+		debug ("it wants %x IO behind the bridge \n", amount_needed->io);
+		io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		
+		if (!io) {
+			err ("out of system memory \n");
+			retval = -ENOMEM;
+			goto error;
+		}
+		memset (io, 0, sizeof (struct resource_node));
+		io->type = IO;
+		io->busno = func->busno;
+		io->devfunc = ((func->device << 3) | (func->function & 0x7));
+		io->len = amount_needed->io;
+		if (ibmphp_check_resource (io, 1) == 0) {
+			debug ("were we able to add io\n");
+			ibmphp_add_resource (io);
+			flag_io = TRUE;
+		}
+	}
+
+	if (!amount_needed->mem) {
+		debug ("it doesn't want n.e.memory?\n");
+		flag_mem = TRUE;
+	} else {
+		debug ("it wants %x memory behind the bridge\n", amount_needed->mem);
+		mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		if (!mem) {
+			err ("out of system memory \n");
+			retval = -ENOMEM;
+			goto error;
+		}
+		memset (mem, 0, sizeof (struct resource_node));
+		mem->type = MEM;
+		mem->busno = func->busno;
+		mem->devfunc = ((func->device << 3) | (func->function & 0x7));
+		mem->len = amount_needed->mem;
+		if (ibmphp_check_resource (mem, 1) == 0) {
+			ibmphp_add_resource (mem);
+			flag_mem = TRUE;
+			debug ("were we able to add mem\n");
+		}
+	}
+
+	if (!amount_needed->pfmem) {
+		debug ("it doesn't want n.e.pfmem mem?\n");
+		flag_pfmem = TRUE;
+	} else {
+		debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
+		pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+		if (!pfmem) {
+			err ("out of system memory \n");
+			retval = -ENOMEM;
+			goto error;
+		}
+		memset (pfmem, 0, sizeof (struct resource_node));
+		pfmem->type = PFMEM;
+		pfmem->busno = func->busno;
+		pfmem->devfunc = ((func->device << 3) | (func->function & 0x7));
+		pfmem->len = amount_needed->pfmem;
+		pfmem->fromMem = FALSE;
+		if (ibmphp_check_resource (pfmem, 1) == 0) {
+			ibmphp_add_resource (pfmem);
+			flag_pfmem = TRUE;
+		} else {
+			mem_tmp = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+			if (!mem_tmp) {
+				err ("out of system memory \n");
+				retval = -ENOMEM;
+				goto error;
+			}
+			memset (mem_tmp, 0, sizeof (struct resource_node));
+			mem_tmp->type = MEM;
+			mem_tmp->busno = pfmem->busno;
+			mem_tmp->devfunc = pfmem->devfunc;
+			mem_tmp->len = pfmem->len;
+			if (ibmphp_check_resource (mem_tmp, 1) == 0) {
+				ibmphp_add_resource (mem_tmp);
+				pfmem->fromMem = TRUE;
+				pfmem->rangeno = mem_tmp->rangeno;
+				ibmphp_add_pfmem_from_mem (pfmem);
+				flag_pfmem = TRUE;
+			}
+		}
+	}
+
+	debug ("b4 if (flag_io && flag_mem && flag_pfmem)\n");
+	debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
+
+	if (flag_io && flag_mem && flag_pfmem) {
+		/* If on bootup, there was a bridged card in this slot,
+		 * then card was removed and ibmphp got unloaded and loaded
+		 * back again, there's no way for us to remove the bus
+		 * struct, so no need to kmalloc, can use existing node
+		 */
+		bus = ibmphp_find_res_bus (sec_number);
+		if (!bus) {
+			bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+			if (!bus) {
+				err ("out of system memory \n");
+				retval = -ENOMEM;
+				goto error;
+			}
+			memset (bus, 0, sizeof (struct bus_node));
+			bus->busno = sec_number;
+			debug ("b4 adding new bus\n");
+			rc = add_new_bus (bus, io, mem, pfmem, func->busno);
+		} else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
+			rc = add_new_bus (bus, io, mem, pfmem, 0xFF);
+		else {
+			err ("expected bus structure not empty? \n");
+			retval = -EIO;
+			goto error;
+		}
+		if (rc) {
+			if (rc == -ENOMEM) {
+				ibmphp_remove_bus (bus, func->busno);
+				kfree (amount_needed);
+				return rc;
+			}
+			retval = rc;
+			goto error;
+		}
+		pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
+		pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
+
+		if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
+			debug ("io 32\n");
+			need_io_upper = TRUE;
+		}
+		if ((io_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
+			debug ("pfmem 64\n");
+			need_pfmem_upper = TRUE;
+		}
+
+		if (bus->noIORanges) {
+			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
+			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);	
+
+			/* _______________This is for debugging purposes only ____________________
+			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
+			debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
+			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
+			debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
+			 ________________________________________________________________________*/
+
+			if (need_io_upper) {	/* since can't support n.e.ways */
+				pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
+				pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
+			}
+		} else {
+			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
+			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
+		}
+
+		if (bus->noMemRanges) {
+			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
+			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
+			
+			/* ____________________This is for debugging purposes only ________________________
+			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
+			debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
+			debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+			 __________________________________________________________________________________*/
+
+		} else {
+			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
+			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
+		}
+		if (bus->noPFMemRanges) {
+			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
+			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
+
+			/* __________________________This is for debugging purposes only _______________________
+			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
+			debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
+			debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
+			 ______________________________________________________________________________________*/
+
+			if (need_pfmem_upper) {	/* since can't support n.e.ways */
+				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
+				pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
+			}
+		} else {
+			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
+			pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
+		}
+
+		debug ("b4 writing control information\n");
+
+		pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
+		if ((irq > 0x00) && (irq < 0x05))
+			pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
+		/*    
+		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
+		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
+		pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
+		 */
+
+		pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
+		pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
+		for (i = 0; i < 32; i++) {
+			if (amount_needed->devices[i]) {
+				debug ("device where devices[i] is 1 = %x\n", i);
+				func->devices[i] = 1;
+			}
+		}
+		func->bus = 1;	/* For unconfiguring, to indicate it's PPB */
+		func_passed = &func;
+		debug ("func->busno b4 returning is %x\n", func->busno);
+		debug ("func->busno b4 returning in the other structure is %x\n", (*func_passed)->busno);
+		kfree (amount_needed);
+		return 0;
+	} else {
+		err ("Configuring bridge was unsuccessful... \n");
+		mem_tmp = NULL;
+		retval = -EIO;
+		goto error;
+	}
+
+error:
+	if (amount_needed)
+		kfree (amount_needed);
+	if (pfmem)
+		ibmphp_remove_resource (pfmem);
+	if (io)
+		ibmphp_remove_resource (io);
+	if (mem)
+		ibmphp_remove_resource (mem);
+	for (i = 0; i < 2; i++) {	/* for 2 BARs */
+		if (bus_io[i]) {
+			ibmphp_remove_resource (bus_io[i]);
+			func->io[i] = NULL;
+		} else if (bus_pfmem[i]) {
+			ibmphp_remove_resource (bus_pfmem[i]);
+			func->pfmem[i] = NULL;
+		} else if (bus_mem[i]) {
+			ibmphp_remove_resource (bus_mem[i]);
+			func->mem[i] = NULL;
+		}
+	}
+	return retval;
+}
+
+/*****************************************************************************
+ * This function adds up the amount of resources needed behind the PPB bridge
+ * and passes it to the configure_bridge function
+ * Input: bridge function
+ * Ouput: amount of resources needed
+ *****************************************************************************/
+static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
+{
+	int count, len[6];
+	u16 vendor_id;
+	u8 hdr_type;
+	u8 device, function;
+	unsigned int devfn;
+	int howmany = 0;	/*this is to see if there are any devices behind the bridge */
+
+	u32 bar[6], class;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	struct res_needed *amount;
+
+	amount = kmalloc (sizeof (struct res_needed), GFP_KERNEL);
+	if (amount == NULL)
+		return NULL;
+	memset (amount, 0, sizeof (struct res_needed));
+
+	ibmphp_pci_bus->number = busno;
+
+	debug ("the bus_no behind the bridge is %x\n", busno);
+	debug ("scanning devices behind the bridge...\n");
+	for (device = 0; device < 32; device++) {
+		amount->devices[device] = 0;
+		for (function = 0; function < 8; function++) {
+			devfn = PCI_DEVFN(device, function);
+
+			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
+
+			if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
+				/* found correct device!!! */
+				howmany++;
+
+				pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+				pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
+
+				debug ("hdr_type behind the bridge is %x\n", hdr_type);
+				if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
+					err ("embedded bridges not supported for hot-plugging.\n");
+					amount->not_correct = TRUE;
+					return amount;
+				}
+
+				class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
+				if (class == PCI_CLASS_NOT_DEFINED_VGA) {
+					err ("The device %x is VGA compatible and as is not supported for hot plugging. "
+					     "Please choose another device.\n", device);
+					amount->not_correct = TRUE;
+					return amount;
+				} else if (class == PCI_CLASS_DISPLAY_VGA) {
+					err ("The device %x is not supported for hot plugging. "
+					     "Please choose another device.\n", device);
+					amount->not_correct = TRUE;
+					return amount;
+				}
+
+				amount->devices[device] = 1;
+
+				for (count = 0; address[count]; count++) {
+					/* for 6 BARs */
+					/*
+					pci_bus_read_config_byte (ibmphp_pci_bus, devfn, address[count], &tmp);
+					if (tmp & 0x01) // IO
+						pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
+					else // MEMORY
+						pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+					*/
+					pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+					pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
+
+					debug ("what is bar[count]? %x, count = %d\n", bar[count], count);
+
+					if (!bar[count])	/* This BAR is not implemented */
+						continue;
+
+					//tmp_bar = bar[count];
+
+					debug ("count %d device %x function %x wants %x resources \n", count, device, function, bar[count]);
+
+					if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
+						/* This is IO */
+						len[count] = bar[count] & 0xFFFFFFFC;
+						len[count] = ~len[count] + 1;
+						amount->io += len[count];
+					} else {
+						/* This is Memory */
+						if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+							/* pfmem */
+							len[count] = bar[count] & 0xFFFFFFF0;
+							len[count] = ~len[count] + 1;
+							amount->pfmem += len[count];
+							if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64)
+								/* takes up another dword */
+								count += 1;
+
+						} else {
+							/* regular memory */
+							len[count] = bar[count] & 0xFFFFFFF0;
+							len[count] = ~len[count] + 1;
+							amount->mem += len[count];
+							if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+								/* takes up another dword */
+								count += 1;
+							}
+						}
+					}
+				}	/* end for */
+			}	/* end if (valid) */
+		}	/* end for */
+	}	/* end for */
+
+	if (!howmany)
+		amount->not_correct = TRUE;
+	else
+		amount->not_correct = FALSE;
+	if ((amount->io) && (amount->io < IOBRIDGE))
+		amount->io = IOBRIDGE;
+	if ((amount->mem) && (amount->mem < MEMBRIDGE))
+		amount->mem = MEMBRIDGE;
+	if ((amount->pfmem) && (amount->pfmem < MEMBRIDGE))
+		amount->pfmem = MEMBRIDGE;
+	return amount;
+}
+
+/* The following 3 unconfigure_boot_ routines deal with the case when we had the card 
+ * upon bootup in the system, since we don't allocate func to such case, we need to read 
+ * the start addresses from pci config space and then find the corresponding entries in 
+ * our resource lists.  The functions return either 0, -ENODEV, or -1 (general failure)
+ * Change: we also call these functions even if we configured the card ourselves (i.e., not
+ * the bootup case), since it should work same way
+ */
+static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
+{
+	u32 start_address;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		PCI_BASE_ADDRESS_2,
+		PCI_BASE_ADDRESS_3,
+		PCI_BASE_ADDRESS_4,
+		PCI_BASE_ADDRESS_5,
+		0
+	};
+	int count;
+	struct resource_node *io;
+	struct resource_node *mem;
+	struct resource_node *pfmem;
+	struct bus_node *bus;
+	u32 end_address;
+	u32 temp_end;
+	u32 size;
+	u32 tmp_address;
+	unsigned int devfn;
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	bus = ibmphp_find_res_bus (busno);
+	if (!bus) {
+		debug ("cannot find corresponding bus.\n");
+		return -EINVAL;
+	}
+
+	devfn = PCI_DEVFN(device, function);
+	ibmphp_pci_bus->number = busno;
+	for (count = 0; address[count]; count++) {	/* for 6 BARs */
+		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
+
+		/* We can do this here, b/c by that time the device driver of the card has been stopped */
+
+		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
+		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &size);
+		pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], start_address);
+
+		debug ("start_address is %x\n", start_address);
+		debug ("busno, device, function %x %x %x\n", busno, device, function);
+		if (!size) {
+			/* This BAR is not implemented */
+			debug ("is this bar no implemented?, count = %d\n", count);
+			continue;
+		}
+		tmp_address = start_address;
+		if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			start_address &= PCI_BASE_ADDRESS_IO_MASK;
+			size = size & 0xFFFFFFFC;
+			size = ~size + 1;
+			end_address = start_address + size - 1;
+			if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
+				err ("cannot find corresponding IO resource to remove\n");
+				return -EIO;
+			}
+			debug ("io->start = %x\n", io->start);
+			temp_end = io->end;
+			start_address = io->end + 1;
+			ibmphp_remove_resource (io);
+			/* This is needed b/c of the old I/O restrictions in the BIOS */
+			while (temp_end < end_address) {
+				if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
+					err ("cannot find corresponding IO resource to remove\n");
+					return -EIO;
+				}
+				debug ("io->start = %x\n", io->start);
+				temp_end = io->end;
+				start_address = io->end + 1;
+				ibmphp_remove_resource (io);
+			}
+
+			/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
+		} else {
+			/* This is Memory */
+			if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+				debug ("start address of pfmem is %x\n", start_address);
+
+				if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
+					err ("cannot find corresponding PFMEM resource to remove\n");
+					return -EIO;
+				}
+				if (pfmem)
+					debug ("pfmem->start = %x\n", pfmem->start);
+
+				ibmphp_remove_resource (pfmem);
+
+				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+				}
+
+			} else {
+				/* regular memory */
+				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+				debug ("start address of mem is %x\n", start_address);
+				if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
+					err ("cannot find corresponding MEM resource to remove\n");
+					return -EIO;
+				}
+				if (mem)
+					debug ("mem->start = %x\n", mem->start);
+
+				ibmphp_remove_resource (mem);
+
+				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+				}
+			}
+		}	/* end of mem */
+	}	/* end of for */
+
+	return 0;
+}
+
+static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
+{
+	int count;
+	int bus_no, pri_no, sub_no, sec_no = 0;
+	u32 start_address, tmp_address;
+	u8 sec_number, sub_number, pri_number;
+	struct resource_node *io = NULL;
+	struct resource_node *mem = NULL;
+	struct resource_node *pfmem = NULL;
+	struct bus_node *bus;
+	u32 address[] = {
+		PCI_BASE_ADDRESS_0,
+		PCI_BASE_ADDRESS_1,
+		0
+	};
+	unsigned int devfn;
+
+	devfn = PCI_DEVFN(device, function);
+	ibmphp_pci_bus->number = busno;
+	bus_no = (int) busno;
+	debug ("busno is %x\n", busno);
+	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
+	debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number);
+
+	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+	debug ("sec_number is %x\n", sec_number);
+	sec_no = (int) sec_number;
+	pri_no = (int) pri_number;
+	if (pri_no != bus_no) {
+		err ("primary numbers in our structures and pci config space don't match.\n");
+		return -EINVAL;
+	}
+
+	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
+	sec_no = (int) sec_no;
+
+	pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
+	sub_no = (int) sub_number;
+	debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
+	if (sec_no != sub_number) {
+		err ("there're more buses behind this bridge.  Hot removal is not supported.  Please choose another card\n");
+		return -ENODEV;
+	}
+
+	bus = ibmphp_find_res_bus (sec_number);
+	debug ("bus->busno is %x\n", bus->busno);
+	debug ("sec_number is %x\n", sec_number);
+	if (!bus) {
+		err ("cannot find Bus structure for the bridged device\n");
+		return -EINVAL;
+	}
+
+	ibmphp_remove_bus (bus, busno);
+
+	for (count = 0; address[count]; count++) {
+		/* for 2 BARs */
+		pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
+
+		if (!start_address) {
+			/* This BAR is not implemented */
+			continue;
+		}
+
+		tmp_address = start_address;
+
+		if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
+			/* This is IO */
+			start_address &= PCI_BASE_ADDRESS_IO_MASK;
+			if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
+				err ("cannot find corresponding IO resource to remove\n");
+				return -EIO;
+			}
+			if (io)
+				debug ("io->start = %x\n", io->start);
+
+			ibmphp_remove_resource (io);
+
+			/* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
+		} else {
+			/* This is Memory */
+			if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+				/* pfmem */
+				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+				if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
+					err ("cannot find corresponding PFMEM resource to remove\n");
+					return -EINVAL;
+				}
+				if (pfmem)
+					debug ("pfmem->start = %x\n", pfmem->start);
+
+				ibmphp_remove_resource (pfmem);
+
+				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+				}
+
+			} else {
+				/* regular memory */
+				start_address &= PCI_BASE_ADDRESS_MEM_MASK;
+				if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
+					err ("cannot find corresponding MEM resource to remove\n");
+					return -EINVAL;
+				}
+				if (mem)
+					debug ("mem->start = %x\n", mem->start);
+
+				ibmphp_remove_resource (mem);
+
+				if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+					/* takes up another dword */
+					count += 1;
+				}
+			}
+		}	/* end of mem */
+	}	/* end of for */
+	debug ("%s - exiting, returning success\n", __FUNCTION__);
+	return 0;
+}
+
+static int unconfigure_boot_card (struct slot *slot_cur)
+{
+	u16 vendor_id;
+	u32 class;
+	u8 hdr_type;
+	u8 device;
+	u8 busno;
+	u8 function;
+	int rc;
+	unsigned int devfn;
+	u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	device = slot_cur->device;
+	busno = slot_cur->bus;
+
+	debug ("b4 for loop, device is %x\n", device);
+	/* For every function on the card */
+	for (function = 0x0; function < 0x08; function++) {
+		devfn = PCI_DEVFN(device, function);
+		ibmphp_pci_bus->number = busno;
+
+		pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
+
+		if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
+			/* found correct device!!! */
+			++valid_device;
+
+			debug ("%s - found correct device\n", __FUNCTION__);
+
+			/* header: x x x x x x x x
+			 *         | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
+			 *         |_=> 0 = single function device, 1 = multi-function device
+			 */
+
+			pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+			pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
+
+			debug ("hdr_type %x, class %x\n", hdr_type, class);
+			class >>= 8;	/* to take revision out, class = class.subclass.prog i/f */
+			if (class == PCI_CLASS_NOT_DEFINED_VGA) {
+				err ("The device %x function %x is VGA compatible and is not supported for hot removing. "
+				     "Please choose another device.\n", device, function);
+				return -ENODEV;
+			} else if (class == PCI_CLASS_DISPLAY_VGA) {
+				err ("The device %x function %x is not supported for hot removing. "
+				     "Please choose another device.\n", device, function);
+				return -ENODEV;
+			}
+
+			switch (hdr_type) {
+				case PCI_HEADER_TYPE_NORMAL:
+					rc = unconfigure_boot_device (busno, device, function);
+					if (rc) {
+						err ("was not able to unconfigure device %x func %x on bus %x. bailing out... \n",
+						     device, function, busno);
+						return rc;
+					}
+					function = 0x8;
+					break;
+				case PCI_HEADER_TYPE_MULTIDEVICE:
+					rc = unconfigure_boot_device (busno, device, function);
+					if (rc) {
+						err ("was not able to unconfigure device %x func %x on bus %x. bailing out... \n",
+						     device, function, busno);
+						return rc;
+					}
+					break;
+				case PCI_HEADER_TYPE_BRIDGE:
+					class >>= 8;
+					if (class != PCI_CLASS_BRIDGE_PCI) {
+						err ("This device %x function %x is not PCI-to-PCI bridge, "
+						     "and is not supported for hot-removing. "
+						     "Please try another card.\n", device, function);
+						return -ENODEV;
+					}
+					rc = unconfigure_boot_bridge (busno, device, function);
+					if (rc != 0) {
+						err ("was not able to hot-remove PPB properly.\n");
+						return rc;
+					}
+
+					function = 0x8;
+					break;
+				case PCI_HEADER_TYPE_MULTIBRIDGE:
+					class >>= 8;
+					if (class != PCI_CLASS_BRIDGE_PCI) {
+						err ("This device %x function %x is not PCI-to-PCI bridge, "
+						     "and is not supported for hot-removing. "
+						     "Please try another card.\n", device, function);
+						return -ENODEV;
+					}
+					rc = unconfigure_boot_bridge (busno, device, function);
+					if (rc != 0) {
+						err ("was not able to hot-remove PPB properly.\n");
+						return rc;
+					}
+					break;
+				default:
+					err ("MAJOR PROBLEM!!!! Cannot read device's header \n");
+					return -1;
+					break;
+			}	/* end of switch */
+		}	/* end of valid device */
+	}	/* end of for */
+
+	if (!valid_device) {
+		err ("Could not find device to unconfigure.  Or could not read the card. \n");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * free the resources of the card (multi, single, or bridged)
+ * Parameters: slot, flag to say if this is for removing entire module or just
+ * unconfiguring the device
+ * TO DO:  will probably need to add some code in case there was some resource,
+ * to remove it... this is from when we have errors in the configure_card...
+ * 			!!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!!
+ * Returns: 0, -1, -ENODEV 
+ */
+int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
+{
+	int i;
+	int count;
+	int rc;
+	struct slot *sl = *slot_cur;
+	struct pci_func *cur_func = NULL;
+	struct pci_func *temp_func;
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	if (!the_end) {
+		/* Need to unconfigure the card */
+		rc = unconfigure_boot_card (sl);
+		if ((rc == -ENODEV) || (rc == -EIO) || (rc == -EINVAL)) {
+			/* In all other cases, will still need to get rid of func structure if it exists */
+			return rc;
+		}
+	}
+
+	if (sl->func) {
+		cur_func = sl->func;
+		while (cur_func) {
+			/* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
+			if (cur_func->bus) {
+				/* in other words, it's a PPB */
+				count = 2;
+			} else {
+				count = 6;
+			}
+
+			for (i = 0; i < count; i++) {
+				if (cur_func->io[i]) {
+					debug ("io[%d] exists \n", i);
+					if (the_end > 0)
+						ibmphp_remove_resource (cur_func->io[i]);
+					cur_func->io[i] = NULL;
+				}
+				if (cur_func->mem[i]) {
+					debug ("mem[%d] exists \n", i);
+					if (the_end > 0)
+						ibmphp_remove_resource (cur_func->mem[i]);
+					cur_func->mem[i] = NULL;
+				}
+				if (cur_func->pfmem[i]) {
+					debug ("pfmem[%d] exists \n", i);
+					if (the_end > 0)
+						ibmphp_remove_resource (cur_func->pfmem[i]);
+					cur_func->pfmem[i] = NULL;
+				}
+			}
+
+			temp_func = cur_func->next;
+			kfree (cur_func);
+			cur_func = temp_func;
+		}
+	}
+
+	sl->func = NULL;
+	*slot_cur = sl;
+	debug ("%s - exit\n", __FUNCTION__);
+	return 0;
+}
+
+/*
+ * add a new bus resulting from hot-plugging a PPB bridge with devices
+ *
+ * Input: bus and the amount of resources needed (we know we can assign those,
+ *        since they've been checked already
+ * Output: bus added to the correct spot
+ *         0, -1, error 
+ */
+static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)
+{
+	struct range_node *io_range = NULL;
+	struct range_node *mem_range = NULL;
+	struct range_node *pfmem_range = NULL;
+	struct bus_node *cur_bus = NULL;
+
+	/* Trying to find the parent bus number */
+	if (parent_busno != 0xFF) {
+		cur_bus	= ibmphp_find_res_bus (parent_busno);
+		if (!cur_bus) {
+			err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
+			return -ENODEV;
+		}
+	
+		list_add (&bus->bus_list, &cur_bus->bus_list);
+	}
+	if (io) {
+		io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		if (!io_range) {
+			err ("out of system memory \n");
+			return -ENOMEM;
+		}
+		memset (io_range, 0, sizeof (struct range_node));
+		io_range->start = io->start;
+		io_range->end = io->end;
+		io_range->rangeno = 1;
+		bus->noIORanges = 1;
+		bus->rangeIO = io_range;
+	}
+	if (mem) {
+		mem_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		if (!mem_range) {
+			err ("out of system memory \n");
+			return -ENOMEM;
+		}
+		memset (mem_range, 0, sizeof (struct range_node));
+		mem_range->start = mem->start;
+		mem_range->end = mem->end;
+		mem_range->rangeno = 1;
+		bus->noMemRanges = 1;
+		bus->rangeMem = mem_range;
+	}
+	if (pfmem) {
+		pfmem_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+		if (!pfmem_range) {	
+			err ("out of system memory \n");
+			return -ENOMEM;
+		}
+		memset (pfmem_range, 0, sizeof (struct range_node));
+		pfmem_range->start = pfmem->start;
+		pfmem_range->end = pfmem->end;
+		pfmem_range->rangeno = 1;
+		bus->noPFMemRanges = 1;
+		bus->rangePFMem = pfmem_range;
+	}
+	return 0;
+}
+
+/*
+ * find the 1st available bus number for PPB to set as its secondary bus
+ * Parameters: bus_number of the primary bus
+ * Returns: bus_number of the secondary bus or 0xff in case of failure
+ */
+static u8 find_sec_number (u8 primary_busno, u8 slotno)
+{
+	int min, max;
+	u8 busno;
+	struct bus_info *bus;
+	struct bus_node *bus_cur;
+
+	bus = ibmphp_find_same_bus_num (primary_busno);
+	if (!bus) {
+		err ("cannot get slot range of the bus from the BIOS\n");
+		return 0xff;
+	}
+	max = bus->slot_max;
+	min = bus->slot_min;
+	if ((slotno > max) || (slotno < min)) {
+		err ("got the wrong range\n");
+		return 0xff;
+	}
+	busno = (u8) (slotno - (u8) min);
+	busno += primary_busno + 0x01;
+	bus_cur = ibmphp_find_res_bus (busno);
+	/* either there is no such bus number, or there are no ranges, which
+	 * can only happen if we removed the bridged device in previous load
+	 * of the driver, and now only have the skeleton bus struct
+	 */
+	if ((!bus_cur) || (!(bus_cur->rangeIO) && !(bus_cur->rangeMem) && !(bus_cur->rangePFMem)))
+		return busno;
+	return 0xff;
+}
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_res.c linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_res.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/ibmphp_res.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/ibmphp_res.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,2157 @@
+/*
+ * IBM Hot Plug Controller Driver
+ *
+ * Written By: Irene Zubarev, IBM Corporation
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001,2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gregkh@us.ibm.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include "ibmphp.h"
+
+static int flags = 0;		/* for testing */
+
+static void update_resources (struct bus_node *bus_cur, int type, int rangeno);
+static int once_over (void);
+static int remove_ranges (struct bus_node *, struct bus_node *);
+static int update_bridge_ranges (struct bus_node **);
+static int add_range (int type, struct range_node *, struct bus_node *);
+static void fix_resources (struct bus_node *);
+static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
+
+static LIST_HEAD(gbuses);
+LIST_HEAD(ibmphp_res_head);
+
+static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 busno, int flag)
+{
+	struct bus_node * newbus;
+
+	if (!(curr) && !(flag)) {
+		err ("NULL pointer passed \n");
+		return NULL;
+	}
+
+	newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+	if (!newbus) {
+		err ("out of system memory \n");
+		return NULL;
+	}
+
+	memset (newbus, 0, sizeof (struct bus_node));
+	if (flag)
+		newbus->busno = busno;
+	else
+		newbus->busno = curr->bus_num;
+	list_add_tail (&newbus->bus_list, &gbuses);
+	return newbus;
+}
+
+static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr)
+{
+	struct resource_node *rs;
+	
+	if (!curr) {
+		err ("NULL passed to allocate \n");
+		return NULL;
+	}
+
+	rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+	if (!rs) {
+		err ("out of system memory \n");
+		return NULL;
+	}
+	memset (rs, 0, sizeof (struct resource_node));
+	rs->busno = curr->bus_num;
+	rs->devfunc = curr->dev_fun;
+	rs->start = curr->start_addr;
+	rs->end = curr->end_addr;
+	rs->len = curr->end_addr - curr->start_addr + 1;
+	return rs;
+}
+
+static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
+{
+	struct bus_node * newbus;
+	struct range_node *newrange;
+	u8 num_ranges = 0;
+
+	if (first_bus) {
+		newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+		if (!newbus) {
+			err ("out of system memory. \n");
+			return -ENOMEM;
+		}
+		memset (newbus, 0, sizeof (struct bus_node));
+		newbus->busno = curr->bus_num;
+	} else {
+		newbus = *new_bus;
+		switch (flag) {
+			case MEM:
+				num_ranges = newbus->noMemRanges;
+				break;
+			case PFMEM:
+				num_ranges = newbus->noPFMemRanges;
+				break;
+			case IO:
+				num_ranges = newbus->noIORanges;
+				break;
+		}
+	}
+
+	newrange = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+	if (!newrange) {
+		if (first_bus)
+			kfree (newbus);
+		err ("out of system memory \n");
+		return -ENOMEM;
+	}
+	memset (newrange, 0, sizeof (struct range_node));
+	newrange->start = curr->start_addr;
+	newrange->end = curr->end_addr;
+		
+	if (first_bus || (!num_ranges))
+		newrange->rangeno = 1;
+	else {
+		/* need to insert our range */
+		add_range (flag, newrange, newbus);
+		debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
+	}
+
+	switch (flag) {
+		case MEM:
+			newbus->rangeMem = newrange;
+			if (first_bus)
+				newbus->noMemRanges = 1;
+			else {
+				debug ("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				++newbus->noMemRanges;
+				fix_resources (newbus);
+			}
+			break;
+		case IO:
+			newbus->rangeIO = newrange;
+			if (first_bus)
+				newbus->noIORanges = 1;
+			else {
+				debug ("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				++newbus->noIORanges;
+				fix_resources (newbus);
+			}
+			break;
+		case PFMEM:
+			newbus->rangePFMem = newrange;
+			if (first_bus)
+				newbus->noPFMemRanges = 1;
+			else {	
+				debug ("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				++newbus->noPFMemRanges;
+				fix_resources (newbus);
+			}
+
+			break;
+	}
+
+	*new_bus = newbus;
+	*new_range = newrange;
+	return 0;
+}
+
+
+/* Notes:
+ * 1. The ranges are ordered.  The buses are not ordered.  (First come)
+ *
+ * 2. If cannot allocate out of PFMem range, allocate from Mem ranges.  PFmemFromMem
+ * are not sorted. (no need since use mem node). To not change the entire code, we
+ * also add mem node whenever this case happens so as not to change
+ * ibmphp_check_mem_resource etc (and since it really is taking Mem resource)
+ */
+
+/*****************************************************************************
+ * This is the Resource Management initialization function.  It will go through
+ * the Resource list taken from EBDA and fill in this module's data structures
+ *
+ * THIS IS NOT TAKING INTO CONSIDERATION IO RESTRICTIONS OF PRIMARY BUSES, 
+ * SINCE WE'RE GOING TO ASSUME FOR NOW WE DON'T HAVE THOSE ON OUR BUSES FOR NOW
+ *
+ * Input: ptr to the head of the resource list from EBDA
+ * Output: 0, -1 or error codes
+ ***************************************************************************/
+int __init ibmphp_rsrc_init (void)
+{
+	struct ebda_pci_rsrc *curr;
+	struct range_node *newrange = NULL;
+	struct bus_node *newbus = NULL;
+	struct bus_node *bus_cur;
+	struct bus_node *bus_prev;
+	struct list_head *tmp;
+	struct resource_node *new_io = NULL;
+	struct resource_node *new_mem = NULL;
+	struct resource_node *new_pfmem = NULL;
+	int rc;
+	struct list_head *tmp_ebda;
+
+	list_for_each (tmp_ebda, &ibmphp_ebda_pci_rsrc_head) {
+		curr = list_entry (tmp_ebda, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+		if (!(curr->rsrc_type & PCIDEVMASK)) {
+			/* EBDA still lists non PCI devices, so ignore... */
+			debug ("this is not a PCI DEVICE in rsrc_init, please take care\n");
+			// continue;
+		}
+
+		/* this is a primary bus resource */
+		if (curr->rsrc_type & PRIMARYBUSMASK) {
+			/* memory */
+			if ((curr->rsrc_type & RESTYPE) == MMASK) {
+				/* no bus structure exists in place yet */
+				if (list_empty (&gbuses)) {
+					if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
+						return rc;
+					list_add_tail (&newbus->bus_list, &gbuses);
+					debug ("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				} else {
+					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+					/* found our bus */
+					if (bus_cur) {
+						rc = alloc_bus_range (&bus_cur, &newrange, curr, MEM, 0);
+						if (rc)
+							return rc;
+					} else {
+						/* went through all the buses and didn't find ours, need to create a new bus node */
+						if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
+							return rc;
+
+						list_add_tail (&newbus->bus_list, &gbuses);
+						debug ("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+					}
+				}
+			} else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
+				/* prefetchable memory */
+				if (list_empty (&gbuses)) {
+					/* no bus structure exists in place yet */
+					if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
+						return rc;
+					list_add_tail (&newbus->bus_list, &gbuses);
+					debug ("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				} else {
+					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+					if (bus_cur) {
+						/* found our bus */
+						rc = alloc_bus_range (&bus_cur, &newrange, curr, PFMEM, 0);
+						if (rc)
+							return rc;
+					} else {
+						/* went through all the buses and didn't find ours, need to create a new bus node */
+						if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
+							return rc;
+						list_add_tail (&newbus->bus_list, &gbuses);
+						debug ("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+					}
+				}
+			} else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
+				/* IO */
+				if (list_empty (&gbuses)) {
+					/* no bus structure exists in place yet */
+					if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
+						return rc;
+					list_add_tail (&newbus->bus_list, &gbuses);
+					debug ("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+				} else {
+					bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
+					if (bus_cur) {
+						rc = alloc_bus_range (&bus_cur, &newrange, curr, IO, 0);
+						if (rc)
+							return rc;
+					} else {
+						/* went through all the buses and didn't find ours, need to create a new bus node */
+						if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
+							return rc;
+						list_add_tail (&newbus->bus_list, &gbuses);
+						debug ("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
+					}
+				}
+
+			} else {
+				;	/* type is reserved  WHAT TO DO IN THIS CASE???
+					   NOTHING TO DO??? */
+			}
+		} else {
+			/* regular pci device resource */
+			if ((curr->rsrc_type & RESTYPE) == MMASK) {
+				/* Memory resource */
+				new_mem = alloc_resources (curr);
+				if (!new_mem)
+					return -ENOMEM;
+				new_mem->type = MEM;
+				/*
+				 * if it didn't find the bus, means PCI dev
+				 * came b4 the Primary Bus info, so need to
+				 * create a bus rangeno becomes a problem...
+				 * assign a -1 and then update once the range
+				 * actually appears...
+				 */
+				if (ibmphp_add_resource (new_mem) < 0) {
+					newbus = alloc_error_bus (curr, 0, 0);
+					if (!newbus)
+						return -ENOMEM;
+					newbus->firstMem = new_mem;
+					++newbus->needMemUpdate;
+					new_mem->rangeno = -1;
+				}
+				debug ("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
+
+			} else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
+				/* PFMemory resource */
+				new_pfmem = alloc_resources (curr);
+				if (!new_pfmem)
+					return -ENOMEM;
+				new_pfmem->type = PFMEM;
+				new_pfmem->fromMem = FALSE;
+				if (ibmphp_add_resource (new_pfmem) < 0) {
+					newbus = alloc_error_bus (curr, 0, 0);
+					if (!newbus)
+						return -ENOMEM;
+					newbus->firstPFMem = new_pfmem;
+					++newbus->needPFMemUpdate;
+					new_pfmem->rangeno = -1;
+				}
+
+				debug ("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
+			} else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
+				/* IO resource */
+				new_io = alloc_resources (curr);
+				if (!new_io)
+					return -ENOMEM;
+				new_io->type = IO;
+
+				/*
+				 * if it didn't find the bus, means PCI dev
+				 * came b4 the Primary Bus info, so need to
+				 * create a bus rangeno becomes a problem...
+				 * Can assign a -1 and then update once the
+				 * range actually appears...
+				 */
+				if (ibmphp_add_resource (new_io) < 0) {
+					newbus = alloc_error_bus (curr, 0, 0);
+					if (!newbus)
+						return -ENOMEM;
+					newbus->firstIO = new_io;
+					++newbus->needIOUpdate;
+					new_io->rangeno = -1;
+				}
+				debug ("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
+			}
+		}
+	}
+
+	list_for_each (tmp, &gbuses) {
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		/* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
+		rc = update_bridge_ranges (&bus_cur);
+		if (rc)
+			return rc;
+	}
+	rc = once_over ();  /* This is to align ranges (so no -1) */
+	if (rc)
+		return rc;
+	return 0;
+}
+
+/********************************************************************************
+ * This function adds a range into a sorted list of ranges per bus for a particular
+ * range type, it then calls another routine to update the range numbers on the
+ * pci devices' resources for the appropriate resource
+ *
+ * Input: type of the resource, range to add, current bus
+ * Output: 0 or -1, bus and range ptrs 
+ ********************************************************************************/
+static int add_range (int type, struct range_node *range, struct bus_node *bus_cur)
+{
+	struct range_node *range_cur = NULL;
+	struct range_node *range_prev;
+	int count = 0, i_init;
+	int noRanges = 0;
+
+	switch (type) {
+		case MEM:
+			range_cur = bus_cur->rangeMem;
+			noRanges = bus_cur->noMemRanges;
+			break;
+		case PFMEM:
+			range_cur = bus_cur->rangePFMem;
+			noRanges = bus_cur->noPFMemRanges;
+			break;
+		case IO:
+			range_cur = bus_cur->rangeIO;
+			noRanges = bus_cur->noIORanges;
+			break;
+	}
+
+	range_prev = NULL;
+	while (range_cur) {
+		if (range->start < range_cur->start)
+			break;
+		range_prev = range_cur;
+		range_cur = range_cur->next;
+		count = count + 1;
+	}
+	if (!count) {
+		/* our range will go at the beginning of the list */
+		switch (type) {
+			case MEM:
+				bus_cur->rangeMem = range;
+				break;
+			case PFMEM:
+				bus_cur->rangePFMem = range;
+				break;
+			case IO:
+				bus_cur->rangeIO = range;
+				break;
+		}
+		range->next = range_cur;
+		range->rangeno = 1;
+		i_init = 0;
+	} else if (!range_cur) {
+		/* our range will go at the end of the list */
+		range->next = NULL;
+		range_prev->next = range;
+		range->rangeno = range_prev->rangeno + 1;
+		return 0;
+	} else {
+		/* the range is in the middle */
+		range_prev->next = range;
+		range->next = range_cur;
+		range->rangeno = range_cur->rangeno;
+		i_init = range_prev->rangeno;
+	}
+
+	for (count = i_init; count < noRanges; ++count) {
+		++range_cur->rangeno;
+		range_cur = range_cur->next;
+	}
+
+	update_resources (bus_cur, type, i_init + 1);
+	return 0;
+}
+
+/*******************************************************************************
+ * This routine goes through the list of resources of type 'type' and updates
+ * the range numbers that they correspond to.  It was called from add_range fnc
+ *
+ * Input: bus, type of the resource, the rangeno starting from which to update
+ ******************************************************************************/
+static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
+{
+	struct resource_node *res = NULL;
+	u8 eol = FALSE;	/* end of list indicator */
+
+	switch (type) {
+		case MEM:
+			if (bus_cur->firstMem) 
+				res = bus_cur->firstMem;
+			break;
+		case PFMEM:
+			if (bus_cur->firstPFMem)
+				res = bus_cur->firstPFMem;
+			break;
+		case IO:
+			if (bus_cur->firstIO)
+				res = bus_cur->firstIO;
+			break;
+	}
+
+	if (res) {
+		while (res) {
+			if (res->rangeno == rangeno)
+				break;
+			if (res->next)
+				res = res->next;
+			else if (res->nextRange)
+				res = res->nextRange;
+			else {
+				eol = TRUE;
+				break;
+			}
+		}
+
+		if (!eol) {
+			/* found the range */
+			while (res) {
+				++res->rangeno;
+				res = res->next;
+			}
+		}
+	}
+}
+
+static void fix_me (struct resource_node *res, struct bus_node *bus_cur, struct range_node *range)
+{
+	char * str = "";
+	switch (res->type) {
+		case IO:
+			str = "io";
+			break;
+		case MEM:
+			str = "mem";
+			break;
+		case PFMEM:
+			str = "pfmem";
+			break;
+	}
+
+	while (res) {
+		if (res->rangeno == -1) {
+			while (range) {
+				if ((res->start >= range->start) && (res->end <= range->end)) {
+					res->rangeno = range->rangeno;
+					debug ("%s->rangeno in fix_resources is %d\n", str, res->rangeno);
+					switch (res->type) {
+						case IO:
+							--bus_cur->needIOUpdate;
+							break;
+						case MEM:
+							--bus_cur->needMemUpdate;
+							break;
+						case PFMEM:
+							--bus_cur->needPFMemUpdate;
+							break;
+					}
+					break;
+				}
+				range = range->next;
+			}
+		}
+		if (res->next)
+			res = res->next;
+		else
+			res = res->nextRange;
+	}
+
+}
+
+/*****************************************************************************
+ * This routine reassigns the range numbers to the resources that had a -1
+ * This case can happen only if upon initialization, resources taken by pci dev
+ * appear in EBDA before the resources allocated for that bus, since we don't
+ * know the range, we assign -1, and this routine is called after a new range
+ * is assigned to see the resources with unknown range belong to the added range
+ *
+ * Input: current bus
+ * Output: none, list of resources for that bus are fixed if can be
+ *******************************************************************************/
+static void fix_resources (struct bus_node *bus_cur)
+{
+	struct range_node *range;
+	struct resource_node *res;
+
+	debug ("%s - bus_cur->busno = %d\n", __FUNCTION__, bus_cur->busno);
+
+	if (bus_cur->needIOUpdate) {
+		res = bus_cur->firstIO;
+		range = bus_cur->rangeIO;
+		fix_me (res, bus_cur, range);
+	}
+	if (bus_cur->needMemUpdate) {
+		res = bus_cur->firstMem;
+		range = bus_cur->rangeMem;
+		fix_me (res, bus_cur, range);
+	}
+	if (bus_cur->needPFMemUpdate) {
+		res = bus_cur->firstPFMem;
+		range = bus_cur->rangePFMem;
+		fix_me (res, bus_cur, range);
+	}
+}
+
+/*******************************************************************************
+ * This routine adds a resource to the list of resources to the appropriate bus 
+ * based on their resource type and sorted by their starting addresses.  It assigns
+ * the ptrs to next and nextRange if needed.
+ *
+ * Input: resource ptr
+ * Output: ptrs assigned (to the node)
+ * 0 or -1
+ *******************************************************************************/
+int ibmphp_add_resource (struct resource_node *res)
+{
+	struct resource_node *res_cur;
+	struct resource_node *res_prev;
+	struct bus_node *bus_cur;
+	struct range_node *range_cur = NULL;
+	struct resource_node *res_start = NULL;
+
+	debug ("%s - enter\n", __FUNCTION__);
+
+	if (!res) {
+		err ("NULL passed to add \n");
+		return -ENODEV;
+	}
+	
+	bus_cur = find_bus_wprev (res->busno, NULL, 0);
+	
+	if (!bus_cur) {
+		/* didn't find a bus, smth's wrong!!! */
+		debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
+		return -ENODEV;
+	}
+
+	/* Normal case */
+	switch (res->type) {
+		case IO:
+			range_cur = bus_cur->rangeIO;
+			res_start = bus_cur->firstIO;
+			break;
+		case MEM:
+			range_cur = bus_cur->rangeMem;
+			res_start = bus_cur->firstMem;
+			break;
+		case PFMEM:
+			range_cur = bus_cur->rangePFMem;
+			res_start = bus_cur->firstPFMem;
+			break;
+		default:
+			err ("cannot read the type of the resource to add... problem \n");
+			return -EINVAL;
+	}
+	while (range_cur) {
+		if ((res->start >= range_cur->start) && (res->end <= range_cur->end)) {
+			res->rangeno = range_cur->rangeno;
+			break;
+		}
+		range_cur = range_cur->next;
+	}
+
+	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	 * this is again the case of rangeno = -1
+	 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	 */
+
+	if (!range_cur) {
+		switch (res->type) {
+			case IO:
+				++bus_cur->needIOUpdate;					
+				break;
+			case MEM:
+				++bus_cur->needMemUpdate;
+				break;
+			case PFMEM:
+				++bus_cur->needPFMemUpdate;
+				break;
+		}
+		res->rangeno = -1;
+	}
+	
+	debug ("The range is %d\n", res->rangeno);
+	if (!res_start) {
+		/* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */
+		switch (res->type) {
+			case IO:
+				bus_cur->firstIO = res;					
+				break;
+			case MEM:
+				bus_cur->firstMem = res;
+				break;
+			case PFMEM:
+				bus_cur->firstPFMem = res;
+				break;
+		}	
+		res->next = NULL;
+		res->nextRange = NULL;
+	} else {
+		res_cur = res_start;
+		res_prev = NULL;
+
+		debug ("res_cur->rangeno is %d\n", res_cur->rangeno);
+
+		while (res_cur) {
+			if (res_cur->rangeno >= res->rangeno)
+				break;
+			res_prev = res_cur;
+			if (res_cur->next)
+				res_cur = res_cur->next;
+			else
+				res_cur = res_cur->nextRange;
+		}
+
+		if (!res_cur) {
+			/* at the end of the resource list */
+			debug ("i should be here, [%x - %x]\n", res->start, res->end);
+			res_prev->nextRange = res;
+			res->next = NULL;
+			res->nextRange = NULL;
+		} else if (res_cur->rangeno == res->rangeno) {
+			/* in the same range */
+			while (res_cur) {
+				if (res->start < res_cur->start)
+					break;
+				res_prev = res_cur;
+				res_cur = res_cur->next;
+			}
+			if (!res_cur) {
+				/* the last resource in this range */
+				res_prev->next = res;
+				res->next = NULL;
+				res->nextRange = res_prev->nextRange;
+				res_prev->nextRange = NULL;
+			} else if (res->start < res_cur->start) {
+				/* at the beginning or middle of the range */
+				if (!res_prev)	{
+					switch (res->type) {
+						case IO:
+							bus_cur->firstIO = res;
+							break;
+						case MEM:
+							bus_cur->firstMem = res;
+							break;
+						case PFMEM:
+							bus_cur->firstPFMem = res;
+							break;
+					}
+				} else if (res_prev->rangeno == res_cur->rangeno)
+					res_prev->next = res;
+				else
+					res_prev->nextRange = res;
+
+				res->next = res_cur;
+				res->nextRange = NULL;
+			}
+		} else {
+			/* this is the case where it is 1st occurrence of the range */
+			if (!res_prev) {
+				/* at the beginning of the resource list */
+				res->next = NULL;
+				switch (res->type) {
+					case IO:
+						res->nextRange = bus_cur->firstIO;
+						bus_cur->firstIO = res;
+						break;
+					case MEM:
+						res->nextRange = bus_cur->firstMem;
+						bus_cur->firstMem = res;
+						break;
+					case PFMEM:
+						res->nextRange = bus_cur->firstPFMem;
+						bus_cur->firstPFMem = res;
+						break;
+				}
+			} else if (res_cur->rangeno > res->rangeno) {
+				/* in the middle of the resource list */
+				res_prev->nextRange = res;
+				res->next = NULL;
+				res->nextRange = res_cur;
+			}
+		}
+	}
+
+	debug ("%s - exit\n", __FUNCTION__);
+	return 0;
+}
+
+/****************************************************************************
+ * This routine will remove the resource from the list of resources
+ *
+ * Input: io, mem, and/or pfmem resource to be deleted
+ * Ouput: modified resource list
+ *        0 or error code
+ ****************************************************************************/
+int ibmphp_remove_resource (struct resource_node *res)
+{
+	struct bus_node *bus_cur;
+	struct resource_node *res_cur = NULL;
+	struct resource_node *res_prev;
+	struct resource_node *mem_cur;
+	char * type = "";
+
+	if (!res)  {
+		err ("resource to remove is NULL \n");
+		return -ENODEV;
+	}
+
+	bus_cur = find_bus_wprev (res->busno, NULL, 0);
+
+	if (!bus_cur) {
+		err ("cannot find corresponding bus of the io resource to remove  "
+			"bailing out...\n");
+		return -ENODEV;
+	}
+
+	switch (res->type) {
+		case IO:
+			res_cur = bus_cur->firstIO;
+			type = "io";
+			break;
+		case MEM:
+			res_cur = bus_cur->firstMem;
+			type = "mem";
+			break;
+		case PFMEM:
+			res_cur = bus_cur->firstPFMem;
+			type = "pfmem";
+			break;
+		default:
+			err ("unknown type for resource to remove \n");
+			return -EINVAL;
+	}
+	res_prev = NULL;
+
+	while (res_cur) {
+		if ((res_cur->start == res->start) && (res_cur->end == res->end))
+			break;
+		res_prev = res_cur;
+		if (res_cur->next)
+			res_cur = res_cur->next;
+		else
+			res_cur = res_cur->nextRange;
+	}
+
+	if (!res_cur) {
+		if (res->type == PFMEM) {
+			/* 
+			 * case where pfmem might be in the PFMemFromMem list
+			 * so will also need to remove the corresponding mem
+			 * entry
+			 */
+			res_cur = bus_cur->firstPFMemFromMem;
+			res_prev = NULL;
+
+			while (res_cur) {
+				if ((res_cur->start == res->start) && (res_cur->end == res->end)) {
+					mem_cur = bus_cur->firstMem;
+					while (mem_cur) {
+						if ((mem_cur->start == res_cur->start)
+						    && (mem_cur->end == res_cur->end))
+							break;
+						if (mem_cur->next)
+							mem_cur = mem_cur->next;
+						else
+							mem_cur = mem_cur->nextRange;
+					}
+					if (!mem_cur) {
+						err ("cannot find corresponding mem node for pfmem...\n");
+						return -EINVAL;
+					}
+
+					ibmphp_remove_resource (mem_cur);
+					if (!res_prev)
+						bus_cur->firstPFMemFromMem = res_cur->next;
+					else
+						res_prev->next = res_cur->next;
+					kfree (res_cur);
+					return 0;
+				}
+				res_prev = res_cur;
+				if (res_cur->next)
+					res_cur = res_cur->next;
+				else
+					res_cur = res_cur->nextRange;
+			}
+			if (!res_cur) {
+				err ("cannot find pfmem to delete...\n");
+				return -EINVAL;
+			}
+		} else {
+			err ("the %s resource is not in the list to be deleted...\n", type);
+			return -EINVAL;
+		}
+	}
+	if (!res_prev) {
+		/* first device to be deleted */
+		if (res_cur->next) {
+			switch (res->type) {
+				case IO:
+					bus_cur->firstIO = res_cur->next;
+					break;
+				case MEM:
+					bus_cur->firstMem = res_cur->next;
+					break;
+				case PFMEM:
+					bus_cur->firstPFMem = res_cur->next;
+					break;
+			}
+		} else if (res_cur->nextRange) {
+			switch (res->type) {
+				case IO:
+					bus_cur->firstIO = res_cur->nextRange;
+					break;
+				case MEM:
+					bus_cur->firstMem = res_cur->nextRange;
+					break;
+				case PFMEM:
+					bus_cur->firstPFMem = res_cur->nextRange;
+					break;
+			}
+		} else {
+			switch (res->type) {
+				case IO:
+					bus_cur->firstIO = NULL;
+					break;
+				case MEM:
+					bus_cur->firstMem = NULL;
+					break;
+				case PFMEM:
+					bus_cur->firstPFMem = NULL;
+					break;
+			}
+		}
+		kfree (res_cur);
+		return 0;
+	} else {
+		if (res_cur->next) {
+			if (res_prev->rangeno == res_cur->rangeno)
+				res_prev->next = res_cur->next;
+			else
+				res_prev->nextRange = res_cur->next;
+		} else if (res_cur->nextRange) {
+			res_prev->next = NULL;
+			res_prev->nextRange = res_cur->nextRange;
+		} else {
+			res_prev->next = NULL;
+			res_prev->nextRange = NULL;
+		}
+		kfree (res_cur);
+		return 0;
+	}
+
+	return 0;
+}
+
+static struct range_node * find_range (struct bus_node *bus_cur, struct resource_node * res)
+{
+	struct range_node * range = NULL;
+
+	switch (res->type) {
+		case IO:
+			range = bus_cur->rangeIO;
+			break;
+		case MEM:
+			range = bus_cur->rangeMem;
+			break;
+		case PFMEM:
+			range = bus_cur->rangePFMem;
+			break;
+		default:
+			err ("cannot read resource type in find_range \n");
+	}
+
+	while (range) {
+		if (res->rangeno == range->rangeno)
+			break;
+		range = range->next;
+	}
+	return range;
+}
+
+/*****************************************************************************
+ * This routine will check to make sure the io/mem/pfmem->len that the device asked for 
+ * can fit w/i our list of available IO/MEM/PFMEM resources.  If cannot, returns -EINVAL,
+ * otherwise, returns 0
+ *
+ * Input: resource
+ * Ouput: the correct start and end address are inputted into the resource node,
+ *        0 or -EINVAL
+ *****************************************************************************/
+int ibmphp_check_resource (struct resource_node *res, u8 bridge)
+{
+	struct bus_node *bus_cur;
+	struct range_node *range = NULL;
+	struct resource_node *res_prev;
+	struct resource_node *res_cur = NULL;
+	u32 len_cur = 0, start_cur = 0, len_tmp = 0;
+	int noranges = 0;
+	u32 tmp_start;		/* this is to make sure start address is divisible by the length needed */
+	u32 tmp_divide;
+	u8 flag = FALSE;
+
+	if (!res)
+		return -EINVAL;
+
+	if (bridge) {
+		/* The rules for bridges are different, 4K divisible for IO, 1M for (pf)mem*/
+		if (res->type == IO)
+			tmp_divide = IOBRIDGE;
+		else
+			tmp_divide = MEMBRIDGE;
+	} else
+		tmp_divide = res->len;
+
+	bus_cur = find_bus_wprev (res->busno, NULL, 0);
+
+	if (!bus_cur) {
+		/* didn't find a bus, smth's wrong!!! */
+		debug ("no bus in the system, either pci_dev's wrong or allocation failed \n");
+		return -EINVAL;
+	}
+
+	debug ("%s - enter\n", __FUNCTION__);
+	debug ("bus_cur->busno is %d\n", bus_cur->busno);
+
+	/* This is a quick fix to not mess up with the code very much.  i.e.,
+	 * 2000-2fff, len = 1000, but when we compare, we need it to be fff */
+	res->len -= 1;
+
+	switch (res->type) {
+		case IO:
+			res_cur = bus_cur->firstIO;
+			noranges = bus_cur->noIORanges;
+			break;
+		case MEM:
+			res_cur = bus_cur->firstMem;
+			noranges = bus_cur->noMemRanges;
+			break;
+		case PFMEM:
+			res_cur = bus_cur->firstPFMem;
+			noranges = bus_cur->noPFMemRanges;
+			break;
+		default:
+			err ("wrong type of resource to check \n");
+			return -EINVAL;
+	}
+	res_prev = NULL;
+
+	while (res_cur) {
+		range = find_range (bus_cur, res_cur);
+		debug ("%s - rangeno = %d\n", __FUNCTION__, res_cur->rangeno);
+
+		if (!range) {
+			err ("no range for the device exists... bailing out...\n");
+			return -EINVAL;
+		}
+
+		/* found our range */
+		if (!res_prev) {
+			/* first time in the loop */
+			if ((res_cur->start != range->start) && ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
+				debug ("len_tmp = %x\n", len_tmp);
+
+				if ((len_tmp < len_cur) || (len_cur == 0)) {
+
+					if ((range->start % tmp_divide) == 0) {
+						/* just perfect, starting address is divisible by length */
+						flag = TRUE;
+						len_cur = len_tmp;
+						start_cur = range->start;
+					} else {
+						/* Needs adjusting */
+						tmp_start = range->start;
+						flag = FALSE;
+
+						while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
+							if ((tmp_start % tmp_divide) == 0) {
+								flag = TRUE;
+								len_cur = len_tmp;
+								start_cur = tmp_start;
+								break;
+							}
+							tmp_start += tmp_divide - tmp_start % tmp_divide;
+							if (tmp_start >= res_cur->start - 1)
+								break;
+						}
+					}
+			
+					if (flag && len_cur == res->len) {
+						debug ("but we are not here, right?\n");
+						res->start = start_cur;
+						res->len += 1; /* To restore the balance */
+						res->end = res->start + res->len - 1;
+						return 0;
+					}
+				}
+			}
+		}
+		if (!res_cur->next) {
+			/* last device on the range */
+			if ((range->end != res_cur->end) && ((len_tmp = range->end - (res_cur->end + 1)) >= res->len)) {
+				debug ("len_tmp = %x\n", len_tmp);
+				if ((len_tmp < len_cur) || (len_cur == 0)) {
+
+					if (((res_cur->end + 1) % tmp_divide) == 0) {
+						/* just perfect, starting address is divisible by length */
+						flag = TRUE;
+						len_cur = len_tmp;
+						start_cur = res_cur->end + 1;
+					} else {
+						/* Needs adjusting */
+						tmp_start = res_cur->end + 1;
+						flag = FALSE;
+
+						while ((len_tmp = range->end - tmp_start) >= res->len) {
+							if ((tmp_start % tmp_divide) == 0) {
+								flag = TRUE;
+								len_cur = len_tmp;
+								start_cur = tmp_start;
+								break;
+							}
+							tmp_start += tmp_divide - tmp_start % tmp_divide;
+							if (tmp_start >= range->end)
+								break;
+						}
+					}
+					if (flag && len_cur == res->len) {
+						res->start = start_cur;
+						res->len += 1; /* To restore the balance */
+						res->end = res->start + res->len - 1;
+						return 0;
+					}
+				}
+			}
+		}
+
+		if (res_prev) {
+			if (res_prev->rangeno != res_cur->rangeno) {
+				/* 1st device on this range */
+				if ((res_cur->start != range->start) && 
+					((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
+					if ((len_tmp < len_cur) || (len_cur == 0)) {
+						if ((range->start % tmp_divide) == 0) {	
+							/* just perfect, starting address is divisible by length */
+							flag = TRUE;
+							len_cur = len_tmp;
+							start_cur = range->start;
+						} else {
+							/* Needs adjusting */
+							tmp_start = range->start;
+							flag = FALSE;
+
+							while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
+								if ((tmp_start % tmp_divide) == 0) {
+									flag = TRUE;
+									len_cur = len_tmp;
+									start_cur = tmp_start;
+									break;
+								}
+								tmp_start += tmp_divide - tmp_start % tmp_divide;
+								if (tmp_start >= res_cur->start - 1)
+									break;
+							}
+						}
+
+						if (flag && len_cur == res->len) {
+							res->start = start_cur;
+							res->len += 1; /* To restore the balance */
+							res->end = res->start + res->len - 1;
+							return 0;
+						}
+					}
+				}
+			} else {
+				/* in the same range */
+				if ((len_tmp = res_cur->start - 1 - res_prev->end - 1) >= res->len) {
+					if ((len_tmp < len_cur) || (len_cur == 0)) {
+						if (((res_prev->end + 1) % tmp_divide) == 0) {
+							/* just perfect, starting address's divisible by length */
+							flag = TRUE;
+							len_cur = len_tmp;
+							start_cur = res_prev->end + 1;
+						} else {
+							/* Needs adjusting */
+							tmp_start = res_prev->end + 1;
+							flag = FALSE;
+
+							while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
+								if ((tmp_start % tmp_divide) == 0) {
+									flag = TRUE;
+									len_cur = len_tmp;
+									start_cur = tmp_start;
+									break;
+								}
+								tmp_start += tmp_divide - tmp_start % tmp_divide;
+								if (tmp_start >= res_cur->start - 1)
+									break;
+							}
+						}
+
+						if (flag && len_cur == res->len) {
+							res->start = start_cur;
+							res->len += 1; /* To restore the balance */
+							res->end = res->start + res->len - 1;
+							return 0;
+						}
+					}
+				}
+			}
+		}
+		/* end if (res_prev) */
+		res_prev = res_cur;
+		if (res_cur->next)
+			res_cur = res_cur->next;
+		else
+			res_cur = res_cur->nextRange;
+	}	/* end of while */
+
+
+	if (!res_prev) {
+		/* 1st device ever */
+		/* need to find appropriate range */
+		switch (res->type) {
+			case IO:
+				range = bus_cur->rangeIO;
+				break;
+			case MEM:
+				range = bus_cur->rangeMem;
+				break;
+			case PFMEM:
+				range = bus_cur->rangePFMem;
+				break;
+		}
+		while (range) {
+			if ((len_tmp = range->end - range->start) >= res->len) {
+				if ((len_tmp < len_cur) || (len_cur == 0)) {
+					if ((range->start % tmp_divide) == 0) {
+						/* just perfect, starting address's divisible by length */
+						flag = TRUE;
+						len_cur = len_tmp;
+						start_cur = range->start;
+					} else {
+						/* Needs adjusting */
+						tmp_start = range->start;
+						flag = FALSE;
+
+						while ((len_tmp = range->end - tmp_start) >= res->len) {
+							if ((tmp_start % tmp_divide) == 0) {
+								flag = TRUE;
+								len_cur = len_tmp;
+								start_cur = tmp_start;
+								break;
+							}
+							tmp_start += tmp_divide - tmp_start % tmp_divide;
+							if (tmp_start >= range->end)
+								break;
+						}
+					}
+
+					if (flag && len_cur == res->len) {
+						res->start = start_cur;
+						res->len += 1; /* To restore the balance */
+						res->end = res->start + res->len - 1;
+						return 0;
+					}
+				}
+			}
+			range = range->next;
+		}		/* end of while */
+
+		if ((!range) && (len_cur == 0)) {
+			/* have gone through the list of devices and ranges and haven't found n.e.thing */
+			err ("no appropriate range.. bailing out...\n");
+			return -EINVAL;
+		} else if (len_cur) {
+			res->start = start_cur;
+			res->len += 1; /* To restore the balance */
+			res->end = res->start + res->len - 1;
+			return 0;
+		}
+	}
+
+	if (!res_cur) {
+		debug ("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges);
+		if (res_prev->rangeno < noranges) {
+			/* if there're more ranges out there to check */
+			switch (res->type) {
+				case IO:
+					range = bus_cur->rangeIO;
+					break;
+				case MEM:
+					range = bus_cur->rangeMem;
+					break;
+				case PFMEM:
+					range = bus_cur->rangePFMem;
+					break;
+			}
+			while (range) {
+				if ((len_tmp = range->end - range->start) >= res->len) {
+					if ((len_tmp < len_cur) || (len_cur == 0)) {
+						if ((range->start % tmp_divide) == 0) {
+							/* just perfect, starting address's divisible by length */
+							flag = TRUE;
+							len_cur = len_tmp;
+							start_cur = range->start;
+						} else {
+							/* Needs adjusting */
+							tmp_start = range->start;
+							flag = FALSE;
+
+							while ((len_tmp = range->end - tmp_start) >= res->len) {
+								if ((tmp_start % tmp_divide) == 0) {
+									flag = TRUE;
+									len_cur = len_tmp;
+									start_cur = tmp_start;
+									break;
+								}
+								tmp_start += tmp_divide - tmp_start % tmp_divide;
+								if (tmp_start >= range->end)
+									break;
+							}
+						}
+
+						if (flag && len_cur == res->len) {
+							res->start = start_cur;
+							res->len += 1; /* To restore the balance */
+							res->end = res->start + res->len - 1;
+							return 0;
+						}
+					}
+				}
+				range = range->next;
+			}	/* end of while */
+
+			if ((!range) && (len_cur == 0)) {
+				/* have gone through the list of devices and ranges and haven't found n.e.thing */
+				err ("no appropriate range.. bailing out...\n");
+				return -EINVAL;
+			} else if (len_cur) {
+				res->start = start_cur;
+				res->len += 1; /* To restore the balance */
+				res->end = res->start + res->len - 1;
+				return 0;
+			}
+		} else {
+			/* no more ranges to check on */
+			if (len_cur) {
+				res->start = start_cur;
+				res->len += 1; /* To restore the balance */
+				res->end = res->start + res->len - 1;
+				return 0;
+			} else {
+				/* have gone through the list of devices and haven't found n.e.thing */
+				err ("no appropriate range.. bailing out...\n");
+				return -EINVAL;
+			}
+		}
+	}	/* end if(!res_cur) */
+	return -EINVAL;
+}
+
+/********************************************************************************
+ * This routine is called from remove_card if the card contained PPB.
+ * It will remove all the resources on the bus as well as the bus itself
+ * Input: Bus
+ * Ouput: 0, -ENODEV
+ ********************************************************************************/
+int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
+{
+	struct resource_node *res_cur;
+	struct resource_node *res_tmp;
+	struct bus_node *prev_bus;
+	int rc;
+
+	prev_bus = find_bus_wprev (parent_busno, NULL, 0);	
+
+	if (!prev_bus) {
+		debug ("something terribly wrong. Cannot find parent bus to the one to remove\n");
+		return -ENODEV;
+	}
+
+	debug ("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno);
+
+	rc = remove_ranges (bus, prev_bus);
+	if (rc)
+		return rc;
+
+	if (bus->firstIO) {
+		res_cur = bus->firstIO;
+		while (res_cur) {
+			res_tmp = res_cur;
+			if (res_cur->next)
+				res_cur = res_cur->next;
+			else
+				res_cur = res_cur->nextRange;
+			kfree (res_tmp);
+			res_tmp = NULL;
+		}
+		bus->firstIO = NULL;
+	}
+	if (bus->firstMem) {
+		res_cur = bus->firstMem;
+		while (res_cur) {
+			res_tmp = res_cur;
+			if (res_cur->next)
+				res_cur = res_cur->next;
+			else
+				res_cur = res_cur->nextRange;
+			kfree (res_tmp);
+			res_tmp = NULL;
+		}
+		bus->firstMem = NULL;
+	}
+	if (bus->firstPFMem) {
+		res_cur = bus->firstPFMem;
+		while (res_cur) {
+			res_tmp = res_cur;
+			if (res_cur->next)
+				res_cur = res_cur->next;
+			else
+				res_cur = res_cur->nextRange;
+			kfree (res_tmp);
+			res_tmp = NULL;
+		}
+		bus->firstPFMem = NULL;
+	}
+
+	if (bus->firstPFMemFromMem) {
+		res_cur = bus->firstPFMemFromMem;
+		while (res_cur) {
+			res_tmp = res_cur;
+			res_cur = res_cur->next;
+
+			kfree (res_tmp);
+			res_tmp = NULL;
+		}
+		bus->firstPFMemFromMem = NULL;
+	}
+
+	list_del (&bus->bus_list);
+	kfree (bus);
+	return 0;
+}
+
+/******************************************************************************
+ * This routine deletes the ranges from a given bus, and the entries from the 
+ * parent's bus in the resources
+ * Input: current bus, previous bus
+ * Output: 0, -EINVAL
+ ******************************************************************************/
+static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
+{
+	struct range_node *range_cur;
+	struct range_node *range_tmp;
+	int i;
+	struct resource_node *res = NULL;
+
+	if (bus_cur->noIORanges) {
+		range_cur = bus_cur->rangeIO;
+		for (i = 0; i < bus_cur->noIORanges; i++) {
+			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, IO) < 0)
+				return -EINVAL;
+			ibmphp_remove_resource (res);
+
+			range_tmp = range_cur;
+			range_cur = range_cur->next;
+			kfree (range_tmp);
+			range_tmp = NULL;
+		}
+		bus_cur->rangeIO = NULL;
+	}
+	if (bus_cur->noMemRanges) {
+		range_cur = bus_cur->rangeMem;
+		for (i = 0; i < bus_cur->noMemRanges; i++) {
+			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, MEM) < 0) 
+				return -EINVAL;
+
+			ibmphp_remove_resource (res);
+			range_tmp = range_cur;
+			range_cur = range_cur->next;
+			kfree (range_tmp);
+			range_tmp = NULL;
+		}
+		bus_cur->rangeMem = NULL;
+	}
+	if (bus_cur->noPFMemRanges) {
+		range_cur = bus_cur->rangePFMem;
+		for (i = 0; i < bus_cur->noPFMemRanges; i++) {
+			if (ibmphp_find_resource (bus_prev, range_cur->start, &res, PFMEM) < 0) 
+				return -EINVAL;
+
+			ibmphp_remove_resource (res);
+			range_tmp = range_cur;
+			range_cur = range_cur->next;
+			kfree (range_tmp);
+			range_tmp = NULL;
+		}
+		bus_cur->rangePFMem = NULL;
+	}
+	return 0;
+}
+
+/*
+ * find the resource node in the bus 
+ * Input: Resource needed, start address of the resource, type of resource
+ */
+int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
+{
+	struct resource_node *res_cur = NULL;
+	char * type = "";
+
+	if (!bus) {
+		err ("The bus passed in NULL to find resource \n");
+		return -ENODEV;
+	}
+
+	switch (flag) {
+		case IO:
+			res_cur = bus->firstIO;
+			type = "io";
+			break;
+		case MEM:
+			res_cur = bus->firstMem;
+			type = "mem";
+			break;
+		case PFMEM:
+			res_cur = bus->firstPFMem;
+			type = "pfmem";
+			break;
+		default:
+			err ("wrong type of flag \n");
+			return -EINVAL;
+	}
+	
+	while (res_cur) {
+		if (res_cur->start == start_address) {
+			*res = res_cur;
+			break;
+		}
+		if (res_cur->next)
+			res_cur = res_cur->next;
+		else
+			res_cur = res_cur->nextRange;
+	}
+
+	if (!res_cur) {
+		if (flag == PFMEM) {
+			res_cur = bus->firstPFMemFromMem;
+			while (res_cur) {
+				if (res_cur->start == start_address) {
+					*res = res_cur;
+					break;
+				}
+				res_cur = res_cur->next;
+			}
+			if (!res_cur) {
+				debug ("SOS...cannot find %s resource in the bus. \n", type);
+				return -EINVAL;
+			}
+		} else {
+			debug ("SOS... cannot find %s resource in the bus. \n", type);
+			return -EINVAL;
+		}
+	}
+
+	if (*res)
+		debug ("*res->start = %x \n", (*res)->start);
+
+	return 0;
+}
+
+/***********************************************************************
+ * This routine will free the resource structures used by the
+ * system.  It is called from cleanup routine for the module
+ * Parameters: none
+ * Returns: none
+ ***********************************************************************/
+void ibmphp_free_resources (void)
+{
+	struct bus_node *bus_cur = NULL;
+	struct bus_node *bus_tmp;
+	struct range_node *range_cur;
+	struct range_node *range_tmp;
+	struct resource_node *res_cur;
+	struct resource_node *res_tmp;
+	struct list_head *tmp;
+	struct list_head *next;
+	int i = 0;
+	flags = 1;
+
+	list_for_each_safe (tmp, next, &gbuses) {
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		if (bus_cur->noIORanges) {
+			range_cur = bus_cur->rangeIO;
+			for (i = 0; i < bus_cur->noIORanges; i++) {
+				if (!range_cur)
+					break;
+				range_tmp = range_cur;
+				range_cur = range_cur->next;
+				kfree (range_tmp);
+				range_tmp = NULL;
+			}
+		}
+		if (bus_cur->noMemRanges) {
+			range_cur = bus_cur->rangeMem;
+			for (i = 0; i < bus_cur->noMemRanges; i++) {
+				if (!range_cur)
+					break;
+				range_tmp = range_cur;
+				range_cur = range_cur->next;
+				kfree (range_tmp);
+				range_tmp = NULL;
+			}
+		}
+		if (bus_cur->noPFMemRanges) {
+			range_cur = bus_cur->rangePFMem;
+			for (i = 0; i < bus_cur->noPFMemRanges; i++) {
+				if (!range_cur)
+					break;
+				range_tmp = range_cur;
+				range_cur = range_cur->next;
+				kfree (range_tmp);
+				range_tmp = NULL;
+			}
+		}
+
+		if (bus_cur->firstIO) {
+			res_cur = bus_cur->firstIO;
+			while (res_cur) {
+				res_tmp = res_cur;
+				if (res_cur->next)
+					res_cur = res_cur->next;
+				else
+					res_cur = res_cur->nextRange;
+				kfree (res_tmp);
+				res_tmp = NULL;
+			}
+			bus_cur->firstIO = NULL;
+		}
+		if (bus_cur->firstMem) {
+			res_cur = bus_cur->firstMem;
+			while (res_cur) {
+				res_tmp = res_cur;
+				if (res_cur->next)
+					res_cur = res_cur->next;
+				else
+					res_cur = res_cur->nextRange;
+				kfree (res_tmp);
+				res_tmp = NULL;
+			}
+			bus_cur->firstMem = NULL;
+		}
+		if (bus_cur->firstPFMem) {
+			res_cur = bus_cur->firstPFMem;
+			while (res_cur) {
+				res_tmp = res_cur;
+				if (res_cur->next)
+					res_cur = res_cur->next;
+				else
+					res_cur = res_cur->nextRange;
+				kfree (res_tmp);
+				res_tmp = NULL;
+			}
+			bus_cur->firstPFMem = NULL;
+		}
+
+		if (bus_cur->firstPFMemFromMem) {
+			res_cur = bus_cur->firstPFMemFromMem;
+			while (res_cur) {
+				res_tmp = res_cur;
+				res_cur = res_cur->next;
+
+				kfree (res_tmp);
+				res_tmp = NULL;
+			}
+			bus_cur->firstPFMemFromMem = NULL;
+		}
+
+		bus_tmp = bus_cur;
+		list_del (&bus_cur->bus_list);
+		kfree (bus_tmp);
+		bus_tmp = NULL;
+	}
+}
+
+/*********************************************************************************
+ * This function will go over the PFmem resources to check if the EBDA allocated
+ * pfmem out of memory buckets of the bus.  If so, it will change the range numbers
+ * and a flag to indicate that this resource is out of memory. It will also move the
+ * Pfmem out of the pfmem resource list to the PFMemFromMem list, and will create
+ * a new Mem node
+ * This routine is called right after initialization
+ *******************************************************************************/
+static int __init once_over (void)
+{
+	struct resource_node *pfmem_cur;
+	struct resource_node *pfmem_prev;
+	struct resource_node *mem;
+	struct bus_node *bus_cur;
+	struct list_head *tmp;
+
+	list_for_each (tmp, &gbuses) {
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) {
+			for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) {
+				pfmem_cur->fromMem = TRUE;
+				if (pfmem_prev)
+					pfmem_prev->next = pfmem_cur->next;
+				else
+					bus_cur->firstPFMem = pfmem_cur->next;
+
+				if (!bus_cur->firstPFMemFromMem)
+					pfmem_cur->next = NULL;
+				else
+					/* we don't need to sort PFMemFromMem since we're using mem node for
+					   all the real work anyways, so just insert at the beginning of the
+					   list
+					 */
+					pfmem_cur->next = bus_cur->firstPFMemFromMem;
+
+				bus_cur->firstPFMemFromMem = pfmem_cur;
+
+				mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);		
+				if (!mem) {
+					err ("out of system memory \n");
+					return -ENOMEM;
+				}
+				memset (mem, 0, sizeof (struct resource_node));
+				mem->type = MEM;
+				mem->busno = pfmem_cur->busno;
+				mem->devfunc = pfmem_cur->devfunc;
+				mem->start = pfmem_cur->start;
+				mem->end = pfmem_cur->end;
+				mem->len = pfmem_cur->len;
+				if (ibmphp_add_resource (mem) < 0)
+					err ("Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n");
+				pfmem_cur->rangeno = mem->rangeno;
+			}	/* end for pfmem */
+		}	/* end if */
+	}	/* end list_for_each bus */
+	return 0; 
+}
+
+int ibmphp_add_pfmem_from_mem (struct resource_node *pfmem)
+{
+	struct bus_node *bus_cur = find_bus_wprev (pfmem->busno, NULL, 0);
+
+	if (!bus_cur) {
+		err ("cannot find bus of pfmem to add...\n");
+		return -ENODEV;
+	}
+
+	if (bus_cur->firstPFMemFromMem)
+		pfmem->next = bus_cur->firstPFMemFromMem;
+	else
+		pfmem->next = NULL;
+
+	bus_cur->firstPFMemFromMem = pfmem;
+
+	return 0;
+}
+
+/* This routine just goes through the buses to see if the bus already exists.
+ * It is called from ibmphp_find_sec_number, to find out a secondary bus number for
+ * bridged cards
+ * Parameters: bus_number
+ * Returns: Bus pointer or NULL
+ */
+struct bus_node *ibmphp_find_res_bus (u8 bus_number)
+{
+	return find_bus_wprev (bus_number, NULL, 0);
+}
+
+static inline struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u8 flag)
+{
+	struct bus_node *bus_cur;
+	struct list_head *tmp;
+	struct list_head *tmp_prev;
+
+	list_for_each (tmp, &gbuses) {
+		tmp_prev = tmp->prev;
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		if (flag) 
+			*prev = list_entry (tmp_prev, struct bus_node, bus_list);
+		if (bus_cur->busno == bus_number) 
+			return bus_cur;
+	}
+
+	return NULL;
+}
+
+void ibmphp_print_test (void)
+{
+	int i = 0;
+	struct bus_node *bus_cur = NULL;
+	struct range_node *range;
+	struct resource_node *res;
+	struct list_head *tmp;
+	
+	debug_pci ("*****************START**********************\n");
+
+	if ((!list_empty(&gbuses)) && flags) {
+		err ("The GBUSES is not NULL?!?!?!?!?\n");
+		return;
+	}
+
+	list_for_each (tmp, &gbuses) {
+		bus_cur = list_entry (tmp, struct bus_node, bus_list);
+		debug_pci ("This is bus # %d.  There are \n", bus_cur->busno);
+		debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
+		debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
+		debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
+		debug_pci ("The IO Ranges are as follows:\n");
+		if (bus_cur->rangeIO) {
+			range = bus_cur->rangeIO;
+			for (i = 0; i < bus_cur->noIORanges; i++) {
+				debug_pci ("rangeno is %d\n", range->rangeno);
+				debug_pci ("[%x - %x]\n", range->start, range->end);
+				range = range->next;
+			}
+		}
+
+		debug_pci ("The Mem Ranges are as follows:\n");
+		if (bus_cur->rangeMem) {
+			range = bus_cur->rangeMem;
+			for (i = 0; i < bus_cur->noMemRanges; i++) {
+				debug_pci ("rangeno is %d\n", range->rangeno);
+				debug_pci ("[%x - %x]\n", range->start, range->end);
+				range = range->next;
+			}
+		}
+
+		debug_pci ("The PFMem Ranges are as follows:\n");
+
+		if (bus_cur->rangePFMem) {
+			range = bus_cur->rangePFMem;
+			for (i = 0; i < bus_cur->noPFMemRanges; i++) {
+				debug_pci ("rangeno is %d\n", range->rangeno);
+				debug_pci ("[%x - %x]\n", range->start, range->end);
+				range = range->next;
+			}
+		}
+
+		debug_pci ("The resources on this bus are as follows\n");
+
+		debug_pci ("IO...\n");
+		if (bus_cur->firstIO) {
+			res = bus_cur->firstIO;
+			while (res) {
+				debug_pci ("The range # is %d\n", res->rangeno);
+				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				if (res->next)
+					res = res->next;
+				else if (res->nextRange)
+					res = res->nextRange;
+				else
+					break;
+			}
+		}
+		debug_pci ("Mem...\n");
+		if (bus_cur->firstMem) {
+			res = bus_cur->firstMem;
+			while (res) {
+				debug_pci ("The range # is %d\n", res->rangeno);
+				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				if (res->next)
+					res = res->next;
+				else if (res->nextRange)
+					res = res->nextRange;
+				else
+					break;
+			}
+		}
+		debug_pci ("PFMem...\n");
+		if (bus_cur->firstPFMem) {
+			res = bus_cur->firstPFMem;
+			while (res) {
+				debug_pci ("The range # is %d\n", res->rangeno);
+				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				if (res->next)
+					res = res->next;
+				else if (res->nextRange)
+					res = res->nextRange;
+				else
+					break;
+			}
+		}
+
+		debug_pci ("PFMemFromMem...\n");
+		if (bus_cur->firstPFMemFromMem) {
+			res = bus_cur->firstPFMemFromMem;
+			while (res) {
+				debug_pci ("The range # is %d\n", res->rangeno);
+				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				res = res->next;
+			}
+		}
+	}
+	debug_pci ("***********************END***********************\n");
+}
+
+static int range_exists_already (struct range_node * range, struct bus_node * bus_cur, u8 type)
+{
+	struct range_node * range_cur = NULL;
+	switch (type) {
+		case IO:
+			range_cur = bus_cur->rangeIO;
+			break;
+		case MEM:
+			range_cur = bus_cur->rangeMem;
+			break;
+		case PFMEM:
+			range_cur = bus_cur->rangePFMem;
+			break;
+		default:
+			err ("wrong type passed to find out if range already exists \n");
+			return -ENODEV;
+	}
+
+	while (range_cur) {
+		if ((range_cur->start == range->start) && (range_cur->end == range->end))
+			return 1;
+		range_cur = range_cur->next;
+	}
+	
+	return 0;
+}
+
+/* This routine will read the windows for any PPB we have and update the
+ * range info for the secondary bus, and will also input this info into
+ * primary bus, since BIOS doesn't. This is for PPB that are in the system
+ * on bootup.  For bridged cards that were added during previous load of the
+ * driver, only the ranges and the bus structure are added, the devices are
+ * added from NVRAM
+ * Input: primary busno
+ * Returns: none
+ * Note: this function doesn't take into account IO restrictions etc,
+ *	 so will only work for bridges with no video/ISA devices behind them It
+ *	 also will not work for onboard PPB's that can have more than 1 *bus
+ *	 behind them All these are TO DO.
+ *	 Also need to add more error checkings... (from fnc returns etc)
+ */
+static int __init update_bridge_ranges (struct bus_node **bus)
+{
+	u8 sec_busno, device, function, hdr_type, start_io_address, end_io_address;
+	u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
+	u32 start_address, end_address, upper_start, upper_end;
+	struct bus_node *bus_sec;
+	struct bus_node *bus_cur;
+	struct resource_node *io;
+	struct resource_node *mem;
+	struct resource_node *pfmem;
+	struct range_node *range;
+	unsigned int devfn;
+
+	bus_cur = *bus;
+	if (!bus_cur)
+		return -ENODEV;
+	ibmphp_pci_bus->number = bus_cur->busno;
+
+	debug ("inside %s \n", __FUNCTION__);
+	debug ("bus_cur->busno = %x\n", bus_cur->busno);
+
+	for (device = 0; device < 32; device++) {
+		for (function = 0x00; function < 0x08; function++) {
+			devfn = PCI_DEVFN(device, function);
+			pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
+
+			if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
+				/* found correct device!!! */
+				pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+
+				switch (hdr_type) {
+					case PCI_HEADER_TYPE_NORMAL:
+						function = 0x8;
+						break;
+					case PCI_HEADER_TYPE_MULTIDEVICE:
+						break;
+					case PCI_HEADER_TYPE_BRIDGE:
+						function = 0x8;
+					case PCI_HEADER_TYPE_MULTIBRIDGE:
+						/* We assume here that only 1 bus behind the bridge 
+						   TO DO: add functionality for several:
+						   temp = secondary;
+						   while (temp < subordinate) {
+						   ...
+						   temp++;
+						   }
+						 */
+						pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno);
+						bus_sec = find_bus_wprev (sec_busno, NULL, 0); 
+						/* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
+						if (!bus_sec) {
+							bus_sec = alloc_error_bus (NULL, sec_busno, 1);
+							/* the rest will be populated during NVRAM call */
+							return 0;
+						}
+						pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address);
+						pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address);
+						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start);
+						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end);
+						start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8;
+						start_address |= (upper_io_start << 16);
+						end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
+						end_address |= (upper_io_end << 16);
+
+						if ((start_address) && (start_address <= end_address)) {
+							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+							if (!range) {
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (range, 0, sizeof (struct range_node));
+							range->start = start_address;
+							range->end = end_address + 0xfff;
+
+							if (bus_sec->noIORanges > 0) {
+								if (!range_exists_already (range, bus_sec, IO)) {
+									add_range (IO, range, bus_sec);
+									++bus_sec->noIORanges;
+								} else {
+									kfree (range);
+									range = NULL;
+								}
+							} else {
+								/* 1st IO Range on the bus */
+								range->rangeno = 1;
+								bus_sec->rangeIO = range;
+								++bus_sec->noIORanges;
+							}
+							fix_resources (bus_sec);
+
+							if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
+								io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);							
+								if (!io) {
+									kfree (range);
+									err ("out of system memory \n");
+									return -ENOMEM;
+								}
+								memset (io, 0, sizeof (struct resource_node));
+								io->type = IO;
+								io->busno = bus_cur->busno;
+								io->devfunc = ((device << 3) | (function & 0x7));
+								io->start = start_address;
+								io->end = end_address + 0xfff;
+								io->len = io->end - io->start + 1;
+								ibmphp_add_resource (io);
+							}
+						}	
+
+						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);
+						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address);
+
+						start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
+						end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
+
+						if ((start_address) && (start_address <= end_address)) {
+
+							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+							if (!range) {
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (range, 0, sizeof (struct range_node));
+							range->start = start_address;
+							range->end = end_address + 0xfffff;
+
+							if (bus_sec->noMemRanges > 0) {
+								if (!range_exists_already (range, bus_sec, MEM)) {
+									add_range (MEM, range, bus_sec);
+									++bus_sec->noMemRanges;
+								} else {
+									kfree (range);
+									range = NULL;
+								}
+							} else {
+								/* 1st Mem Range on the bus */
+								range->rangeno = 1;
+								bus_sec->rangeMem = range;
+								++bus_sec->noMemRanges;
+							}
+
+							fix_resources (bus_sec);
+
+							if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
+								mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+								if (!mem) {
+									kfree (range);
+									err ("out of system memory \n");
+									return -ENOMEM;
+								}
+								memset (mem, 0, sizeof (struct resource_node));
+								mem->type = MEM;
+								mem->busno = bus_cur->busno;
+								mem->devfunc = ((device << 3) | (function & 0x7));
+								mem->start = start_address;
+								mem->end = end_address + 0xfffff;
+								mem->len = mem->end - mem->start + 1;
+								ibmphp_add_resource (mem);
+							}
+						}
+						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
+						pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
+						pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start);
+						pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end);
+						start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
+						end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
+#if BITS_PER_LONG == 64
+						start_address |= ((long) upper_start) << 32;
+						end_address |= ((long) upper_end) << 32;
+#endif
+
+						if ((start_address) && (start_address <= end_address)) {
+
+							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+							if (!range) {
+								err ("out of system memory \n");
+								return -ENOMEM;
+							}
+							memset (range, 0, sizeof (struct range_node));
+							range->start = start_address;
+							range->end = end_address + 0xfffff;
+
+							if (bus_sec->noPFMemRanges > 0) {
+								if (!range_exists_already (range, bus_sec, PFMEM)) {
+									add_range (PFMEM, range, bus_sec);
+									++bus_sec->noPFMemRanges;
+								} else {
+									kfree (range);
+									range = NULL;
+								}
+							} else {
+								/* 1st PFMem Range on the bus */
+								range->rangeno = 1;
+								bus_sec->rangePFMem = range;
+								++bus_sec->noPFMemRanges;
+							}
+
+							fix_resources (bus_sec);
+							if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
+								pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+								if (!pfmem) {
+									kfree (range);
+									err ("out of system memory \n");
+									return -ENOMEM;
+								}
+								memset (pfmem, 0, sizeof (struct resource_node));
+								pfmem->type = PFMEM;
+								pfmem->busno = bus_cur->busno;
+								pfmem->devfunc = ((device << 3) | (function & 0x7));
+								pfmem->start = start_address;
+								pfmem->end = end_address + 0xfffff;
+								pfmem->len = pfmem->end - pfmem->start + 1;
+								pfmem->fromMem = FALSE;
+
+								ibmphp_add_resource (pfmem);
+							}
+						}
+						break;
+				}	/* end of switch */
+			}	/* end if vendor */
+		}	/* end for function */
+	}	/* end for device */
+
+	bus = &bus_cur;
+	return 0;
+}
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/pci_hotplug.h linux-2.5.70-bk10/drivers/pci/hotplug/pci_hotplug.h
--- linux-2.5.70-bk9/drivers/pci/hotplug/pci_hotplug.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/pci_hotplug.h	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,146 @@
+/*
+ * PCI HotPlug Core Functions
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+#ifndef _PCI_HOTPLUG_H
+#define _PCI_HOTPLUG_H
+
+
+/* These values come from the PCI Hotplug Spec */
+enum pci_bus_speed {
+	PCI_SPEED_33MHz			= 0x00,
+	PCI_SPEED_66MHz			= 0x01,
+	PCI_SPEED_66MHz_PCIX		= 0x02,
+	PCI_SPEED_100MHz_PCIX		= 0x03,
+	PCI_SPEED_133MHz_PCIX		= 0x04,
+	PCI_SPEED_66MHz_PCIX_266	= 0x09,
+	PCI_SPEED_100MHz_PCIX_266	= 0x0a,
+	PCI_SPEED_133MHz_PCIX_266	= 0x0b,
+	PCI_SPEED_66MHz_PCIX_533	= 0x11,
+	PCI_SPEED_100MHz_PCIX_533	= 0X12,
+	PCI_SPEED_133MHz_PCIX_533	= 0x13,
+	PCI_SPEED_UNKNOWN		= 0xff,
+};
+
+struct hotplug_slot;
+struct hotplug_slot_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct hotplug_slot *, char *);
+	ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
+};
+/**
+ * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
+ * @owner: The module owner of this structure
+ * @enable_slot: Called when the user wants to enable a specific pci slot
+ * @disable_slot: Called when the user wants to disable a specific pci slot
+ * @set_attention_status: Called to set the specific slot's attention LED to
+ * the specified value
+ * @hardware_test: Called to run a specified hardware test on the specified
+ * slot.
+ * @get_power_status: Called to get the current power status of a slot.
+ * 	If this field is NULL, the value passed in the struct hotplug_slot_info
+ * 	will be used when this value is requested by a user.
+ * @get_attention_status: Called to get the current attention status of a slot.
+ *	If this field is NULL, the value passed in the struct hotplug_slot_info
+ *	will be used when this value is requested by a user.
+ * @get_latch_status: Called to get the current latch status of a slot.
+ *	If this field is NULL, the value passed in the struct hotplug_slot_info
+ *	will be used when this value is requested by a user.
+ * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
+ *	If this field is NULL, the value passed in the struct hotplug_slot_info
+ *	will be used when this value is requested by a user.
+ * @get_max_bus_speed: Called to get the max bus speed for a slot.
+ *	If this field is NULL, the value passed in the struct hotplug_slot_info
+ *	will be used when this value is requested by a user.
+ * @get_cur_bus_speed: Called to get the current bus speed for a slot.
+ *	If this field is NULL, the value passed in the struct hotplug_slot_info
+ *	will be used when this value is requested by a user.
+ *
+ * The table of function pointers that is passed to the hotplug pci core by a
+ * hotplug pci driver.  These functions are called by the hotplug pci core when
+ * the user wants to do something to a specific slot (query it for information,
+ * set an LED, enable / disable power, etc.)
+ */
+struct hotplug_slot_ops {
+	struct module *owner;
+	int (*enable_slot)		(struct hotplug_slot *slot);
+	int (*disable_slot)		(struct hotplug_slot *slot);
+	int (*set_attention_status)	(struct hotplug_slot *slot, u8 value);
+	int (*hardware_test)		(struct hotplug_slot *slot, u32 value);
+	int (*get_power_status)		(struct hotplug_slot *slot, u8 *value);
+	int (*get_attention_status)	(struct hotplug_slot *slot, u8 *value);
+	int (*get_latch_status)		(struct hotplug_slot *slot, u8 *value);
+	int (*get_adapter_status)	(struct hotplug_slot *slot, u8 *value);
+	int (*get_max_bus_speed)	(struct hotplug_slot *slot, enum pci_bus_speed *value);
+	int (*get_cur_bus_speed)	(struct hotplug_slot *slot, enum pci_bus_speed *value);
+};
+
+/**
+ * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
+ * @power: if power is enabled or not (1/0)
+ * @attention_status: if the attention light is enabled or not (1/0)
+ * @latch_status: if the latch (if any) is open or closed (1/0)
+ * @adapter_present: if there is a pci board present in the slot or not (1/0)
+ *
+ * Used to notify the hotplug pci core of the status of a specific slot.
+ */
+struct hotplug_slot_info {
+	u8	power_status;
+	u8	attention_status;
+	u8	latch_status;
+	u8	adapter_status;
+	enum pci_bus_speed	max_bus_speed;
+	enum pci_bus_speed	cur_bus_speed;
+};
+
+/**
+ * struct hotplug_slot - used to register a physical slot with the hotplug pci core
+ * @name: the name of the slot being registered.  This string must
+ * be unique amoung slots registered on this system.
+ * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
+ * @info: pointer to the &struct hotplug_slot_info for the inital values for
+ * this slot.
+ * @private: used by the hotplug pci controller driver to store whatever it
+ * needs.
+ */
+struct hotplug_slot {
+	char				*name;
+	struct hotplug_slot_ops		*ops;
+	struct hotplug_slot_info	*info;
+	void				*private;
+
+	/* Variables below this are for use only by the hotplug pci core. */
+	struct list_head		slot_list;
+	struct kobject			kobj;
+};
+
+extern int pci_hp_register		(struct hotplug_slot *slot);
+extern int pci_hp_deregister		(struct hotplug_slot *slot);
+extern int pci_hp_change_slot_info	(struct hotplug_slot *slot,
+					 struct hotplug_slot_info *info);
+
+#endif
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/pci_hotplug_core.c linux-2.5.70-bk10/drivers/pci/hotplug/pci_hotplug_core.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/pci_hotplug_core.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/pci_hotplug_core.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,666 @@
+/*
+ * PCI HotPlug Controller Core
+ *
+ * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001-2002 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/pci.h>
+#include <asm/uaccess.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+#include "pci_hotplug.h"
+
+
+#if !defined(CONFIG_HOTPLUG_PCI_MODULE)
+	#define MY_NAME	"pci_hotplug"
+#else
+	#define MY_NAME	THIS_MODULE->name
+#endif
+
+#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
+
+
+/* local variables */
+static int debug;
+
+#define DRIVER_VERSION	"0.5"
+#define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>"
+#define DRIVER_DESC	"PCI Hot Plug PCI Core"
+
+
+//////////////////////////////////////////////////////////////////
+
+static LIST_HEAD(pci_hotplug_slot_list);
+
+static struct subsystem hotplug_slots_subsys;
+
+static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->show ? attribute->show(slot, buf) : 0;
+}
+
+static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
+		struct attribute *attr, const char *buf, size_t len)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->store ? attribute->store(slot, buf, len) : 0;
+}
+
+static struct sysfs_ops hotplug_slot_sysfs_ops = {
+	.show = hotplug_slot_attr_show,
+	.store = hotplug_slot_attr_store,
+};
+
+static struct kobj_type hotplug_slot_ktype = {
+	.sysfs_ops = &hotplug_slot_sysfs_ops
+};
+
+static decl_subsys(hotplug_slots, &hotplug_slot_ktype, NULL);
+
+
+/* these strings match up with the values in pci_bus_speed */
+static char *pci_bus_speed_strings[] = {
+	"33 MHz PCI",		/* 0x00 */
+	"66 MHz PCI",		/* 0x01 */
+	"66 MHz PCIX", 		/* 0x02 */
+	"100 MHz PCIX",		/* 0x03 */
+	"133 MHz PCIX",		/* 0x04 */
+	NULL,			/* 0x05 */
+	NULL,			/* 0x06 */
+	NULL,			/* 0x07 */
+	NULL,			/* 0x08 */
+	"66 MHz PCIX 266",	/* 0x09 */
+	"100 MHz PCIX 266",	/* 0x0a */
+	"133 MHz PCIX 266",	/* 0x0b */
+	NULL,			/* 0x0c */
+	NULL,			/* 0x0d */
+	NULL,			/* 0x0e */
+	NULL,			/* 0x0f */
+	NULL,			/* 0x10 */
+	"66 MHz PCIX 533",	/* 0x11 */
+	"100 MHz PCIX 533",	/* 0x12 */
+	"133 MHz PCIX 533",	/* 0x13 */
+};
+
+#ifdef CONFIG_HOTPLUG_PCI_CPCI
+extern int cpci_hotplug_init(int debug);
+extern void cpci_hotplug_exit(void);
+#else
+static inline int cpci_hotplug_init(int debug) { return 0; }
+static inline void cpci_hotplug_exit(void) { }
+#endif
+
+/* Weee, fun with macros... */
+#define GET_STATUS(name,type)	\
+static int get_##name (struct hotplug_slot *slot, type *value)		\
+{									\
+	struct hotplug_slot_ops *ops = slot->ops;			\
+	int retval = 0;							\
+	if (try_module_get(ops->owner)) {				\
+		if (ops->get_##name)					\
+			retval = ops->get_##name (slot, value);		\
+		else							\
+			*value = slot->info->name;			\
+		module_put(ops->owner);					\
+	}								\
+	return retval;							\
+}
+
+GET_STATUS(power_status, u8)
+GET_STATUS(attention_status, u8)
+GET_STATUS(latch_status, u8)
+GET_STATUS(adapter_status, u8)
+GET_STATUS(max_bus_speed, enum pci_bus_speed)
+GET_STATUS(cur_bus_speed, enum pci_bus_speed)
+
+static ssize_t power_read_file (struct hotplug_slot *slot, char *buf)
+{
+	int retval;
+	u8 value;
+
+	retval = get_power_status (slot, &value);
+	if (retval)
+		goto exit;
+	retval = sprintf (buf, "%d\n", value);
+exit:
+	return retval;
+}
+
+static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
+{
+	unsigned long lpower;
+	u8 power;
+	int retval = 0;
+
+	lpower = simple_strtoul (buf, NULL, 10);
+	power = (u8)(lpower & 0xff);
+	dbg ("power = %d\n", power);
+
+	if (!try_module_get(slot->ops->owner)) {
+		retval = -ENODEV;
+		goto exit;
+	}
+	switch (power) {
+		case 0:
+			if (slot->ops->disable_slot)
+				retval = slot->ops->disable_slot(slot);
+			break;
+
+		case 1:
+			if (slot->ops->enable_slot)
+				retval = slot->ops->enable_slot(slot);
+			break;
+
+		default:
+			err ("Illegal value specified for power\n");
+			retval = -EINVAL;
+	}
+	module_put(slot->ops->owner);
+
+exit:	
+	if (retval)
+		return retval;
+	return count;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_power = {
+	.attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = power_read_file,
+	.store = power_write_file
+};
+
+static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf)
+{
+	int retval;
+	u8 value;
+
+	retval = get_attention_status (slot, &value);
+	if (retval)
+		goto exit;
+	retval = sprintf (buf, "%d\n", value);
+
+exit:
+	return retval;
+}
+
+static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
+{
+	unsigned long lattention;
+	u8 attention;
+	int retval = 0;
+
+	lattention = simple_strtoul (buf, NULL, 10);
+	attention = (u8)(lattention & 0xff);
+	dbg (" - attention = %d\n", attention);
+
+	if (!try_module_get(slot->ops->owner)) {
+		retval = -ENODEV;
+		goto exit;
+	}
+	if (slot->ops->set_attention_status)
+		retval = slot->ops->set_attention_status(slot, attention);
+	module_put(slot->ops->owner);
+
+exit:	
+	if (retval)
+		return retval;
+	return count;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_attention = {
+	.attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = attention_read_file,
+	.store = attention_write_file
+};
+
+static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf)
+{
+	int retval;
+	u8 value;
+
+	retval = get_latch_status (slot, &value);
+	if (retval)
+		goto exit;
+	retval = sprintf (buf, "%d\n", value);
+
+exit:
+	return retval;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
+	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = latch_read_file,
+};
+
+static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf)
+{
+	int retval;
+	u8 value;
+
+	retval = get_adapter_status (slot, &value);
+	if (retval)
+		goto exit;
+	retval = sprintf (buf, "%d\n", value);
+
+exit:
+	return retval;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
+	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = presence_read_file,
+};
+
+static char *unknown_speed = "Unknown bus speed";
+
+static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
+{
+	char *speed_string;
+	int retval;
+	enum pci_bus_speed value;
+	
+	retval = get_max_bus_speed (slot, &value);
+	if (retval)
+		goto exit;
+
+	if (value == PCI_SPEED_UNKNOWN)
+		speed_string = unknown_speed;
+	else
+		speed_string = pci_bus_speed_strings[value];
+	
+	retval = sprintf (buf, "%s\n", speed_string);
+
+exit:
+	return retval;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
+	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = max_bus_speed_read_file,
+};
+
+static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
+{
+	char *speed_string;
+	int retval;
+	enum pci_bus_speed value;
+
+	retval = get_cur_bus_speed (slot, &value);
+	if (retval)
+		goto exit;
+
+	if (value == PCI_SPEED_UNKNOWN)
+		speed_string = unknown_speed;
+	else
+		speed_string = pci_bus_speed_strings[value];
+	
+	retval = sprintf (buf, "%s\n", speed_string);
+
+exit:
+	return retval;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
+	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = cur_bus_speed_read_file,
+};
+
+static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
+{
+	unsigned long ltest;
+	u32 test;
+	int retval = 0;
+
+	ltest = simple_strtoul (buf, NULL, 10);
+	test = (u32)(ltest & 0xffffffff);
+	dbg ("test = %d\n", test);
+
+	if (!try_module_get(slot->ops->owner)) {
+		retval = -ENODEV;
+		goto exit;
+	}
+	if (slot->ops->hardware_test)
+		retval = slot->ops->hardware_test(slot, test);
+	module_put(slot->ops->owner);
+
+exit:	
+	if (retval)
+		return retval;
+	return count;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_test = {
+	.attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.store = test_write_file
+};
+
+static int has_power_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if ((slot->ops->enable_slot) ||
+	    (slot->ops->disable_slot) ||
+	    (slot->ops->get_power_status))
+		return 0;
+	return -ENOENT;
+}
+
+static int has_attention_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if ((slot->ops->set_attention_status) ||
+	    (slot->ops->get_attention_status))
+		return 0;
+	return -ENOENT;
+}
+
+static int has_latch_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->get_latch_status)
+		return 0;
+	return -ENOENT;
+}
+
+static int has_adapter_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->get_adapter_status)
+		return 0;
+	return -ENOENT;
+}
+
+static int has_max_bus_speed_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->get_max_bus_speed)
+		return 0;
+	return -ENOENT;
+}
+
+static int has_cur_bus_speed_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->get_cur_bus_speed)
+		return 0;
+	return -ENOENT;
+}
+
+static int has_test_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->hardware_test)
+		return 0;
+	return -ENOENT;
+}
+
+static int fs_add_slot (struct hotplug_slot *slot)
+{
+	if (has_power_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if (has_attention_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (has_latch_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
+
+	if (has_adapter_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (has_max_bus_speed_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if (has_cur_bus_speed_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (has_test_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr);
+
+	return 0;
+}
+
+static void fs_remove_slot (struct hotplug_slot *slot)
+{
+	if (has_power_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if (has_attention_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (has_latch_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
+
+	if (has_adapter_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (has_max_bus_speed_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if (has_cur_bus_speed_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (has_test_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
+}
+
+static struct hotplug_slot *get_slot_from_name (const char *name)
+{
+	struct hotplug_slot *slot;
+	struct list_head *tmp;
+
+	list_for_each (tmp, &pci_hotplug_slot_list) {
+		slot = list_entry (tmp, struct hotplug_slot, slot_list);
+		if (strcmp(slot->name, name) == 0)
+			return slot;
+	}
+	return NULL;
+}
+
+/**
+ * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem
+ * @slot: pointer to the &struct hotplug_slot to register
+ *
+ * Registers a hotplug slot with the pci hotplug subsystem, which will allow
+ * userspace interaction to the slot.
+ *
+ * Returns 0 if successful, anything else for an error.
+ */
+int pci_hp_register (struct hotplug_slot *slot)
+{
+	int result;
+
+	if (slot == NULL)
+		return -ENODEV;
+	if ((slot->info == NULL) || (slot->ops == NULL))
+		return -EINVAL;
+
+	strlcpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
+	kobj_set_kset_s(slot, hotplug_slots_subsys);
+
+	/* this can fail if we have already registered a slot with the same name */
+	if (kobject_register(&slot->kobj)) {
+		err("Unable to register kobject");
+		return -EINVAL;
+	}
+		
+	list_add (&slot->slot_list, &pci_hotplug_slot_list);
+
+	result = fs_add_slot (slot);
+	dbg ("Added slot %s to the list\n", slot->name);
+	return result;
+}
+
+/**
+ * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem
+ * @slot: pointer to the &struct hotplug_slot to deregister
+ *
+ * The @slot must have been registered with the pci hotplug subsystem
+ * previously with a call to pci_hp_register().
+ *
+ * Returns 0 if successful, anything else for an error.
+ */
+int pci_hp_deregister (struct hotplug_slot *slot)
+{
+	struct hotplug_slot *temp;
+
+	if (slot == NULL)
+		return -ENODEV;
+
+	temp = get_slot_from_name (slot->name);
+	if (temp != slot) {
+		return -ENODEV;
+	}
+	list_del (&slot->slot_list);
+
+	fs_remove_slot (slot);
+	dbg ("Removed slot %s from the list\n", slot->name);
+	kobject_unregister(&slot->kobj);
+	return 0;
+}
+
+/**
+ * pci_hp_change_slot_info - changes the slot's information structure in the core
+ * @slot: pointer to the slot whose info has changed
+ * @info: pointer to the info copy into the slot's info structure
+ *
+ * @slot must have been registered with the pci 
+ * hotplug subsystem previously with a call to pci_hp_register().
+ *
+ * Returns 0 if successful, anything else for an error.
+ */
+int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info)
+{
+	if ((slot == NULL) || (info == NULL))
+		return -ENODEV;
+
+	/*
+	* check all fields in the info structure, and update timestamps
+	* for the files referring to the fields that have now changed.
+	*/
+	if ((has_power_file(slot) == 0) &&
+	    (slot->info->power_status != info->power_status))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if ((has_attention_file(slot) == 0) &&
+	    (slot->info->attention_status != info->attention_status))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if ((has_latch_file(slot) == 0) &&
+	    (slot->info->latch_status != info->latch_status))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
+
+	if ((has_adapter_file(slot) == 0) &&
+	    (slot->info->adapter_status != info->adapter_status))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if ((has_max_bus_speed_file(slot) == 0) &&
+	    (slot->info->max_bus_speed != info->max_bus_speed))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if ((has_cur_bus_speed_file(slot) == 0) &&
+	    (slot->info->cur_bus_speed != info->cur_bus_speed))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	memcpy (slot->info, info, sizeof (struct hotplug_slot_info));
+
+	return 0;
+}
+
+static int __init pci_hotplug_init (void)
+{
+	int result;
+
+	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
+	result = subsystem_register(&hotplug_slots_subsys);
+	if (result) {
+		err("Register subsys with error %d\n", result);
+		goto exit;
+	}
+	result = cpci_hotplug_init(debug);
+	if (result) {
+		err ("cpci_hotplug_init with error %d\n", result);
+		goto err_subsys;
+	}
+
+	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
+	goto exit;
+	
+err_subsys:
+	subsystem_unregister(&hotplug_slots_subsys);
+exit:
+	return result;
+}
+
+static void __exit pci_hotplug_exit (void)
+{
+	cpci_hotplug_exit();
+	subsystem_unregister(&hotplug_slots_subsys);
+}
+
+module_init(pci_hotplug_init);
+module_exit(pci_hotplug_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+
+EXPORT_SYMBOL_GPL(pci_hp_register);
+EXPORT_SYMBOL_GPL(pci_hp_deregister);
+EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug/pcihp_skeleton.c linux-2.5.70-bk10/drivers/pci/hotplug/pcihp_skeleton.c
--- linux-2.5.70-bk9/drivers/pci/hotplug/pcihp_skeleton.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/drivers/pci/hotplug/pcihp_skeleton.c	2003-06-05 04:41:36.000000000 -0700
@@ -0,0 +1,432 @@
+/*
+ * PCI Hot Plug Controller Skeleton Driver - 0.1
+ *
+ * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * This driver is to be used as a skeleton driver to be show how to interface
+ * with the pci hotplug core easily.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "pci_hotplug.h"
+
+
+#define SLOT_MAGIC	0x67267322
+struct slot {
+	u32 magic;
+	u8 number;
+	struct hotplug_slot *hotplug_slot;
+	struct list_head slot_list;
+};
+
+static LIST_HEAD(slot_list);
+
+#if !defined(CONFIG_HOTPLUG_PCI_SKELETON_MODULE)
+	#define MY_NAME	"pcihp_skeleton"
+#else
+	#define MY_NAME	THIS_MODULE->name
+#endif
+
+#define dbg(format, arg...)					\
+	do {							\
+		if (debug)					\
+			printk (KERN_DEBUG "%s: " format "\n",	\
+				MY_NAME , ## arg); 		\
+	} while (0)
+#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
+#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
+
+
+
+/* local variables */
+static int debug;
+static int num_slots;
+
+#define DRIVER_VERSION	"0.1"
+#define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>"
+#define DRIVER_DESC	"Hot Plug PCI Controller Skeleton Driver"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
+
+static int enable_slot		(struct hotplug_slot *slot);
+static int disable_slot		(struct hotplug_slot *slot);
+static int set_attention_status (struct hotplug_slot *slot, u8 value);
+static int hardware_test	(struct hotplug_slot *slot, u32 value);
+static int get_power_status	(struct hotplug_slot *slot, u8 *value);
+static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
+static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
+static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
+
+static struct hotplug_slot_ops skel_hotplug_slot_ops = {
+	.owner =		THIS_MODULE,
+	.enable_slot =		enable_slot,
+	.disable_slot =		disable_slot,
+	.set_attention_status =	set_attention_status,
+	.hardware_test =	hardware_test,
+	.get_power_status =	get_power_status,
+	.get_attention_status =	get_attention_status,
+	.get_latch_status =	get_latch_status,
+	.get_adapter_status =	get_adapter_status,
+};
+
+
+/* Inline functions to check the sanity of a pointer that is passed to us */
+static inline int slot_paranoia_check (struct slot *slot, const char *function)
+{
+	if (!slot) {
+		dbg("%s - slot == NULL", function);
+		return -1;
+	}
+	if (slot->magic != SLOT_MAGIC) {
+		dbg("%s - bad magic number for slot", function);
+		return -1;
+	}
+	if (!slot->hotplug_slot) {
+		dbg("%s - slot->hotplug_slot == NULL!", function);
+		return -1;
+	}
+	return 0;
+}
+
+static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
+{ 
+	struct slot *slot;
+
+	if (!hotplug_slot) {
+		dbg("%s - hotplug_slot == NULL\n", function);
+		return NULL;
+	}
+
+	slot = (struct slot *)hotplug_slot->private;
+	if (slot_paranoia_check (slot, function))
+                return NULL;
+	return slot;
+}               
+
+
+static int enable_slot (struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg ("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	/*
+	 * Fill in code here to enable the specified slot
+	 */
+
+	return retval;
+}
+
+
+static int disable_slot (struct hotplug_slot *hotplug_slot)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg ("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	/*
+	 * Fill in code here to disable the specified slot
+	 */
+
+	return retval;
+}
+
+static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg ("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	switch (status) {
+		case 0:
+			/*
+			 * Fill in code here to turn light off
+			 */
+			break;
+
+		case 1:
+		default:
+			/*
+			 * Fill in code here to turn light on
+			 */
+			break;
+	}
+
+	return retval;
+}
+
+static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg ("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	err ("No hardware tests are defined for this driver");
+	retval = -ENODEV;
+
+	/* Or you can specify a test if you want to */
+	
+	return retval;
+}
+
+static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
+
+	/*
+	 * Fill in logic to get the current power status of the specific
+	 * slot and store it in the *value location.
+	 */
+
+	return retval;
+}
+
+static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
+
+	/*
+	 * Fill in logic to get the current attention status of the specific
+	 * slot and store it in the *value location.
+	 */
+
+	return retval;
+}
+
+static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
+
+	/*
+	 * Fill in logic to get the current latch status of the specific
+	 * slot and store it in the *value location.
+	 */
+
+	return retval;
+}
+
+static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	int retval = 0;
+	
+	if (slot == NULL)
+		return -ENODEV;
+	
+	dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name);
+
+	/*
+	 * Fill in logic to get the current adapter status of the specific
+	 * slot and store it in the *value location.
+	 */
+
+	return retval;
+}
+
+#define SLOT_NAME_SIZE	10
+static void make_slot_name (struct slot *slot)
+{
+	/*
+	 * Stupid way to make a filename out of the slot name.
+	 * replace this if your hardware provides a better way to name slots.
+	 */
+	snprintf (slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d", slot->number);
+}
+
+static int init_slots (void)
+{
+	struct slot *slot;
+	struct hotplug_slot *hotplug_slot;
+	struct hotplug_slot_info *info;
+	char *name;
+	int retval = 0;
+	int i;
+
+	/*
+	 * Create a structure for each slot, and register that slot
+	 * with the pci_hotplug subsystem.
+	 */
+	for (i = 0; i < num_slots; ++i) {
+		slot = kmalloc (sizeof (struct slot), GFP_KERNEL);
+		if (!slot)
+			return -ENOMEM;
+		memset(slot, 0, sizeof(struct slot));
+
+		hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
+		if (!hotplug_slot) {
+			kfree (slot);
+			return -ENOMEM;
+		}
+		memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
+		slot->hotplug_slot = hotplug_slot;
+
+		info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+		if (!info) {
+			kfree (hotplug_slot);
+			kfree (slot);
+			return -ENOMEM;
+		}
+		memset(info, 0, sizeof (struct hotplug_slot_info));
+		hotplug_slot->info = info;
+
+		name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
+		if (!name) {
+			kfree (info);
+			kfree (hotplug_slot);
+			kfree (slot);
+			return -ENOMEM;
+		}
+		hotplug_slot->name = name;
+
+		slot->magic = SLOT_MAGIC;
+		slot->number = i;
+
+		hotplug_slot->private = slot;
+		make_slot_name (slot);
+		hotplug_slot->ops = &skel_hotplug_slot_ops;
+		
+		/*
+		 * Initilize the slot info structure with some known
+		 * good values.
+		 */
+		info->power_status = get_skel_power_status(slot);
+		info->attention_status = get_skel_attention_status(slot);
+		info->latch_status = get_skel_latch_status(slot);
+		info->adapter_status = get_skel_adapter_status(slot);
+		
+		dbg ("registering slot %d\n", i);
+		retval = pci_hp_register (slot->hotplug_slot);
+		if (retval) {
+			err ("pci_hp_register failed with error %d\n", retval);
+			kfree (info);
+			kfree (name);
+			kfree (hotplug_slot);
+			kfree (slot);
+			return retval;
+		}
+
+		/* add slot to our internal list */
+		list_add (&slot->slot_list, &slot_list);
+	}
+
+	return retval;
+}
+		
+static void cleanup_slots (void)
+{
+	struct list_head *tmp;
+	struct slot *slot;
+
+	/*
+	 * Unregister all of our slots with the pci_hotplug subsystem,
+	 * and free up all memory that we had allocated.
+	 */
+	list_for_each (tmp, &slot_list) {
+		slot = list_entry (tmp, struct slot, slot_list);
+		list_del (&slot->slot_list);
+		pci_hp_deregister (slot->hotplug_slot);
+		kfree (slot->hotplug_slot->info);
+		kfree (slot->hotplug_slot->name);
+		kfree (slot->hotplug_slot);
+		kfree (slot);
+	}
+
+	return;
+}
+		
+static int __init pcihp_skel_init(void)
+{
+	int retval;
+
+	/*
+	 * Do specific initialization stuff for your driver here
+	 * Like initilizing your controller hardware (if any) and
+	 * determining the number of slots you have in the system
+	 * right now.
+	 */
+	num_slots = 5;
+
+	retval = init_slots();
+	if (retval)
+		return retval;
+
+	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
+	return 0;
+}
+
+static void __exit pcihp_skel_exit(void)
+{
+	/*
+	 * Clean everything up.
+	 */
+	cleanup_slots();
+}
+
+module_init(pcihp_skel_init);
+module_exit(pcihp_skel_exit);
+
diff -urN linux-2.5.70-bk9/drivers/pci/hotplug.c linux-2.5.70-bk10/drivers/pci/hotplug.c
--- linux-2.5.70-bk9/drivers/pci/hotplug.c	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/hotplug.c	2003-06-05 04:41:36.000000000 -0700
@@ -190,9 +190,7 @@
 	list_del(&dev->bus_list);
 	list_del(&dev->global_list);
 	pci_free_resources(dev);
-#ifdef CONFIG_PROC_FS
 	pci_proc_detach_device(dev);
-#endif
 	return 0;
 }
 EXPORT_SYMBOL(pci_remove_device_safe);
@@ -237,10 +235,7 @@
 		struct pci_bus *b = dev->subordinate;
 
 		pci_remove_behind_bridge(dev);
-
-#ifdef CONFIG_PROC_FS
 		pci_proc_detach_bus(b);
-#endif
 
 		list_del(&b->node);
 		kfree(b);
@@ -251,10 +246,7 @@
 	list_del(&dev->bus_list);
 	list_del(&dev->global_list);
 	pci_free_resources(dev);
-#ifdef CONFIG_PROC_FS
 	pci_proc_detach_device(dev);
-#endif
-
 	pci_put_dev(dev);
 }
 
diff -urN linux-2.5.70-bk9/drivers/pci/pci-driver.c linux-2.5.70-bk10/drivers/pci/pci-driver.c
--- linux-2.5.70-bk9/drivers/pci/pci-driver.c	2003-05-26 18:00:44.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/pci-driver.c	2003-06-05 04:41:36.000000000 -0700
@@ -138,10 +138,11 @@
 
 	drv = to_pci_driver(dev->driver);
 	pci_dev = to_pci_dev(dev);
-	if (get_device(dev)) {
-		error = __pci_device_probe(drv, pci_dev);
-		put_device(dev);
-	}
+	pci_get_dev(pci_dev);
+	error = __pci_device_probe(drv, pci_dev);
+	if (error)
+		pci_put_dev(pci_dev);
+
 	return error;
 }
 
@@ -155,6 +156,7 @@
 			drv->remove(pci_dev);
 		pci_dev->driver = NULL;
 	}
+	pci_put_dev(pci_dev);
 	return 0;
 }
 
@@ -235,7 +237,7 @@
 		driver_data : 0UL;
 
 	spin_lock(&pdrv->dynids.lock);
-	list_add(&pdrv->dynids.list, &dynid->node);
+	list_add_tail(&pdrv->dynids.list, &dynid->node);
 	spin_unlock(&pdrv->dynids.lock);
 
 	bus = get_bus(pdrv->driver.bus);
@@ -315,6 +317,22 @@
 	INIT_LIST_HEAD(&dynids->list);
 }
 
+static void
+pci_free_dynids(struct pci_driver *drv)
+{
+	struct list_head *pos, *n;
+	struct dynid *dynid;
+
+	spin_lock(&drv->dynids.lock);
+	list_for_each_safe(pos, n, &drv->dynids.list) {
+		dynid = list_entry(pos, struct dynid, node);
+		list_del(&dynid->node);
+		kfree(dynid);
+	}
+	spin_unlock(&drv->dynids.lock);
+}
+
+
 /**
  * pci_register_driver - register a new pci driver
  * @drv: the driver structure to register
@@ -363,6 +381,7 @@
 pci_unregister_driver(struct pci_driver *drv)
 {
 	driver_unregister(&drv->driver);
+	pci_free_dynids(drv);
 }
 
 static struct pci_driver pci_compat_driver = {
diff -urN linux-2.5.70-bk9/drivers/pci/pci.c linux-2.5.70-bk10/drivers/pci/pci.c
--- linux-2.5.70-bk9/drivers/pci/pci.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/pci.c	2003-06-05 04:41:36.000000000 -0700
@@ -714,9 +714,9 @@
      
 static int __devinit pci_init(void)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_fixup_device(PCI_FIXUP_FINAL, dev);
 	}
 	return 0;
diff -urN linux-2.5.70-bk9/drivers/pci/pci.h linux-2.5.70-bk10/drivers/pci/pci.h
--- linux-2.5.70-bk9/drivers/pci/pci.h	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/pci.h	2003-06-05 04:41:36.000000000 -0700
@@ -3,3 +3,59 @@
 extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
 			 char *buffer, int buffer_size);
 extern void pci_create_sysfs_dev_files(struct pci_dev *pdev);
+extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
+				  unsigned long size, unsigned long align,
+				  unsigned long min, unsigned int type_mask,
+				  void (*alignf)(void *, struct resource *,
+					  	 unsigned long, unsigned long),
+				  void *alignf_data);
+/* PCI /proc functions */
+#ifdef CONFIG_PROC_FS
+extern int pci_proc_attach_device(struct pci_dev *dev);
+extern int pci_proc_detach_device(struct pci_dev *dev);
+extern int pci_proc_attach_bus(struct pci_bus *bus);
+extern int pci_proc_detach_bus(struct pci_bus *bus);
+#else
+static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; }
+static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; }
+static inline int pci_proc_attach_bus(struct pci_bus *bus) { return 0; }
+static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
+#endif
+
+/* Functions for PCI Hotplug drivers to use */
+extern struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
+extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
+extern void pci_remove_bus_device(struct pci_dev *dev);
+extern int pci_remove_device_safe(struct pci_dev *dev);
+extern unsigned char pci_max_busnr(void);
+extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
+extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
+extern struct pci_bus *pci_find_bus(unsigned char busnr);
+
+struct pci_dev_wrapped {
+	struct pci_dev	*dev;
+	void		*data;
+};
+
+struct pci_bus_wrapped {
+	struct pci_bus	*bus;
+	void		*data;
+};
+
+struct pci_visit {
+	int (* pre_visit_pci_bus)	(struct pci_bus_wrapped *,
+					 struct pci_dev_wrapped *);
+	int (* post_visit_pci_bus)	(struct pci_bus_wrapped *,
+					 struct pci_dev_wrapped *);
+
+	int (* pre_visit_pci_dev)	(struct pci_dev_wrapped *,
+					 struct pci_bus_wrapped *);
+	int (* visit_pci_dev)		(struct pci_dev_wrapped *,
+					 struct pci_bus_wrapped *);
+	int (* post_visit_pci_dev)	(struct pci_dev_wrapped *,
+					 struct pci_bus_wrapped *);
+};
+
+extern int pci_visit_dev(struct pci_visit *fn,
+			 struct pci_dev_wrapped *wrapped_dev,
+			 struct pci_bus_wrapped *wrapped_parent);
diff -urN linux-2.5.70-bk9/drivers/pci/pool.c linux-2.5.70-bk10/drivers/pci/pool.c
--- linux-2.5.70-bk9/drivers/pci/pool.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/pool.c	2003-06-05 04:41:36.000000000 -0700
@@ -31,7 +31,7 @@
 #define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
 #define	POOL_POISON_BYTE	0xa7
 
-DECLARE_MUTEX (pools_lock);
+static DECLARE_MUTEX (pools_lock);
 
 static ssize_t
 show_pools (struct device *dev, char *buf)
diff -urN linux-2.5.70-bk9/drivers/pci/probe.c linux-2.5.70-bk10/drivers/pci/probe.c
--- linux-2.5.70-bk9/drivers/pci/probe.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/probe.c	2003-06-05 04:41:36.000000000 -0700
@@ -396,7 +396,7 @@
  * Returns 0 on success and -1 if unknown type of device (not normal, bridge
  * or CardBus).
  */
-int pci_setup_device(struct pci_dev * dev)
+static int pci_setup_device(struct pci_dev * dev)
 {
 	u32 class;
 
@@ -642,7 +642,7 @@
 	return 0;
 }
 
-struct pci_bus * __devinit pci_alloc_primary_bus_parented(struct device *parent, int bus)
+static struct pci_bus * __devinit pci_alloc_primary_bus_parented(struct device *parent, int bus)
 {
 	struct pci_bus *b;
 
@@ -693,7 +693,6 @@
 EXPORT_SYMBOL(pci_root_buses);
 
 #ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pci_setup_device);
 EXPORT_SYMBOL(pci_add_new_bus);
 EXPORT_SYMBOL(pci_do_scan_bus);
 EXPORT_SYMBOL(pci_scan_slot);
diff -urN linux-2.5.70-bk9/drivers/pci/proc.c linux-2.5.70-bk10/drivers/pci/proc.c
--- linux-2.5.70-bk9/drivers/pci/proc.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/proc.c	2003-06-05 04:41:36.000000000 -0700
@@ -581,13 +581,13 @@
 {
 	if (pci_present()) {
 		struct proc_dir_entry *entry;
-		struct pci_dev *dev;
+		struct pci_dev *dev = NULL;
 		proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
 		entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
 		if (entry)
 			entry->proc_fops = &proc_bus_pci_dev_operations;
 		proc_initialized = 1;
-		pci_for_each_dev(dev) {
+		while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 			pci_proc_attach_device(dev);
 		}
 		legacy_proc_init();
@@ -599,7 +599,6 @@
 
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pci_proc_attach_device);
-EXPORT_SYMBOL(pci_proc_detach_device);
 EXPORT_SYMBOL(pci_proc_attach_bus);
 EXPORT_SYMBOL(pci_proc_detach_bus);
 EXPORT_SYMBOL(proc_bus_pci_dir);
diff -urN linux-2.5.70-bk9/drivers/pci/search.c linux-2.5.70-bk10/drivers/pci/search.c
--- linux-2.5.70-bk9/drivers/pci/search.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/search.c	2003-06-05 04:41:36.000000000 -0700
@@ -55,9 +55,9 @@
 struct pci_dev *
 pci_find_slot(unsigned int bus, unsigned int devfn)
 {
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		if (dev->bus->number == bus && dev->devfn == devfn)
 			return dev;
 	}
diff -urN linux-2.5.70-bk9/drivers/pci/setup-irq.c linux-2.5.70-bk10/drivers/pci/setup-irq.c
--- linux-2.5.70-bk9/drivers/pci/setup-irq.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/setup-irq.c	2003-06-05 04:41:36.000000000 -0700
@@ -64,8 +64,8 @@
 pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(struct pci_dev *, u8, u8))
 {
-	struct pci_dev *dev;
-	pci_for_each_dev(dev) {
+	struct pci_dev *dev = NULL;
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pdev_fixup_irq(dev, swizzle, map_irq);
 	}
 }
diff -urN linux-2.5.70-bk9/drivers/pci/setup-res.c linux-2.5.70-bk10/drivers/pci/setup-res.c
--- linux-2.5.70-bk9/drivers/pci/setup-res.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pci/setup-res.c	2003-06-05 04:41:36.000000000 -0700
@@ -23,7 +23,7 @@
 #include <linux/ioport.h>
 #include <linux/cache.h>
 #include <linux/slab.h>
-
+#include "pci.h"
 
 #define DEBUG_CONFIG 0
 #if DEBUG_CONFIG
diff -urN linux-2.5.70-bk9/drivers/pnp/pnpbios/proc.c linux-2.5.70-bk10/drivers/pnp/pnpbios/proc.c
--- linux-2.5.70-bk9/drivers/pnp/pnpbios/proc.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pnp/pnpbios/proc.c	2003-06-05 04:41:36.000000000 -0700
@@ -29,6 +29,8 @@
 #include <linux/pnpbios.h>
 #include <linux/init.h>
 
+#include <asm/uaccess.h>
+
 static struct proc_dir_entry *proc_pnp = NULL;
 static struct proc_dir_entry *proc_pnp_boot = NULL;
 
@@ -178,18 +180,31 @@
 	struct pnp_bios_node *node;
 	int boot = (long)data >> 8;
 	u8 nodenum = (long)data;
+	int ret = count;
 
 	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
-	if (!node) return -ENOMEM;
-	if ( pnp_bios_get_dev_node(&nodenum, boot, node) )
-		return -EIO;
-	if (count != node->size - sizeof(struct pnp_bios_node))
-		return -EINVAL;
-	memcpy(node->data, buf, count);
-	if (pnp_bios_set_dev_node(node->handle, boot, node) != 0)
-	    return -EINVAL;
+	if (!node)
+		return -ENOMEM;
+	if (pnp_bios_get_dev_node(&nodenum, boot, node)) {
+		ret = -EIO;
+		goto out;
+	}
+	if (count != node->size - sizeof(struct pnp_bios_node)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (copy_from_user(node->data, buf, count)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	if (pnp_bios_set_dev_node(node->handle, boot, node) != 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = count;
+out:
 	kfree(node);
-	return count;
+	return ret;
 }
 
 int pnpbios_interface_attach_device(struct pnp_bios_node * node)
diff -urN linux-2.5.70-bk9/drivers/pnp/resource.c linux-2.5.70-bk10/drivers/pnp/resource.c
--- linux-2.5.70-bk9/drivers/pnp/resource.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/drivers/pnp/resource.c	2003-06-05 04:41:36.000000000 -0700
@@ -455,8 +455,8 @@
 #ifdef CONFIG_PCI
 	/* check if the resource is being used by a pci device */
 	if (!pnp_skip_pci_scan) {
-		struct pci_dev * pci;
-		pci_for_each_dev(pci) {
+		struct pci_dev * pci = NULL;
+		while ((pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci)) != NULL) {
 			if (pci->irq == *irq)
 				return CONFLICT_TYPE_PCI;
 		}
diff -urN linux-2.5.70-bk9/drivers/video/pm2fb.c linux-2.5.70-bk10/drivers/video/pm2fb.c
--- linux-2.5.70-bk9/drivers/video/pm2fb.c	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk10/drivers/video/pm2fb.c	2003-06-05 04:41:37.000000000 -0700
@@ -1178,7 +1178,7 @@
 
 static int __init pm2pci_detect(struct pm2fb_info* p) {
 	struct pm2pci_par* pci=&p->board_par.pci;
-	struct pci_dev* dev;
+	struct pci_dev* dev = NULL;
 	int i;
 	unsigned char* m;
 #ifdef __sparc__
@@ -1192,7 +1192,7 @@
 	}
 	DPRINTK("scanning PCI bus for known chipsets...\n");
 
-	pci_for_each_dev(dev) {
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		for (i = 0; pm2pci_cards[i].vendor; i++)
 			if (pm2pci_cards[i].vendor == dev->vendor &&
 			    pm2pci_cards[i].device == dev->device) {
diff -urN linux-2.5.70-bk9/drivers/video/sa1100fb.c linux-2.5.70-bk10/drivers/video/sa1100fb.c
--- linux-2.5.70-bk9/drivers/video/sa1100fb.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk10/drivers/video/sa1100fb.c	2003-06-05 04:41:37.000000000 -0700
@@ -1753,25 +1753,7 @@
 	return fbi;
 }
 
-static struct device_driver sa1100fb_driver = {
-	.name		= "sa1100fb",
-	.bus		= &system_bus_type,
-	.suspend	= sa1100fb_suspend,
-	.resume		= sa1100fb_resume,
-};
-
-static struct sys_device sa1100fb_dev = {
-	.name	= "LCD",
-	.id	= 0,
-	.root	= NULL,
-	.dev	= {
-		.name	= "Intel Corporation SA11x0 [LCD]",
-		.bus_id	= "b0100000",
-		.driver	= &sa1100fb_driver,
-	},
-};
-
-int __init sa1100fb_init(void)
+static int __init sa1100fb_probe(struct device *dev)
 {
 	struct sa1100fb_info *fbi;
 	int ret;
@@ -1779,16 +1761,11 @@
 	if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
 		return -EBUSY;
 
-	driver_register(&sa1100fb_driver);
-	sys_device_register(&sa1100fb_dev);
-
 	fbi = sa1100fb_init_fbinfo();
 	ret = -ENOMEM;
 	if (!fbi)
 		goto failed;
 
-	dev_set_drvdata(&sa1100fb_dev.dev, fbi);
-
 	/* Initialize video memory */
 	ret = sa1100fb_map_video_memory(fbi);
 	if (ret)
@@ -1822,6 +1799,8 @@
 	 */
 	sa1100fb_check_var(&fbi->fb.var, &fbi->fb);
 
+	dev_set_drvdata(dev, fbi);
+
 	ret = register_framebuffer(&fbi->fb);
 	if (ret < 0)
 		goto failed;
@@ -1839,14 +1818,26 @@
 	return 0;
 
 failed:
-	sys_device_unregister(&sa1100fb_dev);
-	driver_unregister(&sa1100fb_driver);
+	dev_set_drvdata(dev, NULL);
 	if (fbi)
 		kfree(fbi);
 	release_mem_region(0xb0100000, 0x10000);
 	return ret;
 }
 
+static struct device_driver sa1100fb_driver = {
+	.name		= "sa11x0-fb",
+	.bus		= &platform_bus_type,
+	.probe		= sa1100fb_probe,
+	.suspend	= sa1100fb_suspend,
+	.resume		= sa1100fb_resume,
+};
+
+int __init sa1100fb_init(void)
+{
+	return driver_register(&sa1100fb_driver);
+}
+
 int __init sa1100fb_setup(char *options)
 {
 #if 0
diff -urN linux-2.5.70-bk9/drivers/video/sis/sis_main.c linux-2.5.70-bk10/drivers/video/sis/sis_main.c
--- linux-2.5.70-bk9/drivers/video/sis/sis_main.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/drivers/video/sis/sis_main.c	2003-06-05 04:41:37.000000000 -0700
@@ -134,15 +134,9 @@
 
 	if (!init) {
 		init = TRUE;
-		pci_for_each_dev(pdev) {
-			DPRINTK("sisfb: Current: 0x%x, target: 0x%x\n",
-			         pdev->device, ivideo.chip_id);
-			if ((pdev->vendor == PCI_VENDOR_ID_SI)
-			           && (pdev->device == ivideo.chip_id)) {
-				valid_pdev = TRUE;
-				break;
-			}
-		}
+		pdev = pci_find_device(PCI_VENDOR_ID_SI, ivideo.chip_id, pdev);
+		if (pdev)
+			valid_pdev = TRUE;
 	}
 
 	if (!valid_pdev) {
@@ -192,15 +186,9 @@
 			break;
 		}
 
-		pci_for_each_dev(pdev) {
-			DPRINTK("Current: 0x%x, target: 0x%x\n",
-					pdev->device, ivideo.chip_id);
-			if ((pdev->vendor == PCI_VENDOR_ID_SI)
-					&& (pdev->device == nbridge_id)) {
-				valid_pdev = TRUE;
-				break;
-			}
-		}
+		pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
+		if (pdev)
+			valid_pdev = TRUE;
 	}
 
 	if (!valid_pdev) {
@@ -2117,40 +2105,36 @@
 
 	} else {		/* 540, 630, 730 */
 
-		pci_for_each_dev(pdev) {
-
-			if ((pdev->vendor == PCI_VENDOR_ID_SI) 
-				       && (pdev->device == nbridge_id)) {
-				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
-				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
-				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
-				pdev_valid = 1;
-	
-				reg = SIS_DATA_BUS_64 << 6;
-				switch (pci_data) {
-				   case BRI_DRAM_SIZE_2MB:
-					reg |= SIS_DRAM_SIZE_2MB;
-					break;
-				   case BRI_DRAM_SIZE_4MB:
-					reg |= SIS_DRAM_SIZE_4MB;
-					break;
-				   case BRI_DRAM_SIZE_8MB:
-					reg |= SIS_DRAM_SIZE_8MB;
-					break;
-				   case BRI_DRAM_SIZE_16MB:
-					reg |= SIS_DRAM_SIZE_16MB;
-					break;
-				   case BRI_DRAM_SIZE_32MB:
-					reg |= SIS_DRAM_SIZE_32MB;
-					break;
-				   case BRI_DRAM_SIZE_64MB:
-					reg |= SIS_DRAM_SIZE_64MB;
-					break;
-				}
-				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+		pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
+		if (pdev) {
+			pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
+			pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
+			ivideo.video_size = (unsigned int)(1 << (pci_data+21));
+			pdev_valid = 1;
+
+			reg = SIS_DATA_BUS_64 << 6;
+			switch (pci_data) {
+			   case BRI_DRAM_SIZE_2MB:
+				reg |= SIS_DRAM_SIZE_2MB;
 				break;
-			}  
-		}   
+			   case BRI_DRAM_SIZE_4MB:
+				reg |= SIS_DRAM_SIZE_4MB;
+				break;
+			   case BRI_DRAM_SIZE_8MB:
+				reg |= SIS_DRAM_SIZE_8MB;
+				break;
+			   case BRI_DRAM_SIZE_16MB:
+				reg |= SIS_DRAM_SIZE_16MB;
+				break;
+			   case BRI_DRAM_SIZE_32MB:
+				reg |= SIS_DRAM_SIZE_32MB;
+				break;
+			   case BRI_DRAM_SIZE_64MB:
+				reg |= SIS_DRAM_SIZE_64MB;
+				break;
+			}
+			outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+		}
 	
 		if (!pdev_valid)  return -1;
 	}
@@ -2334,12 +2318,10 @@
 
 #ifdef LINUXBIOS
 
-		pci_for_each_dev(pdev) {
-
-			if ( (pdev->vendor == PCI_VENDOR_ID_SI)
-				&& ( (pdev->device == PCI_DEVICE_ID_SI_550) ||
-				     (pdev->device == PCI_DEVICE_ID_SI_650) ||
-				     (pdev->device == PCI_DEVICE_ID_SI_740))) {
+		while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev)) != NULL) {
+			if ((pdev->device == PCI_DEVICE_ID_SI_550) ||
+			     (pdev->device == PCI_DEVICE_ID_SI_650) ||
+			     (pdev->device == PCI_DEVICE_ID_SI_740)) {
 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
 				                     &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
@@ -2408,11 +2390,7 @@
 			       "now reading from PCI config\n");
 			pdev_valid = 0;
 
-			pci_for_each_dev(pdev) {
-
-			   if ( (pdev->vendor == PCI_VENDOR_ID_SI)
-			         && (pdev->device == PCI_DEVICE_ID_SI_550) ) {
-
+			while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550, pdev)) != NULL) {
 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
 				                     &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
@@ -2437,7 +2415,6 @@
 					return -1;
 				}
 				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-			   }
 			}
 			if (!pdev_valid) {
 				printk(KERN_INFO "sisfb: Total confusion - No SiS PCI VGA device found?!\n");
@@ -3785,7 +3762,7 @@
 	memset(&sis_disp, 0, sizeof(sis_disp));
 #endif	
 
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		for (b = sisdev_list; b->vendor; b++) {
 			if ((b->vendor == pdev->vendor)
 			    && (b->device == pdev->device)) {
diff -urN linux-2.5.70-bk9/fs/aio.c linux-2.5.70-bk10/fs/aio.c
--- linux-2.5.70-bk9/fs/aio.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/fs/aio.c	2003-06-05 04:41:37.000000000 -0700
@@ -252,7 +252,7 @@
 	return ctx;
 
 out_cleanup:
-	atomic_sub(ctx->max_reqs, &aio_nr);	/* undone by __put_ioctx */
+	atomic_sub(ctx->max_reqs, &aio_nr);
 	ctx->max_reqs = 0;	/* prevent __put_ioctx from sub'ing aio_nr */
 	__put_ioctx(ctx);
 	return ERR_PTR(-EAGAIN);
@@ -405,9 +405,6 @@
 		list_add(&req->ki_list, &ctx->active_reqs);
 		get_ioctx(ctx);
 		ctx->reqs_active++;
-		req->ki_user_obj = NULL;
-		req->ki_ctx = ctx;
-		req->ki_users = 1;
 		okay = 1;
 	}
 	kunmap_atomic(ring, KM_USER0);
@@ -949,7 +946,7 @@
 		goto out;
 
 	ret = -EINVAL;
-	if (unlikely(ctx || !nr_events || (int)nr_events < 0)) {
+	if (unlikely(ctx || (int)nr_events <= 0)) {
 		pr_debug("EINVAL: io_setup: ctx or nr_events > max\n");
 		goto out;
 	}
@@ -984,9 +981,7 @@
 	return -EINVAL;
 }
 
-int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb *user_iocb,
-				  struct iocb *iocb));
-int io_submit_one(struct kioctx *ctx, struct iocb *user_iocb,
+int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
 			 struct iocb *iocb)
 {
 	struct kiocb *req;
@@ -1098,7 +1093,7 @@
  *	fail with -ENOSYS if not implemented.
  */
 asmlinkage long sys_io_submit(aio_context_t ctx_id, long nr,
-			      struct iocb **iocbpp)
+			      struct iocb __user **iocbpp)
 {
 	struct kioctx *ctx;
 	long ret = 0;
@@ -1116,8 +1111,13 @@
 		return -EINVAL;
 	}
 
+	/*
+	 * AKPM: should this return a partial result if some of the IOs were
+	 * successfully submitted?
+	 */
 	for (i=0; i<nr; i++) {
-		struct iocb *user_iocb, tmp;
+		struct iocb __user *user_iocb;
+		struct iocb tmp;
 
 		if (unlikely(__get_user(user_iocb, iocbpp + i))) {
 			ret = -EFAULT;
diff -urN linux-2.5.70-bk9/fs/buffer.c linux-2.5.70-bk10/fs/buffer.c
--- linux-2.5.70-bk9/fs/buffer.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/fs/buffer.c	2003-06-05 04:41:37.000000000 -0700
@@ -822,9 +822,6 @@
 		goto out;
 	}
 
-	if (!PageUptodate(page))
-		buffer_error();
-
 	spin_lock(&mapping->private_lock);
 	if (page_has_buffers(page)) {
 		struct buffer_head *head = page_buffers(page);
diff -urN linux-2.5.70-bk9/fs/devfs/base.c linux-2.5.70-bk10/fs/devfs/base.c
--- linux-2.5.70-bk9/fs/devfs/base.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk10/fs/devfs/base.c	2003-06-05 04:41:37.000000000 -0700
@@ -1710,6 +1710,13 @@
 	if (n < 64 && buf[0]) {
 		devfs_handle_t de = _devfs_find_entry(NULL, buf, 0);
 
+		if (!de) {
+			printk(KERN_ERR "%s: %s not found, cannot remove\n",
+			       __FUNCTION__, buf);
+			dump_stack();
+			return;
+		}
+
 		write_lock(&de->parent->u.dir.lock);
 		_devfs_unregister(de->parent, de);
 		devfs_put(de);
diff -urN linux-2.5.70-bk9/fs/hugetlbfs/inode.c linux-2.5.70-bk10/fs/hugetlbfs/inode.c
--- linux-2.5.70-bk9/fs/hugetlbfs/inode.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/fs/hugetlbfs/inode.c	2003-06-05 04:41:37.000000000 -0700
@@ -48,9 +48,6 @@
 	loff_t len;
 	int ret;
 
-	if (!capable(CAP_IPC_LOCK))
-		return -EPERM;
-
 	if (vma->vm_start & ~HPAGE_MASK)
 		return -EINVAL;
 
@@ -231,6 +228,7 @@
 	spin_unlock(&inode_lock);
 	if (inode->i_data.nrpages)
 		truncate_hugepages(&inode->i_data, 0);
+
 	clear_inode(inode);
 	destroy_inode(inode);
 }
@@ -317,7 +315,6 @@
 	struct inode *inode = dentry->d_inode;
 	int error;
 	unsigned int ia_valid = attr->ia_valid;
-	unsigned long dn_mask;
 
 	BUG_ON(!inode);
 
@@ -335,26 +332,21 @@
 		if (error)
 			goto out;
 		attr->ia_valid &= ~ATTR_SIZE;
-		error = inode_setattr(inode, attr);
 	}
-	if (error)
-		goto out;
-	dn_mask = setattr_mask(ia_valid);
-	if (dn_mask)
-		dnotify_parent(dentry, dn_mask);
+	error = inode_setattr(inode, attr);
 out:
 	return error;
 }
 
-static struct inode *hugetlbfs_get_inode(struct super_block *sb,
-					int mode, dev_t dev)
+static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, 
+					gid_t gid, int mode, dev_t dev)
 {
 	struct inode * inode = new_inode(sb);
 
 	if (inode) {
 		inode->i_mode = mode;
-		inode->i_uid = current->fsuid;
-		inode->i_gid = current->fsgid;
+		inode->i_uid = uid;
+		inode->i_gid = gid;
 		inode->i_blksize = PAGE_CACHE_SIZE;
 		inode->i_blocks = 0;
 		inode->i_rdev = NODEV;
@@ -391,7 +383,8 @@
 static int hugetlbfs_mknod(struct inode *dir,
 			struct dentry *dentry, int mode, dev_t dev)
 {
-	struct inode * inode = hugetlbfs_get_inode(dir->i_sb, mode, dev);
+	struct inode * inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, 
+					current->fsgid, mode, dev);
 	int error = -ENOSPC;
 
 	if (inode) {
@@ -421,7 +414,8 @@
 	struct inode *inode;
 	int error = -ENOSPC;
 
-	inode = hugetlbfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
+	inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
+					current->fsgid, S_IFLNK|S_IRWXUGO, 0);
 	if (inode) {
 		int l = strlen(symname)+1;
 		error = page_symlink(inode, symname, l);
@@ -478,16 +472,68 @@
 };
 
 static int
-hugetlbfs_fill_super(struct super_block * sb, void * data, int silent)
+hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
+{
+	char *opt, *value;
+	int ret = 0;
+
+	if (!options)
+		goto out;
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+
+		value = strchr(opt, '=');
+		if (!value || !*value) {
+			ret = -EINVAL;
+			goto out;
+		} else {
+			*value++ = '\0';
+		}
+
+		if (!strcmp(opt, "uid"))
+			pconfig->uid = simple_strtoul(value, &value, 0);
+		else if (!strcmp(opt, "gid"))
+			pconfig->gid = simple_strtoul(value, &value, 0);
+		else if (!strcmp(opt, "mode"))
+			pconfig->mode = simple_strtoul(value,&value,0) & 0777U;
+		else {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (*value) {
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+	return 0;
+out:
+	pconfig->uid = current->fsuid;
+	pconfig->gid = current->fsgid;
+	pconfig->mode = 0755;
+	return ret;
+}
+
+static int
+hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode * inode;
 	struct dentry * root;
+	int ret;
+	struct hugetlbfs_config config;
 
+	ret = hugetlbfs_parse_options(data, &config);
+	if (ret) {
+		printk("hugetlbfs: invalid mount options: %s.\n", data);
+		return ret;
+	}
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = HUGETLBFS_MAGIC;
 	sb->s_op = &hugetlbfs_ops;
-	inode = hugetlbfs_get_inode(sb, S_IFDIR | 0755, 0);
+	inode = hugetlbfs_get_inode(sb, config.uid, config.gid,
+					S_IFDIR | config.mode, 0);
 	if (!inode)
 		return -ENOMEM;
 
@@ -548,7 +594,8 @@
 		goto out_dentry;
 
 	error = -ENOSPC;
-	inode = hugetlbfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
+	inode = hugetlbfs_get_inode(root->d_sb, current->fsuid,
+				current->fsgid, S_IFREG | S_IRWXUGO, 0);
 	if (!inode)
 		goto out_file;
 
diff -urN linux-2.5.70-bk9/fs/jbd/journal.c linux-2.5.70-bk10/fs/jbd/journal.c
--- linux-2.5.70-bk9/fs/jbd/journal.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/fs/jbd/journal.c	2003-06-05 04:41:37.000000000 -0700
@@ -916,7 +916,7 @@
 		__brelse(bh);
 	}
 
-	fsync_bdev(journal->j_dev);
+	sync_blockdev(journal->j_dev);
 	jbd_debug(1, "JBD: journal cleared.\n");
 
 	/* OK, fill in the initial static fields in the new superblock */
diff -urN linux-2.5.70-bk9/fs/reiserfs/file.c linux-2.5.70-bk10/fs/reiserfs/file.c
--- linux-2.5.70-bk9/fs/reiserfs/file.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk10/fs/reiserfs/file.c	2003-06-05 04:41:37.000000000 -0700
@@ -736,6 +736,7 @@
     struct buffer_head *itembuf=NULL; // Buffer head that contains items that we are going to deal with
     INITIALIZE_PATH(path); // path to item, that we are going to deal with.
     __u32 * item=0; // pointer to item we are going to deal with
+    int item_pos=-1; /* Position in indirect item */
 
 
     if ( num_pages < 1 ) {
@@ -807,7 +808,6 @@
 
     reiserfs_write_lock(inode->i_sb); // We need that for at least search_by_key()
     for ( i = 0; i < num_pages ; i++ ) { 
-	int item_pos=-1; /* Position in indirect item */
 
 	head = page_buffers(prepared_pages[i]);
 	/* For each buffer in the page */
diff -urN linux-2.5.70-bk9/fs/reiserfs/inode.c linux-2.5.70-bk10/fs/reiserfs/inode.c
--- linux-2.5.70-bk9/fs/reiserfs/inode.c	2003-05-26 18:00:28.000000000 -0700
+++ linux-2.5.70-bk10/fs/reiserfs/inode.c	2003-06-05 04:41:37.000000000 -0700
@@ -2109,11 +2109,13 @@
 	 * someone else could have locked them and sent them down the 
 	 * pipe without locking the page
 	 */
+	bh = head ;
 	do {
 	    if (!buffer_uptodate(bh)) {
 	        partial = 1;
 		break;
 	    }
+	    bh = bh->b_this_page;
 	} while(bh != head);
 	if (!partial)
 	    SetPageUptodate(page);
diff -urN linux-2.5.70-bk9/fs/reiserfs/journal.c linux-2.5.70-bk10/fs/reiserfs/journal.c
--- linux-2.5.70-bk9/fs/reiserfs/journal.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/fs/reiserfs/journal.c	2003-06-05 04:41:37.000000000 -0700
@@ -1368,10 +1368,10 @@
 /* compares description block with commit block.  returns 1 if they differ, 0 if they are the same */
 static int journal_compare_desc_commit(struct super_block *p_s_sb, struct reiserfs_journal_desc *desc, 
 			               struct reiserfs_journal_commit *commit) {
-  if (le32_to_cpu(commit->j_trans_id) != le32_to_cpu(desc->j_trans_id) || 
-      le32_to_cpu(commit->j_len) != le32_to_cpu(desc->j_len) || 
-      le32_to_cpu(commit->j_len) > SB_JOURNAL_TRANS_MAX(p_s_sb) || 
-      le32_to_cpu(commit->j_len) <= 0 
+  if (get_commit_trans_id (commit) != get_desc_trans_id (desc) || 
+      get_commit_trans_len (commit) != get_desc_trans_len (desc) || 
+      get_commit_trans_len (commit) > SB_JOURNAL_TRANS_MAX(p_s_sb) || 
+      get_commit_trans_len (commit) <= 0 
   ) {
     return 1 ;
   }
@@ -1391,18 +1391,18 @@
       return 0 ;
 
   desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
-  if (le32_to_cpu(desc->j_len) > 0 && !memcmp(desc->j_magic, JOURNAL_DESC_MAGIC, 8)) {
-    if (oldest_invalid_trans_id && *oldest_invalid_trans_id && le32_to_cpu(desc->j_trans_id) > *oldest_invalid_trans_id) {
+  if (get_desc_trans_len(desc) > 0 && !memcmp(get_journal_desc_magic (d_bh), JOURNAL_DESC_MAGIC, 8)) {
+    if (oldest_invalid_trans_id && *oldest_invalid_trans_id && get_desc_trans_id(desc) > *oldest_invalid_trans_id) {
       reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-986: transaction "
 	              "is valid returning because trans_id %d is greater than "
-		      "oldest_invalid %lu\n", le32_to_cpu(desc->j_trans_id), 
+		      "oldest_invalid %lu\n", get_desc_trans_id(desc), 
 		       *oldest_invalid_trans_id);
       return 0 ;
     }
-    if (newest_mount_id && *newest_mount_id > le32_to_cpu(desc->j_mount_id)) {
+    if (newest_mount_id && *newest_mount_id > get_desc_mount_id (desc)) {
       reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1087: transaction "
                      "is valid returning because mount_id %d is less than "
-		     "newest_mount_id %lu\n", desc->j_mount_id, 
+		     "newest_mount_id %lu\n", get_desc_mount_id (desc), 
 		     *newest_mount_id) ;
       return -1 ;
     }
@@ -1410,7 +1410,7 @@
 
     /* ok, we have a journal description block, lets see if the transaction was valid */
     c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
-		 ((offset + le32_to_cpu(desc->j_len) + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
+		 ((offset + get_desc_trans_len(desc) + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
     if (!c_bh)
       return 0 ;
     commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
@@ -1419,21 +1419,21 @@
                      "journal_transaction_is_valid, commit offset %ld had bad "
 		     "time %d or length %d\n", 
 		     c_bh->b_blocknr -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
-		     le32_to_cpu(commit->j_trans_id), 
-		     le32_to_cpu(commit->j_len));
+		     get_commit_trans_id (commit), 
+		     get_commit_trans_len(commit));
       brelse(c_bh) ;
       if (oldest_invalid_trans_id)
-        *oldest_invalid_trans_id = le32_to_cpu(desc->j_trans_id) ;
+        *oldest_invalid_trans_id = get_desc_trans_id(desc) ;
 	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1004: "
 	               "transaction_is_valid setting oldest invalid trans_id "
-		       "to %d\n", le32_to_cpu(desc->j_trans_id)) ;
+		       "to %d\n", get_desc_trans_id(desc)) ;
       return -1; 
     }
     brelse(c_bh) ;
     reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1006: found valid "
                    "transaction start offset %lu, len %d id %d\n", 
 		   d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-		   le32_to_cpu(desc->j_len), le32_to_cpu(desc->j_trans_id)) ;
+		   get_desc_trans_len(desc), get_desc_trans_id(desc)) ;
     return 1 ;
   } else {
     return 0 ;
@@ -1463,6 +1463,7 @@
   struct buffer_head **real_blocks = NULL ;
   unsigned long trans_offset ;
   int i;
+  int trans_half;
 
   d_bh = journal_bread(p_s_sb, cur_dblock) ;
   if (!d_bh)
@@ -1472,24 +1473,24 @@
   reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1037: "
                  "journal_read_transaction, offset %lu, len %d mount_id %d\n", 
 		 d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-		 le32_to_cpu(desc->j_len), le32_to_cpu(desc->j_mount_id)) ;
-  if (le32_to_cpu(desc->j_trans_id) < oldest_trans_id) {
+		 get_desc_trans_len(desc), get_desc_mount_id(desc)) ;
+  if (get_desc_trans_id(desc) < oldest_trans_id) {
     reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1039: "
                    "journal_read_trans skipping because %lu is too old\n", 
 		   cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb)) ;
     brelse(d_bh) ;
     return 1 ;
   }
-  if (le32_to_cpu(desc->j_mount_id) != newest_mount_id) {
+  if (get_desc_mount_id(desc) != newest_mount_id) {
     reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1146: "
                    "journal_read_trans skipping because %d is != "
-		   "newest_mount_id %lu\n", le32_to_cpu(desc->j_mount_id), 
+		   "newest_mount_id %lu\n", get_desc_mount_id(desc), 
 		    newest_mount_id) ;
     brelse(d_bh) ;
     return 1 ;
   }
   c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
-		((trans_offset + le32_to_cpu(desc->j_len) + 1) % 
+		((trans_offset + get_desc_trans_len(desc) + 1) % 
 		 SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
   if (!c_bh) {
     brelse(d_bh) ;
@@ -1500,30 +1501,31 @@
     reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal_read_transaction, "
                    "commit offset %ld had bad time %d or length %d\n", 
 		   c_bh->b_blocknr -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-		   le32_to_cpu(commit->j_trans_id), le32_to_cpu(commit->j_len));
+		   get_commit_trans_id(commit), get_commit_trans_len(commit));
     brelse(c_bh) ;
     brelse(d_bh) ;
     return 1; 
   }
-  trans_id = le32_to_cpu(desc->j_trans_id) ;
+  trans_id = get_desc_trans_id(desc) ;
   /* now we know we've got a good transaction, and it was inside the valid time ranges */
-  log_blocks = reiserfs_kmalloc(le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), GFP_NOFS, p_s_sb) ;
-  real_blocks = reiserfs_kmalloc(le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), GFP_NOFS, p_s_sb) ;
+  log_blocks = reiserfs_kmalloc(get_desc_trans_len(desc) * sizeof(struct buffer_head *), GFP_NOFS, p_s_sb) ;
+  real_blocks = reiserfs_kmalloc(get_desc_trans_len(desc) * sizeof(struct buffer_head *), GFP_NOFS, p_s_sb) ;
   if (!log_blocks  || !real_blocks) {
     brelse(c_bh) ;
     brelse(d_bh) ;
-    reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
-    reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+    reiserfs_kfree(log_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
+    reiserfs_kfree(real_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
     reiserfs_warning("journal-1169: kmalloc failed, unable to mount FS\n") ;
     return -1 ;
   }
   /* get all the buffer heads */
-  for(i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
+  trans_half = journal_trans_half (p_s_sb->s_blocksize) ;
+  for(i = 0 ; i < get_desc_trans_len(desc) ; i++) {
     log_blocks[i] =  journal_getblk(p_s_sb,  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + (trans_offset + 1 + i) % SB_ONDISK_JOURNAL_SIZE(p_s_sb));
-    if (i < JOURNAL_TRANS_HALF) {
+    if (i < trans_half) {
       real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(desc->j_realblock[i])) ;
     } else {
-      real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(commit->j_realblock[i - JOURNAL_TRANS_HALF])) ;
+      real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(commit->j_realblock[i - trans_half])) ;
     }
     /* make sure we don't try to replay onto log or reserved area */
     if (is_block_in_log_or_reserved_area(p_s_sb, real_blocks[i]->b_blocknr)) {
@@ -1532,23 +1534,23 @@
       brelse_array(real_blocks, i) ;
       brelse(c_bh) ;
       brelse(d_bh) ;
-      reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
-      reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(log_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(real_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
       return -1 ;
     }
   }
   /* read in the log blocks, memcpy to the corresponding real block */
-  ll_rw_block(READ, le32_to_cpu(desc->j_len), log_blocks) ;
-  for (i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
+  ll_rw_block(READ, get_desc_trans_len(desc), log_blocks) ;
+  for (i = 0 ; i < get_desc_trans_len(desc) ; i++) {
     wait_on_buffer(log_blocks[i]) ;
     if (!buffer_uptodate(log_blocks[i])) {
       reiserfs_warning("journal-1212: REPLAY FAILURE fsck required! buffer write failed\n") ;
-      brelse_array(log_blocks + i, le32_to_cpu(desc->j_len) - i) ;
-      brelse_array(real_blocks, le32_to_cpu(desc->j_len)) ;
+      brelse_array(log_blocks + i, get_desc_trans_len(desc) - i) ;
+      brelse_array(real_blocks, get_desc_trans_len(desc)) ;
       brelse(c_bh) ;
       brelse(d_bh) ;
-      reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
-      reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(log_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(real_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
       return -1 ;
     }
     memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data, real_blocks[i]->b_size) ;
@@ -1556,24 +1558,24 @@
     brelse(log_blocks[i]) ;
   }
   /* flush out the real blocks */
-  for (i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
+  for (i = 0 ; i < get_desc_trans_len(desc) ; i++) {
     set_buffer_dirty(real_blocks[i]) ;
     ll_rw_block(WRITE, 1, real_blocks + i) ;
   }
-  for (i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
+  for (i = 0 ; i < get_desc_trans_len(desc) ; i++) {
     wait_on_buffer(real_blocks[i]) ; 
     if (!buffer_uptodate(real_blocks[i])) {
       reiserfs_warning("journal-1226: REPLAY FAILURE, fsck required! buffer write failed\n") ;
-      brelse_array(real_blocks + i, le32_to_cpu(desc->j_len) - i) ;
+      brelse_array(real_blocks + i, get_desc_trans_len(desc) - i) ;
       brelse(c_bh) ;
       brelse(d_bh) ;
-      reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
-      reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(log_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
+      reiserfs_kfree(real_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
       return -1 ;
     }
     brelse(real_blocks[i]) ;
   }
-  cur_dblock =  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + ((trans_offset + le32_to_cpu(desc->j_len) + 2) % SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
+  cur_dblock =  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + ((trans_offset + get_desc_trans_len(desc) + 2) % SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
   reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1095: setting journal "
                  "start to offset %ld\n", 
 		 cur_dblock -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb)) ;
@@ -1716,28 +1718,28 @@
     if (ret == 1) {
       desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
       if (oldest_start == 0) { /* init all oldest_ values */
-        oldest_trans_id = le32_to_cpu(desc->j_trans_id) ;
+        oldest_trans_id = get_desc_trans_id(desc) ;
 	oldest_start = d_bh->b_blocknr ;
-	newest_mount_id = le32_to_cpu(desc->j_mount_id) ;
+	newest_mount_id = get_desc_mount_id(desc) ;
 	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1179: Setting "
 	               "oldest_start to offset %lu, trans_id %lu\n", 
 		       oldest_start - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
 		       oldest_trans_id) ;
-      } else if (oldest_trans_id > le32_to_cpu(desc->j_trans_id)) { 
+      } else if (oldest_trans_id > get_desc_trans_id(desc)) { 
         /* one we just read was older */
-        oldest_trans_id = le32_to_cpu(desc->j_trans_id) ;
+        oldest_trans_id = get_desc_trans_id(desc) ;
 	oldest_start = d_bh->b_blocknr ;
 	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1180: Resetting "
 	               "oldest_start to offset %lu, trans_id %lu\n", 
 			oldest_start - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
 			oldest_trans_id) ;
       }
-      if (newest_mount_id < le32_to_cpu(desc->j_mount_id)) {
-        newest_mount_id = le32_to_cpu(desc->j_mount_id) ;
+      if (newest_mount_id < get_desc_mount_id(desc)) {
+        newest_mount_id = get_desc_mount_id(desc) ;
 	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1299: Setting "
-	              "newest_mount_id to %d\n", le32_to_cpu(desc->j_mount_id));
+	              "newest_mount_id to %d\n", get_desc_mount_id(desc));
       }
-      cur_dblock += le32_to_cpu(desc->j_len) + 2 ;
+      cur_dblock += get_desc_trans_len(desc) + 2 ;
     } else {
       cur_dblock++ ;
     }
@@ -1964,13 +1966,6 @@
     struct reiserfs_journal *journal;
     char b[BDEVNAME_SIZE];
 
-    if (sizeof(struct reiserfs_journal_commit) != 4096 ||
-      sizeof(struct reiserfs_journal_desc) != 4096) {
-	printk("journal-1249: commit or desc struct not 4096 %Zd %Zd\n", sizeof(struct reiserfs_journal_commit), 
-        sizeof(struct reiserfs_journal_desc)) ;
-	return 1 ;
-    }
-
     journal = SB_JOURNAL(p_s_sb) = vmalloc(sizeof (struct reiserfs_journal)) ;
     if (!journal) {
 	printk("journal-1256: unable to get memory for journal structure\n") ;
@@ -1989,6 +1984,16 @@
 					     SB_BMAP_NR(p_s_sb) + 1 :
 					     REISERFS_DISK_OFFSET_IN_BYTES / p_s_sb->s_blocksize + 2); 
     
+    /* Sanity check to see is the standard journal fitting withing first bitmap
+       (actual for small blocksizes) */
+    if ( !SB_ONDISK_JOURNAL_DEVICE( p_s_sb ) &&
+         (SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb) > p_s_sb->s_blocksize * 8) ) {
+	printk("journal-1393: journal does not fit for area addressed by first of bitmap blocks. "
+	       "It starts at %u and its size is %u. Block size %ld\n",
+		SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb), SB_ONDISK_JOURNAL_SIZE(p_s_sb), p_s_sb->s_blocksize) ;
+	goto free_and_return;
+    }
+
     if( journal_init_dev( p_s_sb, journal, j_dev_name ) != 0 ) {
       printk( "sh-462: unable to initialize jornal device\n");
       goto free_and_return;
@@ -2105,6 +2110,7 @@
   SB_JOURNAL(p_s_sb)->j_cnode_free = SB_JOURNAL(p_s_sb)->j_cnode_free_list ? num_cnodes : 0 ;
   SB_JOURNAL(p_s_sb)->j_cnode_used = 0 ;
   SB_JOURNAL(p_s_sb)->j_must_wait = 0 ;
+
   init_journal_hash(p_s_sb) ;
   SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap = get_list_bitmap(p_s_sb, SB_JOURNAL_LIST(p_s_sb)) ;
   if (!(SB_JOURNAL_LIST(p_s_sb)[0].j_list_bitmap)) {
@@ -2882,6 +2888,7 @@
   int commit_now = flags & COMMIT_NOW ;
   int wait_on_commit = flags & WAIT ;
   struct reiserfs_super_block *rs ; 
+  int trans_half ;
 
   if (reiserfs_dont_log(th->t_super)) {
     return 0 ;
@@ -2929,16 +2936,16 @@
   d_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start) ; 
   set_buffer_uptodate(d_bh) ;
   desc = (struct reiserfs_journal_desc *)(d_bh)->b_data ;
-  memset(desc, 0, sizeof(struct reiserfs_journal_desc)) ;
-  memcpy(desc->j_magic, JOURNAL_DESC_MAGIC, 8) ;
-  desc->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ;
+  memset(d_bh->b_data, 0, d_bh->b_size) ;
+  memcpy(get_journal_desc_magic (d_bh), JOURNAL_DESC_MAGIC, 8) ;
+  set_desc_trans_id(desc, SB_JOURNAL(p_s_sb)->j_trans_id) ;
 
   /* setup commit block.  Don't write (keep it clean too) this one until after everyone else is written */
   c_bh =  journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
 		 ((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
   commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
-  memset(commit, 0, sizeof(struct reiserfs_journal_commit)) ;
-  commit->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ;
+  memset(c_bh->b_data, 0, c_bh->b_size) ;
+  set_commit_trans_id(commit, SB_JOURNAL(p_s_sb)->j_trans_id) ;
   set_buffer_uptodate(c_bh) ;
 
   /* init this journal list */
@@ -2963,6 +2970,7 @@
   /* for each real block, add it to the journal list hash,
   ** copy into real block index array in the commit or desc block
   */
+  trans_half = journal_trans_half(p_s_sb->s_blocksize) ;
   for (i = 0, cn = SB_JOURNAL(p_s_sb)->j_first ; cn ; cn = cn->next, i++) {
     if (test_bit(BH_JDirty, &cn->bh->b_state) ) {
       jl_cn = get_cnode(p_s_sb) ;
@@ -2990,27 +2998,27 @@
       jl_cn->bh = cn->bh ;
       jl_cn->jlist = SB_JOURNAL_LIST(p_s_sb) + SB_JOURNAL_LIST_INDEX(p_s_sb) ;
       insert_journal_hash(SB_JOURNAL(p_s_sb)->j_list_hash_table, jl_cn) ; 
-      if (i < JOURNAL_TRANS_HALF) {
+      if (i < trans_half) {
 	desc->j_realblock[i] = cpu_to_le32(cn->bh->b_blocknr) ;
       } else {
-	commit->j_realblock[i - JOURNAL_TRANS_HALF] = cpu_to_le32(cn->bh->b_blocknr) ;
+	commit->j_realblock[i - trans_half] = cpu_to_le32(cn->bh->b_blocknr) ;
       }
     } else {
       i-- ;
     }
   }
-
-  desc->j_len = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_len)  ;
-  desc->j_mount_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_mount_id) ;
-  desc->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ;
-  commit->j_len = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_len) ;
+  
+  set_desc_trans_len(desc, SB_JOURNAL(p_s_sb)->j_len) ;
+  set_desc_mount_id(desc, SB_JOURNAL(p_s_sb)->j_mount_id) ;
+  set_desc_trans_id(desc, SB_JOURNAL(p_s_sb)->j_trans_id) ;
+  set_commit_trans_len(commit, SB_JOURNAL(p_s_sb)->j_len);
 
   /* special check in case all buffers in the journal were marked for not logging */
   if (SB_JOURNAL(p_s_sb)->j_len == 0) {
     brelse(d_bh) ;
     brelse(c_bh) ;
     unlock_journal(p_s_sb) ;
-printk("journal-2020: do_journal_end: BAD desc->j_len is ZERO\n") ;
+    printk("journal-2020: do_journal_end: BAD desc->j_len is ZERO\n") ;
     atomic_set(&(SB_JOURNAL(p_s_sb)->j_jlock), 0) ;
     wake_up(&(SB_JOURNAL(p_s_sb)->j_join_wait)) ;
     return 0 ;
diff -urN linux-2.5.70-bk9/fs/reiserfs/prints.c linux-2.5.70-bk10/fs/reiserfs/prints.c
--- linux-2.5.70-bk9/fs/reiserfs/prints.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/fs/reiserfs/prints.c	2003-06-05 04:41:37.000000000 -0700
@@ -546,12 +546,13 @@
 {
     struct reiserfs_journal_desc * desc;
 
-    desc = (struct reiserfs_journal_desc *)(bh->b_data);
-    if (memcmp(desc->j_magic, JOURNAL_DESC_MAGIC, 8))
+    if (memcmp(get_journal_desc_magic (bh), JOURNAL_DESC_MAGIC, 8))
 	return 1;
 
+    desc = (struct reiserfs_journal_desc *)(bh->b_data);
     printk ("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
-	    (unsigned long long)bh->b_blocknr, desc->j_trans_id, desc->j_mount_id, desc->j_len);
+	    (unsigned long long)bh->b_blocknr, get_desc_trans_id (desc), get_desc_mount_id (desc),
+	    get_desc_trans_len (desc));
 
     return 0;
 }
diff -urN linux-2.5.70-bk9/fs/reiserfs/super.c linux-2.5.70-bk10/fs/reiserfs/super.c
--- linux-2.5.70-bk9/fs/reiserfs/super.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/fs/reiserfs/super.c	2003-06-05 04:41:37.000000000 -0700
@@ -23,9 +23,6 @@
 #include <linux/buffer_head.h>
 #include <linux/vfs.h>
 
-#define REISERFS_OLD_BLOCKSIZE 4096
-#define REISERFS_SUPER_MAGIC_STRING_OFFSET_NJ 20
-
 static struct file_system_type reiserfs_fs_type;
 
 const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
@@ -500,8 +497,11 @@
    mount options that have values rather than being toggles. */
 typedef struct {
     char * value;
-    int bitmask; /* bit which is to be set in mount_options bitmask when this
-                    value is found, 0 is no bits are to be set */
+    int setmask; /* bitmask which is to set on mount_options bitmask when this
+                    value is found, 0 is no bits are to be changed. */
+    int clrmask; /* bitmask which is to clear on mount_options bitmask when  this
+		    value is found, 0 is no bits are to be changed. This is
+		    applied BEFORE setmask */
 } arg_desc_t;
 
 
@@ -511,25 +511,30 @@
     char * option_name;
     int arg_required; /* 0 if argument is not required, not 0 otherwise */
     const arg_desc_t * values; /* list of values accepted by an option */
-    int bitmask;  /* bit which is to be set in mount_options bitmask when this
-		     option is selected, 0 is not bits are to be set */
+    int setmask; /* bitmask which is to set on mount_options bitmask when this
+                    value is found, 0 is no bits are to be changed. */
+    int clrmask; /* bitmask which is to clear on mount_options bitmask when  this
+		    value is found, 0 is no bits are to be changed. This is
+		    applied BEFORE setmask */
 } opt_desc_t;
 
 /* possible values for "-o block-allocator=" and bits which are to be set in
    s_mount_opt of reiserfs specific part of in-core super block */
 static const arg_desc_t balloc[] = {
-    {"noborder", REISERFS_NO_BORDER},
-    {"no_unhashed_relocation", REISERFS_NO_UNHASHED_RELOCATION},
-    {"hashed_relocation", REISERFS_HASHED_RELOCATION},
-    {"test4", REISERFS_TEST4},
-    {NULL, -1}
+    {"noborder", 1<<REISERFS_NO_BORDER, 0},
+    {"border", 0, 1<<REISERFS_NO_BORDER},
+    {"no_unhashed_relocation", 1<<REISERFS_NO_UNHASHED_RELOCATION, 0},
+    {"hashed_relocation", 1<<REISERFS_HASHED_RELOCATION, 0},
+    {"test4", 1<<REISERFS_TEST4, 0},
+    {"notest4", 0, 1<<REISERFS_TEST4},
+    {NULL, 0, 0}
 };
 
 static const arg_desc_t tails[] = {
-    {"on", REISERFS_LARGETAIL},
-    {"off", -1},
-    {"small", REISERFS_SMALLTAIL},
-    {NULL, 0}
+    {"on", 1<<REISERFS_LARGETAIL, 1<<REISERFS_SMALLTAIL},
+    {"off", 0, (1<<REISERFS_LARGETAIL)|(1<<REISERFS_SMALLTAIL)},
+    {"small", 1<<REISERFS_SMALLTAIL, 1<<REISERFS_LARGETAIL},
+    {NULL, 0, 0}
 };
 
 int reiserfs_default_io_size = 128 * 1024; /* Default recommended I/O size is 128k.
@@ -571,16 +576,21 @@
 	/* Ugly special case, probably we should redo options parser so that
 	   it can understand several arguments for some options, also so that
 	   it can fill several bitfields with option values. */
-	reiserfs_parse_alloc_options( s, p + 6);
-	return 0;
+	if ( reiserfs_parse_alloc_options( s, p + 6) ) {
+	    return -1;
+	} else {
+	    return 0;
+	}
     }
 
  
     /* for every option in the list */
     for (opt = opts; opt->option_name; opt ++) {
 	if (!strncmp (p, opt->option_name, strlen (opt->option_name))) {
-	    if (bit_flags && opt->bitmask != -1)
-		set_bit (opt->bitmask, bit_flags);
+	    if (bit_flags) {
+		*bit_flags &= ~opt->clrmask;
+		*bit_flags |= opt->setmask;
+	    }
 	    break;
 	}
     }
@@ -620,7 +630,7 @@
     }
     
     if (!opt->values) {
-	/* *opt_arg contains pointer to argument */
+	/* *=NULLopt_arg contains pointer to argument */
 	*opt_arg = p;
 	return opt->arg_required;
     }
@@ -628,8 +638,10 @@
     /* values possible for this option are listed in opt->values */
     for (arg = opt->values; arg->value; arg ++) {
 	if (!strcmp (p, arg->value)) {
-	    if (bit_flags && arg->bitmask != -1 )
-		set_bit (arg->bitmask, bit_flags);
+	    if (bit_flags) {
+		*bit_flags &= ~arg->clrmask;
+		*bit_flags |= arg->setmask;
+	    }
 	    return opt->arg_required;
 	}
     }
@@ -638,7 +650,6 @@
     return -1;
 }
 
-
 /* returns 0 if something is wrong in option string, 1 - otherwise */
 static int reiserfs_parse_options (struct super_block * s, char * options, /* string given via mount's -o */
 				   unsigned long * mount_options,
@@ -652,18 +663,18 @@
     char * arg = NULL;
     char * pos;
     opt_desc_t opts[] = {
-		{"tails", 't', tails, -1},
-		{"notail", 0, 0, -1}, /* Compatibility stuff, so that -o notail
-for old setups still work */
-		{"conv", 0, 0, REISERFS_CONVERT}, 
-		{"attrs", 0, 0, REISERFS_ATTRS}, 
-		{"nolog", 0, 0, -1},
-		{"replayonly", 0, 0, REPLAYONLY},
-		{"block-allocator", 'a', balloc, -1}, 
-		{"resize", 'r', 0, -1},
-		{"jdev", 'j', 0, -1},
-		{"nolargeio", 'w', 0, -1},
-		{NULL, 0, 0, -1}
+	{"tails", 't', tails, 0, 0}, /* Compatibility stuff, so that -o notail for old setups still work */
+	{"notail", 0, 0, 0,  (1<<REISERFS_LARGETAIL)|(1<<REISERFS_SMALLTAIL)},
+	{"conv", 0, 0, 1<<REISERFS_CONVERT, 0},
+	{"attrs", 0, 0, 1<<REISERFS_ATTRS, 0},
+	{"noattrs", 0, 0, 0, 1<<REISERFS_ATTRS},
+	{"nolog", 0, 0, 0, 0}, /* This is unsupported */
+	{"replayonly", 0, 0, 1<<REPLAYONLY, 0},
+	{"block-allocator", 'a', balloc, 0, 0},
+	{"resize", 'r', 0, 0, 0},
+	{"jdev", 'j', 0, 0, 0},
+	{"nolargeio", 'w', 0, 0, 0},
+	{NULL, 0, 0, 0, 0}
     };
 	
     *blocks = 0;
@@ -671,9 +682,6 @@
 	/* use default configuration: create tails, journaling on, no
 	   conversion to newest format */
 	return 1;
-    else
-	/* Drop defaults to zeroes */
-	*mount_options = 0;
     
     for (pos = options; pos; ) {
 	c = reiserfs_getopt (s, &pos, opts, &arg, mount_options);
@@ -695,11 +703,25 @@
 	}
 
 	if ( c == 'w' ) {
-		reiserfs_default_io_size = PAGE_SIZE;
+		char *p=0;
+		int val = simple_strtoul (arg, &p, 0);
+
+		if ( *p != '\0') {
+		    printk ("reiserfs_parse_options: non-numeric value %s for nolargeio option\n", arg);
+		    return 0;
+		}
+		if ( val ) 
+		    reiserfs_default_io_size = PAGE_SIZE;
+		else
+		    reiserfs_default_io_size = 128 * 1024;
 	}
 
 	if (c == 'j') {
 	    if (arg && *arg && jdev_name) {
+		if ( *jdev_name ) { //Hm, already assigned?
+		    printk("reiserfs_parse_options: journal device was already  specified to be %s\n", *jdev_name);
+		    return 0;
+		}
 		*jdev_name = arg;
 	    }
 	}
@@ -731,14 +753,28 @@
   struct reiserfs_super_block * rs;
   struct reiserfs_transaction_handle th ;
   unsigned long blocks;
-  unsigned long mount_options;
+  unsigned long mount_options = REISERFS_SB(s)->s_mount_opt;
+  unsigned long safe_mask = 0;
 
   rs = SB_DISK_SUPER_BLOCK (s);
 
   if (!reiserfs_parse_options(s, arg, &mount_options, &blocks, NULL))
     return -EINVAL;
   
-  handle_attrs( s );
+  handle_attrs(s);
+
+  /* Add options that are safe here */
+  safe_mask |= 1 << REISERFS_SMALLTAIL;
+  safe_mask |= 1 << REISERFS_LARGETAIL;
+  safe_mask |= 1 << REISERFS_NO_BORDER;
+  safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION;
+  safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
+  safe_mask |= 1 << REISERFS_TEST4;
+  safe_mask |= 1 << REISERFS_ATTRS;
+
+  /* Update the bitmask, taking care to keep
+   * the bits we're not allowed to change here */
+  REISERFS_SB(s)->s_mount_opt = (REISERFS_SB(s)->s_mount_opt & ~safe_mask) |  (mount_options & safe_mask);
 
   if(blocks) {
     int rc = reiserfs_resize(s, blocks);
diff -urN linux-2.5.70-bk9/include/asm-alpha/thread_info.h linux-2.5.70-bk10/include/asm-alpha/thread_info.h
--- linux-2.5.70-bk9/include/asm-alpha/thread_info.h	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-alpha/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -51,7 +51,7 @@
 
 /* Thread information allocation.  */
 #define THREAD_SIZE (2*PAGE_SIZE)
-#define alloc_thread_info() \
+#define alloc_thread_info(tsk) \
   ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
 #define get_thread_info(ti) get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-arm/dma-mapping.h linux-2.5.70-bk10/include/asm-arm/dma-mapping.h
--- linux-2.5.70-bk9/include/asm-arm/dma-mapping.h	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-arm/dma-mapping.h	2003-06-05 04:41:37.000000000 -0700
@@ -42,12 +42,12 @@
 /*
  * Return whether the given device DMA address mask can be supported
  * properly.  For example, if your device can only drive the low 24-bits
- * during PCI bus mastering, then you would pass 0x00ffffff as the mask
+ * during bus mastering, then you would pass 0x00ffffff as the mask
  * to this function.
  */
 static inline int dma_supported(struct device *dev, u64 mask)
 {
-	return 1;
+	return dev->dma_mask && *dev->dma_mask != 0;
 }
 
 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
@@ -81,14 +81,8 @@
  * return the CPU-viewed address, and sets @handle to be the
  * device-viewed address.
  */
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
-{
-	if (dev == NULL || dmadev_is_sa1111(dev) || *dev->dma_mask != 0xffffffff)
-		gfp |= GFP_DMA;
-
-	return consistent_alloc(gfp, size, handle, 0);
-}
+extern void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp);
 
 /**
  * dma_free_coherent - free memory allocated by dma_alloc_coherent
diff -urN linux-2.5.70-bk9/include/asm-arm/hardware.h linux-2.5.70-bk10/include/asm-arm/hardware.h
--- linux-2.5.70-bk9/include/asm-arm/hardware.h	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-arm/hardware.h	2003-06-05 04:41:37.000000000 -0700
@@ -15,4 +15,13 @@
 
 #include <asm/arch/hardware.h>
 
+#ifndef __ASSEMBLY__
+
+struct platform_device;
+
+extern int platform_add_devices(struct platform_device *, int);
+extern int platform_add_device(struct platform_device *);
+
+#endif
+
 #endif
diff -urN linux-2.5.70-bk9/include/asm-arm/thread_info.h linux-2.5.70-bk10/include/asm-arm/thread_info.h
--- linux-2.5.70-bk9/include/asm-arm/thread_info.h	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-arm/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -84,7 +84,7 @@
 
 #define THREAD_SIZE		(8192)
 
-extern struct thread_info *alloc_thread_info(void);
+extern struct thread_info *alloc_thread_info(struct task_struct *task);
 extern void free_thread_info(struct thread_info *);
 
 #define get_thread_info(ti)	get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-h8300/thread_info.h linux-2.5.70-bk10/include/asm-h8300/thread_info.h
--- linux-2.5.70-bk9/include/asm-h8300/thread_info.h	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-h8300/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -65,7 +65,7 @@
 }
 
 /* thread information allocation */
-#define alloc_thread_info() ((struct thread_info *) \
+#define alloc_thread_info(tsk) ((struct thread_info *) \
 				__get_free_pages(GFP_KERNEL, 1))
 #define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
 #define get_thread_info(ti)	get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-i386/thread_info.h linux-2.5.70-bk10/include/asm-i386/thread_info.h
--- linux-2.5.70-bk9/include/asm-i386/thread_info.h	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-i386/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -87,7 +87,7 @@
 
 /* thread information allocation */
 #define THREAD_SIZE (2*PAGE_SIZE)
-#define alloc_thread_info() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
+#define alloc_thread_info(tsk) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
 #define get_thread_info(ti) get_task_struct((ti)->task)
 #define put_thread_info(ti) put_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-m68k/thread_info.h linux-2.5.70-bk10/include/asm-m68k/thread_info.h
--- linux-2.5.70-bk9/include/asm-m68k/thread_info.h	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-m68k/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -28,10 +28,10 @@
 
 /* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */
 #if PAGE_SHIFT == 13 /* 8k machines */
-#define alloc_thread_info()   ((struct thread_info *)__get_free_pages(GFP_KERNEL,0))
+#define alloc_thread_info(tsk)   ((struct thread_info *)__get_free_pages(GFP_KERNEL,0))
 #define free_thread_info(ti)  free_pages((unsigned long)(ti),0)
 #else /* otherwise assume 4k pages */
-#define alloc_thread_info()   ((struct thread_info *)__get_free_pages(GFP_KERNEL,1))
+#define alloc_thread_info(tsk)   ((struct thread_info *)__get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti)  free_pages((unsigned long)(ti),1)
 #endif /* PAGE_SHIFT == 13 */
 
diff -urN linux-2.5.70-bk9/include/asm-m68knommu/thread_info.h linux-2.5.70-bk10/include/asm-m68knommu/thread_info.h
--- linux-2.5.70-bk9/include/asm-m68knommu/thread_info.h	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-m68knommu/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -65,7 +65,7 @@
 }
 
 /* thread information allocation */
-#define alloc_thread_info() ((struct thread_info *) \
+#define alloc_thread_info(tsk) ((struct thread_info *) \
 				__get_free_pages(GFP_KERNEL, 1))
 #define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
 #define get_thread_info(ti)	get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-parisc/thread_info.h linux-2.5.70-bk10/include/asm-parisc/thread_info.h
--- linux-2.5.70-bk9/include/asm-parisc/thread_info.h	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-parisc/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -37,7 +37,7 @@
 #define THREAD_SIZE             (PAGE_SIZE << THREAD_ORDER)
 #define THREAD_SHIFT            (PAGE_SHIFT + THREAD_ORDER)
 
-#define alloc_thread_info() ((struct thread_info *) \
+#define alloc_thread_info(tsk) ((struct thread_info *) \
 			__get_free_pages(GFP_KERNEL, THREAD_ORDER))
 #define free_thread_info(ti)    free_pages((unsigned long) (ti), THREAD_ORDER)
 #define get_thread_info(ti)     get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-ppc/thread_info.h linux-2.5.70-bk10/include/asm-ppc/thread_info.h
--- linux-2.5.70-bk9/include/asm-ppc/thread_info.h	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-ppc/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -54,7 +54,7 @@
 }
 
 /* thread information allocation */
-#define alloc_thread_info() ((struct thread_info *) \
+#define alloc_thread_info(tsk) ((struct thread_info *) \
 				__get_free_pages(GFP_KERNEL, 1))
 #define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
 #define get_thread_info(ti)	get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-ppc64/thread_info.h linux-2.5.70-bk10/include/asm-ppc64/thread_info.h
--- linux-2.5.70-bk9/include/asm-ppc64/thread_info.h	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-ppc64/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -52,7 +52,7 @@
 #define THREAD_SIZE		(PAGE_SIZE << THREAD_ORDER)
 #define THREAD_SHIFT		(PAGE_SHIFT + THREAD_ORDER)
 
-#define alloc_thread_info() ((struct thread_info *) \
+#define alloc_thread_info(tsk) ((struct thread_info *) \
 				__get_free_pages(GFP_KERNEL, THREAD_ORDER))
 #define free_thread_info(ti)	free_pages((unsigned long) (ti), THREAD_ORDER)
 #define get_thread_info(ti)	get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-s390/thread_info.h linux-2.5.70-bk10/include/asm-s390/thread_info.h
--- linux-2.5.70-bk9/include/asm-s390/thread_info.h	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-s390/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -68,7 +68,7 @@
 }
 
 /* thread information allocation */
-#define alloc_thread_info() ((struct thread_info *) \
+#define alloc_thread_info(tsk) ((struct thread_info *) \
 	__get_free_pages(GFP_KERNEL,THREAD_ORDER))
 #define free_thread_info(ti) free_pages((unsigned long) (ti),THREAD_ORDER)
 #define get_thread_info(ti) get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-sparc/thread_info.h linux-2.5.70-bk10/include/asm-sparc/thread_info.h
--- linux-2.5.70-bk9/include/asm-sparc/thread_info.h	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-sparc/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -78,7 +78,7 @@
 #endif
 
 BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info, void)
-#define alloc_thread_info() BTFIXUP_CALL(alloc_thread_info)()
+#define alloc_thread_info(tsk) BTFIXUP_CALL(alloc_thread_info)()
 
 BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
 #define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti)
diff -urN linux-2.5.70-bk9/include/asm-sparc64/thread_info.h linux-2.5.70-bk10/include/asm-sparc64/thread_info.h
--- linux-2.5.70-bk9/include/asm-sparc64/thread_info.h	2003-05-26 18:00:44.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-sparc64/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -142,10 +142,10 @@
 
 /* thread information allocation */
 #if PAGE_SHIFT == 13
-#define alloc_thread_info()   ((struct thread_info *)__get_free_pages(GFP_KERNEL, 1))
+#define alloc_thread_info(tsk)((struct thread_info *)__get_free_pages(GFP_KERNEL, 1))
 #define free_thread_info(ti)  free_pages((unsigned long)(ti),1)
 #else /* PAGE_SHIFT == 13 */
-#define alloc_thread_info()   ((struct thread_info *)__get_free_pages(GFP_KERNEL, 0))
+#define alloc_thread_info(tsk)((struct thread_info *)__get_free_pages(GFP_KERNEL, 0))
 #define free_thread_info(ti)  free_pages((unsigned long)(ti),0)
 #endif /* PAGE_SHIFT == 13 */
 
diff -urN linux-2.5.70-bk9/include/asm-um/thread_info.h linux-2.5.70-bk10/include/asm-um/thread_info.h
--- linux-2.5.70-bk9/include/asm-um/thread_info.h	2003-05-26 18:00:28.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-um/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -49,7 +49,7 @@
 
 /* thread information allocation */
 #define THREAD_SIZE (4*PAGE_SIZE)
-#define alloc_thread_info() ((struct thread_info *) \
+#define alloc_thread_info(tsk) ((struct thread_info *) \
 	__get_free_pages(GFP_KERNEL,2))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
 #define get_thread_info(ti) get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-v850/thread_info.h linux-2.5.70-bk10/include/asm-v850/thread_info.h
--- linux-2.5.70-bk9/include/asm-v850/thread_info.h	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-v850/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -54,7 +54,7 @@
  */
 
 /* thread information allocation */
-#define alloc_thread_info() ((struct thread_info *) \
+#define alloc_thread_info(tsk) ((struct thread_info *) \
 				__get_free_pages(GFP_KERNEL, 1))
 #define free_thread_info(ti)	free_pages((unsigned long) (ti), 1)
 #define get_thread_info(ti)	get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/asm-x86_64/thread_info.h linux-2.5.70-bk10/include/asm-x86_64/thread_info.h
--- linux-2.5.70-bk9/include/asm-x86_64/thread_info.h	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk10/include/asm-x86_64/thread_info.h	2003-06-05 04:41:37.000000000 -0700
@@ -73,7 +73,7 @@
 }
 
 /* thread information allocation */
-#define alloc_thread_info() \
+#define alloc_thread_info(tsk) \
 	((struct thread_info *) __get_free_pages(GFP_KERNEL,THREAD_ORDER))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER)
 #define get_thread_info(ti) get_task_struct((ti)->task)
diff -urN linux-2.5.70-bk9/include/linux/aio.h linux-2.5.70-bk10/include/linux/aio.h
--- linux-2.5.70-bk9/include/linux/aio.h	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk10/include/linux/aio.h	2003-06-05 04:41:37.000000000 -0700
@@ -41,9 +41,9 @@
 #define kiocbClearKicked(iocb)	clear_bit(KIF_KICKED, &(iocb)->ki_flags)
 #define kiocbClearCancelled(iocb)	clear_bit(KIF_CANCELLED, &(iocb)->ki_flags)
 
-#define kiocbIsLocked(iocb)	test_bit(0, &(iocb)->ki_flags)
-#define kiocbIsKicked(iocb)	test_bit(1, &(iocb)->ki_flags)
-#define kiocbIsCancelled(iocb)	test_bit(2, &(iocb)->ki_flags)
+#define kiocbIsLocked(iocb)	test_bit(KIF_LOCKED, &(iocb)->ki_flags)
+#define kiocbIsKicked(iocb)	test_bit(KIF_KICKED, &(iocb)->ki_flags)
+#define kiocbIsCancelled(iocb)	test_bit(KIF_CANCELLED, &(iocb)->ki_flags)
 
 struct kiocb {
 	struct list_head	ki_run_list;
diff -urN linux-2.5.70-bk9/include/linux/device.h linux-2.5.70-bk10/include/linux/device.h
--- linux-2.5.70-bk9/include/linux/device.h	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/include/linux/device.h	2003-06-05 04:41:37.000000000 -0700
@@ -385,6 +385,8 @@
 	struct resource	* resource;
 };
 
+#define to_platform_device(x) container_of((x), struct platform_device, dev)
+
 extern int platform_device_register(struct platform_device *);
 extern void platform_device_unregister(struct platform_device *);
 
diff -urN linux-2.5.70-bk9/include/linux/hugetlb.h linux-2.5.70-bk10/include/linux/hugetlb.h
--- linux-2.5.70-bk9/include/linux/hugetlb.h	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/include/linux/hugetlb.h	2003-06-05 04:41:37.000000000 -0700
@@ -72,6 +72,12 @@
 #endif /* !CONFIG_HUGETLB_PAGE */
 
 #ifdef CONFIG_HUGETLBFS
+struct hugetlbfs_config {
+        uid_t   uid;
+        gid_t   gid;
+        umode_t mode;
+};
+
 extern struct file_operations hugetlbfs_file_operations;
 extern struct vm_operations_struct hugetlb_vm_ops;
 struct file *hugetlb_zero_setup(size_t);
diff -urN linux-2.5.70-bk9/include/linux/pci.h linux-2.5.70-bk10/include/linux/pci.h
--- linux-2.5.70-bk9/include/linux/pci.h	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/include/linux/pci.h	2003-06-05 04:41:37.000000000 -0700
@@ -527,8 +527,6 @@
 	return !list_empty(&pci_devices);
 }
 
-#define pci_for_each_dev(dev) \
-	for(dev = pci_dev_g(pci_devices.next); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.next))
 #define pci_for_each_dev_reverse(dev) \
 	for(dev = pci_dev_g(pci_devices.prev); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.prev))
 #define pci_for_each_bus(bus) \
@@ -551,22 +549,12 @@
 {
 	return pci_scan_bus_parented(NULL, bus, ops, sysdata);
 }
-struct pci_bus *pci_alloc_primary_bus_parented(struct device * parent, int bus);
-static inline struct pci_bus *pci_alloc_primary_bus(int bus)
-{
-	return pci_alloc_primary_bus_parented(NULL, bus);
-}
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 void pci_bus_add_devices(struct pci_bus *bus);
-int pci_proc_attach_device(struct pci_dev *dev);
-int pci_proc_detach_device(struct pci_dev *dev);
-int pci_proc_attach_bus(struct pci_bus *bus);
-int pci_proc_detach_bus(struct pci_bus *bus);
 void pci_name_device(struct pci_dev *dev);
 char *pci_class_name(u32 class);
 void pci_read_bridge_bases(struct pci_bus *child);
 struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
-int pci_setup_device(struct pci_dev *dev);
 int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
 extern struct pci_dev *pci_get_dev(struct pci_dev *dev);
 extern void pci_put_dev(struct pci_dev *dev);
@@ -578,12 +566,8 @@
 				 unsigned int ss_vendor, unsigned int ss_device,
 				 const struct pci_dev *from);
 struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from);
-struct pci_bus *pci_find_bus(unsigned char busnr);
 struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
-unsigned char pci_bus_max_busnr(struct pci_bus* bus);
-unsigned char pci_max_busnr(void);
 int pci_find_capability (struct pci_dev *dev, int cap);
-int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
 
 int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
 int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
@@ -617,8 +601,6 @@
 	return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val);
 }
 
-extern spinlock_t pci_lock;
-
 int pci_enable_device(struct pci_dev *dev);
 int pci_enable_device_bars(struct pci_dev *dev, int mask);
 void pci_disable_device(struct pci_dev *dev);
@@ -638,7 +620,6 @@
 int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
-
 void pci_bus_assign_resources(struct pci_bus *bus);
 void pci_bus_size_bridges(struct pci_bus *bus);
 int pci_claim_resource(struct pci_dev *, int);
@@ -654,24 +635,14 @@
 void pci_release_region(struct pci_dev *, int);
 
 /* drivers/pci/bus.c */
-
-int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
-			   unsigned long size, unsigned long align,
-			   unsigned long min, unsigned int type_mask,
-			   void (*alignf)(void *, struct resource *,
-					  unsigned long, unsigned long),
-			   void *alignf_data);
 void pci_enable_bridges(struct pci_bus *bus);
 
 /* New-style probing supporting hot-pluggable devices */
 int pci_register_driver(struct pci_driver *);
 void pci_unregister_driver(struct pci_driver *);
-void pci_remove_bus_device(struct pci_dev *);
 void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
 const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
-unsigned int pci_do_scan_bus(struct pci_bus *bus);
-struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
 
 /* kmem_cache style wrapper around pci_alloc_consistent() */
@@ -686,42 +657,6 @@
 extern struct pci_dev *isa_bridge;
 #endif
 
-/* Some worker functions that PCI Hotplug drivers find useful */
-struct pci_dev_wrapped {
-	struct pci_dev	*dev;
-	void		*data;
-};
-
-struct pci_bus_wrapped {
-	struct pci_bus	*bus;
-	void		*data;
-};
-
-struct pci_visit {
-	int (* pre_visit_pci_bus)	(struct pci_bus_wrapped *,
-					 struct pci_dev_wrapped *);
-	int (* post_visit_pci_bus)	(struct pci_bus_wrapped *,
-					 struct pci_dev_wrapped *);
-
-	int (* pre_visit_pci_dev)	(struct pci_dev_wrapped *,
-					 struct pci_bus_wrapped *);
-	int (* visit_pci_dev)		(struct pci_dev_wrapped *,
-					 struct pci_bus_wrapped *);
-	int (* post_visit_pci_dev)	(struct pci_dev_wrapped *,
-					 struct pci_bus_wrapped *);
-};
-
-extern int pci_visit_dev(struct pci_visit *fn,
-			 struct pci_dev_wrapped *wrapped_dev,
-			 struct pci_bus_wrapped *wrapped_parent);
-extern int pci_remove_device_safe(struct pci_dev *dev);
-
-static inline void
-pci_dynids_set_use_driver_data(struct pci_driver *pdrv, int val)
-{
-	pdrv->dynids.use_driver_data = val;
-}
-
 #endif /* CONFIG_PCI */
 
 /* Include architecture-dependent settings and functions */
@@ -770,7 +705,6 @@
 static inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir; }
 static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
 static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
-static inline void pci_dynids_set_use_driver_data(struct pci_driver *pdrv, int val) { }
 
 /* Power management related routines */
 static inline int pci_save_state(struct pci_dev *dev, u32 *buffer) { return 0; }
@@ -778,9 +712,6 @@
 static inline int pci_set_power_state(struct pci_dev *dev, int state) { return 0; }
 static inline int pci_enable_wake(struct pci_dev *dev, u32 state, int enable) { return 0; }
 
-#define pci_for_each_dev(dev) \
-	for(dev = NULL; 0; )
-
 #define	isa_bridge	((struct pci_dev *)NULL)
 
 #else
diff -urN linux-2.5.70-bk9/include/linux/reiserfs_fs.h linux-2.5.70-bk10/include/linux/reiserfs_fs.h
--- linux-2.5.70-bk9/include/linux/reiserfs_fs.h	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/include/linux/reiserfs_fs.h	2003-06-05 04:41:37.000000000 -0700
@@ -1631,29 +1631,43 @@
 /***************************************************************************/
 
 /*#ifdef __KERNEL__*/
+#define get_journal_desc_magic(bh) (bh->b_data + bh->b_size - 12)
 
-/* journal.c see journal.c for all the comments here */
-
-#define JOURNAL_TRANS_HALF 1018   /* must be correct to keep the desc and commit structs at 4k */
+#define journal_trans_half(blocksize) \
+	((blocksize - sizeof (struct reiserfs_journal_desc) + sizeof (__u32) - 12) / sizeof (__u32))
 
+/* journal.c see journal.c for all the comments here */
 
 /* first block written in a commit.  */
 struct reiserfs_journal_desc {
   __u32 j_trans_id ;			/* id of commit */
   __u32 j_len ;			/* length of commit. len +1 is the commit block */
   __u32 j_mount_id ;				/* mount id of this trans*/
-  __u32 j_realblock[JOURNAL_TRANS_HALF] ; /* real locations for each block */
-  char j_magic[12] ;
+  __u32 j_realblock[1] ; /* real locations for each block */
 } ;
 
+#define get_desc_trans_id(d)   le32_to_cpu((d)->j_trans_id)
+#define get_desc_trans_len(d)  le32_to_cpu((d)->j_len)
+#define get_desc_mount_id(d)   le32_to_cpu((d)->j_mount_id)
+
+#define set_desc_trans_id(d,val)       do { (d)->j_trans_id = cpu_to_le32 (val); } while (0)
+#define set_desc_trans_len(d,val)      do { (d)->j_len = cpu_to_le32 (val); } while (0)
+#define set_desc_mount_id(d,val)       do { (d)->j_mount_id = cpu_to_le32 (val); } while (0)
+
 /* last block written in a commit */
 struct reiserfs_journal_commit {
   __u32 j_trans_id ;			/* must match j_trans_id from the desc block */
   __u32 j_len ;			/* ditto */
-  __u32 j_realblock[JOURNAL_TRANS_HALF] ; /* real locations for each block */
-  char j_digest[16] ;			/* md5 sum of all the blocks involved, including desc and commit. not used, kill it */
+  __u32 j_realblock[1] ; /* real locations for each block */
 } ;
 
+#define get_commit_trans_id(c) le32_to_cpu((c)->j_trans_id)
+#define get_commit_trans_len(c)        le32_to_cpu((c)->j_len)
+#define get_commit_mount_id(c) le32_to_cpu((c)->j_mount_id)
+
+#define set_commit_trans_id(c,val)     do { (c)->j_trans_id = cpu_to_le32 (val); } while (0)
+#define set_commit_trans_len(c,val)    do { (c)->j_len = cpu_to_le32 (val); } while (0)
+
 /* this header block gets written whenever a transaction is considered fully flushed, and is more recent than the
 ** last fully flushed transaction.  fully flushed means all the log blocks and all the real blocks are on disk,
 ** and this transaction does not need to be replayed.
diff -urN linux-2.5.70-bk9/include/linux/reiserfs_fs_sb.h linux-2.5.70-bk10/include/linux/reiserfs_fs_sb.h
--- linux-2.5.70-bk9/include/linux/reiserfs_fs_sb.h	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/include/linux/reiserfs_fs_sb.h	2003-06-05 04:41:37.000000000 -0700
@@ -253,6 +253,8 @@
   struct reiserfs_journal_cnode *j_list_hash_table[JOURNAL_HASH_SIZE] ; /* hash table for all the real buffer heads in all 
   										the transactions */
   struct list_head j_prealloc_list;     /* list of inodes which have preallocated blocks */
+  unsigned long j_max_trans_size ;
+  unsigned long j_max_batch_size ;
 };
 
 #define JOURNAL_DESC_MAGIC "ReIsErLB" /* ick.  magic string to find desc blocks in the journal */
diff -urN linux-2.5.70-bk9/include/linux/rtnetlink.h linux-2.5.70-bk10/include/linux/rtnetlink.h
--- linux-2.5.70-bk9/include/linux/rtnetlink.h	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/include/linux/rtnetlink.h	2003-06-05 04:41:37.000000000 -0700
@@ -50,7 +50,7 @@
 #define	RTM_MAX		(RTM_BASE+31)
 
 /* 
-   Generic structure for encapsulation optional route information.
+   Generic structure for encapsulation of optional route information.
    It is reminiscent of sockaddr, but with sa_family replaced
    with attribute type.
  */
diff -urN linux-2.5.70-bk9/include/net/ip6_fib.h linux-2.5.70-bk10/include/net/ip6_fib.h
--- linux-2.5.70-bk9/include/net/ip6_fib.h	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk10/include/net/ip6_fib.h	2003-06-05 04:41:37.000000000 -0700
@@ -111,9 +111,10 @@
 struct rt6_statistics {
 	__u32		fib_nodes;
 	__u32		fib_route_nodes;
-	__u32		fib_rt_alloc;		/* permanet routes	*/
+	__u32		fib_rt_alloc;		/* permanent routes	*/
 	__u32		fib_rt_entries;		/* rt entries in table	*/
 	__u32		fib_rt_cache;		/* cache routes		*/
+	__u32		fib_discarded_routes;
 };
 
 #define RTN_TL_ROOT	0x0001
diff -urN linux-2.5.70-bk9/include/net/snmp.h linux-2.5.70-bk10/include/net/snmp.h
--- linux-2.5.70-bk9/include/net/snmp.h	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk10/include/net/snmp.h	2003-06-05 04:41:37.000000000 -0700
@@ -42,6 +42,11 @@
  */ 
 
  
+/*
+ * RFC 1213:  MIB-II
+ * RFC 2011 (updates 1213):  SNMPv2-MIB-IP
+ * RFC 2863:  Interfaces Group MIB
+ */
 struct ip_mib
 {
  	unsigned long	IpInReceives;
@@ -64,6 +69,9 @@
 	unsigned long   __pad[0]; 
 };
  
+/*
+ * RFC 2465:  IPv6 MIB: General Group
+ */
 struct ipv6_mib
 {
 	unsigned long	Ip6InReceives;
@@ -91,6 +99,10 @@
 	unsigned long   __pad[0]; 
 };
  
+/*
+ * RFC 1213:  MIB-II ICMP Group
+ * RFC 2011 (updates 1213):  SNMPv2 MIB for IP: ICMP group
+ */
 struct icmp_mib
 {
  	unsigned long	IcmpInMsgs;
@@ -123,6 +135,9 @@
 	unsigned long   __pad[0]; 
 };
 
+/*
+ * RFC 2466:  ICMPv6-MIB
+ */
 struct icmpv6_mib
 {
 	unsigned long	Icmp6InMsgs;
@@ -161,6 +176,10 @@
 	unsigned long   __pad[0]; 
 };
  
+/*
+ * RFC 1213:  MIB-II TCP group
+ * RFC 2012 (updates 1213):  SNMPv2-MIB-TCP
+ */
 struct tcp_mib
 {
  	unsigned long	TcpRtoAlgorithm;
@@ -180,6 +199,10 @@
 	unsigned long   __pad[0]; 
 };
  
+/*
+ * RFC 1213:  MIB-II UDP group
+ * RFC 2013 (updates 1213):  SNMPv2-MIB-UDP
+ */
 struct udp_mib
 {
  	unsigned long	UdpInDatagrams;
diff -urN linux-2.5.70-bk9/kernel/fork.c linux-2.5.70-bk10/kernel/fork.c
--- linux-2.5.70-bk9/kernel/fork.c	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk10/kernel/fork.c	2003-06-05 04:41:37.000000000 -0700
@@ -38,8 +38,6 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-static kmem_cache_t *task_struct_cachep;
-
 extern int copy_semundo(unsigned long clone_flags, struct task_struct *tsk);
 extern void exit_semundo(struct task_struct *tsk);
 
@@ -74,7 +72,13 @@
 	return total;
 }
 
-static void free_task_struct(struct task_struct *tsk)
+#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
+# define alloc_task_struct()	kmem_cache_alloc(task_struct_cachep, GFP_KERNEL)
+# define free_task_struct(tsk)	kmem_cache_free(task_struct_cachep, (tsk))
+static kmem_cache_t *task_struct_cachep;
+#endif
+
+static void free_task(struct task_struct *tsk)
 {
 	/*
 	 * The task cache is effectively disabled right now.
@@ -84,14 +88,14 @@
 	 */
 	if (tsk != current) {
 		free_thread_info(tsk->thread_info);
-		kmem_cache_free(task_struct_cachep,tsk);
+		free_task_struct(tsk);
 	} else {
 		int cpu = get_cpu();
 
 		tsk = task_cache[cpu];
 		if (tsk) {
 			free_thread_info(tsk->thread_info);
-			kmem_cache_free(task_struct_cachep,tsk);
+			free_task_struct(tsk);
 		}
 		task_cache[cpu] = current;
 		put_cpu();
@@ -106,7 +110,7 @@
 
 	security_task_free(tsk);
 	free_uid(tsk->user);
-	free_task_struct(tsk);
+	free_task(tsk);
 }
 
 void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
@@ -186,6 +190,7 @@
 
 void __init fork_init(unsigned long mempages)
 {
+#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
 	/* create a slab on which task_structs can be allocated */
 	task_struct_cachep =
 		kmem_cache_create("task_struct",
@@ -193,6 +198,7 @@
 				  SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
 	if (!task_struct_cachep)
 		panic("fork_init(): cannot create task_struct SLAB cache");
+#endif
 
 	/*
 	 * The default maximum number of threads is set to a safe
@@ -222,13 +228,13 @@
 	task_cache[cpu] = NULL;
 	put_cpu();
 	if (!tsk) {
-		ti = alloc_thread_info();
-		if (!ti)
+		tsk = alloc_task_struct();
+		if (!tsk)
 			return NULL;
 
-		tsk = kmem_cache_alloc(task_struct_cachep, GFP_KERNEL);
-		if (!tsk) {
-			free_thread_info(ti);
+		ti = alloc_thread_info(tsk);
+		if (!ti) {
+			free_task_struct(tsk);
 			return NULL;
 		}
 	} else
@@ -1041,7 +1047,7 @@
 	atomic_dec(&p->user->processes);
 	free_uid(p->user);
 bad_fork_free:
-	free_task_struct(p);
+	free_task(p);
 	goto fork_out;
 }
 
diff -urN linux-2.5.70-bk9/kernel/timer.c linux-2.5.70-bk10/kernel/timer.c
--- linux-2.5.70-bk9/kernel/timer.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/kernel/timer.c	2003-06-05 04:41:37.000000000 -0700
@@ -1226,47 +1226,36 @@
 }
 
 #ifdef CONFIG_TIME_INTERPOLATION
-
 volatile unsigned long last_nsec_offset;
-
-struct time_interpolator *time_interpolator;
-
 #ifndef __HAVE_ARCH_CMPXCHG
 spinlock_t last_nsec_offset_lock = SPIN_LOCK_UNLOCKED;
 #endif
 
-static struct {
-	spinlock_t lock;		/* lock protecting list */
-	struct time_interpolator *list;	/* list of registered interpolators */
-} ti_global = {
-	.lock = SPIN_LOCK_UNLOCKED
-};
+struct time_interpolator *time_interpolator;
+struct time_interpolator *time_interpolator_list;
+spinlock_t time_interpolator_lock = SPIN_LOCK_UNLOCKED;
 
 static inline int
 is_better_time_interpolator(struct time_interpolator *new)
 {
 	if (!time_interpolator)
 		return 1;
-	return new->frequency > 2*time_interpolator->frequency
-		|| (unsigned long) new->drift < (unsigned long) time_interpolator->drift;
+	return new->frequency > 2*time_interpolator->frequency ||
+	    (unsigned long)new->drift < (unsigned long)time_interpolator->drift;
 }
 
 void
 register_time_interpolator(struct time_interpolator *ti)
 {
-	spin_lock(&ti_global.lock);
-	{
-		write_seqlock_irq(&xtime_lock);
-		{
-			if (is_better_time_interpolator(ti))
-				time_interpolator = ti;
-		}
-		write_sequnlock_irq(&xtime_lock);
-
-		ti->next = ti_global.list;
-		ti_global.list = ti;
-	}
-	spin_unlock(&ti_global.lock);
+	spin_lock(&time_interpolator_lock);
+	write_seqlock_irq(&xtime_lock);
+	if (is_better_time_interpolator(ti))
+		time_interpolator = ti;
+	write_sequnlock_irq(&xtime_lock);
+
+	ti->next = time_interpolator_list;
+	time_interpolator_list = ti;
+	spin_unlock(&time_interpolator_lock);
 }
 
 void
@@ -1274,30 +1263,26 @@
 {
 	struct time_interpolator *curr, **prev;
 
-	spin_lock(&ti_global.lock);
-	{
-		prev = &ti_global.list;
-		for (curr = *prev; curr; curr = curr->next) {
-			if (curr == ti) {
-				*prev = curr->next;
-				break;
-			}
-			prev = &curr->next;
-		}
-		write_seqlock_irq(&xtime_lock);
-		{
-			if (ti == time_interpolator) {
-				/* we lost the best time-interpolator: */
-				time_interpolator = NULL;
-				/* find the next-best interpolator */
-				for (curr = ti_global.list; curr; curr = curr->next)
-					if (is_better_time_interpolator(curr))
-						time_interpolator = curr;
-			}
+	spin_lock(&time_interpolator_lock);
+	prev = &time_interpolator_list;
+	for (curr = *prev; curr; curr = curr->next) {
+		if (curr == ti) {
+			*prev = curr->next;
+			break;
 		}
-		write_sequnlock_irq(&xtime_lock);
+		prev = &curr->next;
 	}
-	spin_unlock(&ti_global.lock);
-}
 
+	write_seqlock_irq(&xtime_lock);
+	if (ti == time_interpolator) {
+		/* we lost the best time-interpolator: */
+		time_interpolator = NULL;
+		/* find the next-best interpolator */
+		for (curr = time_interpolator_list; curr; curr = curr->next)
+			if (is_better_time_interpolator(curr))
+				time_interpolator = curr;
+	}
+	write_sequnlock_irq(&xtime_lock);
+	spin_unlock(&time_interpolator_lock);
+}
 #endif /* CONFIG_TIME_INTERPOLATION */
diff -urN linux-2.5.70-bk9/mm/filemap.c linux-2.5.70-bk10/mm/filemap.c
--- linux-2.5.70-bk9/mm/filemap.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/mm/filemap.c	2003-06-05 04:41:37.000000000 -0700
@@ -81,8 +81,6 @@
 {
 	struct address_space *mapping = page->mapping;
 
-	BUG_ON(PageDirty(page) && !PageSwapCache(page));
-
 	radix_tree_delete(&mapping->page_tree, page->index);
 	list_del(&page->list);
 	page->mapping = NULL;
@@ -1410,6 +1408,11 @@
 	}
 }
 
+/*
+ * Copy as much as we can into the page and return the number of bytes which
+ * were sucessfully copied.  If a fault is encountered then clear the page
+ * out to (offset+bytes) and return the number of bytes which were copied.
+ */
 static inline size_t
 filemap_copy_from_user(struct page *page, unsigned long offset,
 			const char __user *buf, unsigned bytes)
@@ -1427,30 +1430,42 @@
 		left = __copy_from_user(kaddr + offset, buf, bytes);
 		kunmap(page);
 	}
-	return left ? 0 : bytes;
+	return bytes - left;
 }
 
 static size_t
 __filemap_copy_from_user_iovec(char *vaddr, 
 			const struct iovec *iov, size_t base, size_t bytes)
 {
-	size_t copied = 0;
+	size_t copied = 0, left = 0;
 
 	while (bytes) {
 		char __user *buf = iov->iov_base + base;
 		int copy = min(bytes, iov->iov_len - base);
 
 		base = 0;
-		if (__copy_from_user(vaddr, buf, copy))
-			break;
+		left = __copy_from_user(vaddr, buf, copy);
 		copied += copy;
 		bytes -= copy;
 		vaddr += copy;
 		iov++;
+
+		if (unlikely(left)) {
+			/* zero the rest of the target like __copy_from_user */
+			if (bytes)
+				memset(vaddr, 0, bytes);
+			break;
+		}
 	}
-	return copied;
+	return copied - left;
 }
 
+/*
+ * This has the same sideeffects and return value as filemap_copy_from_user().
+ * The difference is that on a fault we need to memset the remainder of the
+ * page (out to offset+bytes), to emulate filemap_copy_from_user()'s
+ * single-segment behaviour.
+ */
 static inline size_t
 filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
 			const struct iovec *iov, size_t base, size_t bytes)
@@ -1718,8 +1733,7 @@
 			copied = filemap_copy_from_user_iovec(page, offset,
 						cur_iov, iov_base, bytes);
 		flush_dcache_page(page);
-		status = a_ops->commit_write(file, page, offset,
-						offset + copied);
+		status = a_ops->commit_write(file, page, offset, offset+bytes);
 		if (likely(copied > 0)) {
 			if (!status)
 				status = copied;
diff -urN linux-2.5.70-bk9/net/core/dst.c linux-2.5.70-bk10/net/core/dst.c
--- linux-2.5.70-bk9/net/core/dst.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk10/net/core/dst.c	2003-06-05 04:41:37.000000000 -0700
@@ -1,7 +1,7 @@
 /*
- * net/dst.c	Protocol independent destination cache.
+ * net/core/dst.c	Protocol independent destination cache.
  *
- * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ * Authors:		Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  *
  */
 
diff -urN linux-2.5.70-bk9/net/core/dv.c linux-2.5.70-bk10/net/core/dv.c
--- linux-2.5.70-bk9/net/core/dv.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk10/net/core/dv.c	2003-06-05 04:41:37.000000000 -0700
@@ -5,8 +5,6 @@
  *
  *		Generic frame diversion
  *
- * Version:	@(#)eth.c	0.41	09/09/2000
- *
  * Authors:	
  * 		Benoit LOCHER:	initial integration within the kernel with support for ethernet
  * 		Dave Miller:	improvement on the code (correctness, performance and source files)
diff -urN linux-2.5.70-bk9/net/core/filter.c linux-2.5.70-bk10/net/core/filter.c
--- linux-2.5.70-bk9/net/core/filter.c	2003-05-26 18:00:28.000000000 -0700
+++ linux-2.5.70-bk10/net/core/filter.c	2003-06-05 04:41:37.000000000 -0700
@@ -36,14 +36,13 @@
 #include <linux/filter.h>
 
 /* No hurry in this branch */
-
 static u8 *load_pointer(struct sk_buff *skb, int k)
 {
 	u8 *ptr = NULL;
 
-	if (k>=SKF_NET_OFF)
+	if (k >= SKF_NET_OFF)
 		ptr = skb->nh.raw + k - SKF_NET_OFF;
-	else if (k>=SKF_LL_OFF)
+	else if (k >= SKF_LL_OFF)
 		ptr = skb->mac.raw + k - SKF_LL_OFF;
 
 	if (ptr >= skb->head && ptr < skb->tail)
@@ -80,268 +79,224 @@
 	/*
 	 * Process array of filter instructions.
 	 */
-
-	for(pc = 0; pc < flen; pc++)
-	{
+	for (pc = 0; pc < flen; pc++) {
 		fentry = &filter[pc];
 			
-		switch(fentry->code)
-		{
-			case BPF_ALU|BPF_ADD|BPF_X:
-				A += X;
-				continue;
-
-			case BPF_ALU|BPF_ADD|BPF_K:
-				A += fentry->k;
-				continue;
-
-			case BPF_ALU|BPF_SUB|BPF_X:
-				A -= X;
-				continue;
-
-			case BPF_ALU|BPF_SUB|BPF_K:
-				A -= fentry->k;
-				continue;
-
-			case BPF_ALU|BPF_MUL|BPF_X:
-				A *= X;
-				continue;
-
-			case BPF_ALU|BPF_MUL|BPF_K:
-				A *= fentry->k;
-				continue;
-
-			case BPF_ALU|BPF_DIV|BPF_X:
-				if(X == 0)
-					return (0);
-				A /= X;
-				continue;
-
-			case BPF_ALU|BPF_DIV|BPF_K:
-				if(fentry->k == 0)
-					return (0);
-				A /= fentry->k;
-				continue;
-
-			case BPF_ALU|BPF_AND|BPF_X:
-				A &= X;
-				continue;
-
-			case BPF_ALU|BPF_AND|BPF_K:
-				A &= fentry->k;
-				continue;
-
-			case BPF_ALU|BPF_OR|BPF_X:
-				A |= X;
-				continue;
-
-			case BPF_ALU|BPF_OR|BPF_K:
-				A |= fentry->k;
-				continue;
-
-			case BPF_ALU|BPF_LSH|BPF_X:
-				A <<= X;
-				continue;
-
-			case BPF_ALU|BPF_LSH|BPF_K:
-				A <<= fentry->k;
-				continue;
-
-			case BPF_ALU|BPF_RSH|BPF_X:
-				A >>= X;
-				continue;
-
-			case BPF_ALU|BPF_RSH|BPF_K:
-				A >>= fentry->k;
-				continue;
-
-			case BPF_ALU|BPF_NEG:
-				A = -A;
-				continue;
-
-			case BPF_JMP|BPF_JA:
-				pc += fentry->k;
-				continue;
-
-			case BPF_JMP|BPF_JGT|BPF_K:
-				pc += (A > fentry->k) ? fentry->jt : fentry->jf;
-				continue;
-
-			case BPF_JMP|BPF_JGE|BPF_K:
-				pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
-				continue;
-
-			case BPF_JMP|BPF_JEQ|BPF_K:
-				pc += (A == fentry->k) ? fentry->jt : fentry->jf;
-				continue;
-
-			case BPF_JMP|BPF_JSET|BPF_K:
-				pc += (A & fentry->k) ? fentry->jt : fentry->jf;
-				continue;
-
-			case BPF_JMP|BPF_JGT|BPF_X:
-				pc += (A > X) ? fentry->jt : fentry->jf;
-				continue;
-
-			case BPF_JMP|BPF_JGE|BPF_X:
-				pc += (A >= X) ? fentry->jt : fentry->jf;
-				continue;
-
-			case BPF_JMP|BPF_JEQ|BPF_X:
-				pc += (A == X) ? fentry->jt : fentry->jf;
-				continue;
-
-			case BPF_JMP|BPF_JSET|BPF_X:
-				pc += (A & X) ? fentry->jt : fentry->jf;
+		switch (fentry->code) {
+		case BPF_ALU|BPF_ADD|BPF_X:
+			A += X;
+			continue;
+		case BPF_ALU|BPF_ADD|BPF_K:
+			A += fentry->k;
+			continue;
+		case BPF_ALU|BPF_SUB|BPF_X:
+			A -= X;
+			continue;
+		case BPF_ALU|BPF_SUB|BPF_K:
+			A -= fentry->k;
+			continue;
+		case BPF_ALU|BPF_MUL|BPF_X:
+			A *= X;
+			continue;
+		case BPF_ALU|BPF_MUL|BPF_K:
+			A *= fentry->k;
+			continue;
+		case BPF_ALU|BPF_DIV|BPF_X:
+			if (X == 0)
+				return 0;
+			A /= X;
+			continue;
+		case BPF_ALU|BPF_DIV|BPF_K:
+			if (fentry->k == 0)
+				return 0;
+			A /= fentry->k;
+			continue;
+		case BPF_ALU|BPF_AND|BPF_X:
+			A &= X;
+			continue;
+		case BPF_ALU|BPF_AND|BPF_K:
+			A &= fentry->k;
+			continue;
+		case BPF_ALU|BPF_OR|BPF_X:
+			A |= X;
+			continue;
+		case BPF_ALU|BPF_OR|BPF_K:
+			A |= fentry->k;
+			continue;
+		case BPF_ALU|BPF_LSH|BPF_X:
+			A <<= X;
+			continue;
+		case BPF_ALU|BPF_LSH|BPF_K:
+			A <<= fentry->k;
+			continue;
+		case BPF_ALU|BPF_RSH|BPF_X:
+			A >>= X;
+			continue;
+		case BPF_ALU|BPF_RSH|BPF_K:
+			A >>= fentry->k;
+			continue;
+		case BPF_ALU|BPF_NEG:
+			A = -A;
+			continue;
+		case BPF_JMP|BPF_JA:
+			pc += fentry->k;
+			continue;
+		case BPF_JMP|BPF_JGT|BPF_K:
+			pc += (A > fentry->k) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_JMP|BPF_JGE|BPF_K:
+			pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_JMP|BPF_JEQ|BPF_K:
+			pc += (A == fentry->k) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_JMP|BPF_JSET|BPF_K:
+			pc += (A & fentry->k) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_JMP|BPF_JGT|BPF_X:
+			pc += (A > X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_JMP|BPF_JGE|BPF_X:
+			pc += (A >= X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_JMP|BPF_JEQ|BPF_X:
+			pc += (A == X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_JMP|BPF_JSET|BPF_X:
+			pc += (A & X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_LD|BPF_W|BPF_ABS:
+			k = fentry->k;
+ load_w:
+			if (k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) {
+				A = ntohl(*(u32*)&data[k]);
 				continue;
+			}
+			if (k < 0) {
+				u8 *ptr;
 
-			case BPF_LD|BPF_W|BPF_ABS:
-				k = fentry->k;
-load_w:
-				if(k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) {
-					A = ntohl(*(u32*)&data[k]);
+				if (k >= SKF_AD_OFF)
+					break;
+				ptr = load_pointer(skb, k);
+				if (ptr) {
+					A = ntohl(*(u32*)ptr);
 					continue;
 				}
-				if (k<0) {
-					u8 *ptr;
-
-					if (k>=SKF_AD_OFF)
-						break;
-					if ((ptr = load_pointer(skb, k)) != NULL) {
-						A = ntohl(*(u32*)ptr);
-						continue;
-					}
-				} else {
-					u32 tmp;
-					if (!skb_copy_bits(skb, k, &tmp, 4)) {
-						A = ntohl(tmp);
-						continue;
-					}
+			} else {
+				u32 tmp;
+				if (!skb_copy_bits(skb, k, &tmp, 4)) {
+					A = ntohl(tmp);
+					continue;
 				}
-				return 0;
+			}
+			return 0;
+		case BPF_LD|BPF_H|BPF_ABS:
+			k = fentry->k;
+ load_h:
+			if (k >= 0 && (unsigned int)(k + sizeof(u16)) <= len) {
+				A = ntohs(*(u16*)&data[k]);
+				continue;
+			}
+			if (k < 0) {
+				u8 *ptr;
 
-			case BPF_LD|BPF_H|BPF_ABS:
-				k = fentry->k;
-load_h:
-				if(k >= 0 && (unsigned int) (k + sizeof(u16)) <= len) {
-					A = ntohs(*(u16*)&data[k]);
+				if (k >= SKF_AD_OFF)
+					break;
+				ptr = load_pointer(skb, k);
+				if (ptr) {
+					A = ntohs(*(u16*)ptr);
 					continue;
 				}
-				if (k<0) {
-					u8 *ptr;
-
-					if (k>=SKF_AD_OFF)
-						break;
-					if ((ptr = load_pointer(skb, k)) != NULL) {
-						A = ntohs(*(u16*)ptr);
-						continue;
-					}
-				} else {
-					u16 tmp;
-					if (!skb_copy_bits(skb, k, &tmp, 2)) {
-						A = ntohs(tmp);
-						continue;
-					}
+			} else {
+				u16 tmp;
+				if (!skb_copy_bits(skb, k, &tmp, 2)) {
+					A = ntohs(tmp);
+					continue;
 				}
-				return 0;
-
-			case BPF_LD|BPF_B|BPF_ABS:
-				k = fentry->k;
+			}
+			return 0;
+		case BPF_LD|BPF_B|BPF_ABS:
+			k = fentry->k;
 load_b:
-				if(k >= 0 && (unsigned int)k < len) {
-					A = data[k];
+			if (k >= 0 && (unsigned int)k < len) {
+				A = data[k];
+				continue;
+			}
+			if (k < 0) {
+				u8 *ptr;
+
+				if (k >= SKF_AD_OFF)
+					break;
+				ptr = load_pointer(skb, k);
+				if (ptr) {
+					A = *ptr;
 					continue;
 				}
-				if (k<0) {
-					u8 *ptr;
-
-					if (k>=SKF_AD_OFF)
-						break;
-					if ((ptr = load_pointer(skb, k)) != NULL) {
-						A = *ptr;
-						continue;
-					}
-				} else {
-					u8 tmp;
-					if (!skb_copy_bits(skb, k, &tmp, 1)) {
-						A = tmp;
-						continue;
-					}
+			} else {
+				u8 tmp;
+				if (!skb_copy_bits(skb, k, &tmp, 1)) {
+					A = tmp;
+					continue;
 				}
+			}
+			return 0;
+		case BPF_LD|BPF_W|BPF_LEN:
+			A = len;
+			continue;
+		case BPF_LDX|BPF_W|BPF_LEN:
+			X = len;
+			continue;
+		case BPF_LD|BPF_W|BPF_IND:
+			k = X + fentry->k;
+			goto load_w;
+		case BPF_LD|BPF_H|BPF_IND:
+			k = X + fentry->k;
+			goto load_h;
+		case BPF_LD|BPF_B|BPF_IND:
+			k = X + fentry->k;
+			goto load_b;
+		case BPF_LDX|BPF_B|BPF_MSH:
+			k = fentry->k;
+			if (k >= 0 && (unsigned int)k >= len)
 				return 0;
-
-			case BPF_LD|BPF_W|BPF_LEN:
-				A = len;
-				continue;
-
-			case BPF_LDX|BPF_W|BPF_LEN:
-				X = len;
-				continue;
-
-			case BPF_LD|BPF_W|BPF_IND:
-				k = X + fentry->k;
-				goto load_w;
-
-                       case BPF_LD|BPF_H|BPF_IND:
-				k = X + fentry->k;
-				goto load_h;
-
-                       case BPF_LD|BPF_B|BPF_IND:
-				k = X + fentry->k;
-				goto load_b;
-
-			case BPF_LDX|BPF_B|BPF_MSH:
-				k = fentry->k;
-				if(k >= 0 && (unsigned int)k >= len)
-					return (0);
-				X = (data[k] & 0xf) << 2;
-				continue;
-
-			case BPF_LD|BPF_IMM:
-				A = fentry->k;
-				continue;
-
-			case BPF_LDX|BPF_IMM:
-				X = fentry->k;
-				continue;
-
-			case BPF_LD|BPF_MEM:
-				A = mem[fentry->k];
-				continue;
-
-			case BPF_LDX|BPF_MEM:
-				X = mem[fentry->k];
-				continue;
-
-			case BPF_MISC|BPF_TAX:
-				X = A;
-				continue;
-
-			case BPF_MISC|BPF_TXA:
-				A = X;
-				continue;
-
-			case BPF_RET|BPF_K:
-				return ((unsigned int)fentry->k);
-
-			case BPF_RET|BPF_A:
-				return ((unsigned int)A);
-
-			case BPF_ST:
-				mem[fentry->k] = A;
-				continue;
-
-			case BPF_STX:
-				mem[fentry->k] = X;
-				continue;
-
-			default:
-				/* Invalid instruction counts as RET */
-				return (0);
+			X = (data[k] & 0xf) << 2;
+			continue;
+		case BPF_LD|BPF_IMM:
+			A = fentry->k;
+			continue;
+		case BPF_LDX|BPF_IMM:
+			X = fentry->k;
+			continue;
+		case BPF_LD|BPF_MEM:
+			A = mem[fentry->k];
+			continue;
+		case BPF_LDX|BPF_MEM:
+			X = mem[fentry->k];
+			continue;
+		case BPF_MISC|BPF_TAX:
+			X = A;
+			continue;
+		case BPF_MISC|BPF_TXA:
+			A = X;
+			continue;
+		case BPF_RET|BPF_K:
+			return ((unsigned int)fentry->k);
+		case BPF_RET|BPF_A:
+			return ((unsigned int)A);
+		case BPF_ST:
+			mem[fentry->k] = A;
+			continue;
+		case BPF_STX:
+			mem[fentry->k] = X;
+			continue;
+		default:
+			/* Invalid instruction counts as RET */
+			return 0;
 		}
 
-		/* Handle ancillary data, which are impossible
-		   (or very difficult) to get parsing packet contents.
+		/*
+		 * Handle ancillary data, which are impossible
+		 * (or very difficult) to get parsing packet contents.
 		 */
 		switch (k-SKF_AD_OFF) {
 		case SKF_AD_PROTOCOL:
@@ -358,7 +313,7 @@
 		}
 	}
 
-	return (0);
+	return 0;
 }
 
 /**
@@ -373,75 +328,55 @@
  *
  * Returns 0 if the rule set is legal or a negative errno code if not.
  */
-
 int sk_chk_filter(struct sock_filter *filter, int flen)
 {
 	struct sock_filter *ftest;
-        int pc;
+	int pc;
 
-	if ((unsigned int) flen >= (~0U / sizeof(struct sock_filter)))
+	if ((unsigned int)flen >= (~0U / sizeof(struct sock_filter)))
 		return -EINVAL;
 
-       /*
-        * Check the filter code now.
-        */
-	for(pc = 0; pc < flen; pc++)
-	{
-		/*
-                 *	All jumps are forward as they are not signed
-                 */
-                 
-                ftest = &filter[pc];
-		if(BPF_CLASS(ftest->code) == BPF_JMP)
-		{
-			/*
-			 *	But they mustn't jump off the end.
-			 */
-			if(BPF_OP(ftest->code) == BPF_JA)
-			{
-				/* Note, the large ftest->k might cause
-				   loops. Compare this with conditional
-				   jumps below, where offsets are limited. --ANK (981016)
+	/* check the filter code now */
+	for (pc = 0; pc < flen; pc++) {
+		/* all jumps are forward as they are not signed */
+		ftest = &filter[pc];
+		if (BPF_CLASS(ftest->code) == BPF_JMP) {
+			/* but they mustn't jump off the end */
+			if (BPF_OP(ftest->code) == BPF_JA) {
+				/*
+				 * Note, the large ftest->k might cause loops.
+				 * Compare this with conditional jumps below,
+				 * where offsets are limited. --ANK (981016)
 				 */
 				if (ftest->k >= (unsigned)(flen-pc-1))
 					return -EINVAL;
-			}
-                        else
-			{
-				/*
-				 *	For conditionals both must be safe
-				 */
- 				if(pc + ftest->jt +1 >= flen || pc + ftest->jf +1 >= flen)
+			} else {
+				/* for conditionals both must be safe */
+ 				if (pc + ftest->jt +1 >= flen ||
+				    pc + ftest->jf +1 >= flen)
 					return -EINVAL;
 			}
-                }
+		}
 
-                /*
-                 *	Check that memory operations use valid addresses.
-                 */
-                 
-                if (ftest->k >= BPF_MEMWORDS)
-                {
-                	/*
-                	 *	But it might not be a memory operation...
-                	 */
+		/* check that memory operations use valid addresses. */
+		if (ftest->k >= BPF_MEMWORDS) {
+			/* but it might not be a memory operation... */
 			switch (ftest->code) {
 			case BPF_ST:	
 			case BPF_STX:	
 			case BPF_LD|BPF_MEM:	
 			case BPF_LDX|BPF_MEM:	
-                		return -EINVAL;
+				return -EINVAL;
 			}
 		}
-        }
+	}
 
 	/*
-	 *	The program must end with a return. We don't care where they
-	 *	jumped within the script (its always forwards) but in the
-	 *	end they _will_ hit this.
+	 * The program must end with a return. We don't care where they
+	 * jumped within the script (its always forwards) but in the end
+	 * they _will_ hit this.
 	 */
-	 
-        return (BPF_CLASS(filter[flen - 1].code) == BPF_RET)?0:-EINVAL;
+        return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL;
 }
 
 /**
@@ -454,7 +389,6 @@
  * occurs or there is insufficient memory for the filter a negative
  * errno code is returned. On success the return is zero.
  */
-
 int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
 {
 	struct sk_filter *fp; 
@@ -463,12 +397,11 @@
 
 	/* Make sure new filter is there and in the right amounts. */
         if (fprog->filter == NULL || fprog->len > BPF_MAXINSNS)
-                return (-EINVAL);
-
-	fp = (struct sk_filter *)sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
-	if(fp == NULL)
-		return (-ENOMEM);
+                return -EINVAL;
 
+	fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
+	if (!fp)
+		return -ENOMEM;
 	if (copy_from_user(fp->insns, fprog->filter, fsize)) {
 		sock_kfree_s(sk, fp, fsize+sizeof(*fp)); 
 		return -EFAULT;
@@ -477,7 +410,8 @@
 	atomic_set(&fp->refcnt, 1);
 	fp->len = fprog->len;
 
-	if ((err = sk_chk_filter(fp->insns, fp->len))==0) {
+	err = sk_chk_filter(fp->insns, fp->len);
+	if (!err) {
 		struct sk_filter *old_fp;
 
 		spin_lock_bh(&sk->lock.slock);
@@ -489,6 +423,5 @@
 
 	if (fp)
 		sk_filter_release(sk, fp);
-
-	return (err);
+	return err;
 }
diff -urN linux-2.5.70-bk9/net/core/iovec.c linux-2.5.70-bk10/net/core/iovec.c
--- linux-2.5.70-bk9/net/core/iovec.c	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk10/net/core/iovec.c	2003-06-05 04:41:37.000000000 -0700
@@ -41,35 +41,36 @@
 {
 	int size, err, ct;
 	
-	if(m->msg_namelen)
-	{
-		if(mode==VERIFY_READ)
-		{
-			err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address);
-			if(err<0)
-				goto out;
+	if (m->msg_namelen) {
+		if (mode == VERIFY_READ) {
+			err = move_addr_to_kernel(m->msg_name, m->msg_namelen,
+						  address);
+			if (err < 0)
+				return err;
 		}
-		
 		m->msg_name = address;
-	} else
+	} else {
 		m->msg_name = NULL;
+	}
 
-	err = -EFAULT;
 	size = m->msg_iovlen * sizeof(struct iovec);
 	if (copy_from_user(iov, m->msg_iov, size))
-		goto out;
-	m->msg_iov=iov;
+		return -EFAULT;
 
-	for (err = 0, ct = 0; ct < m->msg_iovlen; ct++) {
+	m->msg_iov = iov;
+	err = 0;
+
+	for (ct = 0; ct < m->msg_iovlen; ct++) {
 		err += iov[ct].iov_len;
-		/* Goal is not to verify user data, but to prevent returning
-		   negative value, which is interpreted as errno.
-		   Overflow is still possible, but it is harmless.
+		/*
+		 * Goal is not to verify user data, but to prevent returning
+		 * negative value, which is interpreted as errno.
+		 * Overflow is still possible, but it is harmless.
 		 */
 		if (err < 0)
 			return -EMSGSIZE;
 	}
-out:
+
 	return err;
 }
 
@@ -81,25 +82,20 @@
  
 int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
 {
-	int err = -EFAULT; 
-
-	while(len>0)
-	{
-		if(iov->iov_len)
-		{
+	while (len > 0) {
+		if (iov->iov_len) {
 			int copy = min_t(unsigned int, iov->iov_len, len);
 			if (copy_to_user(iov->iov_base, kdata, copy))
-				goto out;
-			kdata+=copy;
-			len-=copy;
-			iov->iov_len-=copy;
-			iov->iov_base+=copy;
+				return -EFAULT;
+			kdata += copy;
+			len -= copy;
+			iov->iov_len -= copy;
+			iov->iov_base += copy;
 		}
 		iov++;
 	}
-	err = 0;
-out:
-	return err;
+
+	return 0;
 }
 
 /*
@@ -110,16 +106,14 @@
  
 void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len)
 {
-	while(len>0)
-	{
-		if(iov->iov_len)
-		{
+	while (len > 0) {
+		if (iov->iov_len) {
 			int copy = min_t(unsigned int, iov->iov_len, len);
 			memcpy(iov->iov_base, kdata, copy);
-			kdata+=copy;
-			len-=copy;
-			iov->iov_len-=copy;
-			iov->iov_base+=copy;
+			kdata += copy;
+			len -= copy;
+			iov->iov_len -= copy;
+			iov->iov_base += copy;
 		}
 		iov++;
 	}
@@ -134,59 +128,47 @@
  
 int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
 {
-	int err = -EFAULT; 
-
-	while(len>0)
-	{
-		if(iov->iov_len)
-		{
+	while (len > 0) {
+		if (iov->iov_len) {
 			int copy = min_t(unsigned int, len, iov->iov_len);
 			if (copy_from_user(kdata, iov->iov_base, copy))
-				goto out;
-			len-=copy;
-			kdata+=copy;
-			iov->iov_base+=copy;
-			iov->iov_len-=copy;
+				return -EFAULT;
+			len -= copy;
+			kdata += copy;
+			iov->iov_base += copy;
+			iov->iov_len -= copy;
 		}
 		iov++;
 	}
-	err = 0;
-out:
-	return err; 
-}
 
+	return 0;
+}
 
 /*
  *	For use with ip_build_xmit
  */
-
 int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
 			int len)
 {
-	int err = -EFAULT;
-
 	/* Skip over the finished iovecs */
-	while(offset >= iov->iov_len)
-	{
+	while (offset >= iov->iov_len) {
 		offset -= iov->iov_len;
 		iov++;
 	}
 
-	while (len > 0)
-	{
+	while (len > 0) {
 		u8 *base = iov->iov_base + offset;
 		int copy = min_t(unsigned int, len, iov->iov_len - offset);
 
 		offset = 0;
 		if (copy_from_user(kdata, base, copy))
-			goto out;
-		len   -= copy;
+			return -EFAULT;
+		len -= copy;
 		kdata += copy;
 		iov++;
 	}
-	err = 0;
-out:
-	return err;
+
+	return 0;
 }
 
 /*
@@ -197,7 +179,6 @@
  *	ip_build_xmit must ensure that when fragmenting only the last
  *	call to this function will be unaligned also.
  */
-
 int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
 				 int offset, unsigned int len, int *csump)
 {
@@ -205,21 +186,19 @@
 	int partial_cnt = 0, err = 0;
 
 	/* Skip over the finished iovecs */
-	while (offset >= iov->iov_len)
-	{
+	while (offset >= iov->iov_len) {
 		offset -= iov->iov_len;
 		iov++;
 	}
 
-	while (len > 0)
-	{
+	while (len > 0) {
 		u8 *base = iov->iov_base + offset;
 		int copy = min_t(unsigned int, len, iov->iov_len - offset);
 
 		offset = 0;
+
 		/* There is a remnant from previous iov. */
-		if (partial_cnt)
-		{
+		if (partial_cnt) {
 			int par_len = 4 - partial_cnt;
 
 			/* iov component is too short ... */
@@ -227,9 +206,9 @@
 				if (copy_from_user(kdata, base, copy))
 					goto out_fault;
 				kdata += copy;
-				base  += copy;
+				base += copy;
 				partial_cnt += copy;
-				len   -= copy;
+				len -= copy;
 				iov++;
 				if (len)
 					continue;
@@ -247,11 +226,9 @@
 			partial_cnt = 0;
 		}
 
-		if (len > copy)
-		{
+		if (len > copy) {
 			partial_cnt = copy % 4;
-			if (partial_cnt)
-			{
+			if (partial_cnt) {
 				copy -= partial_cnt;
 				if (copy_from_user(kdata + copy, base + copy,
 				 		partial_cnt))
diff -urN linux-2.5.70-bk9/net/ipv4/Kconfig linux-2.5.70-bk10/net/ipv4/Kconfig
--- linux-2.5.70-bk9/net/ipv4/Kconfig	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv4/Kconfig	2003-06-05 04:41:37.000000000 -0700
@@ -343,6 +343,10 @@
 
 config INET_AH
 	tristate "IP: AH transformation"
+	select CRYPTO
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
 	---help---
 	  Support for IPsec AH.
 
@@ -350,6 +354,11 @@
 
 config INET_ESP
 	tristate "IP: ESP transformation"
+	select CRYPTO
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
+	select CRYPTO_DES
 	---help---
 	  Support for IPsec ESP.
 
@@ -357,6 +366,8 @@
 
 config INET_IPCOMP
 	tristate "IP: IPComp transformation"
+	select CRYPTO
+	select CRYPTO_DEFLATE
 	---help---
 	  Support for IP Paylod Compression (RFC3173), typically needed
 	  for IPsec.
diff -urN linux-2.5.70-bk9/net/ipv4/Makefile linux-2.5.70-bk10/net/ipv4/Makefile
--- linux-2.5.70-bk9/net/ipv4/Makefile	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv4/Makefile	2003-06-05 04:41:37.000000000 -0700
@@ -16,8 +16,8 @@
 obj-$(CONFIG_NET_IPIP) += ipip.o
 obj-$(CONFIG_NET_IPGRE) += ip_gre.o
 obj-$(CONFIG_SYN_COOKIES) += syncookies.o
-obj-$(CONFIG_INET_AH) += ah.o
-obj-$(CONFIG_INET_ESP) += esp.o
+obj-$(CONFIG_INET_AH) += ah4.o
+obj-$(CONFIG_INET_ESP) += esp4.o
 obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
 obj-$(CONFIG_IP_PNP) += ipconfig.o
 obj-$(CONFIG_NETFILTER)	+= netfilter/
diff -urN linux-2.5.70-bk9/net/ipv4/ah.c linux-2.5.70-bk10/net/ipv4/ah.c
--- linux-2.5.70-bk9/net/ipv4/ah.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv4/ah.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,361 +0,0 @@
-#include <linux/config.h>
-#include <linux/module.h>
-#include <net/ip.h>
-#include <net/xfrm.h>
-#include <net/ah.h>
-#include <linux/crypto.h>
-#include <linux/pfkeyv2.h>
-#include <net/icmp.h>
-#include <asm/scatterlist.h>
-
-
-/* Clear mutable options and find final destination to substitute
- * into IP header for icv calculation. Options are already checked
- * for validity, so paranoia is not required. */
-
-static int ip_clear_mutable_options(struct iphdr *iph, u32 *daddr)
-{
-	unsigned char * optptr = (unsigned char*)(iph+1);
-	int  l = iph->ihl*4 - sizeof(struct iphdr);
-	int  optlen;
-
-	while (l > 0) {
-		switch (*optptr) {
-		case IPOPT_END:
-			return 0;
-		case IPOPT_NOOP:
-			l--;
-			optptr++;
-			continue;
-		}
-		optlen = optptr[1];
-		if (optlen<2 || optlen>l)
-			return -EINVAL;
-		switch (*optptr) {
-		case IPOPT_SEC:
-		case 0x85:	/* Some "Extended Security" crap. */
-		case 0x86:	/* Another "Commercial Security" crap. */
-		case IPOPT_RA:
-		case 0x80|21:	/* RFC1770 */
-			break;
-		case IPOPT_LSRR:
-		case IPOPT_SSRR:
-			if (optlen < 6)
-				return -EINVAL;
-			memcpy(daddr, optptr+optlen-4, 4);
-			/* Fall through */
-		default:
-			memset(optptr+2, 0, optlen-2);
-		}
-		l -= optlen;
-		optptr += optlen;
-	}
-	return 0;
-}
-
-static int ah_output(struct sk_buff *skb)
-{
-	int err;
-	struct dst_entry *dst = skb->dst;
-	struct xfrm_state *x  = dst->xfrm;
-	struct iphdr *iph, *top_iph;
-	struct ip_auth_hdr *ah;
-	struct ah_data *ahp;
-	union {
-		struct iphdr	iph;
-		char 		buf[60];
-	} tmp_iph;
-
-	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
-		err = -EINVAL;
-		goto error_nolock;
-	}
-
-	spin_lock_bh(&x->lock);
-	err = xfrm_check_output(x, skb, AF_INET);
-	if (err)
-		goto error;
-
-	iph = skb->nh.iph;
-	if (x->props.mode) {
-		top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
-		top_iph->ihl = 5;
-		top_iph->version = 4;
-		top_iph->tos = 0;
-		top_iph->tot_len = htons(skb->len);
-		top_iph->frag_off = 0;
-		if (!(iph->frag_off&htons(IP_DF)))
-			__ip_select_ident(top_iph, dst, 0);
-		top_iph->ttl = 0;
-		top_iph->protocol = IPPROTO_AH;
-		top_iph->check = 0;
-		top_iph->saddr = x->props.saddr.a4;
-		top_iph->daddr = x->id.daddr.a4;
-		ah = (struct ip_auth_hdr*)(top_iph+1);
-		ah->nexthdr = IPPROTO_IPIP;
-	} else {
-		memcpy(&tmp_iph, skb->data, iph->ihl*4);
-		top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
-		memcpy(top_iph, &tmp_iph, iph->ihl*4);
-		iph = &tmp_iph.iph;
-		top_iph->tos = 0;
-		top_iph->tot_len = htons(skb->len);
-		top_iph->frag_off = 0;
-		top_iph->ttl = 0;
-		top_iph->protocol = IPPROTO_AH;
-		top_iph->check = 0;
-		if (top_iph->ihl != 5) {
-			err = ip_clear_mutable_options(top_iph, &top_iph->daddr);
-			if (err)
-				goto error;
-		}
-		ah = (struct ip_auth_hdr*)((char*)top_iph+iph->ihl*4);
-		ah->nexthdr = iph->protocol;
-	}
-	ahp = x->data;
-	ah->hdrlen  = (XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + 
-				   ahp->icv_trunc_len) >> 2) - 2;
-
-	ah->reserved = 0;
-	ah->spi = x->id.spi;
-	ah->seq_no = htonl(++x->replay.oseq);
-	ahp->icv(ahp, skb, ah->auth_data);
-	top_iph->tos = iph->tos;
-	top_iph->ttl = iph->ttl;
-	if (x->props.mode) {
-		top_iph->frag_off = iph->frag_off&~htons(IP_MF|IP_OFFSET);
-		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-	} else {
-		top_iph->frag_off = iph->frag_off;
-		top_iph->daddr = iph->daddr;
-		if (iph->ihl != 5)
-			memcpy(top_iph+1, iph+1, iph->ihl*4 - sizeof(struct iphdr));
-	}
-	ip_send_check(top_iph);
-
-	skb->nh.raw = skb->data;
-
-	x->curlft.bytes += skb->len;
-	x->curlft.packets++;
-	spin_unlock_bh(&x->lock);
-	if ((skb->dst = dst_pop(dst)) == NULL) {
-		err = -EHOSTUNREACH;
-		goto error_nolock;
-	}
-	return NET_XMIT_BYPASS;
-
-error:
-	spin_unlock_bh(&x->lock);
-error_nolock:
-	kfree_skb(skb);
-	return err;
-}
-
-int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
-{
-	int ah_hlen;
-	struct iphdr *iph;
-	struct ip_auth_hdr *ah;
-	struct ah_data *ahp;
-	char work_buf[60];
-
-	if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
-		goto out;
-
-	ah = (struct ip_auth_hdr*)skb->data;
-	ahp = x->data;
-	ah_hlen = (ah->hdrlen + 2) << 2;
-	
-	if (ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_full_len) &&
-	    ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len)) 
-		goto out;
-
-	if (!pskb_may_pull(skb, ah_hlen))
-		goto out;
-
-	/* We are going to _remove_ AH header to keep sockets happy,
-	 * so... Later this can change. */
-	if (skb_cloned(skb) &&
-	    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-		goto out;
-
-	skb->ip_summed = CHECKSUM_NONE;
-
-	ah = (struct ip_auth_hdr*)skb->data;
-	iph = skb->nh.iph;
-
-	memcpy(work_buf, iph, iph->ihl*4);
-
-	iph->ttl = 0;
-	iph->tos = 0;
-	iph->frag_off = 0;
-	iph->check = 0;
-	if (iph->ihl != 5) {
-		u32 dummy;
-		if (ip_clear_mutable_options(iph, &dummy))
-			goto out;
-	}
-        {
-		u8 auth_data[ahp->icv_trunc_len];
-		
-		memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
-		skb_push(skb, skb->data - skb->nh.raw);
-		ahp->icv(ahp, skb, ah->auth_data);
-		if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {
-			x->stats.integrity_failed++;
-			goto out;
-		}
-	}
-	((struct iphdr*)work_buf)->protocol = ah->nexthdr;
-	skb->nh.raw = skb_pull(skb, ah_hlen);
-	memcpy(skb->nh.raw, work_buf, iph->ihl*4);
-	skb->nh.iph->tot_len = htons(skb->len);
-	skb_pull(skb, skb->nh.iph->ihl*4);
-	skb->h.raw = skb->data;
-
-	return 0;
-
-out:
-	return -EINVAL;
-}
-
-void ah4_err(struct sk_buff *skb, u32 info)
-{
-	struct iphdr *iph = (struct iphdr*)skb->data;
-	struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+(iph->ihl<<2));
-	struct xfrm_state *x;
-
-	if (skb->h.icmph->type != ICMP_DEST_UNREACH ||
-	    skb->h.icmph->code != ICMP_FRAG_NEEDED)
-		return;
-
-	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
-	if (!x)
-		return;
-	printk(KERN_DEBUG "pmtu discvovery on SA AH/%08x/%08x\n",
-	       ntohl(ah->spi), ntohl(iph->daddr));
-	xfrm_state_put(x);
-}
-
-static int ah_init_state(struct xfrm_state *x, void *args)
-{
-	struct ah_data *ahp = NULL;
-	struct xfrm_algo_desc *aalg_desc;
-
-	/* null auth can use a zero length key */
-	if (x->aalg->alg_key_len > 512)
-		goto error;
-
-	ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
-	if (ahp == NULL)
-		return -ENOMEM;
-
-	memset(ahp, 0, sizeof(*ahp));
-
-	ahp->key = x->aalg->alg_key;
-	ahp->key_len = (x->aalg->alg_key_len+7)/8;
-	ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
-	if (!ahp->tfm)
-		goto error;
-	ahp->icv = ah_hmac_digest;
-	
-	/*
-	 * Lookup the algorithm description maintained by xfrm_algo,
-	 * verify crypto transform properties, and store information
-	 * we need for AH processing.  This lookup cannot fail here
-	 * after a successful crypto_alloc_tfm().
-	 */
-	aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
-	BUG_ON(!aalg_desc);
-
-	if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
-	    crypto_tfm_alg_digestsize(ahp->tfm)) {
-		printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
-		       x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm),
-		       aalg_desc->uinfo.auth.icv_fullbits/8);
-		goto error;
-	}
-	
-	ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
-	ahp->icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
-	
-	ahp->work_icv = kmalloc(ahp->icv_full_len, GFP_KERNEL);
-	if (!ahp->work_icv)
-		goto error;
-	
-	x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len);
-	if (x->props.mode)
-		x->props.header_len += sizeof(struct iphdr);
-	x->data = ahp;
-
-	return 0;
-
-error:
-	if (ahp) {
-		if (ahp->work_icv)
-			kfree(ahp->work_icv);
-		if (ahp->tfm)
-			crypto_free_tfm(ahp->tfm);
-		kfree(ahp);
-	}
-	return -EINVAL;
-}
-
-static void ah_destroy(struct xfrm_state *x)
-{
-	struct ah_data *ahp = x->data;
-
-	if (ahp->work_icv) {
-		kfree(ahp->work_icv);
-		ahp->work_icv = NULL;
-	}
-	if (ahp->tfm) {
-		crypto_free_tfm(ahp->tfm);
-		ahp->tfm = NULL;
-	}
-	kfree(ahp);
-}
-
-
-static struct xfrm_type ah_type =
-{
-	.description	= "AH4",
-	.owner		= THIS_MODULE,
-	.proto	     	= IPPROTO_AH,
-	.init_state	= ah_init_state,
-	.destructor	= ah_destroy,
-	.input		= ah_input,
-	.output		= ah_output
-};
-
-static struct inet_protocol ah4_protocol = {
-	.handler	=	xfrm4_rcv,
-	.err_handler	=	ah4_err,
-	.no_policy	=	1,
-};
-
-static int __init ah4_init(void)
-{
-	if (xfrm_register_type(&ah_type, AF_INET) < 0) {
-		printk(KERN_INFO "ip ah init: can't add xfrm type\n");
-		return -EAGAIN;
-	}
-	if (inet_add_protocol(&ah4_protocol, IPPROTO_AH) < 0) {
-		printk(KERN_INFO "ip ah init: can't add protocol\n");
-		xfrm_unregister_type(&ah_type, AF_INET);
-		return -EAGAIN;
-	}
-	return 0;
-}
-
-static void __exit ah4_fini(void)
-{
-	if (inet_del_protocol(&ah4_protocol, IPPROTO_AH) < 0)
-		printk(KERN_INFO "ip ah close: can't remove protocol\n");
-	if (xfrm_unregister_type(&ah_type, AF_INET) < 0)
-		printk(KERN_INFO "ip ah close: can't remove xfrm type\n");
-}
-
-module_init(ah4_init);
-module_exit(ah4_fini);
-MODULE_LICENSE("GPL");
diff -urN linux-2.5.70-bk9/net/ipv4/ah4.c linux-2.5.70-bk10/net/ipv4/ah4.c
--- linux-2.5.70-bk9/net/ipv4/ah4.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/net/ipv4/ah4.c	2003-06-05 04:41:37.000000000 -0700
@@ -0,0 +1,361 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <net/ip.h>
+#include <net/xfrm.h>
+#include <net/ah.h>
+#include <linux/crypto.h>
+#include <linux/pfkeyv2.h>
+#include <net/icmp.h>
+#include <asm/scatterlist.h>
+
+
+/* Clear mutable options and find final destination to substitute
+ * into IP header for icv calculation. Options are already checked
+ * for validity, so paranoia is not required. */
+
+static int ip_clear_mutable_options(struct iphdr *iph, u32 *daddr)
+{
+	unsigned char * optptr = (unsigned char*)(iph+1);
+	int  l = iph->ihl*4 - sizeof(struct iphdr);
+	int  optlen;
+
+	while (l > 0) {
+		switch (*optptr) {
+		case IPOPT_END:
+			return 0;
+		case IPOPT_NOOP:
+			l--;
+			optptr++;
+			continue;
+		}
+		optlen = optptr[1];
+		if (optlen<2 || optlen>l)
+			return -EINVAL;
+		switch (*optptr) {
+		case IPOPT_SEC:
+		case 0x85:	/* Some "Extended Security" crap. */
+		case 0x86:	/* Another "Commercial Security" crap. */
+		case IPOPT_RA:
+		case 0x80|21:	/* RFC1770 */
+			break;
+		case IPOPT_LSRR:
+		case IPOPT_SSRR:
+			if (optlen < 6)
+				return -EINVAL;
+			memcpy(daddr, optptr+optlen-4, 4);
+			/* Fall through */
+		default:
+			memset(optptr+2, 0, optlen-2);
+		}
+		l -= optlen;
+		optptr += optlen;
+	}
+	return 0;
+}
+
+static int ah_output(struct sk_buff *skb)
+{
+	int err;
+	struct dst_entry *dst = skb->dst;
+	struct xfrm_state *x  = dst->xfrm;
+	struct iphdr *iph, *top_iph;
+	struct ip_auth_hdr *ah;
+	struct ah_data *ahp;
+	union {
+		struct iphdr	iph;
+		char 		buf[60];
+	} tmp_iph;
+
+	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
+		err = -EINVAL;
+		goto error_nolock;
+	}
+
+	spin_lock_bh(&x->lock);
+	err = xfrm_check_output(x, skb, AF_INET);
+	if (err)
+		goto error;
+
+	iph = skb->nh.iph;
+	if (x->props.mode) {
+		top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+		top_iph->ihl = 5;
+		top_iph->version = 4;
+		top_iph->tos = 0;
+		top_iph->tot_len = htons(skb->len);
+		top_iph->frag_off = 0;
+		if (!(iph->frag_off&htons(IP_DF)))
+			__ip_select_ident(top_iph, dst, 0);
+		top_iph->ttl = 0;
+		top_iph->protocol = IPPROTO_AH;
+		top_iph->check = 0;
+		top_iph->saddr = x->props.saddr.a4;
+		top_iph->daddr = x->id.daddr.a4;
+		ah = (struct ip_auth_hdr*)(top_iph+1);
+		ah->nexthdr = IPPROTO_IPIP;
+	} else {
+		memcpy(&tmp_iph, skb->data, iph->ihl*4);
+		top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+		memcpy(top_iph, &tmp_iph, iph->ihl*4);
+		iph = &tmp_iph.iph;
+		top_iph->tos = 0;
+		top_iph->tot_len = htons(skb->len);
+		top_iph->frag_off = 0;
+		top_iph->ttl = 0;
+		top_iph->protocol = IPPROTO_AH;
+		top_iph->check = 0;
+		if (top_iph->ihl != 5) {
+			err = ip_clear_mutable_options(top_iph, &top_iph->daddr);
+			if (err)
+				goto error;
+		}
+		ah = (struct ip_auth_hdr*)((char*)top_iph+iph->ihl*4);
+		ah->nexthdr = iph->protocol;
+	}
+	ahp = x->data;
+	ah->hdrlen  = (XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + 
+				   ahp->icv_trunc_len) >> 2) - 2;
+
+	ah->reserved = 0;
+	ah->spi = x->id.spi;
+	ah->seq_no = htonl(++x->replay.oseq);
+	ahp->icv(ahp, skb, ah->auth_data);
+	top_iph->tos = iph->tos;
+	top_iph->ttl = iph->ttl;
+	if (x->props.mode) {
+		top_iph->frag_off = iph->frag_off&~htons(IP_MF|IP_OFFSET);
+		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+	} else {
+		top_iph->frag_off = iph->frag_off;
+		top_iph->daddr = iph->daddr;
+		if (iph->ihl != 5)
+			memcpy(top_iph+1, iph+1, iph->ihl*4 - sizeof(struct iphdr));
+	}
+	ip_send_check(top_iph);
+
+	skb->nh.raw = skb->data;
+
+	x->curlft.bytes += skb->len;
+	x->curlft.packets++;
+	spin_unlock_bh(&x->lock);
+	if ((skb->dst = dst_pop(dst)) == NULL) {
+		err = -EHOSTUNREACH;
+		goto error_nolock;
+	}
+	return NET_XMIT_BYPASS;
+
+error:
+	spin_unlock_bh(&x->lock);
+error_nolock:
+	kfree_skb(skb);
+	return err;
+}
+
+int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
+{
+	int ah_hlen;
+	struct iphdr *iph;
+	struct ip_auth_hdr *ah;
+	struct ah_data *ahp;
+	char work_buf[60];
+
+	if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
+		goto out;
+
+	ah = (struct ip_auth_hdr*)skb->data;
+	ahp = x->data;
+	ah_hlen = (ah->hdrlen + 2) << 2;
+	
+	if (ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_full_len) &&
+	    ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len)) 
+		goto out;
+
+	if (!pskb_may_pull(skb, ah_hlen))
+		goto out;
+
+	/* We are going to _remove_ AH header to keep sockets happy,
+	 * so... Later this can change. */
+	if (skb_cloned(skb) &&
+	    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		goto out;
+
+	skb->ip_summed = CHECKSUM_NONE;
+
+	ah = (struct ip_auth_hdr*)skb->data;
+	iph = skb->nh.iph;
+
+	memcpy(work_buf, iph, iph->ihl*4);
+
+	iph->ttl = 0;
+	iph->tos = 0;
+	iph->frag_off = 0;
+	iph->check = 0;
+	if (iph->ihl != 5) {
+		u32 dummy;
+		if (ip_clear_mutable_options(iph, &dummy))
+			goto out;
+	}
+        {
+		u8 auth_data[ahp->icv_trunc_len];
+		
+		memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
+		skb_push(skb, skb->data - skb->nh.raw);
+		ahp->icv(ahp, skb, ah->auth_data);
+		if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {
+			x->stats.integrity_failed++;
+			goto out;
+		}
+	}
+	((struct iphdr*)work_buf)->protocol = ah->nexthdr;
+	skb->nh.raw = skb_pull(skb, ah_hlen);
+	memcpy(skb->nh.raw, work_buf, iph->ihl*4);
+	skb->nh.iph->tot_len = htons(skb->len);
+	skb_pull(skb, skb->nh.iph->ihl*4);
+	skb->h.raw = skb->data;
+
+	return 0;
+
+out:
+	return -EINVAL;
+}
+
+void ah4_err(struct sk_buff *skb, u32 info)
+{
+	struct iphdr *iph = (struct iphdr*)skb->data;
+	struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+(iph->ihl<<2));
+	struct xfrm_state *x;
+
+	if (skb->h.icmph->type != ICMP_DEST_UNREACH ||
+	    skb->h.icmph->code != ICMP_FRAG_NEEDED)
+		return;
+
+	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
+	if (!x)
+		return;
+	printk(KERN_DEBUG "pmtu discvovery on SA AH/%08x/%08x\n",
+	       ntohl(ah->spi), ntohl(iph->daddr));
+	xfrm_state_put(x);
+}
+
+static int ah_init_state(struct xfrm_state *x, void *args)
+{
+	struct ah_data *ahp = NULL;
+	struct xfrm_algo_desc *aalg_desc;
+
+	/* null auth can use a zero length key */
+	if (x->aalg->alg_key_len > 512)
+		goto error;
+
+	ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
+	if (ahp == NULL)
+		return -ENOMEM;
+
+	memset(ahp, 0, sizeof(*ahp));
+
+	ahp->key = x->aalg->alg_key;
+	ahp->key_len = (x->aalg->alg_key_len+7)/8;
+	ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
+	if (!ahp->tfm)
+		goto error;
+	ahp->icv = ah_hmac_digest;
+	
+	/*
+	 * Lookup the algorithm description maintained by xfrm_algo,
+	 * verify crypto transform properties, and store information
+	 * we need for AH processing.  This lookup cannot fail here
+	 * after a successful crypto_alloc_tfm().
+	 */
+	aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
+	BUG_ON(!aalg_desc);
+
+	if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
+	    crypto_tfm_alg_digestsize(ahp->tfm)) {
+		printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
+		       x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm),
+		       aalg_desc->uinfo.auth.icv_fullbits/8);
+		goto error;
+	}
+	
+	ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
+	ahp->icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
+	
+	ahp->work_icv = kmalloc(ahp->icv_full_len, GFP_KERNEL);
+	if (!ahp->work_icv)
+		goto error;
+	
+	x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len);
+	if (x->props.mode)
+		x->props.header_len += sizeof(struct iphdr);
+	x->data = ahp;
+
+	return 0;
+
+error:
+	if (ahp) {
+		if (ahp->work_icv)
+			kfree(ahp->work_icv);
+		if (ahp->tfm)
+			crypto_free_tfm(ahp->tfm);
+		kfree(ahp);
+	}
+	return -EINVAL;
+}
+
+static void ah_destroy(struct xfrm_state *x)
+{
+	struct ah_data *ahp = x->data;
+
+	if (ahp->work_icv) {
+		kfree(ahp->work_icv);
+		ahp->work_icv = NULL;
+	}
+	if (ahp->tfm) {
+		crypto_free_tfm(ahp->tfm);
+		ahp->tfm = NULL;
+	}
+	kfree(ahp);
+}
+
+
+static struct xfrm_type ah_type =
+{
+	.description	= "AH4",
+	.owner		= THIS_MODULE,
+	.proto	     	= IPPROTO_AH,
+	.init_state	= ah_init_state,
+	.destructor	= ah_destroy,
+	.input		= ah_input,
+	.output		= ah_output
+};
+
+static struct inet_protocol ah4_protocol = {
+	.handler	=	xfrm4_rcv,
+	.err_handler	=	ah4_err,
+	.no_policy	=	1,
+};
+
+static int __init ah4_init(void)
+{
+	if (xfrm_register_type(&ah_type, AF_INET) < 0) {
+		printk(KERN_INFO "ip ah init: can't add xfrm type\n");
+		return -EAGAIN;
+	}
+	if (inet_add_protocol(&ah4_protocol, IPPROTO_AH) < 0) {
+		printk(KERN_INFO "ip ah init: can't add protocol\n");
+		xfrm_unregister_type(&ah_type, AF_INET);
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+static void __exit ah4_fini(void)
+{
+	if (inet_del_protocol(&ah4_protocol, IPPROTO_AH) < 0)
+		printk(KERN_INFO "ip ah close: can't remove protocol\n");
+	if (xfrm_unregister_type(&ah_type, AF_INET) < 0)
+		printk(KERN_INFO "ip ah close: can't remove xfrm type\n");
+}
+
+module_init(ah4_init);
+module_exit(ah4_fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.5.70-bk9/net/ipv4/esp.c linux-2.5.70-bk10/net/ipv4/esp.c
--- linux-2.5.70-bk9/net/ipv4/esp.c	2003-06-05 04:41:32.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv4/esp.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,603 +0,0 @@
-#include <linux/config.h>
-#include <linux/module.h>
-#include <net/ip.h>
-#include <net/xfrm.h>
-#include <net/esp.h>
-#include <asm/scatterlist.h>
-#include <linux/crypto.h>
-#include <linux/pfkeyv2.h>
-#include <linux/random.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-
-#define MAX_SG_ONSTACK 4
-
-/* decapsulation data for use when post-processing */
-struct esp_decap_data {
-	xfrm_address_t	saddr;
-	__u16		sport;
-	__u8		proto;
-};
-
-int esp_output(struct sk_buff *skb)
-{
-	int err;
-	struct dst_entry *dst = skb->dst;
-	struct xfrm_state *x  = dst->xfrm;
-	struct iphdr *iph, *top_iph;
-	struct ip_esp_hdr *esph;
-	struct crypto_tfm *tfm;
-	struct esp_data *esp;
-	struct sk_buff *trailer;
-	struct udphdr *uh = NULL;
-	struct xfrm_encap_tmpl *encap = NULL;
-	int blksize;
-	int clen;
-	int alen;
-	int nfrags;
-	union {
-		struct iphdr	iph;
-		char 		buf[60];
-	} tmp_iph;
-
-	/* First, if the skb is not checksummed, complete checksum. */
-	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
-		err = -EINVAL;
-		goto error_nolock;
-	}
-
-	spin_lock_bh(&x->lock);
-	err = xfrm_check_output(x, skb, AF_INET);
-	if (err)
-		goto error;
-	err = -ENOMEM;
-
-	/* Strip IP header in transport mode. Save it. */
-	if (!x->props.mode) {
-		iph = skb->nh.iph;
-		memcpy(&tmp_iph, iph, iph->ihl*4);
-		__skb_pull(skb, iph->ihl*4);
-	}
-	/* Now skb is pure payload to encrypt */
-
-	/* Round to block size */
-	clen = skb->len;
-
-	esp = x->data;
-	alen = esp->auth.icv_trunc_len;
-	tfm = esp->conf.tfm;
-	blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3;
-	clen = (clen + 2 + blksize-1)&~(blksize-1);
-	if (esp->conf.padlen)
-		clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
-
-	if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
-		goto error;
-
-	/* Fill padding... */
-	do {
-		int i;
-		for (i=0; i<clen-skb->len - 2; i++)
-			*(u8*)(trailer->tail + i) = i+1;
-	} while (0);
-	*(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
-	pskb_put(skb, trailer, clen - skb->len);
-
-	encap = x->encap;
-
-	iph = skb->nh.iph;
-	if (x->props.mode) {
-		top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
-		esph = (struct ip_esp_hdr*)(top_iph+1);
-		if (encap && encap->encap_type) {
-			switch (encap->encap_type) {
-			case UDP_ENCAP_ESPINUDP:
-				uh = (struct udphdr*) esph;
-				esph = (struct ip_esp_hdr*)(uh+1);
-				top_iph->protocol = IPPROTO_UDP;
-				break;
-			default:
-				printk(KERN_INFO
-				       "esp_output(): Unhandled encap: %u\n",
-				       encap->encap_type);
-				top_iph->protocol = IPPROTO_ESP;
-				break;
-			}
-		} else
-			top_iph->protocol = IPPROTO_ESP;
-		*(u8*)(trailer->tail - 1) = IPPROTO_IPIP;
-		top_iph->ihl = 5;
-		top_iph->version = 4;
-		top_iph->tos = iph->tos;	/* DS disclosed */
-		top_iph->tot_len = htons(skb->len + alen);
-		top_iph->frag_off = iph->frag_off&htons(IP_DF);
-		if (!(top_iph->frag_off))
-			ip_select_ident(top_iph, dst, 0);
-		top_iph->ttl = iph->ttl;	/* TTL disclosed */
-		top_iph->check = 0;
-		top_iph->saddr = x->props.saddr.a4;
-		top_iph->daddr = x->id.daddr.a4;
-		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-	} else {
-		esph = (struct ip_esp_hdr*)skb_push(skb, x->props.header_len);
-		top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4);
-		memcpy(top_iph, &tmp_iph, iph->ihl*4);
-		if (encap && encap->encap_type) {
-			switch (encap->encap_type) {
-			case UDP_ENCAP_ESPINUDP:
-				uh = (struct udphdr*) esph;
-				esph = (struct ip_esp_hdr*)(uh+1);
-				top_iph->protocol = IPPROTO_UDP;
-				break;
-			default:
-				printk(KERN_INFO
-				       "esp_output(): Unhandled encap: %u\n",
-				       encap->encap_type);
-				top_iph->protocol = IPPROTO_ESP;
-				break;
-			}
-		} else
-			top_iph->protocol = IPPROTO_ESP;
-		iph = &tmp_iph.iph;
-		top_iph->tot_len = htons(skb->len + alen);
-		top_iph->check = 0;
-		top_iph->frag_off = iph->frag_off;
-		*(u8*)(trailer->tail - 1) = iph->protocol;
-	}
-
-	/* this is non-NULL only with UDP Encapsulation */
-	if (encap && uh) {
-		uh->source = encap->encap_sport;
-		uh->dest = encap->encap_dport;
-		uh->len = htons(skb->len + alen - sizeof(struct iphdr));
-		uh->check = 0;
-	}
-
-	esph->spi = x->id.spi;
-	esph->seq_no = htonl(++x->replay.oseq);
-
-	if (esp->conf.ivlen)
-		crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
-
-	do {
-		struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
-		struct scatterlist *sg = sgbuf;
-
-		if (unlikely(nfrags > MAX_SG_ONSTACK)) {
-			sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
-			if (!sg)
-				goto error;
-		}
-		skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
-		crypto_cipher_encrypt(tfm, sg, sg, clen);
-		if (unlikely(sg != sgbuf))
-			kfree(sg);
-	} while (0);
-
-	if (esp->conf.ivlen) {
-		memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
-		crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
-	}
-
-	if (esp->auth.icv_full_len) {
-		esp->auth.icv(esp, skb, (u8*)esph-skb->data,
-		              sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);
-		pskb_put(skb, trailer, alen);
-	}
-
-	ip_send_check(top_iph);
-
-	skb->nh.raw = skb->data;
-
-	x->curlft.bytes += skb->len;
-	x->curlft.packets++;
-	spin_unlock_bh(&x->lock);
-	if ((skb->dst = dst_pop(dst)) == NULL) {
-		err = -EHOSTUNREACH;
-		goto error_nolock;
-	}
-	return NET_XMIT_BYPASS;
-
-error:
-	spin_unlock_bh(&x->lock);
-error_nolock:
-	kfree_skb(skb);
-	return err;
-}
-
-/*
- * Note: detecting truncated vs. non-truncated authentication data is very
- * expensive, so we only support truncated data, which is the recommended
- * and common case.
- */
-int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
-{
-	struct iphdr *iph;
-	struct ip_esp_hdr *esph;
-	struct esp_data *esp = x->data;
-	struct sk_buff *trailer;
-	int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
-	int alen = esp->auth.icv_trunc_len;
-	int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;
-	int nfrags;
-	int encap_len = 0;
-
-	if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr)))
-		goto out;
-
-	if (elen <= 0 || (elen & (blksize-1)))
-		goto out;
-
-	/* If integrity check is required, do this. */
-	if (esp->auth.icv_full_len) {
-		u8 sum[esp->auth.icv_full_len];
-		u8 sum1[alen];
-		
-		esp->auth.icv(esp, skb, 0, skb->len-alen, sum);
-
-		if (skb_copy_bits(skb, skb->len-alen, sum1, alen))
-			BUG();
-
-		if (unlikely(memcmp(sum, sum1, alen))) {
-			x->stats.integrity_failed++;
-			goto out;
-		}
-	}
-
-	if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0)
-		goto out;
-
-	skb->ip_summed = CHECKSUM_NONE;
-
-	esph = (struct ip_esp_hdr*)skb->data;
-	iph = skb->nh.iph;
-
-	/* Get ivec. This can be wrong, check against another impls. */
-	if (esp->conf.ivlen)
-		crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm));
-
-        {
-		u8 nexthdr[2];
-		struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
-		struct scatterlist *sg = sgbuf;
-		u8 workbuf[60];
-		int padlen;
-
-		if (unlikely(nfrags > MAX_SG_ONSTACK)) {
-			sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
-			if (!sg)
-				goto out;
-		}
-		skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
-		crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
-		if (unlikely(sg != sgbuf))
-			kfree(sg);
-
-		if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
-			BUG();
-
-		padlen = nexthdr[0];
-		if (padlen+2 >= elen)
-			goto out;
-
-		/* ... check padding bits here. Silly. :-) */ 
-
-		if (x->encap && decap && decap->decap_type) {
-			struct esp_decap_data *encap_data;
-			struct udphdr *uh = (struct udphdr *) (iph+1);
-
-			encap_data = (struct esp_decap_data *) (decap->decap_data);
-			encap_data->proto = 0;
-
-			switch (decap->decap_type) {
-			case UDP_ENCAP_ESPINUDP:
-
-				if ((void*)uh == (void*)esph) {
-					printk(KERN_DEBUG
-					       "esp_input(): Got ESP; expecting ESPinUDP\n");
-					break;
-				}
-
-				encap_data->proto = AF_INET;
-				encap_data->saddr.a4 = iph->saddr;
-				encap_data->sport = uh->source;
-				encap_len = (void*)esph - (void*)uh;
-				if (encap_len != sizeof(*uh))
-				  printk(KERN_DEBUG
-					 "esp_input(): UDP -> ESP: too much room: %d\n",
-					 encap_len);
-				break;
-
-			default:
-				printk(KERN_INFO
-			       "esp_input(): processing unknown encap type: %u\n",
-				       decap->decap_type);
-				break;
-			}
-		}
-
-		iph->protocol = nexthdr[1];
-		pskb_trim(skb, skb->len - alen - padlen - 2);
-		memcpy(workbuf, skb->nh.raw, iph->ihl*4);
-		skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen);
-		skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
-		memcpy(skb->nh.raw, workbuf, iph->ihl*4);
-		skb->nh.iph->tot_len = htons(skb->len);
-	}
-
-	return 0;
-
-out:
-	return -EINVAL;
-}
-
-int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
-{
-  
-	if (x->encap) {
-		struct xfrm_encap_tmpl *encap;
-		struct esp_decap_data *decap_data;
-
-		encap = x->encap;
-		decap_data = (struct esp_decap_data *)(decap->decap_data);
-
-		/* first, make sure that the decap type == the encap type */
-		if (encap->encap_type != decap->decap_type)
-			return -EINVAL;
-
-		/* Next, if we don't have an encap type, then ignore it */
-		if (!encap->encap_type)
-			return 0;
-
-		switch (encap->encap_type) {
-		case UDP_ENCAP_ESPINUDP:
-			/*
-			 * 1) if the NAT-T peer's IP or port changed then
-			 *    advertize the change to the keying daemon.
-			 *    This is an inbound SA, so just compare
-			 *    SRC ports.
-			 */
-			if (decap_data->proto == AF_INET &&
-			    (decap_data->saddr.a4 != x->props.saddr.a4 ||
-			     decap_data->sport != encap->encap_sport)) {
-				xfrm_address_t ipaddr;
-
-				ipaddr.a4 = decap_data->saddr.a4;
-				km_new_mapping(x, &ipaddr, decap_data->sport);
-					
-				/* XXX: perhaps add an extra
-				 * policy check here, to see
-				 * if we should allow or
-				 * reject a packet from a
-				 * different source
-				 * address/port.
-				 */
-			}
-		
-			/*
-			 * 2) ignore UDP/TCP checksums in case
-			 *    of NAT-T in Transport Mode, or
-			 *    perform other post-processing fixes
-			 *    as per * draft-ietf-ipsec-udp-encaps-06,
-			 *    section 3.1.2
-			 */
-			if (!x->props.mode)
-				skb->ip_summed = CHECKSUM_UNNECESSARY;
-
-			break;
-		default:
-			printk(KERN_INFO
-			       "esp4_post_input(): Unhandled encap type: %u\n",
-			       encap->encap_type);
-			break;
-		}
-	}
-	return 0;
-}
-
-static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
-{
-	struct esp_data *esp = x->data;
-	u32 blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
-
-	if (x->props.mode) {
-		mtu = (mtu + 2 + blksize-1)&~(blksize-1);
-	} else {
-		/* The worst case. */
-		mtu += 2 + blksize;
-	}
-	if (esp->conf.padlen)
-		mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1);
-
-	return mtu + x->props.header_len + esp->auth.icv_trunc_len;
-}
-
-void esp4_err(struct sk_buff *skb, u32 info)
-{
-	struct iphdr *iph = (struct iphdr*)skb->data;
-	struct ip_esp_hdr *esph = (struct ip_esp_hdr*)(skb->data+(iph->ihl<<2));
-	struct xfrm_state *x;
-
-	if (skb->h.icmph->type != ICMP_DEST_UNREACH ||
-	    skb->h.icmph->code != ICMP_FRAG_NEEDED)
-		return;
-
-	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
-	if (!x)
-		return;
-	printk(KERN_DEBUG "pmtu discvovery on SA ESP/%08x/%08x\n",
-	       ntohl(esph->spi), ntohl(iph->daddr));
-	xfrm_state_put(x);
-}
-
-void esp_destroy(struct xfrm_state *x)
-{
-	struct esp_data *esp = x->data;
-
-	if (esp->conf.tfm) {
-		crypto_free_tfm(esp->conf.tfm);
-		esp->conf.tfm = NULL;
-	}
-	if (esp->conf.ivec) {
-		kfree(esp->conf.ivec);
-		esp->conf.ivec = NULL;
-	}
-	if (esp->auth.tfm) {
-		crypto_free_tfm(esp->auth.tfm);
-		esp->auth.tfm = NULL;
-	}
-	if (esp->auth.work_icv) {
-		kfree(esp->auth.work_icv);
-		esp->auth.work_icv = NULL;
-	}
-	kfree(esp);
-}
-
-int esp_init_state(struct xfrm_state *x, void *args)
-{
-	struct esp_data *esp = NULL;
-
-	/* null auth and encryption can have zero length keys */
-	if (x->aalg) {
-		if (x->aalg->alg_key_len > 512)
-			goto error;
-	}
-	if (x->ealg == NULL)
-		goto error;
-
-	esp = kmalloc(sizeof(*esp), GFP_KERNEL);
-	if (esp == NULL)
-		return -ENOMEM;
-
-	memset(esp, 0, sizeof(*esp));
-
-	if (x->aalg) {
-		struct xfrm_algo_desc *aalg_desc;
-
-		esp->auth.key = x->aalg->alg_key;
-		esp->auth.key_len = (x->aalg->alg_key_len+7)/8;
-		esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
-		if (esp->auth.tfm == NULL)
-			goto error;
-		esp->auth.icv = esp_hmac_digest;
-
-		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
-		BUG_ON(!aalg_desc);
-
-		if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
-		    crypto_tfm_alg_digestsize(esp->auth.tfm)) {
-			printk(KERN_INFO "ESP: %s digestsize %u != %hu\n",
-			       x->aalg->alg_name,
-			       crypto_tfm_alg_digestsize(esp->auth.tfm),
-			       aalg_desc->uinfo.auth.icv_fullbits/8);
-			goto error;
-		}
-
-		esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
-		esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
-
-		esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL);
-		if (!esp->auth.work_icv)
-			goto error;
-	}
-	esp->conf.key = x->ealg->alg_key;
-	esp->conf.key_len = (x->ealg->alg_key_len+7)/8;
-	esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC);
-	if (esp->conf.tfm == NULL)
-		goto error;
-	esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm);
-	esp->conf.padlen = 0;
-	if (esp->conf.ivlen) {
-		esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
-		get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
-	}
-	crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len);
-	x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
-	if (x->props.mode)
-		x->props.header_len += sizeof(struct iphdr);
-	if (x->encap) {
-		struct xfrm_encap_tmpl *encap = x->encap;
-
-		if (encap->encap_type) {
-			switch (encap->encap_type) {
-			case UDP_ENCAP_ESPINUDP:
-				x->props.header_len += sizeof(struct udphdr);
-				break;
-			default:
-				printk (KERN_INFO
-				"esp_init_state(): Unhandled encap type: %u\n",
-					encap->encap_type);
-				break;
-			}
-		}
-	}
-	x->data = esp;
-	x->props.trailer_len = esp4_get_max_size(x, 0) - x->props.header_len;
-	return 0;
-
-error:
-	if (esp) {
-		if (esp->auth.tfm)
-			crypto_free_tfm(esp->auth.tfm);
-		if (esp->auth.work_icv)
-			kfree(esp->auth.work_icv);
-		if (esp->conf.tfm)
-			crypto_free_tfm(esp->conf.tfm);
-		kfree(esp);
-	}
-	return -EINVAL;
-}
-
-static struct xfrm_type esp_type =
-{
-	.description	= "ESP4",
-	.owner		= THIS_MODULE,
-	.proto	     	= IPPROTO_ESP,
-	.init_state	= esp_init_state,
-	.destructor	= esp_destroy,
-	.get_max_size	= esp4_get_max_size,
-	.input		= esp_input,
-	.post_input	= esp_post_input,
-	.output		= esp_output
-};
-
-static struct inet_protocol esp4_protocol = {
-	.handler	=	xfrm4_rcv,
-	.err_handler	=	esp4_err,
-	.no_policy	=	1,
-};
-
-static int __init esp4_init(void)
-{
-	struct xfrm_decap_state decap;
-
-	if (sizeof(struct esp_decap_data)  <
-	    sizeof(decap.decap_data)) {
-		extern void decap_data_too_small(void);
-
-		decap_data_too_small();
-	}
-
-	if (xfrm_register_type(&esp_type, AF_INET) < 0) {
-		printk(KERN_INFO "ip esp init: can't add xfrm type\n");
-		return -EAGAIN;
-	}
-	if (inet_add_protocol(&esp4_protocol, IPPROTO_ESP) < 0) {
-		printk(KERN_INFO "ip esp init: can't add protocol\n");
-		xfrm_unregister_type(&esp_type, AF_INET);
-		return -EAGAIN;
-	}
-	return 0;
-}
-
-static void __exit esp4_fini(void)
-{
-	if (inet_del_protocol(&esp4_protocol, IPPROTO_ESP) < 0)
-		printk(KERN_INFO "ip esp close: can't remove protocol\n");
-	if (xfrm_unregister_type(&esp_type, AF_INET) < 0)
-		printk(KERN_INFO "ip esp close: can't remove xfrm type\n");
-}
-
-module_init(esp4_init);
-module_exit(esp4_fini);
-MODULE_LICENSE("GPL");
diff -urN linux-2.5.70-bk9/net/ipv4/esp4.c linux-2.5.70-bk10/net/ipv4/esp4.c
--- linux-2.5.70-bk9/net/ipv4/esp4.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk10/net/ipv4/esp4.c	2003-06-05 04:41:37.000000000 -0700
@@ -0,0 +1,603 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <net/ip.h>
+#include <net/xfrm.h>
+#include <net/esp.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+#include <linux/pfkeyv2.h>
+#include <linux/random.h>
+#include <net/icmp.h>
+#include <net/udp.h>
+
+#define MAX_SG_ONSTACK 4
+
+/* decapsulation data for use when post-processing */
+struct esp_decap_data {
+	xfrm_address_t	saddr;
+	__u16		sport;
+	__u8		proto;
+};
+
+int esp_output(struct sk_buff *skb)
+{
+	int err;
+	struct dst_entry *dst = skb->dst;
+	struct xfrm_state *x  = dst->xfrm;
+	struct iphdr *iph, *top_iph;
+	struct ip_esp_hdr *esph;
+	struct crypto_tfm *tfm;
+	struct esp_data *esp;
+	struct sk_buff *trailer;
+	struct udphdr *uh = NULL;
+	struct xfrm_encap_tmpl *encap = NULL;
+	int blksize;
+	int clen;
+	int alen;
+	int nfrags;
+	union {
+		struct iphdr	iph;
+		char 		buf[60];
+	} tmp_iph;
+
+	/* First, if the skb is not checksummed, complete checksum. */
+	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
+		err = -EINVAL;
+		goto error_nolock;
+	}
+
+	spin_lock_bh(&x->lock);
+	err = xfrm_check_output(x, skb, AF_INET);
+	if (err)
+		goto error;
+	err = -ENOMEM;
+
+	/* Strip IP header in transport mode. Save it. */
+	if (!x->props.mode) {
+		iph = skb->nh.iph;
+		memcpy(&tmp_iph, iph, iph->ihl*4);
+		__skb_pull(skb, iph->ihl*4);
+	}
+	/* Now skb is pure payload to encrypt */
+
+	/* Round to block size */
+	clen = skb->len;
+
+	esp = x->data;
+	alen = esp->auth.icv_trunc_len;
+	tfm = esp->conf.tfm;
+	blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3;
+	clen = (clen + 2 + blksize-1)&~(blksize-1);
+	if (esp->conf.padlen)
+		clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
+
+	if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
+		goto error;
+
+	/* Fill padding... */
+	do {
+		int i;
+		for (i=0; i<clen-skb->len - 2; i++)
+			*(u8*)(trailer->tail + i) = i+1;
+	} while (0);
+	*(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
+	pskb_put(skb, trailer, clen - skb->len);
+
+	encap = x->encap;
+
+	iph = skb->nh.iph;
+	if (x->props.mode) {
+		top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+		esph = (struct ip_esp_hdr*)(top_iph+1);
+		if (encap && encap->encap_type) {
+			switch (encap->encap_type) {
+			case UDP_ENCAP_ESPINUDP:
+				uh = (struct udphdr*) esph;
+				esph = (struct ip_esp_hdr*)(uh+1);
+				top_iph->protocol = IPPROTO_UDP;
+				break;
+			default:
+				printk(KERN_INFO
+				       "esp_output(): Unhandled encap: %u\n",
+				       encap->encap_type);
+				top_iph->protocol = IPPROTO_ESP;
+				break;
+			}
+		} else
+			top_iph->protocol = IPPROTO_ESP;
+		*(u8*)(trailer->tail - 1) = IPPROTO_IPIP;
+		top_iph->ihl = 5;
+		top_iph->version = 4;
+		top_iph->tos = iph->tos;	/* DS disclosed */
+		top_iph->tot_len = htons(skb->len + alen);
+		top_iph->frag_off = iph->frag_off&htons(IP_DF);
+		if (!(top_iph->frag_off))
+			ip_select_ident(top_iph, dst, 0);
+		top_iph->ttl = iph->ttl;	/* TTL disclosed */
+		top_iph->check = 0;
+		top_iph->saddr = x->props.saddr.a4;
+		top_iph->daddr = x->id.daddr.a4;
+		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+	} else {
+		esph = (struct ip_esp_hdr*)skb_push(skb, x->props.header_len);
+		top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4);
+		memcpy(top_iph, &tmp_iph, iph->ihl*4);
+		if (encap && encap->encap_type) {
+			switch (encap->encap_type) {
+			case UDP_ENCAP_ESPINUDP:
+				uh = (struct udphdr*) esph;
+				esph = (struct ip_esp_hdr*)(uh+1);
+				top_iph->protocol = IPPROTO_UDP;
+				break;
+			default:
+				printk(KERN_INFO
+				       "esp_output(): Unhandled encap: %u\n",
+				       encap->encap_type);
+				top_iph->protocol = IPPROTO_ESP;
+				break;
+			}
+		} else
+			top_iph->protocol = IPPROTO_ESP;
+		iph = &tmp_iph.iph;
+		top_iph->tot_len = htons(skb->len + alen);
+		top_iph->check = 0;
+		top_iph->frag_off = iph->frag_off;
+		*(u8*)(trailer->tail - 1) = iph->protocol;
+	}
+
+	/* this is non-NULL only with UDP Encapsulation */
+	if (encap && uh) {
+		uh->source = encap->encap_sport;
+		uh->dest = encap->encap_dport;
+		uh->len = htons(skb->len + alen - sizeof(struct iphdr));
+		uh->check = 0;
+	}
+
+	esph->spi = x->id.spi;
+	esph->seq_no = htonl(++x->replay.oseq);
+
+	if (esp->conf.ivlen)
+		crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
+
+	do {
+		struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
+		struct scatterlist *sg = sgbuf;
+
+		if (unlikely(nfrags > MAX_SG_ONSTACK)) {
+			sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
+			if (!sg)
+				goto error;
+		}
+		skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
+		crypto_cipher_encrypt(tfm, sg, sg, clen);
+		if (unlikely(sg != sgbuf))
+			kfree(sg);
+	} while (0);
+
+	if (esp->conf.ivlen) {
+		memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
+		crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
+	}
+
+	if (esp->auth.icv_full_len) {
+		esp->auth.icv(esp, skb, (u8*)esph-skb->data,
+		              sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);
+		pskb_put(skb, trailer, alen);
+	}
+
+	ip_send_check(top_iph);
+
+	skb->nh.raw = skb->data;
+
+	x->curlft.bytes += skb->len;
+	x->curlft.packets++;
+	spin_unlock_bh(&x->lock);
+	if ((skb->dst = dst_pop(dst)) == NULL) {
+		err = -EHOSTUNREACH;
+		goto error_nolock;
+	}
+	return NET_XMIT_BYPASS;
+
+error:
+	spin_unlock_bh(&x->lock);
+error_nolock:
+	kfree_skb(skb);
+	return err;
+}
+
+/*
+ * Note: detecting truncated vs. non-truncated authentication data is very
+ * expensive, so we only support truncated data, which is the recommended
+ * and common case.
+ */
+int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
+{
+	struct iphdr *iph;
+	struct ip_esp_hdr *esph;
+	struct esp_data *esp = x->data;
+	struct sk_buff *trailer;
+	int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
+	int alen = esp->auth.icv_trunc_len;
+	int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;
+	int nfrags;
+	int encap_len = 0;
+
+	if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr)))
+		goto out;
+
+	if (elen <= 0 || (elen & (blksize-1)))
+		goto out;
+
+	/* If integrity check is required, do this. */
+	if (esp->auth.icv_full_len) {
+		u8 sum[esp->auth.icv_full_len];
+		u8 sum1[alen];
+		
+		esp->auth.icv(esp, skb, 0, skb->len-alen, sum);
+
+		if (skb_copy_bits(skb, skb->len-alen, sum1, alen))
+			BUG();
+
+		if (unlikely(memcmp(sum, sum1, alen))) {
+			x->stats.integrity_failed++;
+			goto out;
+		}
+	}
+
+	if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0)
+		goto out;
+
+	skb->ip_summed = CHECKSUM_NONE;
+
+	esph = (struct ip_esp_hdr*)skb->data;
+	iph = skb->nh.iph;
+
+	/* Get ivec. This can be wrong, check against another impls. */
+	if (esp->conf.ivlen)
+		crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm));
+
+        {
+		u8 nexthdr[2];
+		struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
+		struct scatterlist *sg = sgbuf;
+		u8 workbuf[60];
+		int padlen;
+
+		if (unlikely(nfrags > MAX_SG_ONSTACK)) {
+			sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
+			if (!sg)
+				goto out;
+		}
+		skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
+		crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
+		if (unlikely(sg != sgbuf))
+			kfree(sg);
+
+		if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
+			BUG();
+
+		padlen = nexthdr[0];
+		if (padlen+2 >= elen)
+			goto out;
+
+		/* ... check padding bits here. Silly. :-) */ 
+
+		if (x->encap && decap && decap->decap_type) {
+			struct esp_decap_data *encap_data;
+			struct udphdr *uh = (struct udphdr *) (iph+1);
+
+			encap_data = (struct esp_decap_data *) (decap->decap_data);
+			encap_data->proto = 0;
+
+			switch (decap->decap_type) {
+			case UDP_ENCAP_ESPINUDP:
+
+				if ((void*)uh == (void*)esph) {
+					printk(KERN_DEBUG
+					       "esp_input(): Got ESP; expecting ESPinUDP\n");
+					break;
+				}
+
+				encap_data->proto = AF_INET;
+				encap_data->saddr.a4 = iph->saddr;
+				encap_data->sport = uh->source;
+				encap_len = (void*)esph - (void*)uh;
+				if (encap_len != sizeof(*uh))
+				  printk(KERN_DEBUG
+					 "esp_input(): UDP -> ESP: too much room: %d\n",
+					 encap_len);
+				break;
+
+			default:
+				printk(KERN_INFO
+			       "esp_input(): processing unknown encap type: %u\n",
+				       decap->decap_type);
+				break;
+			}
+		}
+
+		iph->protocol = nexthdr[1];
+		pskb_trim(skb, skb->len - alen - padlen - 2);
+		memcpy(workbuf, skb->nh.raw, iph->ihl*4);
+		skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen);
+		skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
+		memcpy(skb->nh.raw, workbuf, iph->ihl*4);
+		skb->nh.iph->tot_len = htons(skb->len);
+	}
+
+	return 0;
+
+out:
+	return -EINVAL;
+}
+
+int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
+{
+  
+	if (x->encap) {
+		struct xfrm_encap_tmpl *encap;
+		struct esp_decap_data *decap_data;
+
+		encap = x->encap;
+		decap_data = (struct esp_decap_data *)(decap->decap_data);
+
+		/* first, make sure that the decap type == the encap type */
+		if (encap->encap_type != decap->decap_type)
+			return -EINVAL;
+
+		/* Next, if we don't have an encap type, then ignore it */
+		if (!encap->encap_type)
+			return 0;
+
+		switch (encap->encap_type) {
+		case UDP_ENCAP_ESPINUDP:
+			/*
+			 * 1) if the NAT-T peer's IP or port changed then
+			 *    advertize the change to the keying daemon.
+			 *    This is an inbound SA, so just compare
+			 *    SRC ports.
+			 */
+			if (decap_data->proto == AF_INET &&
+			    (decap_data->saddr.a4 != x->props.saddr.a4 ||
+			     decap_data->sport != encap->encap_sport)) {
+				xfrm_address_t ipaddr;
+
+				ipaddr.a4 = decap_data->saddr.a4;
+				km_new_mapping(x, &ipaddr, decap_data->sport);
+					
+				/* XXX: perhaps add an extra
+				 * policy check here, to see
+				 * if we should allow or
+				 * reject a packet from a
+				 * different source
+				 * address/port.
+				 */
+			}
+		
+			/*
+			 * 2) ignore UDP/TCP checksums in case
+			 *    of NAT-T in Transport Mode, or
+			 *    perform other post-processing fixes
+			 *    as per * draft-ietf-ipsec-udp-encaps-06,
+			 *    section 3.1.2
+			 */
+			if (!x->props.mode)
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+			break;
+		default:
+			printk(KERN_INFO
+			       "esp4_post_input(): Unhandled encap type: %u\n",
+			       encap->encap_type);
+			break;
+		}
+	}
+	return 0;
+}
+
+static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
+{
+	struct esp_data *esp = x->data;
+	u32 blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
+
+	if (x->props.mode) {
+		mtu = (mtu + 2 + blksize-1)&~(blksize-1);
+	} else {
+		/* The worst case. */
+		mtu += 2 + blksize;
+	}
+	if (esp->conf.padlen)
+		mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1);
+
+	return mtu + x->props.header_len + esp->auth.icv_trunc_len;
+}
+
+void esp4_err(struct sk_buff *skb, u32 info)
+{
+	struct iphdr *iph = (struct iphdr*)skb->data;
+	struct ip_esp_hdr *esph = (struct ip_esp_hdr*)(skb->data+(iph->ihl<<2));
+	struct xfrm_state *x;
+
+	if (skb->h.icmph->type != ICMP_DEST_UNREACH ||
+	    skb->h.icmph->code != ICMP_FRAG_NEEDED)
+		return;
+
+	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
+	if (!x)
+		return;
+	printk(KERN_DEBUG "pmtu discvovery on SA ESP/%08x/%08x\n",
+	       ntohl(esph->spi), ntohl(iph->daddr));
+	xfrm_state_put(x);
+}
+
+void esp_destroy(struct xfrm_state *x)
+{
+	struct esp_data *esp = x->data;
+
+	if (esp->conf.tfm) {
+		crypto_free_tfm(esp->conf.tfm);
+		esp->conf.tfm = NULL;
+	}
+	if (esp->conf.ivec) {
+		kfree(esp->conf.ivec);
+		esp->conf.ivec = NULL;
+	}
+	if (esp->auth.tfm) {
+		crypto_free_tfm(esp->auth.tfm);
+		esp->auth.tfm = NULL;
+	}
+	if (esp->auth.work_icv) {
+		kfree(esp->auth.work_icv);
+		esp->auth.work_icv = NULL;
+	}
+	kfree(esp);
+}
+
+int esp_init_state(struct xfrm_state *x, void *args)
+{
+	struct esp_data *esp = NULL;
+
+	/* null auth and encryption can have zero length keys */
+	if (x->aalg) {
+		if (x->aalg->alg_key_len > 512)
+			goto error;
+	}
+	if (x->ealg == NULL)
+		goto error;
+
+	esp = kmalloc(sizeof(*esp), GFP_KERNEL);
+	if (esp == NULL)
+		return -ENOMEM;
+
+	memset(esp, 0, sizeof(*esp));
+
+	if (x->aalg) {
+		struct xfrm_algo_desc *aalg_desc;
+
+		esp->auth.key = x->aalg->alg_key;
+		esp->auth.key_len = (x->aalg->alg_key_len+7)/8;
+		esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
+		if (esp->auth.tfm == NULL)
+			goto error;
+		esp->auth.icv = esp_hmac_digest;
+
+		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
+		BUG_ON(!aalg_desc);
+
+		if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
+		    crypto_tfm_alg_digestsize(esp->auth.tfm)) {
+			printk(KERN_INFO "ESP: %s digestsize %u != %hu\n",
+			       x->aalg->alg_name,
+			       crypto_tfm_alg_digestsize(esp->auth.tfm),
+			       aalg_desc->uinfo.auth.icv_fullbits/8);
+			goto error;
+		}
+
+		esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
+		esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
+
+		esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL);
+		if (!esp->auth.work_icv)
+			goto error;
+	}
+	esp->conf.key = x->ealg->alg_key;
+	esp->conf.key_len = (x->ealg->alg_key_len+7)/8;
+	esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC);
+	if (esp->conf.tfm == NULL)
+		goto error;
+	esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm);
+	esp->conf.padlen = 0;
+	if (esp->conf.ivlen) {
+		esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
+		get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
+	}
+	crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len);
+	x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
+	if (x->props.mode)
+		x->props.header_len += sizeof(struct iphdr);
+	if (x->encap) {
+		struct xfrm_encap_tmpl *encap = x->encap;
+
+		if (encap->encap_type) {
+			switch (encap->encap_type) {
+			case UDP_ENCAP_ESPINUDP:
+				x->props.header_len += sizeof(struct udphdr);
+				break;
+			default:
+				printk (KERN_INFO
+				"esp_init_state(): Unhandled encap type: %u\n",
+					encap->encap_type);
+				break;
+			}
+		}
+	}
+	x->data = esp;
+	x->props.trailer_len = esp4_get_max_size(x, 0) - x->props.header_len;
+	return 0;
+
+error:
+	if (esp) {
+		if (esp->auth.tfm)
+			crypto_free_tfm(esp->auth.tfm);
+		if (esp->auth.work_icv)
+			kfree(esp->auth.work_icv);
+		if (esp->conf.tfm)
+			crypto_free_tfm(esp->conf.tfm);
+		kfree(esp);
+	}
+	return -EINVAL;
+}
+
+static struct xfrm_type esp_type =
+{
+	.description	= "ESP4",
+	.owner		= THIS_MODULE,
+	.proto	     	= IPPROTO_ESP,
+	.init_state	= esp_init_state,
+	.destructor	= esp_destroy,
+	.get_max_size	= esp4_get_max_size,
+	.input		= esp_input,
+	.post_input	= esp_post_input,
+	.output		= esp_output
+};
+
+static struct inet_protocol esp4_protocol = {
+	.handler	=	xfrm4_rcv,
+	.err_handler	=	esp4_err,
+	.no_policy	=	1,
+};
+
+static int __init esp4_init(void)
+{
+	struct xfrm_decap_state decap;
+
+	if (sizeof(struct esp_decap_data)  <
+	    sizeof(decap.decap_data)) {
+		extern void decap_data_too_small(void);
+
+		decap_data_too_small();
+	}
+
+	if (xfrm_register_type(&esp_type, AF_INET) < 0) {
+		printk(KERN_INFO "ip esp init: can't add xfrm type\n");
+		return -EAGAIN;
+	}
+	if (inet_add_protocol(&esp4_protocol, IPPROTO_ESP) < 0) {
+		printk(KERN_INFO "ip esp init: can't add protocol\n");
+		xfrm_unregister_type(&esp_type, AF_INET);
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+static void __exit esp4_fini(void)
+{
+	if (inet_del_protocol(&esp4_protocol, IPPROTO_ESP) < 0)
+		printk(KERN_INFO "ip esp close: can't remove protocol\n");
+	if (xfrm_unregister_type(&esp_type, AF_INET) < 0)
+		printk(KERN_INFO "ip esp close: can't remove xfrm type\n");
+}
+
+module_init(esp4_init);
+module_exit(esp4_fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.5.70-bk9/net/ipv6/Kconfig linux-2.5.70-bk10/net/ipv6/Kconfig
--- linux-2.5.70-bk9/net/ipv6/Kconfig	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv6/Kconfig	2003-06-05 04:41:37.000000000 -0700
@@ -4,6 +4,8 @@
 config IPV6_PRIVACY
 	bool "IPv6: Privacy Extensions (RFC 3041) support"
 	depends on IPV6
+	select CRYPTO
+	select CRYPTO_MD5
 	---help---
 	  Privacy Extensions for Stateless Address Autoconfiguration in IPv6
 	  support.  With this option, additional periodically-alter 
@@ -20,6 +22,10 @@
 config INET6_AH
 	tristate "IPv6: AH transformation"
 	depends on IPV6
+	select CRYPTO
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
 	---help---
 	  Support for IPsec AH.
 
@@ -28,6 +34,11 @@
 config INET6_ESP
 	tristate "IPv6: ESP transformation"
 	depends on IPV6
+	select CRYPTO
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
+	select CRYPTO_DES
 	---help---
 	  Support for IPsec ESP.
 
@@ -36,6 +47,8 @@
 config INET6_IPCOMP
 	tristate "IPv6: IPComp transformation"
 	depends on IPV6
+	select CRYPTO
+	select CRYPTO_DEFLATE
 	---help---
 	  Support for IP Paylod Compression (RFC3173), typically needed
 	  for IPsec.
diff -urN linux-2.5.70-bk9/net/ipv6/addrconf.c linux-2.5.70-bk10/net/ipv6/addrconf.c
--- linux-2.5.70-bk9/net/ipv6/addrconf.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv6/addrconf.c	2003-06-05 04:41:37.000000000 -0700
@@ -19,7 +19,7 @@
  *
  *	Janos Farkas			:	delete timer on ifdown
  *	<chexum@bankinf.banki.hu>
- *	Andi Kleen			:	kill doube kfree on module
+ *	Andi Kleen			:	kill double kfree on module
  *						unload.
  *	Maciej W. Rozycki		:	FDDI support
  *	sekiya@USAGI			:	Don't send too many RS
@@ -343,6 +343,7 @@
 				"%s(): cannot create /proc/net/dev_snmp6/%s\n",
 				__FUNCTION__, dev->name));
 			neigh_parms_release(&nd_tbl, ndev->nd_parms);
+			ndev->dead = 1;
 			in6_dev_finish_destroy(ndev);
 			return NULL;
 		}
@@ -1256,7 +1257,7 @@
 	rtmsg.rtmsg_type	= RTMSG_NEWROUTE;
 	rtmsg.rtmsg_metric	= IP6_RT_PRIO_ADDRCONF;
 
-	/* prefix length - 96 bytes "::d.d.d.d" */
+	/* prefix length - 96 bits "::d.d.d.d" */
 	rtmsg.rtmsg_dst_len	= 96;
 	rtmsg.rtmsg_flags	= RTF_UP|RTF_NONEXTHOP;
 	rtmsg.rtmsg_ifindex	= dev->ifindex;
diff -urN linux-2.5.70-bk9/net/ipv6/af_inet6.c linux-2.5.70-bk10/net/ipv6/af_inet6.c
--- linux-2.5.70-bk9/net/ipv6/af_inet6.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv6/af_inet6.c	2003-06-05 04:41:37.000000000 -0700
@@ -310,7 +310,7 @@
 	} else {
 		if (addr_type != IPV6_ADDR_ANY) {
 			/* ipv4 addr of the socket is invalid.  Only the
-			 * unpecified and mapped address have a v4 equivalent.
+			 * unspecified and mapped address have a v4 equivalent.
 			 */
 			v4addr = LOOPBACK4_IPV6;
 			if (!(addr_type & IPV6_ADDR_MULTICAST))	{
diff -urN linux-2.5.70-bk9/net/ipv6/ip6_fib.c linux-2.5.70-bk10/net/ipv6/ip6_fib.c
--- linux-2.5.70-bk9/net/ipv6/ip6_fib.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv6/ip6_fib.c	2003-06-05 04:41:37.000000000 -0700
@@ -40,7 +40,6 @@
 #include <net/ip6_route.h>
 
 #define RT6_DEBUG 2
-#undef CONFIG_IPV6_SUBTREES
 
 #if RT6_DEBUG >= 3
 #define RT6_TRACE(x...) printk(KERN_DEBUG x)
@@ -594,8 +593,8 @@
 	   is orphan. If it is, shoot it.
 	 */
 st_failure:
-	if (fn && !(fn->fn_flags&RTN_RTINFO|RTN_ROOT))
-		fib_repair_tree(fn);
+	if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT)))
+		fib6_repair_tree(fn);
 	dst_free(&rt->u.dst);
 	return err;
 #endif
@@ -896,6 +895,7 @@
 	*rtp = rt->u.next;
 	rt->rt6i_node = NULL;
 	rt6_stats.fib_rt_entries--;
+	rt6_stats.fib_discarded_routes++;
 
 	/* Adjust walkers */
 	read_lock(&fib6_walker_lock);
diff -urN linux-2.5.70-bk9/net/ipv6/route.c linux-2.5.70-bk10/net/ipv6/route.c
--- linux-2.5.70-bk9/net/ipv6/route.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv6/route.c	2003-06-05 04:41:37.000000000 -0700
@@ -336,7 +336,7 @@
 	return err;
 }
 
-/* No rt6_lock! If COW faild, the function returns dead route entry
+/* No rt6_lock! If COW failed, the function returns dead route entry
    with dst->error set to errno value.
  */
 
@@ -1786,11 +1786,12 @@
 
 static int rt6_stats_seq_show(struct seq_file *seq, void *v)
 {
-	seq_printf(seq, "%04x %04x %04x %04x %04x %04x\n",
+	seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
 		      rt6_stats.fib_nodes, rt6_stats.fib_route_nodes,
 		      rt6_stats.fib_rt_alloc, rt6_stats.fib_rt_entries,
 		      rt6_stats.fib_rt_cache,
-		      atomic_read(&ip6_dst_ops.entries));
+		      atomic_read(&ip6_dst_ops.entries),
+		      rt6_stats.fib_discarded_routes);
 
 	return 0;
 }
diff -urN linux-2.5.70-bk9/net/ipv6/udp.c linux-2.5.70-bk10/net/ipv6/udp.c
--- linux-2.5.70-bk9/net/ipv6/udp.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv6/udp.c	2003-06-05 04:41:38.000000000 -0700
@@ -254,7 +254,6 @@
 	struct inet_opt      	*inet = inet_sk(sk);
 	struct ipv6_pinfo      	*np = inet6_sk(sk);
 	struct in6_addr		*daddr;
-	struct in6_addr		saddr;
 	struct dst_entry	*dst;
 	struct flowi		fl;
 	struct ip6_flowlabel	*flowlabel = NULL;
@@ -355,7 +354,7 @@
 
 	fl.proto = IPPROTO_UDP;
 	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-	ipv6_addr_copy(&fl.fl6_src, &saddr);
+	ipv6_addr_copy(&fl.fl6_src, &np->saddr);
 	fl.oif = sk->bound_dev_if;
 	fl.fl_ip_dport = inet->dport;
 	fl.fl_ip_sport = inet->sport;
@@ -381,20 +380,23 @@
 		return err;
 	}
 
-	ip6_dst_store(sk, dst, &fl.fl6_dst);
-
 	/* get the source address used in the appropriate device */
 
-	err = ipv6_get_saddr(dst, daddr, &saddr);
+	err = ipv6_get_saddr(dst, daddr, &fl.fl6_src);
 
 	if (err == 0) {
 		if (ipv6_addr_any(&np->saddr))
-			ipv6_addr_copy(&np->saddr, &saddr);
+			ipv6_addr_copy(&np->saddr, &fl.fl6_src);
 
 		if (ipv6_addr_any(&np->rcv_saddr)) {
-			ipv6_addr_copy(&np->rcv_saddr, &saddr);
+			ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
 			inet->rcv_saddr = LOOPBACK4_IPV6;
 		}
+
+		ip6_dst_store(sk, dst,
+			      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+			      &np->daddr : NULL);
+
 		sk->state = TCP_ESTABLISHED;
 	}
 	fl6_sock_release(flowlabel);
diff -urN linux-2.5.70-bk9/net/ipv6/xfrm6_policy.c linux-2.5.70-bk10/net/ipv6/xfrm6_policy.c
--- linux-2.5.70-bk9/net/ipv6/xfrm6_policy.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk10/net/ipv6/xfrm6_policy.c	2003-06-05 04:41:38.000000000 -0700
@@ -146,7 +146,7 @@
 		memcpy(&dst_prev->metrics, &rt->u.dst.metrics, sizeof(dst_prev->metrics));
 		dst_prev->path		= &rt->u.dst;
 
-		/* Copy neighbout for reachability confirmation */
+		/* Copy neighbour for reachability confirmation */
 		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
 		dst_prev->input		= rt->u.dst.input;
 		dst_prev->output	= dst_prev->xfrm->type->output;
diff -urN linux-2.5.70-bk9/scripts/Makefile.build linux-2.5.70-bk10/scripts/Makefile.build
--- linux-2.5.70-bk9/scripts/Makefile.build	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk10/scripts/Makefile.build	2003-06-05 04:41:38.000000000 -0700
@@ -71,55 +71,7 @@
 quiet_cmd_checksrc = CHECK   $<
       cmd_checksrc = $(CHECK) $(c_flags) $< ;
 endif
- 
-# Module versioning
-# ---------------------------------------------------------------------------
 
-ifdef CONFIG_MODVERSIONS
-
-# $(call if_changed_rule,vcc_o_c) does essentially the same as the
-# normal $(call if_changed_dep,cc_o_c), i.e. compile an object file
-# from a C file, keeping track of the command line and dependencies.
-#
-# However, actually it does:
-# o compile a .tmp_<file>.o from <file>.c
-# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
-#   not export symbols, we just rename .tmp_<file>.o to <file>.o and
-#   are done.
-# o otherwise, we calculate symbol versions using the good old
-#   genksyms on the preprocessed source and postprocess them in a way
-#   that they are usable as a linker script
-# o generate <file>.o from .tmp_<file>.o using the linker to
-#   replace the unresolved symbols __crc_exported_symbol with
-#   the actual value of the checksum generated by genksyms
-
-quiet_cmd_vcc_o_c = CC $(quiet_modtag)  $@
-cmd_vcc_o_c       = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
-
-define rule_vcc_o_c
-	$(if $($(quiet)cmd_checksrc),echo '  $($(quiet)cmd_checksrc)';)	      \
-	$(cmd_checksrc)							      \
-	$(if $($(quiet)cmd_vcc_o_c),echo '  $($(quiet)cmd_vcc_o_c)';)	      \
-	$(cmd_vcc_o_c);							      \
-									      \
-	if ! $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then	      \
-		mv $(@D)/.tmp_$(@F) $@;					      \
-	else								      \
-		$(CPP) -D__GENKSYMS__ $(c_flags) $<			      \
-		| $(GENKSYMS)						      \
-		> $(@D)/.tmp_$(@F:.o=.ver);				      \
-									      \
-		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		      \
-			-T $(@D)/.tmp_$(@F:.o=.ver);			      \
-		rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);	      \
-	fi;			
-					      \
-	scripts/fixdep $(depfile) $@ '$(cmd_vcc_o_c)' > $(@D)/.$(@F).tmp;     \
-	rm -f $(depfile);						      \
-	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
-endef
-
-endif
 
 # Compile C sources (.c)
 # ---------------------------------------------------------------------------
@@ -164,35 +116,63 @@
 %.i: %.c FORCE
 	$(call if_changed_dep,cc_i_c)
 
+# C (.c) files
+# The C file is compiled and updated dependency information is generated.
+# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
+
 quiet_cmd_cc_o_c = CC $(quiet_modtag)  $@
-cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
+
+ifndef CONFIG_MODVERSIONS
+cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
+
+else
+# When module versioning is enabled the following steps are executed:
+# o compile a .tmp_<file>.o from <file>.c
+# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
+#   not export symbols, we just rename .tmp_<file>.o to <file>.o and
+#   are done.
+# o otherwise, we calculate symbol versions using the good old
+#   genksyms on the preprocessed source and postprocess them in a way
+#   that they are usable as a linker script
+# o generate <file>.o from .tmp_<file>.o using the linker to
+#   replace the unresolved symbols __crc_exported_symbol with
+#   the actual value of the checksum generated by genksyms
+
+cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
+cmd_modversions =							\
+	if ! $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then	\
+		mv $(@D)/.tmp_$(@F) $@;					\
+	else								\
+		$(CPP) -D__GENKSYMS__ $(c_flags) $<			\
+		| $(GENKSYMS)						\
+		> $(@D)/.tmp_$(@F:.o=.ver);				\
+									\
+		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		\
+			-T $(@D)/.tmp_$(@F:.o=.ver);			\
+		rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);	\
+	fi;
+endif
+
 define rule_cc_o_c
-	$(if $($(quiet)cmd_checksrc),echo '  $($(quiet)cmd_checksrc)';)	      \
-	$(cmd_checksrc)							      \
-	$(if $($(quiet)cmd_cc_o_c),echo '  $($(quiet)cmd_cc_o_c)';)	      \
-	$(cmd_cc_o_c);							      \
-	scripts/fixdep $(depfile) $@ '$(cmd_cc_o_c)' > $(@D)/.$(@F).tmp;      \
-	rm -f $(depfile);						      \
+	$(if $($(quiet)cmd_checksrc),echo '  $($(quiet)cmd_checksrc)';)   \
+	$(cmd_checksrc)							  \
+	$(if $($(quiet)cmd_cc_o_c),echo '  $($(quiet)cmd_cc_o_c)';)	  \
+	$(cmd_cc_o_c);							  \
+	$(cmd_modversions)						  \
+	scripts/fixdep $(depfile) $@ '$(cmd_cc_o_c)' > $(@D)/.$(@F).tmp;  \
+	rm -f $(depfile);						  \
 	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
 endef
 
 # Built-in and composite module parts
 
 %.o: %.c FORCE
-ifdef CONFIG_MODVERSIONS
-	$(call if_changed_rule,vcc_o_c)
-else
 	$(call if_changed_rule,cc_o_c)
-endif
 
 # Single-part modules are special since we need to mark them in $(MODVERDIR)
 
 $(single-used-m): %.o: %.c FORCE
-ifdef CONFIG_MODVERSIONS
-	$(call if_changed_rule,vcc_o_c)
-else
 	$(call if_changed_rule,cc_o_c)
-endif
 	$(touch-module)
 
 quiet_cmd_cc_lst_c = MKLST   $@
diff -urN linux-2.5.70-bk9/scripts/kconfig/conf.c linux-2.5.70-bk10/scripts/kconfig/conf.c
--- linux-2.5.70-bk9/scripts/kconfig/conf.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/scripts/kconfig/conf.c	2003-06-05 04:41:38.000000000 -0700
@@ -286,10 +286,14 @@
 			break;
 		}
 	} else {
-		sym->user = sym->curr;
-		if (sym->curr.tri == mod) {
+		switch (sym_get_tristate_value(sym)) {
+		case no:
+			return 1;
+		case mod:
 			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
 			return 0;
+		case yes:
+			break;
 		}
 	}
 
diff -urN linux-2.5.70-bk9/scripts/kconfig/confdata.c linux-2.5.70-bk10/scripts/kconfig/confdata.c
--- linux-2.5.70-bk9/scripts/kconfig/confdata.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/scripts/kconfig/confdata.c	2003-06-05 04:41:38.000000000 -0700
@@ -243,7 +243,8 @@
 		prop = sym_get_choice_prop(sym);
 		sym->flags &= ~SYMBOL_NEW;
 		for (e = prop->expr; e; e = e->left.expr)
-			sym->flags |= e->right.sym->flags & SYMBOL_NEW;
+			if (e->right.sym->visible != no)
+				sym->flags |= e->right.sym->flags & SYMBOL_NEW;
 	}
 
 	sym_change_count = 1;
diff -urN linux-2.5.70-bk9/scripts/kconfig/menu.c linux-2.5.70-bk10/scripts/kconfig/menu.c
--- linux-2.5.70-bk9/scripts/kconfig/menu.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/scripts/kconfig/menu.c	2003-06-05 04:41:38.000000000 -0700
@@ -221,11 +221,18 @@
 	for (menu = parent->list; menu; menu = menu->next) {
 		if (sym && sym_is_choice(sym) && menu->sym) {
 			menu->sym->flags |= SYMBOL_CHOICEVAL;
+			if (!menu->prompt)
+				fprintf(stderr, "%s:%d:warning: choice value must have a prompt\n",
+					menu->file->name, menu->lineno);
 			for (prop = menu->sym->prop; prop; prop = prop->next) {
-				if (prop->type != P_DEFAULT)
-					continue;
-				fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n",
-					prop->file->name, prop->lineno);
+				if (prop->type == P_PROMPT && prop->menu != menu) {
+					fprintf(stderr, "%s:%d:warning: choice values currently only support a single prompt\n",
+						prop->file->name, prop->lineno);
+					
+				}
+				if (prop->type == P_DEFAULT)
+					fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n",
+						prop->file->name, prop->lineno);
 			}
 			current_entry = menu;
 			menu_set_type(sym->type);
@@ -311,14 +318,6 @@
 	} else
 		visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
 
-	if (sym && sym_is_choice(sym)) {
-		for (child = menu->list; child; child = child->next)
-			if (menu_is_visible(child))
-				break;
-		if (!child)
-			return false;
-	}
-
 	if (visible != no)
 		return true;
 	if (!sym || sym_get_tristate_value(menu->sym) == no)
diff -urN linux-2.5.70-bk9/scripts/kconfig/symbol.c linux-2.5.70-bk10/scripts/kconfig/symbol.c
--- linux-2.5.70-bk9/scripts/kconfig/symbol.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/scripts/kconfig/symbol.c	2003-06-05 04:41:38.000000000 -0700
@@ -201,6 +201,9 @@
 		if (def_sym->visible != no)
 			return def_sym;
 	}
+
+	/* no choice? reset tristate value */
+	sym->curr.tri = no;
 	return NULL;
 }
 
diff -urN linux-2.5.70-bk9/sound/core/memalloc.c linux-2.5.70-bk10/sound/core/memalloc.c
--- linux-2.5.70-bk9/sound/core/memalloc.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/sound/core/memalloc.c	2003-06-05 04:41:38.000000000 -0700
@@ -823,12 +823,12 @@
 
 static void __init preallocate_cards(void)
 {
-	struct pci_dev *pci;
+	struct pci_dev *pci = NULL;
 	int card;
 
 	card = 0;
 
-	pci_for_each_dev(pci) {
+	while ((pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci)) != NULL) {
 		struct prealloc_dev *dev;
 		if (card >= SNDRV_CARDS)
 			break;
diff -urN linux-2.5.70-bk9/sound/oss/cmpci.c linux-2.5.70-bk10/sound/oss/cmpci.c
--- linux-2.5.70-bk9/sound/oss/cmpci.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk10/sound/oss/cmpci.c	2003-06-05 04:41:38.000000000 -0700
@@ -580,15 +580,17 @@
 	spin_unlock_irqrestore(&s->lock, flags);
 }
 
-static void trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
+static int trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
 {
 	int   i = size / 2;
+	int err;
 	unsigned long data;
 	unsigned long *dst = (unsigned long *) dest;
 	unsigned short *src = (unsigned short *)source;
 
 	do {
-		data = (unsigned long) *src++;
+		if ((err = __get_user(data, src++)))
+			return err;
 		data <<= 12;			// ok for 16-bit data
 		if (s->spdif_counter == 2 || s->spdif_counter == 3)
 			data |= 0x40000000;	// indicate AC-3 raw data
@@ -605,6 +607,8 @@
 		if (s->spdif_counter == 384)
 			s->spdif_counter = 0;
 	} while (--i);
+
+	return 0;
 }
 
 static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate)
@@ -1655,13 +1659,16 @@
 			continue;
 		}
 		if (s->status & DO_AC3_SW) {
+			int err;
+
 			// clip exceeded data, caught by 033 and 037
 			if (swptr + 2 * cnt > s->dma_dac.dmasize)
 				cnt = (s->dma_dac.dmasize - swptr) / 2;
-			trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt);
+			if ((err = trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt)))
+				return err;
 			swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
 		} else if (s->status & DO_DUAL_DAC) {
-			int	i;
+			int	i, err;
 			unsigned long *src, *dst0, *dst1;
 
 			src = (unsigned long *) buffer;
@@ -1669,8 +1676,10 @@
 			dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
 			// copy left/right sample at one time
 			for (i = 0; i <= cnt / 4; i++) {
-				*dst0++ = *src++;
-				*dst1++ = *src++;
+				if ((err = __get_user(*dst0++, src++)))
+					return err;
+				if ((err = __get_user(*dst1++, src++)))
+					return err;
 			}
 			swptr = (swptr + cnt) % s->dma_dac.dmasize;
 		} else {
diff -urN linux-2.5.70-bk9/sound/oss/esssolo1.c linux-2.5.70-bk10/sound/oss/esssolo1.c
--- linux-2.5.70-bk9/sound/oss/esssolo1.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk10/sound/oss/esssolo1.c	2003-06-05 04:41:38.000000000 -0700
@@ -915,9 +915,9 @@
 {
 	unsigned int minor = minor(inode->i_rdev);
 	struct solo1_state *s = NULL;
-	struct pci_dev *pci_dev;
+	struct pci_dev *pci_dev = NULL;
 
-	pci_for_each_dev(pci_dev) {
+	while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
 		struct pci_driver *drvr;
 		drvr = pci_dev_driver (pci_dev);
 		if (drvr != &solo1_driver)
@@ -1597,9 +1597,9 @@
 	unsigned int minor = minor(inode->i_rdev);
 	DECLARE_WAITQUEUE(wait, current);
 	struct solo1_state *s = NULL;
-	struct pci_dev *pci_dev;
+	struct pci_dev *pci_dev = NULL;
 	
-	pci_for_each_dev(pci_dev) {
+	while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
 		struct pci_driver *drvr;
 
 		drvr = pci_dev_driver(pci_dev);
@@ -1888,9 +1888,9 @@
 	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
 	struct solo1_state *s = NULL;
-	struct pci_dev *pci_dev;
+	struct pci_dev *pci_dev = NULL;
 
-	pci_for_each_dev(pci_dev) {
+	while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
 		struct pci_driver *drvr;
 
 		drvr = pci_dev_driver(pci_dev);
@@ -2113,9 +2113,9 @@
 	unsigned int minor = minor(inode->i_rdev);
 	DECLARE_WAITQUEUE(wait, current);
 	struct solo1_state *s = NULL;
-	struct pci_dev *pci_dev;
+	struct pci_dev *pci_dev = NULL;
 
-	pci_for_each_dev(pci_dev) {
+	while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
 		struct pci_driver *drvr;
 
 		drvr = pci_dev_driver(pci_dev);
diff -urN linux-2.5.70-bk9/sound/oss/maestro.c linux-2.5.70-bk10/sound/oss/maestro.c
--- linux-2.5.70-bk9/sound/oss/maestro.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk10/sound/oss/maestro.c	2003-06-05 04:41:38.000000000 -0700
@@ -2132,10 +2132,10 @@
 {
 	unsigned int minor = minor(inode->i_rdev);
 	struct ess_card *card = NULL;
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 	struct pci_driver *drvr;
 
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		drvr = pci_dev_driver (pdev);
 		if (drvr == &maestro_pci_driver) {
 			card = (struct ess_card*)pci_get_drvdata (pdev);
@@ -2978,13 +2978,13 @@
 	unsigned int minor = minor(inode->i_rdev);
 	struct ess_state *s = NULL;
 	unsigned char fmtm = ~0, fmts = 0;
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 	/*
 	 *	Scan the cards and find the channel. We only
 	 *	do this at open time so it is ok
 	 */
 
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		struct ess_card *c;
 		struct pci_driver *drvr;
 
diff -urN linux-2.5.70-bk9/sound/oss/via82cxxx_audio.c linux-2.5.70-bk10/sound/oss/via82cxxx_audio.c
--- linux-2.5.70-bk9/sound/oss/via82cxxx_audio.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk10/sound/oss/via82cxxx_audio.c	2003-06-05 04:41:38.000000000 -0700
@@ -1357,12 +1357,12 @@
 {
 	int minor = minor(inode->i_rdev);
 	struct via_info *card;
-	struct pci_dev *pdev;
+	struct pci_dev *pdev = NULL;
 	struct pci_driver *drvr;
 
 	DPRINTK ("ENTER\n");
 
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		drvr = pci_dev_driver (pdev);
 		if (drvr == &via_driver) {
 			assert (pci_get_drvdata (pdev) != NULL);
@@ -2982,8 +2982,8 @@
 static int via_dsp_open (struct inode *inode, struct file *file)
 {
 	int minor = minor(inode->i_rdev);
-	struct via_info *card;
-	struct pci_dev *pdev;
+	struct via_info *card = NULL;
+	struct pci_dev *pdev = NULL;
 	struct via_channel *chan;
 	struct pci_driver *drvr;
 	int nonblock = (file->f_flags & O_NONBLOCK);
@@ -2995,8 +2995,7 @@
 		return -EINVAL;
 	}
 
-	card = NULL;
-	pci_for_each_dev(pdev) {
+	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
 		drvr = pci_dev_driver (pdev);
 		if (drvr == &via_driver) {
 			assert (pci_get_drvdata (pdev) != NULL);
diff -urN linux-2.5.70-bk9/sound/pci/rme9652/hammerfall_mem.c linux-2.5.70-bk10/sound/pci/rme9652/hammerfall_mem.c
--- linux-2.5.70-bk9/sound/pci/rme9652/hammerfall_mem.c	2003-06-05 04:41:33.000000000 -0700
+++ linux-2.5.70-bk10/sound/pci/rme9652/hammerfall_mem.c	2003-06-05 04:41:38.000000000 -0700
@@ -185,7 +185,7 @@
 static int __init alsa_hammerfall_mem_init(void)
 {
 	int i;
-	struct pci_dev *pci;
+	struct pci_dev *pci = NULL;
 	hammerfall_buf_t *rbuf;
 
 	/* make sure our buffer records are clean */
@@ -205,12 +205,12 @@
 	
 	i = 0;	/* card number */
 	rbuf = hammerfall_buffers;
-	pci_for_each_dev(pci) {
+	while ((pci = pci_find_device(PCI_VENDOR_ID_XILINX, PCI_ANY_ID, pci)) != NULL) {
 		int k;
 		
 		/* check for Hammerfall and Hammerfall DSP cards */
 
-		if (pci->vendor != 0x10ee || (pci->device != 0x3fc4 && pci->device != 0x3fc5)) 
+		if (pci->device != 0x3fc4 && pci->device != 0x3fc5)
 			continue;
 
 		if (!enable[i])
