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

diff -urN linux-2.5.70-bk15/MAINTAINERS linux-2.5.70-bk16/MAINTAINERS
--- linux-2.5.70-bk15/MAINTAINERS	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/MAINTAINERS	2003-06-11 04:48:00.000000000 -0700
@@ -771,27 +771,24 @@
 L:	linux-hippi@sunsite.dk
 S:	Maintained
 
-HP (was COMPAQ) FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA
-P:	Stephen Cameron
-M:	arrays@hp.com 
-M:	steve.cameron@hp.com
-L:	cpqfc-discuss@lists.sourceforge.net
-S:	Odd Fixes
-
-HP (was COMPAQ) SMART2 RAID DRIVER
-P:	Stephen Cameron
-M:	arrays@hp.com
-M:	steve.cameron@hp.com
-L:	cpqarray-discuss@lists.sourceforge.net
-S:	Odd Fixes
-
-HP (was COMPAQ) SMART CISS RAID DRIVER
-P:	Stephen Cameron
-M:	arrays@hp.com
-M:	steve.cameron@hp.com
-L:	cciss-discuss@lists.sourceforge.net
-S:	Supported
-
+COMPAQ FIBRE CHANNEL 64-bit/66MHz PCI non-intelligent HBA
+P:	Chase Maupin
+M:	Chase Maupin (support@compaq.com)
+L:	compaqandlinux@cpqlin.van-dijk.net
+S:	Supported
+
+COMPAQ SMART2 RAID DRIVER
+P:	Francis Wiran
+M:	Francis Wiran <support@compaq.com>
+L:	compaqandlinux@cpqlin.van-dijk.net
+S:	Supported	
+
+COMPAQ SMART CISS RAID DRIVER 
+P:	Mike Miller, Michael Ni
+M:	Mike Miller, Michael Ni <support@compaq.com>
+L:	compaqandlinux@cpqlin.van-dijk.net
+S:	Supported 
+  
 HP100:	Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
 P:	Jaroslav Kysela
 M:	perex@suse.cz
diff -urN linux-2.5.70-bk15/Makefile linux-2.5.70-bk16/Makefile
--- linux-2.5.70-bk15/Makefile	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/Makefile	2003-06-11 04:48:00.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 70
-EXTRAVERSION = -bk15
+EXTRAVERSION = -bk16
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -204,7 +204,7 @@
 DEPMOD		= /sbin/depmod
 KALLSYMS	= scripts/kallsyms
 PERL		= perl
-CHECK		= /home/torvalds/parser/check
+CHECK		= sparse
 MODFLAGS	= -DMODULE
 CFLAGS_MODULE   = $(MODFLAGS)
 AFLAGS_MODULE   = $(MODFLAGS)
diff -urN linux-2.5.70-bk15/arch/alpha/Kconfig linux-2.5.70-bk16/arch/alpha/Kconfig
--- linux-2.5.70-bk15/arch/alpha/Kconfig	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/arch/alpha/Kconfig	2003-06-11 04:48:00.000000000 -0700
@@ -295,6 +295,10 @@
 	  information about which PCI hardware does work under Linux and which
 	  doesn't.
 
+config PCI_DOMAINS
+	bool
+	default PCI
+
 config ALPHA_CORE_AGP
 	bool
 	depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL
diff -urN linux-2.5.70-bk15/arch/alpha/kernel/pci.c linux-2.5.70-bk16/arch/alpha/kernel/pci.c
--- linux-2.5.70-bk15/arch/alpha/kernel/pci.c	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/arch/alpha/kernel/pci.c	2003-06-11 04:48:00.000000000 -0700
@@ -484,11 +484,3 @@
 
 	return -EOPNOTSUPP;
 }
-
-/* Return the index of the PCI controller for device PDEV. */
-int
-pci_controller_num(struct pci_dev *pdev)
-{
-        struct pci_controller *hose = pdev->sysdata;
-	return (hose ? (int) hose->index : -ENXIO);
-}
diff -urN linux-2.5.70-bk15/arch/arm/kernel/pm.c linux-2.5.70-bk16/arch/arm/kernel/pm.c
--- linux-2.5.70-bk15/arch/arm/kernel/pm.c	2003-05-26 18:01:01.000000000 -0700
+++ linux-2.5.70-bk16/arch/arm/kernel/pm.c	2003-06-11 04:48:00.000000000 -0700
@@ -11,7 +11,6 @@
 #include <linux/config.h>
 #include <linux/pm.h>
 #include <linux/device.h>
-#include <linux/cpufreq.h>
 
 #include <asm/leds.h>
 #include <asm/system.h>
@@ -67,13 +66,6 @@
 	device_resume(RESUME_POWER_ON);
 
 	/*
-	 * Restore the CPU frequency settings.
-	 */
-#ifdef CONFIG_CPU_FREQ
-	cpufreq_restore();
-#endif
-
-	/*
 	 * Resume LDM devices.
 	 */
 	device_resume(RESUME_RESTORE_STATE);
diff -urN linux-2.5.70-bk15/arch/i386/kernel/apic.c linux-2.5.70-bk16/arch/i386/kernel/apic.c
--- linux-2.5.70-bk15/arch/i386/kernel/apic.c	2003-05-26 18:01:02.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/kernel/apic.c	2003-06-11 04:48:00.000000000 -0700
@@ -25,6 +25,9 @@
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
+#include <linux/sysdev.h>
+#include <linux/module.h>
+
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -460,9 +463,6 @@
 
 #ifdef CONFIG_PM
 
-#include <linux/device.h>
-#include <linux/module.h>
-
 static struct {
 	/* 'active' is true if the local APIC was enabled by us and
 	   not the BIOS; this signifies that we are also responsible
@@ -484,13 +484,11 @@
 	unsigned int apic_thmr;
 } apic_pm_state;
 
-static int lapic_suspend(struct device *dev, u32 state, u32 level)
+static int lapic_suspend(struct sys_device *dev, u32 state)
 {
 	unsigned int l, h;
 	unsigned long flags;
 
-	if (level != SUSPEND_POWER_DOWN)
-		return 0;
 	if (!apic_pm_state.active)
 		return 0;
 
@@ -517,13 +515,11 @@
 	return 0;
 }
 
-static int lapic_resume(struct device *dev, u32 level)
+static int lapic_resume(struct sys_device *dev)
 {
 	unsigned int l, h;
 	unsigned long flags;
 
-	if (level != RESUME_POWER_ON)
-		return 0;
 	if (!apic_pm_state.active)
 		return 0;
 
@@ -557,38 +553,37 @@
 	return 0;
 }
 
-static struct device_driver lapic_driver = {
-	.name		= "lapic",
-	.bus		= &system_bus_type,
+
+static struct sysdev_class lapic_sysclass = {
+	set_kset_name("lapic"),
 	.resume		= lapic_resume,
 	.suspend	= lapic_suspend,
 };
 
-/* not static, needed by child devices */
-struct sys_device device_lapic = {
-	.name		= "lapic",
-	.id		= 0,
-	.dev		= {
-		.name	= "lapic",
-		.driver	= &lapic_driver,
-	},
+static struct sys_device device_lapic = {
+	.id	= 0,
+	.cls	= &lapic_sysclass,
 };
-EXPORT_SYMBOL(device_lapic);
 
 static void __init apic_pm_activate(void)
 {
 	apic_pm_state.active = 1;
 }
 
-static int __init init_lapic_devicefs(void)
+static int __init init_lapic_sysfs(void)
 {
+	int error;
+
 	if (!cpu_has_apic)
 		return 0;
 	/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
-	driver_register(&lapic_driver);
-	return sys_device_register(&device_lapic);
+
+	error = sysdev_class_register(&lapic_sysclass);
+	if (!error)
+		error = sys_device_register(&device_lapic);
+	return error;
 }
-device_initcall(init_lapic_devicefs);
+device_initcall(init_lapic_sysfs);
 
 #else	/* CONFIG_PM */
 
diff -urN linux-2.5.70-bk15/arch/i386/kernel/cpu/mtrr/main.c linux-2.5.70-bk16/arch/i386/kernel/cpu/mtrr/main.c
--- linux-2.5.70-bk15/arch/i386/kernel/cpu/mtrr/main.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/kernel/cpu/mtrr/main.c	2003-06-11 04:48:00.000000000 -0700
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
+#include <linux/cpu.h>
 
 #include <asm/mtrr.h>
 
@@ -546,6 +547,58 @@
 	}
 }
 
+
+struct mtrr_value {
+	mtrr_type	ltype;
+	unsigned long	lbase;
+	unsigned int	lsize;
+};
+
+static struct mtrr_value * mtrr_state;
+
+static int mtrr_save(struct sys_device * sysdev, u32 state)
+{
+	int i;
+	int size = num_var_ranges * sizeof(struct mtrr_value);
+
+	mtrr_state = kmalloc(size,GFP_KERNEL);
+	if (mtrr_state)
+		memset(mtrr_state,0,size);
+	else
+		return -ENOMEM;
+
+	for (i = 0; i < num_var_ranges; i++) {
+		mtrr_if->get(i,
+			     &mtrr_state[i].lbase,
+			     &mtrr_state[i].lsize,
+			     &mtrr_state[i].ltype);
+	}
+	return 0;
+}
+
+static int mtrr_restore(struct sys_device * sysdev)
+{
+	int i;
+
+	for (i = 0; i < num_var_ranges; i++) {
+		if (mtrr_state[i].lsize) 
+			set_mtrr(i,
+				 mtrr_state[i].lbase,
+				 mtrr_state[i].lsize,
+				 mtrr_state[i].ltype);
+	}
+	kfree(mtrr_state);
+	return 0;
+}
+
+
+
+static struct sysdev_driver mtrr_sysdev_driver = {
+	.save		= mtrr_save,
+	.restore	= mtrr_restore,
+};
+
+
 /**
  * mtrr_init - initialie mtrrs on the boot CPU
  *
@@ -630,8 +683,11 @@
 		set_num_var_ranges();
 		init_table();
 		init_other_cpus();
+
+		return sysdev_driver_register(&cpu_sysdev_class,
+					      &mtrr_sysdev_driver);
 	}
-	return mtrr_if ? -ENXIO : 0;
+	return -ENXIO;
 }
 
 char *mtrr_strings[MTRR_NUM_TYPES] =
@@ -645,5 +701,5 @@
     "write-back",               /* 6 */
 };
 
-core_initcall(mtrr_init);
+subsys_initcall(mtrr_init);
 
diff -urN linux-2.5.70-bk15/arch/i386/kernel/i8259.c linux-2.5.70-bk16/arch/i386/kernel/i8259.c
--- linux-2.5.70-bk15/arch/i386/kernel/i8259.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/kernel/i8259.c	2003-06-11 04:48:00.000000000 -0700
@@ -10,7 +10,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
-#include <linux/device.h>
+#include <linux/sysdev.h>
 
 #include <asm/atomic.h>
 #include <asm/system.h>
@@ -238,35 +238,31 @@
 	}
 }
 
-static int i8259A_resume(struct device *dev, u32 level)
+static int i8259A_resume(struct sys_device *dev)
 {
-	if (level == RESUME_POWER_ON)
-		init_8259A(0);
+	init_8259A(0);
 	return 0;
 }
 
-static struct device_driver i8259A_driver = {
-	.name		= "pic",
-	.bus		= &system_bus_type,
-	.resume		= i8259A_resume,
+static struct sysdev_class i8259_sysdev_class = {
+	set_kset_name("i8259"),
+	.resume = i8259A_resume,
 };
 
 static struct sys_device device_i8259A = {
-	.name		= "pic",
-	.id		= 0,
-	.dev		= {
-		.name	= "i8259A PIC",
-		.driver	= &i8259A_driver,
-	},
+	.id	= 0,
+	.cls	= &i8259_sysdev_class,
 };
 
-static int __init init_8259A_devicefs(void)
+static int __init i8259A_init_sysfs(void)
 {
-	driver_register(&i8259A_driver);
-	return sys_device_register(&device_i8259A);
+	int error = sysdev_class_register(&i8259_sysdev_class);
+	if (!error)
+		error = sys_device_register(&device_i8259A);
+	return error;
 }
 
-device_initcall(init_8259A_devicefs);
+device_initcall(i8259A_init_sysfs);
 
 void init_8259A(int auto_eoi)
 {
@@ -385,35 +381,31 @@
 	spin_unlock_irqrestore(&i8253_lock, flags);
 }
 
-static int timer_resume(struct device *dev, u32 level)
+static int timer_resume(struct sys_device *dev)
 {
-	if (level == RESUME_POWER_ON)
-		setup_timer();
+	setup_timer();
 	return 0;
 }
 
-static struct device_driver timer_driver = {
-	.name		= "timer",
-	.bus		= &system_bus_type,
-	.resume		= timer_resume,
+static struct sysdev_class timer_sysclass = {
+	set_kset_name("timer"),
+	.resume	= timer_resume,
 };
 
 static struct sys_device device_timer = {
-	.name		= "timer",
-	.id		= 0,
-	.dev		= {
-		.name	= "timer",
-		.driver	= &timer_driver,
-	},
+	.id	= 0,
+	.cls	= &timer_sysclass,
 };
 
-static int __init init_timer_devicefs(void)
+static int __init init_timer_sysfs(void)
 {
-	driver_register(&timer_driver);
-	return sys_device_register(&device_timer);
+	int error = sysdev_class_register(&timer_sysclass);
+	if (!error)
+		error = sys_device_register(&device_timer);
+	return error;
 }
 
-device_initcall(init_timer_devicefs);
+device_initcall(init_timer_sysfs);
 
 void __init init_IRQ(void)
 {
diff -urN linux-2.5.70-bk15/arch/i386/kernel/io_apic.c linux-2.5.70-bk16/arch/i386/kernel/io_apic.c
--- linux-2.5.70-bk15/arch/i386/kernel/io_apic.c	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/kernel/io_apic.c	2003-06-11 04:48:00.000000000 -0700
@@ -1160,7 +1160,8 @@
 		entry.delivery_mode = INT_DELIVERY_MODE;
 		entry.dest_mode = INT_DEST_MODE;
 		entry.mask = 0;				/* enable IRQ */
-		entry.dest.logical.logical_dest = TARGET_CPUS;
+		entry.dest.logical.logical_dest = 
+					cpu_mask_to_apicid(TARGET_CPUS);
 
 		idx = find_irq_entry(apic,pin,mp_INT);
 		if (idx == -1) {
@@ -1239,7 +1240,7 @@
 	 */
 	entry.dest_mode = INT_DEST_MODE;
 	entry.mask = 0;					/* unmask IRQ now */
-	entry.dest.logical.logical_dest = TARGET_CPUS;
+	entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
 	entry.delivery_mode = INT_DELIVERY_MODE;
 	entry.polarity = 0;
 	entry.trigger = 0;
@@ -2309,7 +2310,7 @@
 
 	entry.delivery_mode = INT_DELIVERY_MODE;
 	entry.dest_mode = INT_DEST_MODE;
-	entry.dest.logical.logical_dest = TARGET_CPUS;
+	entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
 	entry.mask = 1;					 /* Disabled (masked) */
 	entry.trigger = 1;				   /* Level sensitive */
 	entry.polarity = 1;					/* Low active */
diff -urN linux-2.5.70-bk15/arch/i386/kernel/nmi.c linux-2.5.70-bk16/arch/i386/kernel/nmi.c
--- linux-2.5.70-bk15/arch/i386/kernel/nmi.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/kernel/nmi.c	2003-06-11 04:48:01.000000000 -0700
@@ -23,6 +23,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
+#include <linux/sysdev.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -180,53 +181,48 @@
 
 #ifdef CONFIG_PM
 
-#include <linux/device.h>
 static int nmi_pm_active; /* nmi_active before suspend */
 
-static int lapic_nmi_suspend(struct device *dev, u32 state, u32 level)
+static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
 {
-	if (level != SUSPEND_POWER_DOWN)
-		return 0;
 	nmi_pm_active = nmi_active;
 	disable_lapic_nmi_watchdog();
 	return 0;
 }
 
-static int lapic_nmi_resume(struct device *dev, u32 level)
+static int lapic_nmi_resume(struct sys_device *dev)
 {
-	if (level != RESUME_POWER_ON)
-		return 0;
 	if (nmi_pm_active > 0)
 		enable_lapic_nmi_watchdog();
 	return 0;
 }
 
-static struct device_driver lapic_nmi_driver = {
-	.name		= "lapic_nmi",
-	.bus		= &system_bus_type,
+
+static struct sysdev_class nmi_sysclass = {
+	set_kset_name("lapic_nmi"),
 	.resume		= lapic_nmi_resume,
 	.suspend	= lapic_nmi_suspend,
 };
 
 static struct sys_device device_lapic_nmi = {
-	.name		= "lapic_nmi",
-	.id		= 0,
-	.dev		= {
-		.name	= "lapic_nmi",
-		.driver	= &lapic_nmi_driver,
-		.parent = &device_lapic.dev,
-	},
+	.id	= 0,
+	.cls	= &nmi_sysclass,
 };
 
-static int __init init_lapic_nmi_devicefs(void)
+static int __init init_lapic_nmi_sysfs(void)
 {
+	int error;
+
 	if (nmi_active == 0)
 		return 0;
-	driver_register(&lapic_nmi_driver);
-	return sys_device_register(&device_lapic_nmi);
+
+	error = sysdev_class_register(&nmi_sysclass);
+	if (!error)
+		error = sys_device_register(&device_lapic_nmi);
+	return error;
 }
 /* must come after the local APIC's device_initcall() */
-late_initcall(init_lapic_nmi_devicefs);
+late_initcall(init_lapic_nmi_sysfs);
 
 #endif	/* CONFIG_PM */
 
diff -urN linux-2.5.70-bk15/arch/i386/kernel/time.c linux-2.5.70-bk16/arch/i386/kernel/time.c
--- linux-2.5.70-bk15/arch/i386/kernel/time.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/kernel/time.c	2003-06-11 04:48:01.000000000 -0700
@@ -42,7 +42,7 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/module.h>
-#include <linux/device.h>
+#include <linux/sysdev.h>
 #include <linux/bcd.h>
 
 #include <asm/io.h>
@@ -278,18 +278,22 @@
 	return retval;
 }
 
+static struct sysdev_class rtc_sysclass = {
+	set_kset_name("rtc"),
+};
+
 /* XXX this driverfs stuff should probably go elsewhere later -john */
 static struct sys_device device_i8253 = {
-	.name		= "rtc",
 	.id		= 0,
-	.dev	= {
-		.name	= "i8253 Real Time Clock",
-	},
+	.cls	= &rtc_sysclass,
 };
 
 static int time_init_device(void)
 {
-	return sys_device_register(&device_i8253);
+	int error = sysdev_class_register(&rtc_sysclass);
+	if (!error)
+		error = sys_device_register(&device_i8253);
+	return error;
 }
 
 device_initcall(time_init_device);
diff -urN linux-2.5.70-bk15/arch/i386/mm/discontig.c linux-2.5.70-bk16/arch/i386/mm/discontig.c
--- linux-2.5.70-bk15/arch/i386/mm/discontig.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/mm/discontig.c	2003-06-11 04:48:01.000000000 -0700
@@ -114,10 +114,16 @@
  */
 static void __init find_max_pfn_node(int nid)
 {
-	if (node_start_pfn[nid] >= node_end_pfn[nid])
-		BUG();
 	if (node_end_pfn[nid] > max_pfn)
 		node_end_pfn[nid] = max_pfn;
+	/*
+	 * if a user has given mem=XXXX, then we need to make sure 
+	 * that the node _starts_ before that, too, not just ends
+	 */
+	if (node_start_pfn[nid] > max_pfn)
+		node_start_pfn[nid] = max_pfn;
+	if (node_start_pfn[nid] > node_end_pfn[nid])
+		BUG();
 }
 
 /* 
diff -urN linux-2.5.70-bk15/arch/i386/oprofile/nmi_int.c linux-2.5.70-bk16/arch/i386/oprofile/nmi_int.c
--- linux-2.5.70-bk15/arch/i386/oprofile/nmi_int.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/oprofile/nmi_int.c	2003-06-11 04:48:01.000000000 -0700
@@ -11,7 +11,7 @@
 #include <linux/notifier.h>
 #include <linux/smp.h>
 #include <linux/oprofile.h>
-#include <linux/device.h>
+#include <linux/sysdev.h>
 #include <asm/nmi.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
@@ -31,53 +31,48 @@
 
 #ifdef CONFIG_PM
 
-static int nmi_suspend(struct device *dev, u32 state, u32 level)
+static int nmi_suspend(struct sys_device *dev, u32 state)
 {
-	if (level != SUSPEND_POWER_DOWN)
-		return 0;
 	if (nmi_enabled == 1)
 		nmi_stop();
 	return 0;
 }
 
 
-static int nmi_resume(struct device *dev, u32 level)
+static int nmi_resume(struct sys_device *dev)
 {
-	if (level != RESUME_POWER_ON)
-		return 0;
 	if (nmi_enabled == 1)
 		nmi_start();
 	return 0;
 }
 
 
-static struct device_driver nmi_driver = {
-	.name		= "oprofile",
-	.bus		= &system_bus_type,
+static struct sysdev_class oprofile_sysclass = {
+	set_kset_name("oprofile"),
 	.resume		= nmi_resume,
 	.suspend	= nmi_suspend,
 };
 
 
-static struct device device_nmi = {
-	.name	= "oprofile",
-	.bus_id = "oprofile",
-	.driver	= &nmi_driver,
-	.parent = &device_lapic.dev,
+static struct sys_device device_oprofile = {
+	.id	= 0,
+	.cls	= &oprofile_sysclass,
 };
 
 
 static int __init init_driverfs(void)
 {
-	driver_register(&nmi_driver);
-	return device_register(&device_nmi);
+	int error;
+	if (!(error = sysdev_class_register(&oprofile_sysclass)))
+		error = sys_device_register(&device_oprofile);
+	return error;
 }
 
 
 static void __exit exit_driverfs(void)
 {
-	device_unregister(&device_nmi);
-	driver_unregister(&nmi_driver);
+	sys_device_unregister(&device_oprofile);
+	sysdev_class_unregister(&oprofile_sysclass);
 }
 
 #else
diff -urN linux-2.5.70-bk15/arch/i386/pci/common.c linux-2.5.70-bk16/arch/i386/pci/common.c
--- linux-2.5.70-bk15/arch/i386/pci/common.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk16/arch/i386/pci/common.c	2003-06-11 04:48:01.000000000 -0700
@@ -104,11 +104,9 @@
 
 struct pci_bus * __devinit pcibios_scan_root(int busnum)
 {
-	struct list_head *list;
-	struct pci_bus *bus;
+	struct pci_bus *bus = NULL;
 
-	list_for_each(list, &pci_root_buses) {
-		bus = pci_bus_b(list);
+	while ((bus = pci_find_next_bus(bus)) != NULL) {
 		if (bus->number == busnum) {
 			/* Already scanned */
 			return bus;
diff -urN linux-2.5.70-bk15/arch/ia64/Kconfig linux-2.5.70-bk16/arch/ia64/Kconfig
--- linux-2.5.70-bk15/arch/ia64/Kconfig	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/arch/ia64/Kconfig	2003-06-11 04:48:01.000000000 -0700
@@ -543,6 +543,10 @@
 	  information about which PCI hardware does work under Linux and which
 	  doesn't.
 
+config PCI_DOMAINS
+	bool
+	default PCI
+
 source "drivers/pci/Kconfig"
 
 config HOTPLUG
diff -urN linux-2.5.70-bk15/arch/ia64/hp/common/sba_iommu.c linux-2.5.70-bk16/arch/ia64/hp/common/sba_iommu.c
--- linux-2.5.70-bk15/arch/ia64/hp/common/sba_iommu.c	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/arch/ia64/hp/common/sba_iommu.c	2003-06-11 04:48:01.000000000 -0700
@@ -1889,7 +1889,7 @@
 		handle = parent;
 	} while (ACPI_SUCCESS(status));
 
-	printk(KERN_WARNING "No IOC for PCI Bus %02x:%02x in ACPI\n", PCI_SEGMENT(bus), bus->number);
+	printk(KERN_WARNING "No IOC for PCI Bus %04x:%02x in ACPI\n", pci_domain_nr(bus), bus->number);
 }
 
 static int __init
@@ -1939,8 +1939,8 @@
 
 #ifdef CONFIG_PCI
 	{
-		struct pci_bus *b;
-		pci_for_each_bus(b)
+		struct pci_bus *b = NULL;
+		while ((b = pci_find_next_bus(b)) != NULL)
 			sba_connect_bus(b);
 	}
 #endif
diff -urN linux-2.5.70-bk15/arch/ia64/pci/pci.c linux-2.5.70-bk16/arch/ia64/pci/pci.c
--- linux-2.5.70-bk15/arch/ia64/pci/pci.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk16/arch/ia64/pci/pci.c	2003-06-11 04:48:02.000000000 -0700
@@ -87,14 +87,14 @@
 static int
 pci_sal_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
 {
-	return __pci_sal_read(PCI_SEGMENT(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
+	return __pci_sal_read(pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
 			      where, size, value);
 }
 
 static int
 pci_sal_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
 {
-	return __pci_sal_write(PCI_SEGMENT(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
+	return __pci_sal_write(pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
 			       where, size, value);
 }
 
diff -urN linux-2.5.70-bk15/arch/ppc/Kconfig linux-2.5.70-bk16/arch/ppc/Kconfig
--- linux-2.5.70-bk15/arch/ppc/Kconfig	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/arch/ppc/Kconfig	2003-06-11 04:48:03.000000000 -0700
@@ -773,6 +773,10 @@
 	  your box.  If you say Y here, the kernel will include drivers and
 	  infrastructure code to support PCI bus devices.
 
+config PCI_DOMAINS
+	bool
+	default PCI
+
 config PC_KEYBOARD
 	bool "PC PS/2 style Keyboard"
 	depends on 4xx || 8260
diff -urN linux-2.5.70-bk15/arch/ppc/kernel/pci.c linux-2.5.70-bk16/arch/ppc/kernel/pci.c
--- linux-2.5.70-bk15/arch/ppc/kernel/pci.c	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/arch/ppc/kernel/pci.c	2003-06-11 04:48:03.000000000 -0700
@@ -1483,16 +1483,6 @@
 }
 
 /*
- * Return the index of the PCI controller for device pdev.
- */
-int pci_controller_num(struct pci_dev *dev)
-{
-	struct pci_controller *hose = (struct pci_controller *) dev->sysdata;
-
-	return hose->index;
-}
-
-/*
  * Platform support for /proc/bus/pci/X/Y mmap()s,
  * modelled on the sparc64 implementation by Dave Miller.
  *  -- paulus.
diff -urN linux-2.5.70-bk15/arch/ppc64/Kconfig linux-2.5.70-bk16/arch/ppc64/Kconfig
--- linux-2.5.70-bk15/arch/ppc64/Kconfig	2003-06-11 04:47:45.000000000 -0700
+++ linux-2.5.70-bk16/arch/ppc64/Kconfig	2003-06-11 04:48:03.000000000 -0700
@@ -171,6 +171,10 @@
 	  your box.  If you say Y here, the kernel will include drivers and
 	  infrastructure code to support PCI bus devices.
 
+config PCI_DOMAINS
+	bool
+	default PCI
+
 # only elf supported, a.out is not -- Cort
 config KCORE_ELF
 	bool
diff -urN linux-2.5.70-bk15/arch/ppc64/kernel/pci.c linux-2.5.70-bk16/arch/ppc64/kernel/pci.c
--- linux-2.5.70-bk15/arch/ppc64/kernel/pci.c	2003-06-11 04:47:46.000000000 -0700
+++ linux-2.5.70-bk16/arch/ppc64/kernel/pci.c	2003-06-11 04:48:03.000000000 -0700
@@ -371,11 +371,11 @@
 }
 
 /*
- * Return the index of the PCI controller for device pdev.
+ * Return the domain number for this bus.
  */
-int pci_controller_num(struct pci_dev *dev)
+int pci_domain_nr(struct pci_bus *bus)
 {
-	struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+	struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
 
 	return hose->global_number;
 }
diff -urN linux-2.5.70-bk15/arch/sparc/kernel/ebus.c linux-2.5.70-bk16/arch/sparc/kernel/ebus.c
--- linux-2.5.70-bk15/arch/sparc/kernel/ebus.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk16/arch/sparc/kernel/ebus.c	2003-06-11 04:48:03.000000000 -0700
@@ -267,9 +267,6 @@
 	int reg, nreg;
 	int num_ebus = 0;
 
-	if (!pci_present())
-		return;
-
 	prom_getstring(prom_root_node, "name", lbuf, sizeof(lbuf));
 	for (sp = ebus_blacklist; sp->esname != NULL; sp++) {
 		if (strcmp(lbuf, sp->esname) == 0) {
diff -urN linux-2.5.70-bk15/arch/sparc64/Kconfig linux-2.5.70-bk16/arch/sparc64/Kconfig
--- linux-2.5.70-bk15/arch/sparc64/Kconfig	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk16/arch/sparc64/Kconfig	2003-06-11 04:48:03.000000000 -0700
@@ -318,6 +318,10 @@
 	  information about which PCI hardware does work under Linux and which
 	  doesn't.
 
+config PCI_DOMAINS
+	bool
+	default PCI
+
 config RTC
 	tristate
 	depends on PCI
diff -urN linux-2.5.70-bk15/arch/sparc64/kernel/ebus.c linux-2.5.70-bk16/arch/sparc64/kernel/ebus.c
--- linux-2.5.70-bk15/arch/sparc64/kernel/ebus.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk16/arch/sparc64/kernel/ebus.c	2003-06-11 04:48:03.000000000 -0700
@@ -525,9 +525,6 @@
 	int nd, ebusnd, is_rio;
 	int num_ebus = 0;
 
-	if (!pci_present())
-		return;
-
 	pdev = find_next_ebus(NULL, &is_rio);
 	if (!pdev) {
 		printk("ebus: No EBus's found.\n");
diff -urN linux-2.5.70-bk15/arch/sparc64/kernel/pci.c linux-2.5.70-bk16/arch/sparc64/kernel/pci.c
--- linux-2.5.70-bk15/arch/sparc64/kernel/pci.c	2003-05-26 18:00:19.000000000 -0700
+++ linux-2.5.70-bk16/arch/sparc64/kernel/pci.c	2003-06-11 04:48:03.000000000 -0700
@@ -802,11 +802,11 @@
 	return 0;
 }
 
-/* Return the index of the PCI controller for device PDEV. */
+/* Return the domain nuber for this pci bus */
 
-int pci_controller_num(struct pci_dev *pdev)
+int pci_domain_nr(struct pci_bus *bus)
 {
-	struct pcidev_cookie *cookie = pdev->sysdata;
+	struct pcidev_cookie *cookie = bus->sysdata;
 	int ret;
 
 	if (cookie != NULL) {
diff -urN linux-2.5.70-bk15/arch/x86_64/kernel/i8259.c linux-2.5.70-bk16/arch/x86_64/kernel/i8259.c
--- linux-2.5.70-bk15/arch/x86_64/kernel/i8259.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk16/arch/x86_64/kernel/i8259.c	2003-06-11 04:48:04.000000000 -0700
@@ -11,7 +11,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
-#include <linux/device.h>
+#include <linux/sysdev.h>
 
 #include <asm/atomic.h>
 #include <asm/system.h>
@@ -413,35 +413,31 @@
 	outb(LATCH >> 8 , 0x40);	/* MSB */
 }
 
-static int timer_resume(struct device *dev, u32 level)
+static int timer_resume(struct sys_device *dev)
 {
-	if (level == RESUME_POWER_ON)
-		setup_timer();
+	setup_timer();
 	return 0;
 }
 
-static struct device_driver timer_driver = {
-	.name		= "timer",
-	.bus		= &system_bus_type,
+static struct sysdev_class timer_sysclass = {
+	set_kset_name("timer"),
 	.resume		= timer_resume,
 };
 
 static struct sys_device device_timer = {
-	.name		= "timer",
 	.id		= 0,
-	.dev		= {
-		.name	= "timer",
-		.driver	= &timer_driver,
-	},
+	.cls		&timer_sysclass,
 };
 
-static int __init init_timer_devicefs(void)
+static int __init init_timer_sysfs(void)
 {
-	driver_register(&timer_driver);
-	return sys_device_register(&device_timer);
+	int error = sysdev_class_register(&timer_sysclass);
+	if (!error)
+		error = sys_device_register(&device_timer);
+	return error;
 }
 
-device_initcall(init_timer_devicefs);
+device_initcall(init_timer_sysfs);
 
 void __init init_IRQ(void)
 {
diff -urN linux-2.5.70-bk15/drivers/atm/ambassador.c linux-2.5.70-bk16/drivers/atm/ambassador.c
--- linux-2.5.70-bk15/drivers/atm/ambassador.c	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk16/drivers/atm/ambassador.c	2003-06-11 04:48:04.000000000 -0700
@@ -2509,9 +2509,6 @@
   
   PRINTD (DBG_FLOW, "amb_probe");
   
-  if (!pci_present())
-    return 0;
-  
   devs = 0;
   pci_dev = NULL;
   while ((pci_dev = pci_find_device
diff -urN linux-2.5.70-bk15/drivers/atm/fore200e.c linux-2.5.70-bk16/drivers/atm/fore200e.c
--- linux-2.5.70-bk15/drivers/atm/fore200e.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk16/drivers/atm/fore200e.c	2003-06-11 04:48:04.000000000 -0700
@@ -633,11 +633,6 @@
     struct pci_dev*  pci_dev = NULL;
     int              count = index;
     
-    if (pci_present() == 0) {
-	printk(FORE200E "no PCI subsystem\n");
-	return NULL;
-    }
-
     do {
 	pci_dev = pci_find_device(PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, pci_dev);
 	if (pci_dev == NULL)
diff -urN linux-2.5.70-bk15/drivers/atm/nicstar.c linux-2.5.70-bk16/drivers/atm/nicstar.c
--- linux-2.5.70-bk15/drivers/atm/nicstar.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk16/drivers/atm/nicstar.c	2003-06-11 04:48:04.000000000 -0700
@@ -283,11 +283,6 @@
    struct pci_dev *pcidev;
 
    XPRINTK("nicstar: nicstar_module_init() called.\n");
-   if(!pci_present())
-   {
-      printk("nicstar: no PCI subsystem found.\n");
-      return -EIO;
-   }
 
    for(i = 0; i < NS_MAX_CARDS; i++)
       cards[i] = NULL;
diff -urN linux-2.5.70-bk15/drivers/base/cpu.c linux-2.5.70-bk16/drivers/base/cpu.c
--- linux-2.5.70-bk15/drivers/base/cpu.c	2003-06-11 04:47:46.000000000 -0700
+++ linux-2.5.70-bk16/drivers/base/cpu.c	2003-06-11 04:48:04.000000000 -0700
@@ -2,23 +2,18 @@
  * drivers/base/cpu.c - basic CPU class support
  */
 
-#include <linux/device.h>
+#include <linux/sysdev.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
 #include <linux/topology.h>
 
 
-struct class cpu_class = {
-	.name		= "cpu",
+struct sysdev_class cpu_sysdev_class = {
+	set_kset_name("cpu"),
 };
 
 
-struct device_driver cpu_driver = {
-	.name		= "cpu",
-	.bus		= &system_bus_type,
-};
-
 /*
  * register_cpu - Setup a driverfs device for a CPU.
  * @num - CPU number to use when creating the device.
@@ -27,42 +22,15 @@
  */
 int __init register_cpu(struct cpu *cpu, int num, struct node *root)
 {
-	int retval;
-
 	cpu->node_id = cpu_to_node(num);
-	cpu->sysdev.name = "cpu";
 	cpu->sysdev.id = num;
-	if (root)
-		cpu->sysdev.root = &root->sysroot;
-	snprintf(cpu->sysdev.dev.name, DEVICE_NAME_SIZE, "CPU %u", num);
-	cpu->sysdev.dev.driver = &cpu_driver;
-	retval = sys_device_register(&cpu->sysdev);
-	if (retval)
-		return retval;
-	memset(&cpu->sysdev.class_dev, 0x00, sizeof(struct class_device));
-	cpu->sysdev.class_dev.dev = &cpu->sysdev.dev;
-	cpu->sysdev.class_dev.class = &cpu_class;
-	snprintf(cpu->sysdev.class_dev.class_id, BUS_ID_SIZE, "cpu%d", num);
-	retval = class_device_register(&cpu->sysdev.class_dev);
-	if (retval) {
-		sys_device_unregister(&cpu->sysdev);
-		return retval;
-	}
-	return 0;
+	cpu->sysdev.cls = &cpu_sysdev_class;
+	return sys_device_register(&cpu->sysdev);
 }
 
 
+
 int __init cpu_dev_init(void)
 {
-	int error;
-
-	error = class_register(&cpu_class);
-	if (error)
-		goto out;
-	
-	error = driver_register(&cpu_driver);
-	if (error)
-		class_unregister(&cpu_class);
-out:
-	return error;
+	return sysdev_class_register(&cpu_sysdev_class);
 }
diff -urN linux-2.5.70-bk15/drivers/base/memblk.c linux-2.5.70-bk16/drivers/base/memblk.c
--- linux-2.5.70-bk15/drivers/base/memblk.c	2003-06-11 04:47:46.000000000 -0700
+++ linux-2.5.70-bk16/drivers/base/memblk.c	2003-06-11 04:48:04.000000000 -0700
@@ -2,7 +2,6 @@
  * drivers/base/memblk.c - basic Memory Block class support
  */
 
-#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/memblk.h>
@@ -10,8 +9,8 @@
 #include <linux/topology.h>
 
 
-static struct class memblk_class = {
-	.name		= "memblk",
+static struct sysdev_class memblk_class = {
+	set_kset_name("memblk"),
 };
 
 
@@ -29,27 +28,23 @@
  */
 int __init register_memblk(struct memblk *memblk, int num, struct node *root)
 {
+	int error;
+
 	memblk->node_id = memblk_to_node(num);
-	memblk->sysdev.name = "memblk";
+	memblk->sysdev.cls = &memblk_class,
 	memblk->sysdev.id = num;
-	if (root)
-		memblk->sysdev.root = &root->sysroot;
-	snprintf(memblk->sysdev.dev.name, DEVICE_NAME_SIZE, "Memory Block %u", num);
-	memblk->sysdev.dev.driver = &memblk_driver;
-	return sys_device_register(&memblk->sysdev);
+
+	error = sys_device_register(&memblk->sysdev);
+	if (!error) 
+		error = sysfs_create_link(&root->sysdev.kobj,
+					  &memblk->sysdev,kobj,
+					  memblk->sysdev.kobj.name);
+	return error;
 }
 
 
 int __init register_memblk_type(void)
 {
-	int error;
-
-	error = class_register(&memblk_class);
-	if (!error) {
-		error = driver_register(&memblk_driver);
-		if (error)
-			class_unregister(&memblk_class);
-	}
-	return error;
+	return sysdev_class_register(&memblk_class);
 }
 postcore_initcall(register_memblk_type);
diff -urN linux-2.5.70-bk15/drivers/base/node.c linux-2.5.70-bk16/drivers/base/node.c
--- linux-2.5.70-bk15/drivers/base/node.c	2003-06-11 04:47:46.000000000 -0700
+++ linux-2.5.70-bk16/drivers/base/node.c	2003-06-11 04:48:04.000000000 -0700
@@ -9,15 +9,8 @@
 #include <linux/node.h>
 #include <linux/topology.h>
 
-
-static struct class node_class = {
-	.name		= "node",
-};
-
-
-static struct device_driver node_driver = {
-	.name		= "node",
-	.bus		= &system_bus_type,
+static struct sysdev_class node_class = {
+	set_kset_name("node"),
 };
 
 
@@ -26,7 +19,7 @@
 	struct node *node_dev = to_node(to_root(dev));
         return sprintf(buf,"%lx\n",node_dev->cpumap);
 }
-static DEVICE_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
+static SYSDEV_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
 
 #define K(x) ((x) << (PAGE_SHIFT - 10))
 static ssize_t node_read_meminfo(struct device * dev, char * buf)
@@ -52,7 +45,7 @@
 		       nid, K(i.freeram-i.freehigh));
 }
 #undef K 
-static DEVICE_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
+static SYSDEV_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
 
 
 /*
@@ -66,17 +59,13 @@
 	int error;
 
 	node->cpumap = node_to_cpumask(num);
-	node->sysroot.id = num;
-	if (parent)
-		node->sysroot.dev.parent = &parent->sysroot.sysdev;
-	snprintf(node->sysroot.dev.name, DEVICE_NAME_SIZE, "Node %u", num);
-	snprintf(node->sysroot.dev.bus_id, BUS_ID_SIZE, "node%u", num);
-	node->sysroot.dev.driver = &node_driver;
-	node->sysroot.dev.bus = &system_bus_type;
-	error = sys_register_root(&node->sysroot);
+	node->sysdev.id = num;
+	node->sysdev.cls = &node_class;
+	error = sys_device_register(&node->sysdev);
+
 	if (!error){
-		device_create_file(&node->sysroot.dev, &dev_attr_cpumap);
-		device_create_file(&node->sysroot.dev, &dev_attr_meminfo);
+		sys_device_create_file(&node->sysroot.dev, &attr_cpumap);
+		sys_device_create_file(&node->sysroot.dev, &attr_meminfo);
 	}
 	return error;
 }
@@ -84,14 +73,6 @@
 
 int __init register_node_type(void)
 {
-	int error;
-	
-	error = class_register(&node_class);
-	if (!error) {
-		error = driver_register(&node_driver);
-		if (error)
-			class_unregister(&node_class);
-	}
-	return error;
+	return sysdev_class_register(&node_class);
 }
 postcore_initcall(register_node_type);
diff -urN linux-2.5.70-bk15/drivers/base/power.c linux-2.5.70-bk16/drivers/base/power.c
--- linux-2.5.70-bk15/drivers/base/power.c	2003-06-11 04:47:46.000000000 -0700
+++ linux-2.5.70-bk16/drivers/base/power.c	2003-06-11 04:48:04.000000000 -0700
@@ -22,6 +22,21 @@
 extern struct subsystem devices_subsys;
 
 /**
+ * We handle system devices differently - we suspend and shut them 
+ * down first and resume them first. That way, we do anything stupid like
+ * shutting down the interrupt controller before any devices..
+ *
+ * Note that there are not different stages for power management calls - 
+ * they only get one called once when interrupts are disabled. 
+ */
+
+extern int sysdev_shutdown(void);
+extern int sysdev_save(u32 state);
+extern int sysdev_suspend(u32 state);
+extern int sysdev_resume(void);
+extern int sysdev_restore(void);
+
+/**
  * device_suspend - suspend/remove all devices on the device ree
  * @state:	state we're entering
  * @level:	what stage of the suspend process we're at
@@ -50,6 +65,21 @@
 		}
 	}
 	up_write(&devices_subsys.rwsem);
+
+	/*
+	 * Make sure system devices are suspended.
+	 */
+	switch(level) {
+	case SUSPEND_SAVE_STATE:
+		sysdev_save(state);
+		break;
+	case SUSPEND_POWER_DOWN:
+		sysdev_suspend(state);
+		break;
+	default:
+		break;
+	}
+
 	return error;
 }
 
@@ -65,6 +95,17 @@
 {
 	struct list_head * node;
 
+	switch (level) {
+	case RESUME_POWER_ON:
+		sysdev_resume();
+		break;
+	case RESUME_RESTORE_STATE:
+		sysdev_restore();
+		break;
+	default:
+		break;
+	}
+
 	down_write(&devices_subsys.rwsem);
 	list_for_each_prev(node,&devices_subsys.kset.list) {
 		struct device * dev = to_dev(node);
@@ -98,6 +139,8 @@
 			pr_debug("Ignored.\n");
 	}
 	up_write(&devices_subsys.rwsem);
+
+	sysdev_shutdown();
 }
 
 EXPORT_SYMBOL(device_suspend);
diff -urN linux-2.5.70-bk15/drivers/base/sys.c linux-2.5.70-bk16/drivers/base/sys.c
--- linux-2.5.70-bk15/drivers/base/sys.c	2003-06-11 04:47:46.000000000 -0700
+++ linux-2.5.70-bk16/drivers/base/sys.c	2003-06-11 04:48:04.000000000 -0700
@@ -12,9 +12,9 @@
  * add themselves as children of the system bus.
  */
 
-#undef DEBUG
+#define DEBUG
 
-#include <linux/device.h>
+#include <linux/sysdev.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -22,130 +22,435 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 
-/* The default system device parent. */
-static struct device system_bus = {
-       .name           = "System Bus",
-       .bus_id         = "sys",
+
+extern struct subsystem devices_subsys;
+
+#define to_sysdev(k) container_of(k,struct sys_device,kobj)
+#define to_sysdev_attr(a) container_of(a,struct sysdev_attribute,attr)
+
+
+static ssize_t 
+sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
+{
+	struct sys_device * sysdev = to_sysdev(kobj);
+	struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+
+	if (sysdev_attr->show)
+		return sysdev_attr->show(sysdev,buffer);
+	return 0;
+}
+
+
+static ssize_t
+sysdev_store(struct kobject * kobj, struct attribute * attr, 
+	     const char * buffer, size_t count)
+{
+	struct sys_device * sysdev = to_sysdev(kobj);
+	struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+
+	if (sysdev_attr->store)
+		return sysdev_attr->store(sysdev,buffer,count);
+	return 0;
+}
+
+static struct sysfs_ops sysfs_ops = {
+	.show	= sysdev_show,
+	.store	= sysdev_store,
+};
+
+static struct kobj_type ktype_sysdev = {
+	.sysfs_ops	= &sysfs_ops,
 };
 
+/* 
+ * declare system_subsys 
+ */
+decl_subsys(system,&ktype_sysdev,NULL);
+
+int sysdev_class_register(struct sysdev_class * cls)
+{
+	pr_debug("Registering sysdev class '%s'\n",cls->kset.kobj.name);
+	INIT_LIST_HEAD(&cls->drivers);
+	cls->kset.subsys = &system_subsys;
+	kset_set_kset_s(cls,system_subsys);
+	return kset_register(&cls->kset);
+}
+
+void sysdev_class_unregister(struct sysdev_class * cls)
+{
+	pr_debug("Unregistering sysdev class '%s'\n",cls->kset.kobj.name);
+	kset_unregister(&cls->kset);
+}
+
+EXPORT_SYMBOL(sysdev_class_register);
+EXPORT_SYMBOL(sysdev_class_unregister);
+
+
+static LIST_HEAD(global_drivers);
+
+/**
+ *	sysdev_driver_register - Register auxillary driver
+ * 	@cls:	Device class driver belongs to.
+ *	@drv:	Driver.
+ *
+ *	If @cls is valid, then @drv is inserted into @cls->drivers to be 
+ *	called on each operation on devices of that class. The refcount
+ *	of @cls is incremented. 
+ *	Otherwise, @drv is inserted into global_drivers, and called for 
+ *	each device.
+ */
+
+int sysdev_driver_register(struct sysdev_class * cls, 
+			   struct sysdev_driver * drv)
+{
+	down_write(&system_subsys.rwsem);
+	if (cls && kset_get(&cls->kset))
+		list_add_tail(&drv->entry,&cls->drivers);
+	else
+		list_add_tail(&drv->entry,&global_drivers);
+	up_write(&system_subsys.rwsem);
+	return 0;
+}
+
 
 /**
- *	sys_register_root - add a subordinate system root
- *	@root:	new root
- *	
- *	This is for NUMA-like systems so they can accurately 
- *	represent the topology of the entire system.
- *	As boards are discovered, a new struct sys_root should 
- *	be allocated and registered. 
- *	The discovery mechanism should initialize the id field
- *	of the struture, as well as much of the embedded device
- *	structure as possible, inlcuding the name, the bus_id
- *	and parent fields.
- *
- *	This simply calls device_register on the embedded device.
- *	On success, it will use the struct @root->sysdev 
- *	device to create a pseudo-parent for system devices
- *	on that board.
- *
- *	The platform code can then use @root to specifiy the
- *	controlling board when discovering and registering 
- *	system devices.
+ *	sysdev_driver_unregister - Remove an auxillary driver.
+ *	@cls:	Class driver belongs to.
+ *	@drv:	Driver.
  */
-int sys_register_root(struct sys_root * root)
+void sysdev_driver_unregister(struct sysdev_class * cls,
+			      struct sysdev_driver * drv)
 {
-	int error = 0;
+	down_write(&system_subsys.rwsem);
+	list_del_init(&drv->entry);
+	if (cls)
+		kset_put(&cls->kset);
+	up_write(&system_subsys.rwsem);
+}
+
 
-	if (!root)
+/**
+ *	sys_device_register - add a system device to the tree
+ *	@sysdev:	device in question
+ *
+ */
+int sys_device_register(struct sys_device * sysdev)
+{
+	int error;
+	struct sysdev_class * cls = sysdev->cls;
+
+	if (!cls)
 		return -EINVAL;
 
-	if (!root->dev.parent)
-		root->dev.parent = &system_bus;
+	/* Make sure the kset is set */
+	sysdev->kobj.kset = &cls->kset;
+
+	/* set the kobject name */
+	snprintf(sysdev->kobj.name,KOBJ_NAME_LEN,"%s%d",
+		 cls->kset.kobj.name,sysdev->id);
 
-	pr_debug("Registering system board %d\n",root->id);
+	pr_debug("Registering sys device '%s'\n",sysdev->kobj.name);
+
+	/* Register the object */
+	error = kobject_register(&sysdev->kobj);
 
-	error = device_register(&root->dev);
 	if (!error) {
-		strlcpy(root->sysdev.bus_id,"sys",BUS_ID_SIZE);
-		strlcpy(root->sysdev.name,"System Bus",DEVICE_NAME_SIZE);
-		root->sysdev.parent = &root->dev;
-		error = device_register(&root->sysdev);
-	};
+		struct sysdev_driver * drv;
 
+		down_read(&system_subsys.rwsem);
+		/* Generic notification is implicit, because it's that 
+		 * code that should have called us. 
+		 */
+
+		/* Notify global drivers */
+		list_for_each_entry(drv,&global_drivers,entry) {
+			if (drv->add)
+				drv->add(sysdev);
+		}
+
+		/* Notify class auxillary drivers */
+		list_for_each_entry(drv,&cls->drivers,entry) {
+			if (drv->add)
+				drv->add(sysdev);
+		}
+		up_read(&system_subsys.rwsem);
+	}
 	return error;
 }
 
+void sys_device_unregister(struct sys_device * sysdev)
+{
+	struct sysdev_driver * drv;
+
+	down_read(&system_subsys.rwsem);
+	list_for_each_entry(drv,&global_drivers,entry) {
+		if (drv->remove)
+			drv->remove(sysdev);
+	}
+
+	list_for_each_entry(drv,&sysdev->cls->drivers,entry) {
+		if (drv->remove)
+			drv->remove(sysdev);
+	}
+	up_read(&system_subsys.rwsem);
+
+	kobject_unregister(&sysdev->kobj);
+}
+
+
+
 /**
- *	sys_unregister_root - remove subordinate root from tree
- *	@root:	subordinate root in question.
+ *	sysdev_shutdown - Shut down all system devices.
+ *
+ *	Loop over each class of system devices, and the devices in each
+ *	of those classes. For each device, we call the shutdown method for
+ *	each driver registered for the device - the globals, the auxillaries,
+ *	and the class driver. 
  *
- *	We only decrement the reference count on @root->sysdev 
- *	and @root->dev.
- *	If both are 0, they will be cleaned up by the core.
+ *	Note: The list is iterated in reverse order, so that we shut down
+ *	child devices before we shut down thier parents. The list ordering
+ *	is guaranteed by virtue of the fact that child devices are registered
+ *	after their parents. 
  */
-void sys_unregister_root(struct sys_root *root)
+
+void sysdev_shutdown(void)
 {
-	device_unregister(&root->sysdev);
-	device_unregister(&root->dev);
+	struct sysdev_class * cls;
+
+	pr_debug("Shutting Down System Devices\n");
+
+	down_write(&system_subsys.rwsem);
+	list_for_each_entry_reverse(cls,&system_subsys.kset.list,
+				    kset.kobj.entry) {
+		struct sys_device * sysdev;
+
+		pr_debug("Shutting down type '%s':\n",cls->kset.kobj.name);
+
+		list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+			struct sysdev_driver * drv;
+			pr_debug(" %s\n",sysdev->kobj.name);
+
+			/* Call global drivers first. */
+			list_for_each_entry(drv,&global_drivers,entry) {
+				if (drv->shutdown)
+					drv->shutdown(sysdev);
+			}
+
+			/* Call auxillary drivers next. */
+			list_for_each_entry(drv,&cls->drivers,entry) {
+				if (drv->shutdown)
+					drv->shutdown(sysdev);
+			}
+
+			/* Now call the generic one */
+			if (cls->shutdown)
+				cls->shutdown(sysdev);
+		}
+	}
+	up_write(&system_subsys.rwsem);
 }
 
+
 /**
- *	sys_device_register - add a system device to the tree
- *	@sysdev:	device in question
+ *	sysdev_save - Save system device state
+ *	@state:	Power state we're entering.
  *
- *	The hardest part about this is getting the ancestry right.
- *	If the device has a parent - super! We do nothing.
- *	If the device doesn't, but @dev->root is set, then we're
- *	dealing with a NUMA like architecture where each root
- *	has a system pseudo-bus to foster the device.
- *	If not, then we fallback to system_bus (at the top of 
- *	this file). 
+ *	This is called when the system is going to sleep, but before interrupts 
+ *	have been disabled. This allows system device drivers to allocate and 
+ *	save device state, including sleeping during the process..
+ */
+
+int sysdev_save(u32 state)
+{
+	struct sysdev_class * cls;
+
+	pr_debug("Saving System Device State\n");
+
+	down_write(&system_subsys.rwsem);
+
+	list_for_each_entry_reverse(cls,&system_subsys.kset.list,
+				    kset.kobj.entry) {
+		struct sys_device * sysdev;
+		pr_debug("Saving state for type '%s':\n",cls->kset.kobj.name);
+
+		list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+			struct sysdev_driver * drv;
+
+			pr_debug(" %s\n",sysdev->kobj.name);
+
+			list_for_each_entry(drv,&global_drivers,entry) {
+				if (drv->save)
+					drv->save(sysdev,state);
+			}
+
+			list_for_each_entry(drv,&cls->drivers,entry) {
+				if (drv->save)
+					drv->save(sysdev,state);
+			}
+
+			if (cls->save)
+				cls->save(sysdev,state);
+		}
+	}
+	up_write(&system_subsys.rwsem);
+	return 0;
+}
+
+
+/**
+ *	sysdev_suspend - Suspend all system devices.
+ *	@state:		Power state to enter.
  *
- *	One way or another, we call device_register() on it and 
- *	are done.
+ *	We perform an almost identical operation as sys_device_shutdown()
+ *	above, though calling ->suspend() instead.
  *
- *	The caller is also responsible for initializing the bus_id 
- *	and name fields of @sysdev->dev.
+ *	Note: Interrupts are disabled when called, so we can't sleep when
+ *	trying to get the subsystem's rwsem. If that happens, print a nasty
+ *	warning and return an error.
  */
-int sys_device_register(struct sys_device * sysdev)
+
+int sysdev_suspend(u32 state)
 {
-	if (!sysdev)
-		return -EINVAL;
+	struct sysdev_class * cls;
 
-	if (!sysdev->dev.parent) {
-		if (sysdev->root)
-			sysdev->dev.parent = &sysdev->root->sysdev;
-		else
-			sysdev->dev.parent = &system_bus;
+	pr_debug("Suspending System Devices\n");
+
+	if (!down_write_trylock(&system_subsys.rwsem)) {
+		printk("%s: Cannot acquire semaphore; Failing\n",__FUNCTION__);
+		return -EFAULT;
 	}
 
-	/* make sure bus type is set */
-	if (!sysdev->dev.bus)
-		sysdev->dev.bus = &system_bus_type;
+	list_for_each_entry_reverse(cls,&system_subsys.kset.list,
+				    kset.kobj.entry) {
+		struct sys_device * sysdev;
+
+		pr_debug("Suspending type '%s':\n",cls->kset.kobj.name);
+
+		list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+			struct sysdev_driver * drv;
+			pr_debug(" %s\n",sysdev->kobj.name);
+
+			/* Call global drivers first. */
+			list_for_each_entry(drv,&global_drivers,entry) {
+				if (drv->suspend)
+					drv->suspend(sysdev,state);
+			}
+
+			/* Call auxillary drivers next. */
+			list_for_each_entry(drv,&cls->drivers,entry) {
+				if (drv->suspend)
+					drv->suspend(sysdev,state);
+			}
+
+			/* Now call the generic one */
+			if (cls->suspend)
+				cls->suspend(sysdev,state);
+		}
+	}
+	up_write(&system_subsys.rwsem);
 
-	/* construct bus_id */
-	snprintf(sysdev->dev.bus_id,BUS_ID_SIZE,"%s%u",sysdev->name,sysdev->id);
+	return 0;
+}
 
-	pr_debug("Registering system device %s\n", sysdev->dev.bus_id);
 
-	return device_register(&sysdev->dev);
+/**
+ *	sysdev_resume - Bring system devices back to life.
+ *
+ *	Similar to sys_device_suspend(), but we iterate the list forwards
+ *	to guarantee that parent devices are resumed before their children.
+ *
+ *	Note: Interrupts are disabled when called.
+ */
+
+int sysdev_resume(void)
+{
+	struct sysdev_class * cls;
+
+	pr_debug("Resuming System Devices\n");
+
+	if(!down_write_trylock(&system_subsys.rwsem))
+		return -EFAULT;
+
+	list_for_each_entry(cls,&system_subsys.kset.list,kset.kobj.entry) {
+		struct sys_device * sysdev;
+
+		pr_debug("Resuming type '%s':\n",cls->kset.kobj.name);
+
+		list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+			struct sysdev_driver * drv;
+			pr_debug(" %s\n",sysdev->kobj.name);
+
+			/* First, call the class-specific one */
+			if (cls->resume)
+				cls->resume(sysdev);
+
+			/* Call auxillary drivers next. */
+			list_for_each_entry(drv,&cls->drivers,entry) {
+				if (drv->resume)
+					drv->resume(sysdev);
+			}
+
+			/* Call global drivers. */
+			list_for_each_entry(drv,&global_drivers,entry) {
+				if (drv->resume)
+					drv->resume(sysdev);
+			}
+
+		}
+	}
+	up_write(&system_subsys.rwsem);
+	return 0;
 }
 
-void sys_device_unregister(struct sys_device * sysdev)
+
+/**
+ *	sysdev_restore - Restore system device state
+ *
+ *	This is called during a suspend/resume cycle last, after interrupts 
+ *	have been re-enabled. This is intended for auxillary drivers, etc, 
+ *	that may sleep when restoring state.
+ */
+
+int sysdev_restore(void)
 {
-	if (sysdev)
-		device_unregister(&sysdev->dev);
+	struct sysdev_class * cls;
+
+	down_write(&system_subsys.rwsem);
+	pr_debug("Restoring System Device State\n");
+
+	list_for_each_entry(cls,&system_subsys.kset.list,kset.kobj.entry) {
+		struct sys_device * sysdev;
+
+		pr_debug("Restoring state for type '%s':\n",cls->kset.kobj.name);
+		list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+			struct sysdev_driver * drv;
+			pr_debug(" %s\n",sysdev->kobj.name);
+
+			if (cls->restore)
+				cls->restore(sysdev);
+
+			list_for_each_entry(drv,&cls->drivers,entry) {
+				if (drv->restore)
+					drv->restore(sysdev);
+			}
+
+			list_for_each_entry(drv,&global_drivers,entry) {
+				if (drv->restore)
+					drv->restore(sysdev);
+			}
+		}
+	}
+
+	up_write(&system_subsys.rwsem);
+	return 0;
 }
 
-struct bus_type system_bus_type = {
-	.name		= "system",
-};
 
 int __init sys_bus_init(void)
 {
-	bus_register(&system_bus_type);
-	return device_register(&system_bus);
+	system_subsys.kset.kobj.parent = &devices_subsys.kset.kobj;
+	return subsystem_register(&system_subsys);
 }
 
-EXPORT_SYMBOL(system_bus_type);
 EXPORT_SYMBOL(sys_device_register);
 EXPORT_SYMBOL(sys_device_unregister);
diff -urN linux-2.5.70-bk15/drivers/block/cpqarray.c linux-2.5.70-bk16/drivers/block/cpqarray.c
--- linux-2.5.70-bk15/drivers/block/cpqarray.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk16/drivers/block/cpqarray.c	2003-06-11 04:48:04.000000000 -0700
@@ -1028,7 +1028,7 @@
 	int diskinfo[4];
 	struct hd_geometry *geo = (struct hd_geometry *)arg;
 	ida_ioctl_t *io = (ida_ioctl_t*)arg;
-	ida_ioctl_t my_io;
+	ida_ioctl_t *my_io;
 
 	switch(cmd) {
 	case HDIO_GETGEO:
@@ -1051,12 +1051,24 @@
 			return -EFAULT;
 		return 0;
 	case IDAPASSTHRU:
-		if (!capable(CAP_SYS_RAWIO)) return -EPERM;
-		if (copy_from_user(&my_io, io, sizeof(my_io)))
-			return -EFAULT;
-		error = ida_ctlr_ioctl(host, drv - host->drv, &my_io);
-		if (error) return error;
-		return copy_to_user(io, &my_io, sizeof(my_io)) ? -EFAULT : 0;
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		my_io = kmalloc(sizeof(ida_ioctl_t), GFP_KERNEL);
+		if (!my_io)
+			return -ENOMEM;
+		error = -EFAULT;
+		if (copy_from_user(my_io, io, sizeof(*my_io)))
+			goto out_passthru;
+		error = ida_ctlr_ioctl(host, drv - host->drv, my_io);
+		if (error)
+			goto out_passthru;
+		error = -EFAULT;
+		if (copy_to_user(io, &my_io, sizeof(*my_io)))
+			goto out_passthru;
+		error = 0;
+out_passthru:
+		kfree(my_io);
+		return error;
 	case IDAGETCTLRSIG:
 		if (!arg) return -EINVAL;
 		put_user(host->ctlr_sig, (int*)arg);
diff -urN linux-2.5.70-bk15/drivers/char/epca.c linux-2.5.70-bk16/drivers/char/epca.c
--- linux-2.5.70-bk15/drivers/char/epca.c	2003-06-11 04:47:47.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/epca.c	2003-06-11 04:48:04.000000000 -0700
@@ -1639,16 +1639,9 @@
 	--------------------------------------------------------------------- */
   
 	pci_boards_found = 0;
-	if (pci_present())
-	{
-		if(num_cards < MAXBOARDS)
-			pci_boards_found += init_PCI();
-		num_cards += pci_boards_found;
-	}
-	else 
-	{
-		printk(KERN_ERR "<Error> - No PCI BIOS found\n");
-	}
+	if(num_cards < MAXBOARDS)
+		pci_boards_found += init_PCI();
+	num_cards += pci_boards_found;
 
 #endif /* ENABLE_PCI */
 
diff -urN linux-2.5.70-bk15/drivers/char/ip2main.c linux-2.5.70-bk16/drivers/char/ip2main.c
--- linux-2.5.70-bk15/drivers/char/ip2main.c	2003-06-11 04:47:49.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/ip2main.c	2003-06-11 04:48:04.000000000 -0700
@@ -691,41 +691,39 @@
 				} 
 			} 
 #else /* LINUX_VERSION_CODE > 2.1.99 */
-			if (pci_present()) {
-				struct pci_dev *pci_dev_i = NULL;
-				pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
-							  PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
-				if (pci_dev_i != NULL) {
-					unsigned int addr;
-					unsigned char pci_irq;
-
-					ip2config.type[i] = PCI;
-					status =
-					pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
-					if ( addr & 1 ) {
-						ip2config.addr[i]=(USHORT)(addr&0xfffe);
-					} else {
-						printk( KERN_ERR "IP2: PCI I/O address error\n");
-					}
-					status =
-					pci_read_config_byte(pci_dev_i, PCI_INTERRUPT_LINE, &pci_irq);
+			struct pci_dev *pci_dev_i = NULL;
+			pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
+						  PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
+			if (pci_dev_i != NULL) {
+				unsigned int addr;
+				unsigned char pci_irq;
+
+				ip2config.type[i] = PCI;
+				status =
+				pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
+				if ( addr & 1 ) {
+					ip2config.addr[i]=(USHORT)(addr&0xfffe);
+				} else {
+					printk( KERN_ERR "IP2: PCI I/O address error\n");
+				}
+				status =
+				pci_read_config_byte(pci_dev_i, PCI_INTERRUPT_LINE, &pci_irq);
 
 //		If the PCI BIOS assigned it, lets try and use it.  If we
 //		can't acquire it or it screws up, deal with it then.
 
-//					if (!is_valid_irq(pci_irq)) {
-//						printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
-//						pci_irq = 0;
-//					}
-					ip2config.irq[i] = pci_irq;
-				} else {	// ann error
-					ip2config.addr[i] = 0;
-					if (status == PCIBIOS_DEVICE_NOT_FOUND) {
-						printk( KERN_ERR "IP2: PCI board %d not found\n", i );
-					} else {
-						pcibios_strerror(status);
-					}
-				} 
+//				if (!is_valid_irq(pci_irq)) {
+//					printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
+//					pci_irq = 0;
+//				}
+				ip2config.irq[i] = pci_irq;
+			} else {	// ann error
+				ip2config.addr[i] = 0;
+				if (status == PCIBIOS_DEVICE_NOT_FOUND) {
+					printk( KERN_ERR "IP2: PCI board %d not found\n", i );
+				} else {
+					pcibios_strerror(status);
+				}
 			} 
 #endif	/* ! 2_0_X */
 #else
diff -urN linux-2.5.70-bk15/drivers/char/isicom.c linux-2.5.70-bk16/drivers/char/isicom.c
--- linux-2.5.70-bk15/drivers/char/isicom.c	2003-06-11 04:47:49.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/isicom.c	2003-06-11 04:48:04.000000000 -0700
@@ -1905,7 +1905,7 @@
 		}
 	}	
 	
-	if (pci_present() && (card < BOARD_COUNT)) {
+	if (card < BOARD_COUNT) {
 		for (idx=0; idx < DEVID_COUNT; idx++) {
 			dev = NULL;
 			for (;;){
diff -urN linux-2.5.70-bk15/drivers/char/istallion.c linux-2.5.70-bk16/drivers/char/istallion.c
--- linux-2.5.70-bk15/drivers/char/istallion.c	2003-06-11 04:47:49.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/istallion.c	2003-06-11 04:48:04.000000000 -0700
@@ -4670,9 +4670,6 @@
 	printk("stli_findpcibrds()\n");
 #endif
 
-	if (! pci_present())
-		return(0);
-
 	while ((dev = pci_find_device(PCI_VENDOR_ID_STALLION,
 	    PCI_DEVICE_ID_ECRA, dev))) {
 		if ((rc = stli_initpcibrd(BRD_ECPPCI, dev)))
diff -urN linux-2.5.70-bk15/drivers/char/mem.c linux-2.5.70-bk16/drivers/char/mem.c
--- linux-2.5.70-bk15/drivers/char/mem.c	2003-06-11 04:47:49.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/mem.c	2003-06-11 04:48:04.000000000 -0700
@@ -29,13 +29,56 @@
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
+#ifdef CONFIG_IA64
+# include <linux/efi.h>
+#endif
+
 #ifdef CONFIG_FB
 extern void fbmem_init(void);
 #endif
 #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
 extern void tapechar_init(void);
 #endif
-     
+
+/*
+ * Architectures vary in how they handle caching for addresses
+ * outside of main memory.
+ *
+ */
+static inline int uncached_access(struct file *file, unsigned long addr)
+{
+#if defined(__i386__)
+	/*
+	 * On the PPro and successors, the MTRRs are used to set
+	 * memory types for physical addresses outside main memory,
+	 * so blindly setting PCD or PWT on those pages is wrong.
+	 * For Pentiums and earlier, the surround logic should disable
+	 * caching for the high addresses through the KEN pin, but
+	 * we maintain the tradition of paranoia in this code.
+	 */
+	if (file->f_flags & O_SYNC)
+		return 1;
+ 	return !( test_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability) ||
+		  test_bit(X86_FEATURE_K6_MTRR, boot_cpu_data.x86_capability) ||
+		  test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) ||
+		  test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability) )
+	  && addr >= __pa(high_memory);
+#elif defined(CONFIG_IA64)
+	/*
+	 * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
+	 */
+	return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
+#else
+	/*
+	 * Accessing memory above the top the kernel knows about or through a file pointer
+	 * that was marked O_SYNC will be done non-cached.
+	 */
+	if (file->f_flags & O_SYNC)
+		return 1;
+	return addr >= __pa(high_memory);
+#endif
+}
+
 static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
 			    const char * buf, size_t count, loff_t *ppos)
 {
@@ -72,7 +115,7 @@
 	unsigned long p = *ppos;
 	unsigned long end_mem;
 	ssize_t read;
-	
+
 	end_mem = __pa(high_memory);
 	if (p >= end_mem)
 		return 0;
@@ -116,77 +159,16 @@
 	return do_write_mem(file, __va(p), p, buf, count, ppos);
 }
 
-#ifndef pgprot_noncached
-
-/*
- * This should probably be per-architecture in <asm/pgtable.h>
- */
-static inline pgprot_t pgprot_noncached(pgprot_t _prot)
-{
-	unsigned long prot = pgprot_val(_prot);
-
-#if defined(__i386__) || defined(__x86_64__)
-	/* On PPro and successors, PCD alone doesn't always mean 
-	    uncached because of interactions with the MTRRs. PCD | PWT
-	    means definitely uncached. */ 
-	if (boot_cpu_data.x86 > 3)
-		prot |= _PAGE_PCD | _PAGE_PWT;
-#elif defined(__powerpc__)
-	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-#elif defined(__mc68000__) && defined(CONFIG_MMU)
-#ifdef SUN3_PAGE_NOCACHE
-	if (MMU_IS_SUN3)
-		prot |= SUN3_PAGE_NOCACHE;
-	else
-#endif
-	if (MMU_IS_851 || MMU_IS_030)
-		prot |= _PAGE_NOCACHE030;
-	/* Use no-cache mode, serialized */
-	else if (MMU_IS_040 || MMU_IS_060)
-		prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
-#endif
-
-	return __pgprot(prot);
-}
-
-#endif /* !pgprot_noncached */
-
-/*
- * Architectures vary in how they handle caching for addresses 
- * outside of main memory.
- */
-static inline int noncached_address(unsigned long addr)
-{
-#if defined(__i386__)
-	/* 
-	 * On the PPro and successors, the MTRRs are used to set
-	 * memory types for physical addresses outside main memory, 
-	 * so blindly setting PCD or PWT on those pages is wrong.
-	 * For Pentiums and earlier, the surround logic should disable 
-	 * caching for the high addresses through the KEN pin, but
-	 * we maintain the tradition of paranoia in this code.
-	 */
- 	return !( test_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability) ||
-		  test_bit(X86_FEATURE_K6_MTRR, boot_cpu_data.x86_capability) ||
-		  test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) ||
-		  test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability) )
-	  && addr >= __pa(high_memory);
-#else
-	return addr >= __pa(high_memory);
-#endif
-}
-
 static int mmap_mem(struct file * file, struct vm_area_struct * vma)
 {
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	int uncached;
 
-	/*
-	 * Accessing memory above the top the kernel knows about or
-	 * through a file pointer that was marked O_SYNC will be
-	 * done non-cached.
-	 */
-	if (noncached_address(offset) || (file->f_flags & O_SYNC))
+	uncached = uncached_access(file, offset);
+#ifdef pgprot_noncached
+	if (uncached)
 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#endif
 
 	/* Don't try to swap out physical pages.. */
 	vma->vm_flags |= VM_RESERVED;
@@ -194,7 +176,7 @@
 	/*
 	 * Don't dump addresses that are not real memory to a core file.
 	 */
-	if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
+	if (uncached)
 		vma->vm_flags |= VM_IO;
 
 	if (remap_page_range(vma, vma->vm_start, offset, vma->vm_end-vma->vm_start,
@@ -713,4 +695,4 @@
 	return 0;
 }
 
-subsys_initcall(chr_dev_init);
+fs_initcall(chr_dev_init);
diff -urN linux-2.5.70-bk15/drivers/char/rio/rio_linux.c linux-2.5.70-bk16/drivers/char/rio/rio_linux.c
--- linux-2.5.70-bk15/drivers/char/rio/rio_linux.c	2003-06-11 04:47:50.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/rio/rio_linux.c	2003-06-11 04:48:05.000000000 -0700
@@ -1126,7 +1126,6 @@
   }
 
 #ifdef CONFIG_PCI
-  if (pci_present ()) {
     /* First look for the JET devices: */
 #ifndef TWO_ZERO
     while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
@@ -1277,7 +1276,6 @@
 #else
     }  /* Emacs from getting confused we have two closing braces too. */
 #endif
-  }
 #endif /* PCI */
 
   /* Now probe for ISA cards... */
@@ -1431,3 +1429,4 @@
  * tab-width: 8
  * End:
  */
+
diff -urN linux-2.5.70-bk15/drivers/char/rocket.c linux-2.5.70-bk16/drivers/char/rocket.c
--- linux-2.5.70-bk15/drivers/char/rocket.c	2003-06-11 04:47:50.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/rocket.c	2003-06-11 04:48:05.000000000 -0700
@@ -2713,12 +2713,8 @@
 	}
 
 #ifdef CONFIG_PCI
-	if (pci_present()) {
-		if (isa_boards_found < NUM_BOARDS)
-			pci_boards_found = init_PCI(isa_boards_found);
-	} else {
-		printk(KERN_INFO "No PCI BIOS found\n");
-	}
+	if (isa_boards_found < NUM_BOARDS)
+		pci_boards_found = init_PCI(isa_boards_found);
 #endif
 
 	max_board = pci_boards_found + isa_boards_found;
diff -urN linux-2.5.70-bk15/drivers/char/rtc.c linux-2.5.70-bk16/drivers/char/rtc.c
--- linux-2.5.70-bk15/drivers/char/rtc.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/rtc.c	2003-06-11 04:48:05.000000000 -0700
@@ -284,12 +284,13 @@
 
 	add_wait_queue(&rtc_wait, &wait);
 
-	current->state = TASK_INTERRUPTIBLE;
-		
 	do {
 		/* First make it right. Then make it fast. Putting this whole
 		 * block within the parentheses of a while would be too
 		 * confusing. And no, xchg() is not the answer. */
+
+		__set_current_state(TASK_INTERRUPTIBLE);
+		
 		spin_lock_irq (&rtc_lock);
 		data = rtc_irq_data;
 		rtc_irq_data = 0;
diff -urN linux-2.5.70-bk15/drivers/char/specialix.c linux-2.5.70-bk16/drivers/char/specialix.c
--- linux-2.5.70-bk15/drivers/char/specialix.c	2003-06-11 04:47:50.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/specialix.c	2003-06-11 04:48:05.000000000 -0700
@@ -2294,7 +2294,7 @@
 			found++;
 
 #ifdef CONFIG_PCI
-	if (pci_present()) {
+	{
 		struct pci_dev *pdev = NULL;
 
 		i=0;
diff -urN linux-2.5.70-bk15/drivers/char/stallion.c linux-2.5.70-bk16/drivers/char/stallion.c
--- linux-2.5.70-bk15/drivers/char/stallion.c	2003-06-11 04:47:50.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/stallion.c	2003-06-11 04:48:05.000000000 -0700
@@ -2804,9 +2804,6 @@
 	printk("stl_findpcibrds()\n");
 #endif
 
-	if (! pci_present())
-		return(0);
-
 	for (i = 0; (i < stl_nrpcibrds); i++)
 		while ((dev = pci_find_device(stl_pcibrds[i].vendid,
 		    stl_pcibrds[i].devid, dev))) {
diff -urN linux-2.5.70-bk15/drivers/char/sx.c linux-2.5.70-bk16/drivers/char/sx.c
--- linux-2.5.70-bk15/drivers/char/sx.c	2003-06-11 04:47:50.000000000 -0700
+++ linux-2.5.70-bk16/drivers/char/sx.c	2003-06-11 04:48:05.000000000 -0700
@@ -2460,69 +2460,68 @@
 	}
 
 #ifdef CONFIG_PCI
-	if (pci_present ()) {
 #ifndef TWO_ZERO
-		while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
-		                                PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
-			                              pdev))) {
-			if (pci_enable_device(pdev))
-				continue;
+	while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+					PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
+					      pdev))) {
+		if (pci_enable_device(pdev))
+			continue;
 #else
-			for (i=0;i< SX_NBOARDS;i++) {
-				if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, 
-				                         PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, i,
-					                       &pci_bus, &pci_fun)) break;
+	for (i=0;i< SX_NBOARDS;i++) {
+		if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, 
+					 PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, i,
+					       &pci_bus, &pci_fun))
+			break;
 #endif
-			/* Specialix has a whole bunch of cards with
-			   0x2000 as the device ID. They say its because
-			   the standard requires it. Stupid standard. */
-			/* It seems that reading a word doesn't work reliably on 2.0.
-			   Also, reading a non-aligned dword doesn't work. So we read the
-			   whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID)
-			   ourselves */
-			/* I don't know why the define doesn't work, constant 0x2c does --REW */ 
-			pci_read_config_dword (pdev, 0x2c, &tint);
-			tshort = (tint >> 16) & 0xffff;
-			sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
-			/* sx_dprintk (SX_DEBUG_PROBE, "pdev = %d/%d	(%x)\n", pdev, tint); */ 
-			if ((tshort != 0x0200) && (tshort != 0x0300)) {
-				sx_dprintk (SX_DEBUG_PROBE, "But it's not an SX card (%d)...\n", 
-				            tshort);
-				continue;
-			}
-			board = &boards[found];
+		/* Specialix has a whole bunch of cards with
+		   0x2000 as the device ID. They say its because
+		   the standard requires it. Stupid standard. */
+		/* It seems that reading a word doesn't work reliably on 2.0.
+		   Also, reading a non-aligned dword doesn't work. So we read the
+		   whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID)
+		   ourselves */
+		/* I don't know why the define doesn't work, constant 0x2c does --REW */ 
+		pci_read_config_dword (pdev, 0x2c, &tint);
+		tshort = (tint >> 16) & 0xffff;
+		sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
+		/* sx_dprintk (SX_DEBUG_PROBE, "pdev = %d/%d	(%x)\n", pdev, tint); */ 
+		if ((tshort != 0x0200) && (tshort != 0x0300)) {
+			sx_dprintk (SX_DEBUG_PROBE, "But it's not an SX card (%d)...\n", 
+				    tshort);
+			continue;
+		}
+		board = &boards[found];
 
-			board->flags &= ~SX_BOARD_TYPE;
-			board->flags |= (tshort == 0x200)?SX_PCI_BOARD:
-			                                  SX_CFPCI_BOARD;
+		board->flags &= ~SX_BOARD_TYPE;
+		board->flags |= (tshort == 0x200)?SX_PCI_BOARD:
+						  SX_CFPCI_BOARD;
 
-			/* CF boards use base address 3.... */
-			if (IS_CF_BOARD (board))
-				board->hw_base = pci_resource_start (pdev, 3);
-			else
-				board->hw_base = pci_resource_start (pdev, 2);
-			board->base2 = 
-			board->base = (ulong) ioremap(board->hw_base, WINDOW_LEN (board));
-			if (!board->base) {
-				printk(KERN_ERR "ioremap failed\n");
-				/* XXX handle error */
-			}
-
-			/* Most of the stuff on the CF board is offset by
-			   0x18000 ....  */
-			if (IS_CF_BOARD (board)) board->base += 0x18000;
-
-			board->irq = pdev->irq;
-
-			sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%lx(%d) %x.\n", 
-			            tint, boards[found].base, board->irq, board->flags);
-
-			if (probe_sx (board)) {
-				found++;
-				fix_sx_pci (pdev, board);
-			} else 
-				iounmap ((char *) (board->base));
-		}
+		/* CF boards use base address 3.... */
+		if (IS_CF_BOARD (board))
+			board->hw_base = pci_resource_start (pdev, 3);
+		else
+			board->hw_base = pci_resource_start (pdev, 2);
+		board->base2 = 
+		board->base = (ulong) ioremap(board->hw_base, WINDOW_LEN (board));
+		if (!board->base) {
+			printk(KERN_ERR "ioremap failed\n");
+			/* XXX handle error */
+		}
+
+		/* Most of the stuff on the CF board is offset by
+		   0x18000 ....  */
+		if (IS_CF_BOARD (board)) board->base += 0x18000;
+
+		board->irq = pdev->irq;
+
+		sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%lx(%d) %x.\n", 
+			    tint, boards[found].base, board->irq, board->flags);
+
+		if (probe_sx (board)) {
+			found++;
+			fix_sx_pci (pdev, board);
+		} else 
+			iounmap ((char *) (board->base));
 	}
 #endif
 
@@ -2649,3 +2648,4 @@
 module_init(sx_init);
 module_exit(sx_exit);
 
+
diff -urN linux-2.5.70-bk15/drivers/i2c/i2c-elektor.c linux-2.5.70-bk16/drivers/i2c/i2c-elektor.c
--- linux-2.5.70-bk15/drivers/i2c/i2c-elektor.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk16/drivers/i2c/i2c-elektor.c	2003-06-11 04:48:05.000000000 -0700
@@ -188,7 +188,7 @@
 #ifdef __alpha__
 	/* check to see we have memory mapped PCF8584 connected to the 
 	Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
-	if ((base == 0) && pci_present()) {
+	if (base == 0) {
 		
 		struct pci_dev *cy693_dev =
                     pci_find_device(PCI_VENDOR_ID_CONTAQ, 
diff -urN linux-2.5.70-bk15/drivers/ide/ide.c linux-2.5.70-bk16/drivers/ide/ide.c
--- linux-2.5.70-bk15/drivers/ide/ide.c	2003-06-11 04:47:51.000000000 -0700
+++ linux-2.5.70-bk16/drivers/ide/ide.c	2003-06-11 04:48:05.000000000 -0700
@@ -332,7 +332,7 @@
 		if (idebus_parameter) {
 			/* user supplied value */
 			system_bus_speed = idebus_parameter;
-		} else if (pci_present()) {
+		} else if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) != NULL) {
 			/* safe default value for PCI */
 			system_bus_speed = 33;
 		} else {
@@ -2115,10 +2115,7 @@
 static void __init probe_for_hwifs (void)
 {
 #ifdef CONFIG_BLK_DEV_IDEPCI
-	if (pci_present())
-	{
-		ide_scan_pcibus(ide_scan_direction);
-	}
+	ide_scan_pcibus(ide_scan_direction);
 #endif /* CONFIG_BLK_DEV_IDEPCI */
 
 #ifdef CONFIG_ETRAX_IDE
diff -urN linux-2.5.70-bk15/drivers/isdn/eicon/Divas_mod.c linux-2.5.70-bk16/drivers/isdn/eicon/Divas_mod.c
--- linux-2.5.70-bk15/drivers/isdn/eicon/Divas_mod.c	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk16/drivers/isdn/eicon/Divas_mod.c	2003-06-11 04:48:05.000000000 -0700
@@ -50,17 +50,9 @@
 
 	DivasInitDpc();
 
-	if (pci_present())
+	if (DivasCardsDiscover() < 0)
 	{
-		if (DivasCardsDiscover() < 0)
-		{
-			printk(KERN_WARNING "Divas: Not loaded\n");
-			return -ENODEV;
-		}
-	}
-	else
-	{
-		printk(KERN_WARNING "Divas: No PCI bus present\n");
+		printk(KERN_WARNING "Divas: Not loaded\n");
 		return -ENODEV;
 	}
 
diff -urN linux-2.5.70-bk15/drivers/isdn/hysdn/hysdn_init.c linux-2.5.70-bk16/drivers/isdn/hysdn/hysdn_init.c
--- linux-2.5.70-bk15/drivers/isdn/hysdn/hysdn_init.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/drivers/isdn/hysdn/hysdn_init.c	2003-06-11 04:48:05.000000000 -0700
@@ -203,10 +203,6 @@
 	printk(KERN_NOTICE "HYSDN: module Rev: %s loaded\n", hysdn_getrev(tmp));
 	strcpy(tmp, hysdn_net_revision);
 	printk(KERN_NOTICE "HYSDN: network interface Rev: %s \n", hysdn_getrev(tmp));
-	if (!pci_present()) {
-		printk(KERN_ERR "HYSDN: no PCI bus present, module not loaded\n");
-		return (-1);
-	}
 	search_cards();
 	printk(KERN_INFO "HYSDN: %d card(s) found.\n", cardmax);
 
diff -urN linux-2.5.70-bk15/drivers/md/linear.c linux-2.5.70-bk16/drivers/md/linear.c
--- linux-2.5.70-bk15/drivers/md/linear.c	2003-06-11 04:47:51.000000000 -0700
+++ linux-2.5.70-bk16/drivers/md/linear.c	2003-06-11 04:48:05.000000000 -0700
@@ -93,7 +93,7 @@
 			GFP_KERNEL);
 	if (!conf)
 		goto out;
-	memset(conf, 0, sizeof(*conf));
+	memset(conf, 0, sizeof(*conf) + mddev->raid_disks*sizeof(dev_info_t));
 	mddev->private = conf;
 
 	/*
diff -urN linux-2.5.70-bk15/drivers/md/multipath.c linux-2.5.70-bk16/drivers/md/multipath.c
--- linux-2.5.70-bk15/drivers/md/multipath.c	2003-06-11 04:47:51.000000000 -0700
+++ linux-2.5.70-bk16/drivers/md/multipath.c	2003-06-11 04:48:05.000000000 -0700
@@ -397,6 +397,7 @@
 			mdidx(mddev));
 		goto out_free_conf;
 	}
+	memset(conf->multipaths, 0, sizeof(struct multipath_info)*mddev->raid_disks);
 
 	conf->working_disks = 0;
 	ITERATE_RDEV(mddev,rdev,tmp) {
diff -urN linux-2.5.70-bk15/drivers/md/raid0.c linux-2.5.70-bk16/drivers/md/raid0.c
--- linux-2.5.70-bk15/drivers/md/raid0.c	2003-06-11 04:47:51.000000000 -0700
+++ linux-2.5.70-bk16/drivers/md/raid0.c	2003-06-11 04:48:05.000000000 -0700
@@ -90,6 +90,9 @@
 
 	memset(conf->strip_zone, 0,sizeof(struct strip_zone)*
 				   conf->nr_strip_zones);
+	memset(conf->devlist, 0,
+	       sizeof(mdk_rdev_t*) * conf->nr_strip_zones * mddev->raid_disks);
+
 	/* The first zone must contain all devices, so here we check that
 	 * there is a proper alignment of slots to devices and find them all
 	 */
diff -urN linux-2.5.70-bk15/drivers/md/raid1.c linux-2.5.70-bk16/drivers/md/raid1.c
--- linux-2.5.70-bk15/drivers/md/raid1.c	2003-06-11 04:47:51.000000000 -0700
+++ linux-2.5.70-bk16/drivers/md/raid1.c	2003-06-11 04:48:05.000000000 -0700
@@ -47,7 +47,7 @@
 	r1_bio = kmalloc(sizeof(r1bio_t) + sizeof(struct bio*)*mddev->raid_disks,
 			 gfp_flags);
 	if (r1_bio)
-		memset(r1_bio, 0, sizeof(*r1_bio));
+		memset(r1_bio, 0, sizeof(*r1_bio) + sizeof(struct bio*)*mddev->raid_disks);
 
 	return r1_bio;
 }
@@ -1057,6 +1057,7 @@
 		       mdidx(mddev));
 		goto out_free_conf;
 	}
+	memset(conf->mirrors, 0, sizeof(struct mirror_info)*mddev->raid_disks);
 
 	conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
 						r1bio_pool_free, mddev);
diff -urN linux-2.5.70-bk15/drivers/md/raid5.c linux-2.5.70-bk16/drivers/md/raid5.c
--- linux-2.5.70-bk15/drivers/md/raid5.c	2003-06-11 04:47:51.000000000 -0700
+++ linux-2.5.70-bk16/drivers/md/raid5.c	2003-06-11 04:48:05.000000000 -0700
@@ -1458,7 +1458,7 @@
 				  GFP_KERNEL);
 	if ((conf = mddev->private) == NULL)
 		goto abort;
-	memset (conf, 0, sizeof (*conf));
+	memset (conf, 0, sizeof (*conf) + mddev->raid_disks * sizeof(struct disk_info) );
 	conf->mddev = mddev;
 
 	if ((conf->stripe_hashtbl = (struct stripe_head **) __get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER)) == NULL)
diff -urN linux-2.5.70-bk15/drivers/media/radio/radio-maestro.c linux-2.5.70-bk16/drivers/media/radio/radio-maestro.c
--- linux-2.5.70-bk15/drivers/media/radio/radio-maestro.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk16/drivers/media/radio/radio-maestro.c	2003-06-11 04:48:05.000000000 -0700
@@ -285,8 +285,6 @@
 {
 	register __u16 found=0;
 	struct pci_dev *pcidev = NULL;
-	if(!pci_present())
-		return -ENODEV;
 	while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS, 
 						  PCI_DEVICE_ID_ESS_ESS1968,
 						  pcidev)))
diff -urN linux-2.5.70-bk15/drivers/mtd/devices/pmc551.c linux-2.5.70-bk16/drivers/mtd/devices/pmc551.c
--- linux-2.5.70-bk15/drivers/mtd/devices/pmc551.c	2003-06-11 04:47:51.000000000 -0700
+++ linux-2.5.70-bk16/drivers/mtd/devices/pmc551.c	2003-06-11 04:48:05.000000000 -0700
@@ -681,11 +681,6 @@
 
         printk(KERN_INFO PMC551_VERSION);
 
-        if(!pci_present()) {
-                printk(KERN_NOTICE "pmc551: PCI not enabled.\n");
-                return -ENODEV;
-        }
-
         /*
          * PCU-bus chipset probe.
          */
diff -urN linux-2.5.70-bk15/drivers/net/acenic.c linux-2.5.70-bk16/drivers/net/acenic.c
--- linux-2.5.70-bk15/drivers/net/acenic.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/acenic.c	2003-06-11 04:48:06.000000000 -0700
@@ -618,9 +618,6 @@
 		return -ENODEV;
 	probed++;
 
-	if (!pci_present())		/* is PCI support present? */
-		return -ENODEV;
-
 	version_disp = 0;
 
 	while ((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET<<8, pdev))) {
diff -urN linux-2.5.70-bk15/drivers/net/dgrs.c linux-2.5.70-bk16/drivers/net/dgrs.c
--- linux-2.5.70-bk15/drivers/net/dgrs.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/dgrs.c	2003-06-11 04:48:06.000000000 -0700
@@ -1356,55 +1356,51 @@
 	uint	irq;
 	uint	plxreg;
 	uint	plxdma;
+	struct pci_dev *pdev = NULL;
 
 	/*
 	 *	First, check for PCI boards
 	 */
-	if (pci_present())
+	while ((pdev = pci_find_device(SE6_PCI_VENDOR_ID, SE6_PCI_DEVICE_ID, pdev)) != NULL)
 	{
-		struct pci_dev *pdev = NULL;
+		/*
+		 * Get and check the bus-master and latency values.
+		 * Some PCI BIOSes fail to set the master-enable bit,
+		 * and the latency timer must be set to the maximum
+		 * value to avoid data corruption that occurs when the
+		 * timer expires during a transfer.  Yes, it's a bug.
+		 */
+		if (pci_enable_device(pdev))
+			continue;
+		pci_set_master(pdev);
+
+		plxreg = pci_resource_start (pdev, 0);
+		io = pci_resource_start (pdev, 1);
+		mem = pci_resource_start (pdev, 2);
+		pci_read_config_dword(pdev, 0x30, &plxdma);
+		irq = pdev->irq;
+		plxdma &= ~15;
+
+		/*
+		 * On some BIOSES, the PLX "expansion rom" (used for DMA)
+		 * address comes up as "0".  This is probably because
+		 * the BIOS doesn't see a valid 55 AA ROM signature at
+		 * the "ROM" start and zeroes the address.  To get
+		 * around this problem the SE-6 is configured to ask
+		 * for 4 MB of space for the dual port memory.  We then
+		 * must set its range back to 2 MB, and use the upper
+		 * half for DMA register access
+		 */
+		OUTL(io + PLX_SPACE0_RANGE, 0xFFE00000L);
+		if (plxdma == 0)
+			plxdma = mem + (2048L * 1024L);
+		pci_write_config_dword(pdev, 0x30, plxdma + 1);
+		pci_read_config_dword(pdev, 0x30, &plxdma);
+		plxdma &= ~15;
 
-		while ((pdev = pci_find_device(SE6_PCI_VENDOR_ID, SE6_PCI_DEVICE_ID, pdev)) != NULL)
-		{
-			/*
-			 * Get and check the bus-master and latency values.
-			 * Some PCI BIOSes fail to set the master-enable bit,
-			 * and the latency timer must be set to the maximum
-			 * value to avoid data corruption that occurs when the
-			 * timer expires during a transfer.  Yes, it's a bug.
-			 */
-			if (pci_enable_device(pdev))
-				continue;
-			pci_set_master(pdev);
-
-			plxreg = pci_resource_start (pdev, 0);
-			io = pci_resource_start (pdev, 1);
-			mem = pci_resource_start (pdev, 2);
-			pci_read_config_dword(pdev, 0x30, &plxdma);
-			irq = pdev->irq;
-			plxdma &= ~15;
-
-			/*
-			 * On some BIOSES, the PLX "expansion rom" (used for DMA)
-			 * address comes up as "0".  This is probably because
-			 * the BIOS doesn't see a valid 55 AA ROM signature at
-			 * the "ROM" start and zeroes the address.  To get
-			 * around this problem the SE-6 is configured to ask
-			 * for 4 MB of space for the dual port memory.  We then
-			 * must set its range back to 2 MB, and use the upper
-			 * half for DMA register access
-			 */
-			OUTL(io + PLX_SPACE0_RANGE, 0xFFE00000L);
-			if (plxdma == 0)
-				plxdma = mem + (2048L * 1024L);
-			pci_write_config_dword(pdev, 0x30, plxdma + 1);
-			pci_read_config_dword(pdev, 0x30, &plxdma);
-			plxdma &= ~15;
+		dgrs_found_device(io, mem, irq, plxreg, plxdma);
 
-			dgrs_found_device(io, mem, irq, plxreg, plxdma);
-
-			cards_found++;
-		}
+		cards_found++;
 	}
 
 	/*
diff -urN linux-2.5.70-bk15/drivers/net/fc/iph5526.c linux-2.5.70-bk16/drivers/net/fc/iph5526.c
--- linux-2.5.70-bk15/drivers/net/fc/iph5526.c	2003-06-11 04:47:52.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/fc/iph5526.c	2003-06-11 04:48:06.000000000 -0700
@@ -232,7 +232,7 @@
 
 int __init iph5526_probe(struct net_device *dev)
 {
-	if (pci_present() && (iph5526_probe_pci(dev) == 0))
+	if (iph5526_probe_pci(dev) == 0)
 		return 0;
 	return -ENODEV;
 }
@@ -3720,10 +3720,6 @@
 	unsigned long timeout;
 
 	tmpt->proc_name = "iph5526";
-	if (pci_present() == 0) {
-		printk("iph5526: PCI not present\n");
-		return 0;
-	}
 
 	for (i = 0; i <= MAX_FC_CARDS; i++) 
 		fc[i] = NULL;
diff -urN linux-2.5.70-bk15/drivers/net/hp100.c linux-2.5.70-bk16/drivers/net/hp100.c
--- linux-2.5.70-bk15/drivers/net/hp100.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/hp100.c	2003-06-11 04:48:06.000000000 -0700
@@ -405,7 +405,7 @@
 	/* First: scan PCI bus(es) */
 
 #ifdef CONFIG_PCI
-	if (pci_present()) {
+	{
 		int pci_index;
 		struct pci_dev *pci_dev = NULL;
 		int pci_id_index;
@@ -2973,8 +2973,10 @@
 {
 	int i, cards;
 
-	if (hp100_port == 0 && !EISA_bus && !pci_present())
+#ifndef CONFIG_PCI
+	if (hp100_port == 0 && !EISA_bus)
 		printk("hp100: You should not use auto-probing with insmod!\n");
+#endif
 
 	/* Loop on all possible base addresses */
 	i = -1;
diff -urN linux-2.5.70-bk15/drivers/net/saa9730.c linux-2.5.70-bk16/drivers/net/saa9730.c
--- linux-2.5.70-bk15/drivers/net/saa9730.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/saa9730.c	2003-06-11 04:48:06.000000000 -0700
@@ -1050,31 +1050,30 @@
 static int __init saa9730_probe(void)
 {
 	struct net_device *dev = NULL;
+	struct pci_dev *pdev = NULL;
 
-	if (pci_present()) {
-		struct pci_dev *pdev = NULL;
-		if (lan_saa9730_debug > 1)
-			printk
-			    ("saa9730.c: PCI bios is present, checking for devices...\n");
-
-		while ((pdev = pci_find_device(PCI_VENDOR_ID_PHILIPS,
-					       PCI_DEVICE_ID_PHILIPS_SAA9730,
-					       pdev))) {
-			unsigned int pci_ioaddr;
-
-			pci_irq_line = pdev->irq;
-			/* LAN base address in located at BAR 1. */
-
-			pci_ioaddr = pci_resource_start(pdev, 1);
-			pci_set_master(pdev);
-
-			printk("Found SAA9730 (PCI) at %#x, irq %d.\n",
-			       pci_ioaddr, pci_irq_line);
-			if (!lan_saa9730_init
-			    (dev, pci_ioaddr, pci_irq_line)) return 0;
-			else
-				printk("Lan init failed.\n");
-		}
+	if (lan_saa9730_debug > 1)
+		printk
+		    ("saa9730.c: PCI bios is present, checking for devices...\n");
+
+	while ((pdev = pci_find_device(PCI_VENDOR_ID_PHILIPS,
+				       PCI_DEVICE_ID_PHILIPS_SAA9730,
+				       pdev))) {
+		unsigned int pci_ioaddr;
+
+		pci_irq_line = pdev->irq;
+		/* LAN base address in located at BAR 1. */
+
+		pci_ioaddr = pci_resource_start(pdev, 1);
+		pci_set_master(pdev);
+
+		printk("Found SAA9730 (PCI) at %#x, irq %d.\n",
+		       pci_ioaddr, pci_irq_line);
+		if (!lan_saa9730_init
+		    (dev, pci_ioaddr, pci_irq_line))
+			return 0;
+		else
+			printk("Lan init failed.\n");
 	}
 
 	return -ENODEV;
diff -urN linux-2.5.70-bk15/drivers/net/sk98lin/skge.c linux-2.5.70-bk16/drivers/net/sk98lin/skge.c
--- linux-2.5.70-bk15/drivers/net/sk98lin/skge.c	2003-06-11 04:47:52.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/sk98lin/skge.c	2003-06-11 04:48:06.000000000 -0700
@@ -409,9 +409,6 @@
 		printk("%s\n", BootString);
 	}
 
-	if (!pci_present())		/* is PCI support present? */
-		return -ENODEV;
-
 	while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
 				      PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
 
diff -urN linux-2.5.70-bk15/drivers/net/skfp/skfddi.c linux-2.5.70-bk16/drivers/net/skfp/skfddi.c
--- linux-2.5.70-bk15/drivers/net/skfp/skfddi.c	2003-06-11 04:47:52.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/skfp/skfddi.c	2003-06-11 04:48:06.000000000 -0700
@@ -298,10 +298,6 @@
 	printk("%s\n", boot_msg);
 
 	/* Scan for Syskonnect FDDI PCI controllers */
-	if (!pci_present()) {	/* is PCI BIOS even present? */
-		printk("no PCI BIOS present\n");
-		return (-ENODEV);
-	}
 	for (i = 0; i < SKFP_MAX_NUM_BOARDS; i++) {	// scan for PCI cards
 		PRINTK(KERN_INFO "Check device %d\n", i);
 		if ((pdev=pci_find_device(PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP,
diff -urN linux-2.5.70-bk15/drivers/net/tc35815.c linux-2.5.70-bk16/drivers/net/tc35815.c
--- linux-2.5.70-bk15/drivers/net/tc35815.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/tc35815.c	2003-06-11 04:48:06.000000000 -0700
@@ -488,9 +488,6 @@
 		return -ENODEV;
 	called++;
 
-	if (!pci_present())
-		return -ENODEV;
-
 	if (pdev) {
 		unsigned int pci_memaddr;
 		unsigned int pci_irq_line;
diff -urN linux-2.5.70-bk15/drivers/net/tulip/de4x5.c linux-2.5.70-bk16/drivers/net/tulip/de4x5.c
--- linux-2.5.70-bk15/drivers/net/tulip/de4x5.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/tulip/de4x5.c	2003-06-11 04:48:06.000000000 -0700
@@ -2182,11 +2182,6 @@
 
     if (lastPCI == NO_MORE_PCI) return;
 
-    if (!pci_present()) {
-	lastPCI = NO_MORE_PCI;
-	return;          /* No PCI bus in this machine! */
-    }
-    
     lp->bus = PCI;
     lp->bus_num = 0;
 
@@ -5863,7 +5858,6 @@
 	if (EISA_signature(name, EISA_ID)) j++;
     }
 #endif
-    if (!pci_present()) return j;
 
     for (i=0; (pdev=pci_find_class(class, pdev))!= NULL; i++) {
 	vendor = pdev->vendor;
diff -urN linux-2.5.70-bk15/drivers/net/wan/lmc/lmc_main.c linux-2.5.70-bk16/drivers/net/wan/lmc/lmc_main.c
--- linux-2.5.70-bk15/drivers/net/wan/lmc/lmc_main.c	2003-06-11 04:47:52.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/wan/lmc/lmc_main.c	2003-06-11 04:48:06.000000000 -0700
@@ -1034,14 +1034,6 @@
     u8 intcf = 0;
     struct pci_dev *pdev = NULL;
 
-    /* The card is only available on PCI, so if we don't have a
-     * PCI bus, we are in trouble.
-     */
-
-    if (!pci_present()) {
-/*        printk ("%s: We really want a pci bios!\n", dev->name);*/
-        return -1;
-    }
     /* Loop basically until we don't find anymore. */
     while ((pdev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) {
 	if (pci_enable_device(pdev))
diff -urN linux-2.5.70-bk15/drivers/net/wan/lmc/lmc_ver.h linux-2.5.70-bk16/drivers/net/wan/lmc/lmc_ver.h
--- linux-2.5.70-bk15/drivers/net/wan/lmc/lmc_ver.h	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/wan/lmc/lmc_ver.h	2003-06-11 04:48:06.000000000 -0700
@@ -69,12 +69,10 @@
 #if LINUX_VERSION_CODE < 0x20155 /* basically 2.2 plus */
 
 #define LMC_DEV_KFREE_SKB(skb) dev_kfree_skb((skb), FREE_WRITE)
-#define LMC_PCI_PRESENT() pcibios_present()
 
 #else /* Mostly 2.0 kernels */
 
 #define LMC_DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
-#define LMC_PCI_PRESENT() pci_present()
 
 #endif
 
diff -urN linux-2.5.70-bk15/drivers/net/wan/sbni.c linux-2.5.70-bk16/drivers/net/wan/sbni.c
--- linux-2.5.70-bk15/drivers/net/wan/sbni.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/wan/sbni.c	2003-06-11 04:48:06.000000000 -0700
@@ -263,9 +263,6 @@
 {
 	struct pci_dev  *pdev = NULL;
 
-	if( !pci_present( ) )
-		return  -ENODEV;
-
 	while( (pdev = pci_find_class( PCI_CLASS_NETWORK_OTHER << 8, pdev ))
 	       != NULL ) {
 		int  pci_irq_line;
diff -urN linux-2.5.70-bk15/drivers/net/wan/sdladrv.c linux-2.5.70-bk16/drivers/net/wan/sdladrv.c
--- linux-2.5.70-bk15/drivers/net/wan/sdladrv.c	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk16/drivers/net/wan/sdladrv.c	2003-06-11 04:48:06.000000000 -0700
@@ -1905,13 +1905,7 @@
 	struct pci_dev *pci_dev;
 
 
-#ifdef CONFIG_PCI
-        if(!pci_present())
-        {
-                printk(KERN_INFO "%s: PCI BIOS not present!\n", modname);
-                return 0;
-        }
-#else
+#ifndef CONFIG_PCI
         printk(KERN_INFO "%s: Linux not compiled for PCI usage!\n", modname);
         return 0;
 #endif
diff -urN linux-2.5.70-bk15/drivers/pci/pci.c linux-2.5.70-bk16/drivers/pci/pci.c
--- linux-2.5.70-bk15/drivers/pci/pci.c	2003-06-11 04:47:53.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pci/pci.c	2003-06-11 04:48:06.000000000 -0700
@@ -55,11 +55,11 @@
 unsigned char __devinit
 pci_max_busnr(void)
 {
-	struct pci_bus* bus;
+	struct pci_bus *bus = NULL;
 	unsigned char max, n;
 
 	max = 0;
-	pci_for_each_bus(bus) {
+	while ((bus = pci_find_next_bus(bus)) != NULL) {
 		n = pci_bus_max_busnr(bus);
 		if(n > max)
 			max = n;
diff -urN linux-2.5.70-bk15/drivers/pci/pool.c linux-2.5.70-bk16/drivers/pci/pool.c
--- linux-2.5.70-bk15/drivers/pci/pool.c	2003-06-11 04:47:53.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pci/pool.c	2003-06-11 04:48:06.000000000 -0700
@@ -29,7 +29,8 @@
 };
 
 #define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
-#define	POOL_POISON_BYTE	0xa7
+#define	POOL_POISON_FREED	0xa7	/* !inuse */
+#define	POOL_POISON_ALLOCATED	0xa9	/* !initted */
 
 static DECLARE_MUTEX (pools_lock);
 
@@ -172,7 +173,7 @@
 	if (page->vaddr) {
 		memset (page->bitmap, 0xff, mapsize);	// bit set == free
 #ifdef	CONFIG_DEBUG_SLAB
-		memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+		memset (page->vaddr, POOL_POISON_FREED, pool->allocation);
 #endif
 		list_add (&page->page_list, &pool->page_list);
 		page->in_use = 0;
@@ -201,7 +202,7 @@
 	dma_addr_t	dma = page->dma;
 
 #ifdef	CONFIG_DEBUG_SLAB
-	memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+	memset (page->vaddr, POOL_POISON_FREED, pool->allocation);
 #endif
 	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
 	list_del (&page->page_list);
@@ -309,6 +310,9 @@
 	page->in_use++;
 	retval = offset + page->vaddr;
 	*handle = offset + page->dma;
+#ifdef	CONFIG_DEBUG_SLAB
+	memset (retval, POOL_POISON_ALLOCATED, pool->size);
+#endif
 done:
 	spin_unlock_irqrestore (&pool->lock, flags);
 	return retval;
@@ -378,7 +382,7 @@
 			pool->name, (unsigned long long)dma);
 		return;
 	}
-	memset (vaddr, POOL_POISON_BYTE, pool->size);
+	memset (vaddr, POOL_POISON_FREED, pool->size);
 #endif
 
 	spin_lock_irqsave (&pool->lock, flags);
diff -urN linux-2.5.70-bk15/drivers/pci/power.c linux-2.5.70-bk16/drivers/pci/power.c
--- linux-2.5.70-bk15/drivers/pci/power.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pci/power.c	2003-06-11 04:48:06.000000000 -0700
@@ -97,12 +97,10 @@
 
 static int pci_pm_save_state(u32 state)
 {
-	struct list_head *list;
-	struct pci_bus *bus;
+	struct pci_bus *bus = NULL;
 	int error = 0;
 
-	list_for_each(list, &pci_root_buses) {
-		bus = pci_bus_b(list);
+	while ((bus = pci_find_next_bus(bus)) != NULL) {
 		error = pci_pm_save_state_bus(bus,state);
 		if (!error)
 			error = pci_pm_save_state_device(bus->self,state);
@@ -112,11 +110,9 @@
 
 static int pci_pm_suspend(u32 state)
 {
-	struct list_head *list;
-	struct pci_bus *bus;
+	struct pci_bus *bus = NULL;
 
-	list_for_each(list, &pci_root_buses) {
-		bus = pci_bus_b(list);
+	while ((bus = pci_find_next_bus(bus)) != NULL) {
 		pci_pm_suspend_bus(bus,state);
 		pci_pm_suspend_device(bus->self,state);
 	}
@@ -125,11 +121,9 @@
 
 static int pci_pm_resume(void)
 {
-	struct list_head *list;
-	struct pci_bus *bus;
+	struct pci_bus *bus = NULL;
 
-	list_for_each(list, &pci_root_buses) {
-		bus = pci_bus_b(list);
+	while ((bus = pci_find_next_bus(bus)) != NULL) {
 		pci_pm_resume_device(bus->self);
 		pci_pm_resume_bus(bus);
 	}
diff -urN linux-2.5.70-bk15/drivers/pci/probe.c linux-2.5.70-bk16/drivers/pci/probe.c
--- linux-2.5.70-bk15/drivers/pci/probe.c	2003-06-11 04:47:53.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pci/probe.c	2003-06-11 04:48:06.000000000 -0700
@@ -529,7 +529,8 @@
 	pci_name_device(dev);
 
 	/* now put in global tree */
-	strcpy(dev->dev.bus_id,dev->slot_name);
+	sprintf(dev->dev.bus_id, "%04x:%s", pci_domain_nr(bus),
+			dev->slot_name);
 	dev->dev.dma_mask = &dev->dma_mask;
 
 	return dev;
diff -urN linux-2.5.70-bk15/drivers/pci/proc.c linux-2.5.70-bk16/drivers/pci/proc.c
--- linux-2.5.70-bk15/drivers/pci/proc.c	2003-06-11 04:47:53.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pci/proc.c	2003-06-11 04:48:06.000000000 -0700
@@ -44,7 +44,7 @@
 }
 
 static ssize_t
-proc_bus_pci_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
 	const struct inode *ino = file->f_dentry->d_inode;
 	const struct proc_dir_entry *dp = PDE(ino);
@@ -126,7 +126,7 @@
 }
 
 static ssize_t
-proc_bus_pci_write(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos)
 {
 	const struct inode *ino = file->f_dentry->d_inode;
 	const struct proc_dir_entry *dp = PDE(ino);
@@ -210,7 +210,7 @@
 
 	switch (cmd) {
 	case PCIIOC_CONTROLLER:
-		ret = pci_controller_num(dev);
+		ret = pci_domain_nr(dev->bus);
 		break;
 
 #ifdef HAVE_PCI_MMAP
@@ -323,7 +323,7 @@
 {
 	struct list_head *p = v;
 	(*pos)++;
-	return p->next != &pci_devices ? p->next : NULL;
+	return p->next != &pci_devices ? (void *)p->next : NULL;
 }
 static void pci_seq_stop(struct seq_file *m, void *v)
 {
@@ -579,19 +579,17 @@
 
 static int __init pci_proc_init(void)
 {
-	if (pci_present()) {
-		struct proc_dir_entry *entry;
-		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;
-		while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-			pci_proc_attach_device(dev);
-		}
-		legacy_proc_init();
+	struct proc_dir_entry *entry;
+	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;
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+		pci_proc_attach_device(dev);
 	}
+	legacy_proc_init();
 	return 0;
 }
 
diff -urN linux-2.5.70-bk15/drivers/pci/search.c linux-2.5.70-bk16/drivers/pci/search.c
--- linux-2.5.70-bk15/drivers/pci/search.c	2003-06-11 04:47:53.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pci/search.c	2003-06-11 04:48:06.000000000 -0700
@@ -29,10 +29,10 @@
 struct pci_bus *
 pci_find_bus(unsigned char busnr)
 {
-	struct pci_bus* bus;
+	struct pci_bus* bus = NULL;
 	struct pci_bus* tmp_bus;
 
-	pci_for_each_bus(bus) {
+	while ((bus = pci_find_next_bus(bus)) != NULL)  {
 		tmp_bus = pci_do_find_bus(bus, busnr);
 		if(tmp_bus)
 			return tmp_bus;
@@ -41,6 +41,26 @@
 }
 
 /**
+ * pci_find_next_bus - begin or continue searching for a PCI bus
+ * @from: Previous PCI bus found, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI busses.  A new search is
+ * initiated by passing %NULL to the @from argument.  Otherwise if
+ * @from is not %NULL, searches continue from next device on the
+ * global list.
+ */
+struct pci_bus * 
+pci_find_next_bus(const struct pci_bus *from)
+{
+	struct list_head *n = from ? from->node.next : pci_root_buses.next;
+	struct pci_bus *b = NULL;
+
+	if (n != &pci_root_buses)
+		b = pci_bus_b(n);
+	return b;
+}
+
+/**
  * pci_find_slot - locate PCI device from a given PCI slot
  * @bus: number of PCI bus on which desired PCI device resides
  * @devfn: encodes number of PCI slot in which the desired PCI 
@@ -97,7 +117,6 @@
 	return NULL;
 }
 
-
 /**
  * pci_find_device - begin or continue searching for a PCI device by vendor/device id
  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
@@ -171,20 +190,9 @@
 	return NULL;
 }
 
-/**
- * pci_present - determine if there are any pci devices on this system
- *
- * Returns 0 if no pci devices are present, 1 if pci devices are present.
- */
-int pci_present(void)
-{
-	return !list_empty(&pci_devices);
-}
-
 EXPORT_SYMBOL(pci_find_bus);
 EXPORT_SYMBOL(pci_find_class);
 EXPORT_SYMBOL(pci_find_device);
 EXPORT_SYMBOL(pci_find_device_reverse);
 EXPORT_SYMBOL(pci_find_slot);
 EXPORT_SYMBOL(pci_find_subsys);
-EXPORT_SYMBOL(pci_present);
diff -urN linux-2.5.70-bk15/drivers/pci/syscall.c linux-2.5.70-bk16/drivers/pci/syscall.c
--- linux-2.5.70-bk15/drivers/pci/syscall.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pci/syscall.c	2003-06-11 04:48:06.000000000 -0700
@@ -98,8 +98,6 @@
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
-	if (!pci_present())
-		return -ENOSYS;
 
 	dev = pci_find_slot(bus, dfn);
 	if (!dev)
diff -urN linux-2.5.70-bk15/drivers/pnp/isapnp/core.c linux-2.5.70-bk16/drivers/pnp/isapnp/core.c
--- linux-2.5.70-bk15/drivers/pnp/isapnp/core.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pnp/isapnp/core.c	2003-06-11 04:48:06.000000000 -0700
@@ -1028,6 +1028,7 @@
  */
 
 
+EXPORT_SYMBOL(isapnp_protocol);
 EXPORT_SYMBOL(isapnp_present);
 EXPORT_SYMBOL(isapnp_cfg_begin);
 EXPORT_SYMBOL(isapnp_cfg_end);
diff -urN linux-2.5.70-bk15/drivers/pnp/pnpbios/core.c linux-2.5.70-bk16/drivers/pnp/pnpbios/core.c
--- linux-2.5.70-bk15/drivers/pnp/pnpbios/core.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk16/drivers/pnp/pnpbios/core.c	2003-06-11 04:48:06.000000000 -0700
@@ -1168,3 +1168,5 @@
 module_exit(pnpbios_exit);
 
 #endif
+
+EXPORT_SYMBOL(pnpbios_protocol);
diff -urN linux-2.5.70-bk15/drivers/s390/block/xpram.c linux-2.5.70-bk16/drivers/s390/block/xpram.c
--- linux-2.5.70-bk15/drivers/s390/block/xpram.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/drivers/s390/block/xpram.c	2003-06-11 04:48:06.000000000 -0700
@@ -34,7 +34,7 @@
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 #include <linux/hdreg.h>  /* HDIO_GETGEO */
-#include <linux/device.h>
+#include <linux/sysdev.h>
 #include <linux/bio.h>
 #include <linux/devfs_fs_kernel.h>
 #include <asm/uaccess.h>
@@ -48,12 +48,14 @@
 #define PRINT_WARN(x...)	printk(KERN_WARNING XPRAM_NAME " warning:" x)
 #define PRINT_ERR(x...)		printk(KERN_ERR XPRAM_NAME " error:" x)
 
+
+static struct sysdev_class xpram_sysclass = {
+	set_kset_name("xpram"),
+};
+
 static struct sys_device xpram_sys_device = {
-	.name = "S/390 expanded memory RAM disk",
-	.dev  = {
-		.name   = "S/390 expanded memory RAM disk",
-		.bus_id = "xpram",
-	},
+	.id	= 0,
+	.cls	= &xpram_sysclass,
 }; 
 
 typedef struct {
@@ -485,6 +487,7 @@
 	unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
 	devfs_remove("slram");
 	sys_device_unregister(&xpram_sys_device);
+	sysdev_class_unregister(&xpram_sys_class);
 }
 
 static int __init xpram_init(void)
@@ -502,9 +505,15 @@
 	rc = xpram_setup_sizes(xpram_pages);
 	if (rc)
 		return rc;
-	rc = sys_device_register(&xpram_sys_device);
+	rc = sysdev_class_register(&xpram_sysclass);
 	if (rc)
 		return rc;
+
+	rc = sys_device_register(&xpram_sys_device);
+	if (rc) {
+		sysdev_class_unregister(&xpram_syclass);
+		return rc;
+	}
 	rc = xpram_setup_blkdev();
 	if (rc)
 		sys_device_unregister(&xpram_sys_device);
diff -urN linux-2.5.70-bk15/drivers/sbus/sbus.c linux-2.5.70-bk16/drivers/sbus/sbus.c
--- linux-2.5.70-bk15/drivers/sbus/sbus.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk16/drivers/sbus/sbus.c	2003-06-11 04:48:06.000000000 -0700
@@ -334,7 +334,7 @@
 		nd = prom_searchsiblings(topnd, "sbus");
 		if(nd == 0) {
 #ifdef CONFIG_PCI
-			if (!pci_present()) {
+			if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) == NULL) {
 				prom_printf("Neither SBUS nor PCI found.\n");
 				prom_halt();
 			} else {
diff -urN linux-2.5.70-bk15/drivers/scsi/3w-xxxx.c linux-2.5.70-bk16/drivers/scsi/3w-xxxx.c
--- linux-2.5.70-bk15/drivers/scsi/3w-xxxx.c	2003-06-11 04:47:53.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/3w-xxxx.c	2003-06-11 04:48:06.000000000 -0700
@@ -2379,12 +2379,6 @@
 
 	printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
 
-	/* Check if the kernel has PCI interface compiled in */
-	if (!pci_present()) {
-		printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
-		return 0;
-	}
-
 	ret = tw_findcards(tw_host);
 
 	return ret;
diff -urN linux-2.5.70-bk15/drivers/scsi/BusLogic.c linux-2.5.70-bk16/drivers/scsi/BusLogic.c
--- linux-2.5.70-bk15/drivers/scsi/BusLogic.c	2003-06-11 04:47:53.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/BusLogic.c	2003-06-11 04:48:06.000000000 -0700
@@ -1183,7 +1183,7 @@
     If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
     Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
   */
-  if (!BusLogic_ProbeOptions.NoProbePCI && pci_present())
+  if (!BusLogic_ProbeOptions.NoProbePCI)
     {
       if (BusLogic_ProbeOptions.MultiMasterFirst)
 	{
@@ -5133,3 +5133,4 @@
 	.use_clustering		= ENABLE_CLUSTERING,
 };
 #include "scsi_module.c"
+
diff -urN linux-2.5.70-bk15/drivers/scsi/aic7xxx_old.c linux-2.5.70-bk16/drivers/scsi/aic7xxx_old.c
--- linux-2.5.70-bk15/drivers/scsi/aic7xxx_old.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/aic7xxx_old.c	2003-06-11 04:48:06.000000000 -0700
@@ -9033,7 +9033,6 @@
   /*
    * PCI-bus probe.
    */
-  if (pci_present())
   {
     struct
     {
@@ -9692,7 +9691,7 @@
         }
       } /* while(pdev=....) */
     } /* for PCI_DEVICES */
-  } /* PCI BIOS present */
+  }
 #endif /* CONFIG_PCI */
 
 #if defined(__i386__) || defined(__alpha__)
diff -urN linux-2.5.70-bk15/drivers/scsi/atp870u.c linux-2.5.70-bk16/drivers/scsi/atp870u.c
--- linux-2.5.70-bk15/drivers/scsi/atp870u.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/atp870u.c	2003-06-11 04:48:07.000000000 -0700
@@ -2321,10 +2321,6 @@
 	};
 
 	printk(KERN_INFO "aec671x_detect: \n");
-	if (!pci_present()) {
-		printk(KERN_INFO "   NO PCI SUPPORT.\n");
-		return count;
-	}
 	tpnt->proc_name = "atp870u";
 
 	h = 0;
diff -urN linux-2.5.70-bk15/drivers/scsi/cpqfcTSinit.c linux-2.5.70-bk16/drivers/scsi/cpqfcTSinit.c
--- linux-2.5.70-bk15/drivers/scsi/cpqfcTSinit.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/cpqfcTSinit.c	2003-06-11 04:48:07.000000000 -0700
@@ -298,12 +298,6 @@
   ScsiHostTemplate->proc_name = "cpqfcTS";
 #endif
 
-  if( pci_present() == 0) // no PCI busses?
-  {
-    printk( "  no PCI bus?@#!\n");
-    return NumberOfAdapters;
-  }
-
   for( i=0; i < HBA_TYPES; i++)
   {
     // look for all HBAs of each type
diff -urN linux-2.5.70-bk15/drivers/scsi/dmx3191d.c linux-2.5.70-bk16/drivers/scsi/dmx3191d.c
--- linux-2.5.70-bk15/drivers/scsi/dmx3191d.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/dmx3191d.c	2003-06-11 04:48:07.000000000 -0700
@@ -58,11 +58,6 @@
 	struct Scsi_Host *instance = NULL;
 	struct pci_dev *pdev = NULL;
 
-	if (!pci_present()) {
-		printk(KERN_WARNING "dmx3191: PCI support not enabled\n");
-		return 0;
-	}
-
 	tmpl->proc_name = DMX3191D_DRIVER_NAME;
 
 	while ((pdev = pci_find_device(PCI_VENDOR_ID_DOMEX,
@@ -139,3 +134,4 @@
         .use_clustering		= DISABLE_CLUSTERING,
 };
 #include "scsi_module.c"
+
diff -urN linux-2.5.70-bk15/drivers/scsi/eata.c linux-2.5.70-bk16/drivers/scsi/eata.c
--- linux-2.5.70-bk15/drivers/scsi/eata.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/eata.c	2003-06-11 04:48:07.000000000 -0700
@@ -959,8 +959,6 @@
    unsigned int addr;
    struct pci_dev *dev = NULL;
 
-   if (!pci_present()) return NULL;
-
    while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
       addr = pci_resource_start (dev, 0);
 
@@ -983,8 +981,6 @@
 
    struct pci_dev *dev = NULL;
 
-   if (!pci_present()) return;
-
    while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
 
 #if defined(DEBUG_PCI_DETECT)
@@ -1410,8 +1406,6 @@
 
    struct pci_dev *dev = NULL;
 
-   if (!pci_present()) return;
-
    for (k = 0; k < MAX_PCI; k++) {
 
       if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
diff -urN linux-2.5.70-bk15/drivers/scsi/gdth.c linux-2.5.70-bk16/drivers/scsi/gdth.c
--- linux-2.5.70-bk15/drivers/scsi/gdth.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/gdth.c	2003-06-11 04:48:07.000000000 -0700
@@ -4460,9 +4460,7 @@
     }
 
     /* scanning for PCI controllers */
-#if LINUX_VERSION_CODE >= 0x2015C
-    if (pci_present())
-#else
+#if LINUX_VERSION_CODE < 0x2015C
     if (pcibios_present())
 #endif
     {
diff -urN linux-2.5.70-bk15/drivers/scsi/inia100.c linux-2.5.70-bk16/drivers/scsi/inia100.c
--- linux-2.5.70-bk15/drivers/scsi/inia100.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/inia100.c	2003-06-11 04:48:07.000000000 -0700
@@ -218,7 +218,7 @@
 	/*
 	 * PCI-bus probe.
 	 */
-	if (pci_present()) {
+	{
 		/*
 		 * Note: I removed the struct pci_device_list stuff since this
 		 * driver only cares about one device ID.  If that changes in
diff -urN linux-2.5.70-bk15/drivers/scsi/pci2000.c linux-2.5.70-bk16/drivers/scsi/pci2000.c
--- linux-2.5.70-bk15/drivers/scsi/pci2000.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/pci2000.c	2003-06-11 04:48:07.000000000 -0700
@@ -668,13 +668,6 @@
 	UCHAR			   *consistent;
 	dma_addr_t			consistentDma;
 
-
-	if ( !pci_present () )
-		{
-		printk ("pci2000: PCI BIOS not present\n");
-		return 0;
-		}
-
 	while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_ROY_1, pdev)) != NULL )
 		{
 		if (pci_enable_device(pdev))
diff -urN linux-2.5.70-bk15/drivers/scsi/pci2220i.c linux-2.5.70-bk16/drivers/scsi/pci2220i.c
--- linux-2.5.70-bk15/drivers/scsi/pci2220i.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/pci2220i.c	2003-06-11 04:48:07.000000000 -0700
@@ -2534,12 +2534,6 @@
 	UCHAR				device;
 	struct pci_dev	   *pcidev = NULL;
 
-	if ( !pci_present () )
-		{
-		printk ("pci2220i: PCI BIOS not present\n");
-		return 0;
-		}
-
 	while ( (pcidev = pci_find_device (VENDOR_PSI, DEVICE_DALE_1, pcidev)) != NULL )
 		{
 		if (pci_enable_device(pcidev))
diff -urN linux-2.5.70-bk15/drivers/scsi/qla1280.c linux-2.5.70-bk16/drivers/scsi/qla1280.c
--- linux-2.5.70-bk15/drivers/scsi/qla1280.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/qla1280.c	2003-06-11 04:48:07.000000000 -0700
@@ -360,7 +360,6 @@
  */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
 #define pci_set_dma_mask(dev, mask)		dev->dma_mask = mask;
-#define pci_present()				pcibios_present()
 #define pci_enable_device(pdev)			0
 #define pci_find_subsys(id, dev, sid, sdev, pdev) pci_find_device(id,dev,pdev)
 #define scsi_set_pci_device(host, pdev)
@@ -1009,11 +1008,6 @@
 	       "qla1280: insmod or else it might trash certain memory areas.\n");
 #endif
 
-	if (!pci_present()) {
-		printk(KERN_INFO "scsi: PCI not present\n");
-		return 0;
-	}
-
 	bdp = &ql1280_board_tbl[0];
 	qla1280_hostlist = NULL;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
diff -urN linux-2.5.70-bk15/drivers/scsi/qlogicfc.c linux-2.5.70-bk16/drivers/scsi/qlogicfc.c
--- linux-2.5.70-bk15/drivers/scsi/qlogicfc.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/qlogicfc.c	2003-06-11 04:48:07.000000000 -0700
@@ -711,11 +711,6 @@
 
 	tmpt->proc_name = "isp2x00";
 
-	if (pci_present() == 0) {
-		printk(KERN_INFO "qlogicfc : PCI not present\n");
-		return 0;
-	}
-
 	for (i=0; i<2; i++){
 		pdev = NULL;
 	        while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, device_ids[i], pdev))) {
diff -urN linux-2.5.70-bk15/drivers/scsi/qlogicisp.c linux-2.5.70-bk16/drivers/scsi/qlogicisp.c
--- linux-2.5.70-bk15/drivers/scsi/qlogicisp.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/qlogicisp.c	2003-06-11 04:48:07.000000000 -0700
@@ -666,11 +666,6 @@
 
 	tmpt->proc_name = "isp1020";
 
-	if (pci_present() == 0) {
-		printk("qlogicisp : PCI not present\n");
-		return 0;
-	}
-
 	while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020, pdev)))
 	{
 		if (pci_enable_device(pdev))
diff -urN linux-2.5.70-bk15/drivers/scsi/sym53c8xx.c linux-2.5.70-bk16/drivers/scsi/sym53c8xx.c
--- linux-2.5.70-bk15/drivers/scsi/sym53c8xx.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/sym53c8xx.c	2003-06-11 04:48:07.000000000 -0700
@@ -493,8 +493,6 @@
 #define PciDeviceFn(d)		((d)&0xff)
 #define __PciDev(busn, devfn)	(((busn)<<8)+(devfn))
 
-#define pci_present pcibios_present
-
 #define pci_read_config_byte(d, w, v) \
 	pcibios_read_config_byte(PciBusNumber(d), PciDeviceFn(d), w, v)
 #define pci_read_config_word(d, w, v) \
@@ -12905,12 +12903,6 @@
 #endif
 
 	/*
-	**    PCI is required.
-	*/
-	if (!pci_present())
-		return 0;
-
-	/*
 	**    Initialize driver general stuff.
 	*/
 #ifdef SCSI_NCR_PROC_INFO_SUPPORT
diff -urN linux-2.5.70-bk15/drivers/scsi/sym53c8xx_2/sym_glue.c linux-2.5.70-bk16/drivers/scsi/sym53c8xx_2/sym_glue.c
--- linux-2.5.70-bk15/drivers/scsi/sym53c8xx_2/sym_glue.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/sym53c8xx_2/sym_glue.c	2003-06-11 04:48:07.000000000 -0700
@@ -2694,12 +2694,6 @@
 #endif
 
 	/*
-	 *  PCI is required.
-	 */
-	if (!pci_present())
-		return 0;
-
-	/*
 	 *    Initialize driver general stuff.
 	 */
 #ifdef SYM_LINUX_BOOT_COMMAND_LINE_SUPPORT
diff -urN linux-2.5.70-bk15/drivers/scsi/sym53c8xx_comm.h linux-2.5.70-bk16/drivers/scsi/sym53c8xx_comm.h
--- linux-2.5.70-bk15/drivers/scsi/sym53c8xx_comm.h	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/sym53c8xx_comm.h	2003-06-11 04:48:07.000000000 -0700
@@ -319,8 +319,6 @@
 #define PciDeviceFn(d)		((d)&0xff)
 #define __PciDev(busn, devfn)	(((busn)<<8)+(devfn))
 
-#define pci_present pcibios_present
-
 #define pci_read_config_byte(d, w, v) \
 	pcibios_read_config_byte(PciBusNumber(d), PciDeviceFn(d), w, v)
 #define pci_read_config_word(d, w, v) \
@@ -2531,12 +2529,6 @@
 	ncr_nvram  nvram0, nvram, *nvp;
 #endif
 
-	/*
-	**    PCI is required.
-	*/
-	if (!pci_present())
-		return 0;
-
 #ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
 	ncr_debug = driver_setup.debug;
 #endif
diff -urN linux-2.5.70-bk15/drivers/scsi/tmscsim.c linux-2.5.70-bk16/drivers/scsi/tmscsim.c
--- linux-2.5.70-bk15/drivers/scsi/tmscsim.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/scsi/tmscsim.c	2003-06-11 04:48:07.000000000 -0700
@@ -394,7 +394,7 @@
 # define PCI_WRITE_CONFIG_WORD(pd, rv, bv) pci_write_config_word (pd, rv, bv)
 # define PCI_READ_CONFIG_WORD(pd, rv, bv) pci_read_config_word (pd, rv, bv)
 # define PCI_BUS_DEV pdev->bus->number, pdev->devfn
-# define PCI_PRESENT pci_present ()
+# define PCI_PRESENT (1)
 # define PCI_SET_MASTER pci_set_master (pdev)
 # define PCI_FIND_DEVICE(vend, id) (pdev = pci_find_device (vend, id, pdev))
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,10)
diff -urN linux-2.5.70-bk15/drivers/serial/core.c linux-2.5.70-bk16/drivers/serial/core.c
--- linux-2.5.70-bk15/drivers/serial/core.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/serial/core.c	2003-06-11 04:48:07.000000000 -0700
@@ -2189,11 +2189,11 @@
 void uart_unregister_driver(struct uart_driver *drv)
 {
 	struct tty_driver *p = drv->tty_driver;
-	drv->tty_driver = NULL;
 	tty_unregister_driver(p);
 	kfree(drv->state);
-	kfree(drv->tty_driver->termios);
-	kfree(drv->tty_driver);
+	kfree(p->termios);
+	kfree(p);
+	drv->tty_driver = NULL;
 }
 
 struct tty_driver *uart_console_device(struct console *co, int *index)
diff -urN linux-2.5.70-bk15/drivers/telephony/ixj.c linux-2.5.70-bk16/drivers/telephony/ixj.c
--- linux-2.5.70-bk15/drivers/telephony/ixj.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk16/drivers/telephony/ixj.c	2003-06-11 04:48:07.000000000 -0700
@@ -7821,9 +7821,6 @@
 	IXJ *j = NULL;
 	int result;
 
-	if(!pci_present())
-		return 0;
-
 	for (i = 0; i < IXJMAX - *cnt; i++) {
 		pci = pci_find_device(0x15E2, 0x0500, pci);
 		if (!pci)
@@ -7869,10 +7866,8 @@
 	if ((probe = ixj_probe_isa(&cnt)) < 0) {
 		return probe;
 	}
-	if (pci_present()) {
-		if ((probe = ixj_probe_pci(&cnt)) < 0) {
-			return probe;
-		}
+	if ((probe = ixj_probe_pci(&cnt)) < 0) {
+		return probe;
 	}
 	printk("%s\n", ixj_c_rcsid);
 	create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
diff -urN linux-2.5.70-bk15/drivers/usb/core/devices.c linux-2.5.70-bk16/drivers/usb/core/devices.c
--- linux-2.5.70-bk15/drivers/usb/core/devices.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/core/devices.c	2003-06-11 04:48:07.000000000 -0700
@@ -444,7 +444,7 @@
  * skip_bytes - the number of bytes to skip before writing anything
  * file_offset - the offset into the devices file on completion
  */
-static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
+static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
 				struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count)
 {
 	int chix;
@@ -554,7 +554,7 @@
 	return total_written;
 }
 
-static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
 	struct list_head *buslist;
 	struct usb_bus *bus;
diff -urN linux-2.5.70-bk15/drivers/usb/core/devio.c linux-2.5.70-bk16/drivers/usb/core/devio.c
--- linux-2.5.70-bk15/drivers/usb/core/devio.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/core/devio.c	2003-06-11 04:48:08.000000000 -0700
@@ -49,14 +49,14 @@
 #include "hcd.h"	/* for usbcore internals */
 
 struct async {
-        struct list_head asynclist;
-        struct dev_state *ps;
+	struct list_head asynclist;
+	struct dev_state *ps;
 	struct task_struct *task;
 	unsigned int signr;
 	unsigned int intf;
-	void *userbuffer;
-        void *userurb;
-        struct urb *urb;
+	void __user *userbuffer;
+	void __user *userurb;
+	struct urb *urb;
 };
 
 static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)
@@ -83,7 +83,7 @@
 	return ret;
 }
 
-static ssize_t usbdev_read(struct file *file, char * buf, size_t nbytes, loff_t *ppos)
+static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
 	struct dev_state *ps = (struct dev_state *)file->private_data;
 	ssize_t ret = 0;
@@ -235,7 +235,7 @@
         return as;
 }
 
-extern __inline__ struct async *async_getpending(struct dev_state *ps, void *userurb)
+extern __inline__ struct async *async_getpending(struct dev_state *ps, void __user *userurb)
 {
         unsigned long flags;
         struct async *as;
@@ -265,7 +265,7 @@
 		sinfo.si_signo = as->signr;
 		sinfo.si_errno = as->urb->status;
 		sinfo.si_code = SI_ASYNCIO;
-		sinfo.si_addr = as->userurb;
+		sinfo.si_addr = (void *)as->userurb;
 		send_sig_info(as->signr, &sinfo, as->task);
 	}
 }
@@ -536,7 +536,7 @@
         return 0;
 }
 
-static int proc_control(struct dev_state *ps, void *arg)
+static int proc_control(struct dev_state *ps, void __user *arg)
 {
 	struct usb_device *dev = ps->dev;
 	struct usbdevfs_ctrltransfer ctrl;
@@ -544,7 +544,7 @@
 	unsigned char *tbuf;
 	int i, ret;
 
-	if (copy_from_user(&ctrl, (void *)arg, sizeof(ctrl)))
+	if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
 		return -EFAULT;
 	if ((ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex)))
 		return ret;
@@ -578,13 +578,15 @@
 	}
 	free_page((unsigned long)tbuf);
 	if (i<0) {
-		printk(KERN_DEBUG "usbfs: USBDEVFS_CONTROL failed dev %d rqt %u rq %u len %u ret %d\n", 
+		printk(KERN_DEBUG "usbfs: USBDEVFS_CONTROL failed "
+			"cmd %s dev %d rqt %u rq %u len %u ret %d\n", 
+			current->comm,
 		       dev->devnum, ctrl.bRequestType, ctrl.bRequest, ctrl.wLength, i);
 	}
 	return i;
 }
 
-static int proc_bulk(struct dev_state *ps, void *arg)
+static int proc_bulk(struct dev_state *ps, void __user *arg)
 {
 	struct usb_device *dev = ps->dev;
 	struct usbdevfs_bulktransfer bulk;
@@ -593,7 +595,7 @@
 	unsigned char *tbuf;
 	int i, ret;
 
-	if (copy_from_user(&bulk, (void *)arg, sizeof(bulk)))
+	if (copy_from_user(&bulk, arg, sizeof(bulk)))
 		return -EFAULT;
 	if ((ret = findintfep(ps->dev, bulk.ep)) < 0)
 		return ret;
@@ -639,12 +641,12 @@
 	return len2;
 }
 
-static int proc_resetep(struct dev_state *ps, void *arg)
+static int proc_resetep(struct dev_state *ps, void __user *arg)
 {
 	unsigned int ep;
 	int ret;
 
-	if (get_user(ep, (unsigned int *)arg))
+	if (get_user(ep, (unsigned int __user *)arg))
 		return -EFAULT;
 	if ((ret = findintfep(ps->dev, ep)) < 0)
 		return ret;
@@ -654,13 +656,13 @@
 	return 0;
 }
 
-static int proc_clearhalt(struct dev_state *ps, void *arg)
+static int proc_clearhalt(struct dev_state *ps, void __user *arg)
 {
 	unsigned int ep;
 	int pipe;
 	int ret;
 
-	if (get_user(ep, (unsigned int *)arg))
+	if (get_user(ep, (unsigned int __user *)arg))
 		return -EFAULT;
 	if ((ret = findintfep(ps->dev, ep)) < 0)
 		return ret;
@@ -675,7 +677,7 @@
 }
 		
 
-static int proc_getdriver(struct dev_state *ps, void *arg)
+static int proc_getdriver(struct dev_state *ps, void __user *arg)
 {
 	struct usbdevfs_getdriver gd;
 	struct usb_interface *interface;
@@ -696,7 +698,7 @@
 	return 0;
 }
 
-static int proc_connectinfo(struct dev_state *ps, void *arg)
+static int proc_connectinfo(struct dev_state *ps, void __user *arg)
 {
 	struct usbdevfs_connectinfo ci;
 
@@ -731,7 +733,7 @@
 	return 0;
 }
 
-static int proc_setintf(struct dev_state *ps, void *arg)
+static int proc_setintf(struct dev_state *ps, void __user *arg)
 {
 	struct usbdevfs_setinterface setintf;
 	struct usb_interface *interface;
@@ -753,18 +755,18 @@
 	return 0;
 }
 
-static int proc_setconfig(struct dev_state *ps, void *arg)
+static int proc_setconfig(struct dev_state *ps, void __user *arg)
 {
 	unsigned int u;
 
-	if (get_user(u, (unsigned int *)arg))
+	if (get_user(u, (unsigned int __user *)arg))
 		return -EFAULT;
 	if (usb_set_configuration(ps->dev, u) < 0)
 		return -EINVAL;
 	return 0;
 }
 
-static int proc_submiturb(struct dev_state *ps, void *arg)
+static int proc_submiturb(struct dev_state *ps, void __user *arg)
 {
 	struct usbdevfs_urb uurb;
 	struct usbdevfs_iso_packet_desc *isopkt = NULL;
@@ -802,7 +804,7 @@
 			return -EINVAL;
 		if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL)))
 			return -ENOMEM;
-		if (copy_from_user(dr, (unsigned char*)uurb.buffer, 8)) {
+		if (copy_from_user(dr, uurb.buffer, 8)) {
 			kfree(dr);
 			return -EFAULT;
 		}
@@ -928,7 +930,7 @@
         return 0;
 }
 
-static int proc_unlinkurb(struct dev_state *ps, void *arg)
+static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
 {
 	struct async *as;
 
@@ -970,11 +972,11 @@
 	return 0;
 }
 
-static int proc_reapurb(struct dev_state *ps, void *arg)
+static int proc_reapurb(struct dev_state *ps, void __user *arg)
 {
         DECLARE_WAITQUEUE(wait, current);
 	struct async *as = NULL;
-	void *addr;
+	void __user *addr;
 	int ret;
 
 	add_wait_queue(&ps->wait, &wait);
@@ -1005,10 +1007,10 @@
 	return -EIO;
 }
 
-static int proc_reapurbnonblock(struct dev_state *ps, void *arg)
+static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
 {
 	struct async *as;
-	void *addr;
+	void __user *addr;
 	int ret;
 
 	if (!(as = async_getcompleted(ps)))
@@ -1023,7 +1025,7 @@
 	return 0;
 }
 
-static int proc_disconnectsignal(struct dev_state *ps, void *arg)
+static int proc_disconnectsignal(struct dev_state *ps, void __user *arg)
 {
 	struct usbdevfs_disconnectsignal ds;
 
@@ -1036,24 +1038,24 @@
 	return 0;
 }
 
-static int proc_claiminterface(struct dev_state *ps, void *arg)
+static int proc_claiminterface(struct dev_state *ps, void __user *arg)
 {
 	unsigned int intf;
 	int ret;
 
-	if (get_user(intf, (unsigned int *)arg))
+	if (get_user(intf, (unsigned int __user *)arg))
 		return -EFAULT;
 	if ((ret = findintfif(ps->dev, intf)) < 0)
 		return ret;
 	return claimintf(ps, ret);
 }
 
-static int proc_releaseinterface(struct dev_state *ps, void *arg)
+static int proc_releaseinterface(struct dev_state *ps, void __user *arg)
 {
 	unsigned int intf;
 	int ret;
 
-	if (get_user(intf, (unsigned int *)arg))
+	if (get_user(intf, (unsigned int __user *)arg))
 		return -EFAULT;
 	if ((ret = findintfif(ps->dev, intf)) < 0)
 		return ret;
@@ -1063,7 +1065,7 @@
 	return 0;
 }
 
-static int proc_ioctl (struct dev_state *ps, void *arg)
+static int proc_ioctl (struct dev_state *ps, void __user *arg)
 {
 	struct usbdevfs_ioctl	ctrl;
 	int			size;
@@ -1073,7 +1075,7 @@
 	struct usb_driver       *driver = 0;
 
 	/* get input parameters and alloc buffer */
-	if (copy_from_user(&ctrl, (void *) arg, sizeof (ctrl)))
+	if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
 		return -EFAULT;
 	if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) {
 		if ((buf = kmalloc (size, GFP_KERNEL)) == 0)
@@ -1171,19 +1173,19 @@
 	}
 	switch (cmd) {
 	case USBDEVFS_CONTROL:
-		ret = proc_control(ps, (void *)arg);
+		ret = proc_control(ps, (void __user *)arg);
 		if (ret >= 0)
 			inode->i_mtime = CURRENT_TIME;
 		break;
 
 	case USBDEVFS_BULK:
-		ret = proc_bulk(ps, (void *)arg);
+		ret = proc_bulk(ps, (void __user *)arg);
 		if (ret >= 0)
 			inode->i_mtime = CURRENT_TIME;
 		break;
 
 	case USBDEVFS_RESETEP:
-		ret = proc_resetep(ps, (void *)arg);
+		ret = proc_resetep(ps, (void __user *)arg);
 		if (ret >= 0)
 			inode->i_mtime = CURRENT_TIME;
 		break;
@@ -1193,59 +1195,59 @@
 		break;
 
 	case USBDEVFS_CLEAR_HALT:
-		ret = proc_clearhalt(ps, (void *)arg);
+		ret = proc_clearhalt(ps, (void __user *)arg);
 		if (ret >= 0)
 			inode->i_mtime = CURRENT_TIME;
 		break;
 
 	case USBDEVFS_GETDRIVER:
-		ret = proc_getdriver(ps, (void *)arg);
+		ret = proc_getdriver(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_CONNECTINFO:
-		ret = proc_connectinfo(ps, (void *)arg);
+		ret = proc_connectinfo(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_SETINTERFACE:
-		ret = proc_setintf(ps, (void *)arg);
+		ret = proc_setintf(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_SETCONFIGURATION:
-		ret = proc_setconfig(ps, (void *)arg);
+		ret = proc_setconfig(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_SUBMITURB:
-		ret = proc_submiturb(ps, (void *)arg);
+		ret = proc_submiturb(ps, (void __user *)arg);
 		if (ret >= 0)
 			inode->i_mtime = CURRENT_TIME;
 		break;
 
 	case USBDEVFS_DISCARDURB:
-		ret = proc_unlinkurb(ps, (void *)arg);
+		ret = proc_unlinkurb(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_REAPURB:
-		ret = proc_reapurb(ps, (void *)arg);
+		ret = proc_reapurb(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_REAPURBNDELAY:
-		ret = proc_reapurbnonblock(ps, (void *)arg);
+		ret = proc_reapurbnonblock(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_DISCSIGNAL:
-		ret = proc_disconnectsignal(ps, (void *)arg);
+		ret = proc_disconnectsignal(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_CLAIMINTERFACE:
-		ret = proc_claiminterface(ps, (void *)arg);
+		ret = proc_claiminterface(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_RELEASEINTERFACE:
-		ret = proc_releaseinterface(ps, (void *)arg);
+		ret = proc_releaseinterface(ps, (void __user *)arg);
 		break;
 
 	case USBDEVFS_IOCTL:
-		ret = proc_ioctl(ps, (void *) arg);
+		ret = proc_ioctl(ps, (void __user *) arg);
 		break;
 	}
 	up_read(&ps->devsem);
diff -urN linux-2.5.70-bk15/drivers/usb/core/hub.c linux-2.5.70-bk16/drivers/usb/core/hub.c
--- linux-2.5.70-bk15/drivers/usb/core/hub.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/core/hub.c	2003-06-11 04:48:08.000000000 -0700
@@ -64,17 +64,17 @@
 }
 
 /* USB 2.0 spec Section 11.24.4.5 */
-static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
+static int get_hub_descriptor(struct usb_device *dev, void *data, int size)
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
-		USB_DT_HUB << 8, 0, data, size, HZ);
+		USB_DT_HUB << 8, 0, data, size, HZ * USB_CTRL_GET_TIMEOUT);
 }
 
 /*
  * USB 2.0 spec Section 11.24.2.1
  */
-static int usb_clear_hub_feature(struct usb_device *dev, int feature)
+static int clear_hub_feature(struct usb_device *dev, int feature)
 {
 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature, 0, NULL, 0, HZ);
@@ -84,7 +84,7 @@
  * USB 2.0 spec Section 11.24.2.2
  * BUG: doesn't handle port indicator selector in high byte of wIndex
  */
-static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
+static int clear_port_feature(struct usb_device *dev, int port, int feature)
 {
 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
@@ -94,7 +94,7 @@
  * USB 2.0 spec Section 11.24.2.13
  * BUG: doesn't handle port indicator selector in high byte of wIndex
  */
-static int usb_set_port_feature(struct usb_device *dev, int port, int feature)
+static int set_port_feature(struct usb_device *dev, int port, int feature)
 {
 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
@@ -103,21 +103,23 @@
 /*
  * USB 2.0 spec Section 11.24.2.6
  */
-static int usb_get_hub_status(struct usb_device *dev, void *data)
+static int get_hub_status(struct usb_device *dev,
+		struct usb_hub_status *data)
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
-		data, sizeof(struct usb_hub_status), HZ);
+		data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT);
 }
 
 /*
  * USB 2.0 spec Section 11.24.2.7
  */
-static int usb_get_port_status(struct usb_device *dev, int port, void *data)
+static int get_port_status(struct usb_device *dev, int port,
+		struct usb_port_status *data)
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
-		data, sizeof(struct usb_hub_status), HZ);
+		data, sizeof(*data), HZ * USB_CTRL_GET_TIMEOUT);
 }
 
 /* completion function, fires on port status changes and various faults */
@@ -256,7 +258,7 @@
 	spin_unlock_irqrestore (&tt->lock, flags);
 }
 
-static void usb_hub_power_on(struct usb_hub *hub)
+static void hub_power_on(struct usb_hub *hub)
 {
 	struct usb_device *dev;
 	int i;
@@ -266,22 +268,55 @@
 		"enabling power on all ports\n");
 	dev = interface_to_usbdev(hub->intf);
 	for (i = 0; i < hub->descriptor->bNbrPorts; i++)
-		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+		set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
 
 	/* Wait for power to be enabled */
 	wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
 }
 
-static int usb_hub_configure(struct usb_hub *hub,
+static int hub_hub_status(struct usb_hub *hub,
+		u16 *status, u16 *change)
+{
+	struct usb_device *dev = interface_to_usbdev (hub->intf);
+	int ret;
+
+	ret = get_hub_status(dev, &hub->status->hub);
+	if (ret < 0)
+		dev_err (hubdev (dev),
+			"%s failed (err = %d)\n", __FUNCTION__, ret);
+	else {
+		*status = le16_to_cpu(hub->status->hub.wHubStatus);
+		*change = le16_to_cpu(hub->status->hub.wHubChange); 
+		ret = 0;
+	}
+	return ret;
+}
+
+static int hub_configure(struct usb_hub *hub,
 	struct usb_endpoint_descriptor *endpoint)
 {
 	struct usb_device *dev = interface_to_usbdev (hub->intf);
 	struct device *hub_dev;
-	struct usb_hub_status hubstatus;
+	u16 hubstatus, hubchange;
 	unsigned int pipe;
 	int maxp, ret;
 	char *message;
 
+	hub->buffer = usb_buffer_alloc(dev, sizeof(*hub->buffer), GFP_KERNEL,
+			&hub->buffer_dma);
+	if (!hub->buffer) {
+		message = "can't allocate hub irq buffer";
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);
+	if (!hub->status) {
+		message = "can't kmalloc hub status buffer";
+		ret = -ENOMEM;
+		goto fail;
+	}
+
 	hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
 	if (!hub->descriptor) {
 		message = "can't kmalloc hub descriptor";
@@ -293,7 +328,7 @@
 	 * hub->descriptor can handle USB_MAXCHILDREN ports,
 	 * but the hub can/will return fewer bytes here.
 	 */
-	ret = usb_get_hub_descriptor(dev, hub->descriptor,
+	ret = get_hub_descriptor(dev, hub->descriptor,
 			sizeof(*hub->descriptor));
 	if (ret < 0) {
 		message = "can't read hub descriptor";
@@ -396,27 +431,25 @@
 	dev_dbg(hub_dev, "hub controller current requirement: %dmA\n",
 		hub->descriptor->bHubContrCurrent);
 
-	ret = usb_get_hub_status(dev, &hubstatus);
+	ret = hub_hub_status(hub, &hubstatus, &hubchange);
 	if (ret < 0) {
 		message = "can't get hub status";
 		goto fail;
 	}
 
-	le16_to_cpus(&hubstatus.wHubStatus);
-
 	dev_dbg(hub_dev, "local power source is %s\n",
-		(hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER)
+		(hubstatus & HUB_STATUS_LOCAL_POWER)
 		? "lost (inactive)" : "good");
 
 	dev_dbg(hub_dev, "%sover-current condition exists\n",
-		(hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+		(hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
 
 	/* Start the interrupt endpoint */
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
-	if (maxp > sizeof(hub->buffer))
-		maxp = sizeof(hub->buffer);
+	if (maxp > sizeof(*hub->buffer))
+		maxp = sizeof(*hub->buffer);
 
 	hub->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!hub->urb) {
@@ -425,8 +458,10 @@
 		goto fail;
 	}
 
-	usb_fill_int_urb(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
+	usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq,
 		hub, endpoint->bInterval);
+	hub->urb->transfer_dma = hub->buffer_dma;
+	hub->urb->transfer_flags |= URB_NO_DMA_MAP;
 	ret = usb_submit_urb(hub->urb, GFP_KERNEL);
 	if (ret) {
 		message = "couldn't submit status urb";
@@ -436,7 +471,7 @@
 	/* Wake up khubd */
 	wake_up(&khubd_wait);
 
-	usb_hub_power_on(hub);
+	hub_power_on(hub);
 
 	return 0;
 
@@ -484,6 +519,18 @@
 		hub->descriptor = NULL;
 	}
 
+	if (hub->status) {
+		kfree(hub->status);
+		hub->status = NULL;
+	}
+
+	if (hub->buffer) {
+		usb_buffer_free(interface_to_usbdev(intf),
+				sizeof(*hub->buffer), hub->buffer,
+				hub->buffer_dma);
+		hub->buffer = NULL;
+	}
+
 	/* Free the memory */
 	kfree(hub);
 }
@@ -550,7 +597,7 @@
 
 	usb_set_intfdata (intf, hub);
 
-	if (usb_hub_configure(hub, endpoint) >= 0) {
+	if (hub_configure(hub, endpoint) >= 0) {
 		strcpy (intf->dev.name, "Hub");
 		return 0;
 	}
@@ -594,7 +641,7 @@
 	}
 }
 
-static int usb_hub_reset(struct usb_hub *hub)
+static int hub_reset(struct usb_hub *hub)
 {
 	struct usb_device *dev = interface_to_usbdev(hub->intf);
 	int i;
@@ -618,12 +665,12 @@
 	if (usb_submit_urb(hub->urb, GFP_KERNEL))
 		return -1;
 
-	usb_hub_power_on(hub);
+	hub_power_on(hub);
 
 	return 0;
 }
 
-static void usb_hub_disconnect(struct usb_device *dev)
+static void hub_start_disconnect(struct usb_device *dev)
 {
 	struct usb_device *parent = dev->parent;
 	int i;
@@ -641,25 +688,20 @@
 	err("cannot disconnect hub %s", dev->devpath);
 }
 
-static int usb_hub_port_status(struct usb_device *hub, int port,
+static int hub_port_status(struct usb_device *dev, int port,
 			       u16 *status, u16 *change)
 {
-	struct usb_port_status *portsts;
-	int ret = -ENOMEM;
+	struct usb_hub *hub = usb_get_intfdata (dev->actconfig->interface);
+	int ret;
 
-	portsts = kmalloc(sizeof(*portsts), GFP_NOIO);
-	if (portsts) {
-		ret = usb_get_port_status(hub, port + 1, portsts);
-		if (ret < 0)
-			dev_err (hubdev (hub),
-				"%s failed (err = %d)\n", __FUNCTION__,
-				ret);
-		else {
-			*status = le16_to_cpu(portsts->wPortStatus);
-			*change = le16_to_cpu(portsts->wPortChange); 
-			ret = 0;
-		}
-		kfree(portsts);
+	ret = get_port_status(dev, port + 1, &hub->status->port);
+	if (ret < 0)
+		dev_err (hubdev (dev),
+			"%s failed (err = %d)\n", __FUNCTION__, ret);
+	else {
+		*status = le16_to_cpu(hub->status->port.wPortStatus);
+		*change = le16_to_cpu(hub->status->port.wPortChange); 
+		ret = 0;
 	}
 	return ret;
 }
@@ -671,7 +713,7 @@
 #define HUB_RESET_TIMEOUT	500
 
 /* return: -1 on error, 0 on success, 1 on disconnect.  */
-static int usb_hub_port_wait_reset(struct usb_device *hub, int port,
+static int hub_port_wait_reset(struct usb_device *hub, int port,
 				struct usb_device *dev, unsigned int delay)
 {
 	int delay_time, ret;
@@ -685,7 +727,7 @@
 		wait_ms(delay);
 
 		/* read and decode port status */
-		ret = usb_hub_port_status(hub, port, &portstatus, &portchange);
+		ret = hub_port_status(hub, port, &portstatus, &portchange);
 		if (ret < 0) {
 			return -1;
 		}
@@ -723,19 +765,19 @@
 }
 
 /* return: -1 on error, 0 on success, 1 on disconnect.  */
-static int usb_hub_port_reset(struct usb_device *hub, int port,
+static int hub_port_reset(struct usb_device *hub, int port,
 				struct usb_device *dev, unsigned int delay)
 {
 	int i, status;
 
 	/* Reset the port */
 	for (i = 0; i < HUB_RESET_TRIES; i++) {
-		usb_set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
+		set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
 
 		/* return on disconnect or reset */
-		status = usb_hub_port_wait_reset(hub, port, dev, delay);
+		status = hub_port_wait_reset(hub, port, dev, delay);
 		if (status != -1) {
-			usb_clear_port_feature(hub,
+			clear_port_feature(hub,
 				port + 1, USB_PORT_FEAT_C_RESET);
 			dev->state = status
 					? USB_STATE_NOTATTACHED
@@ -756,11 +798,11 @@
 	return -1;
 }
 
-int usb_hub_port_disable(struct usb_device *hub, int port)
+int hub_port_disable(struct usb_device *hub, int port)
 {
 	int ret;
 
-	ret = usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
+	ret = clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
 	if (ret)
 		dev_err(hubdev(hub), "cannot disable port %d (err = %d)\n",
 			port + 1, ret);
@@ -787,7 +829,7 @@
 #define HUB_DEBOUNCE_STABLE	  4
 
 /* return: -1 on error, 0 on success, 1 on disconnect.  */
-static int usb_hub_port_debounce(struct usb_device *hub, int port)
+static int hub_port_debounce(struct usb_device *hub, int port)
 {
 	int ret;
 	int delay_time, stable_count;
@@ -799,7 +841,7 @@
 	for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; delay_time += HUB_DEBOUNCE_STEP) {
 		wait_ms(HUB_DEBOUNCE_STEP);
 
-		ret = usb_hub_port_status(hub, port, &portstatus, &portchange);
+		ret = hub_port_status(hub, port, &portstatus, &portchange);
 		if (ret < 0)
 			return -1;
 
@@ -814,7 +856,7 @@
 		connection = portstatus & USB_PORT_STAT_CONNECTION;
 
 		if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
-			usb_clear_port_feature(hub, port+1, USB_PORT_FEAT_C_CONNECTION);
+			clear_port_feature(hub, port+1, USB_PORT_FEAT_C_CONNECTION);
 		}
 	}
 
@@ -826,7 +868,7 @@
 	return ((portstatus&USB_PORT_STAT_CONNECTION)) ? 0 : 1;
 }
 
-static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
+static void hub_port_connect_change(struct usb_hub *hubstate, int port,
 					u16 portstatus, u16 portchange)
 {
 	struct usb_device *hub = interface_to_usbdev(hubstate->intf);
@@ -839,7 +881,7 @@
 		port + 1, portstatus, portchange, portspeed (portstatus));
 
 	/* Clear the connection change status */
-	usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
+	clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
 
 	/* Disconnect any existing devices under this port */
 	if (hub->children[port])
@@ -848,16 +890,16 @@
 	/* Return now if nothing is connected */
 	if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
 		if (portstatus & USB_PORT_STAT_ENABLE)
-			usb_hub_port_disable(hub, port);
+			hub_port_disable(hub, port);
 
 		return;
 	}
 
-	if (usb_hub_port_debounce(hub, port)) {
+	if (hub_port_debounce(hub, port)) {
 		dev_err (&hubstate->intf->dev,
 			"connect-debounce failed, port %d disabled\n",
 			port+1);
-		usb_hub_port_disable(hub, port);
+		hub_port_disable(hub, port);
 		return;
 	}
 
@@ -884,7 +926,7 @@
 		dev->state = USB_STATE_POWERED;
 
 		/* Reset the device, and detect its speed */
-		if (usb_hub_port_reset(hub, port, dev, delay)) {
+		if (hub_port_reset(hub, port, dev, delay)) {
 			usb_put_dev(dev);
 			break;
 		}
@@ -944,18 +986,17 @@
 	}
 
 	hub->children[port] = NULL;
-	usb_hub_port_disable(hub, port);
+	hub_port_disable(hub, port);
 done:
 	up(&usb_address0_sem);
 }
 
-static void usb_hub_events(void)
+static void hub_events(void)
 {
 	unsigned long flags;
 	struct list_head *tmp;
 	struct usb_device *dev;
 	struct usb_hub *hub;
-	struct usb_hub_status hubsts;
 	u16 hubstatus;
 	u16 hubchange;
 	u16 portstatus;
@@ -991,11 +1032,11 @@
 			dev_dbg (&hub->intf->dev, "resetting for error %d\n",
 				hub->error);
 
-			if (usb_hub_reset(hub)) {
+			if (hub_reset(hub)) {
 				dev_dbg (&hub->intf->dev,
 					"can't reset; disconnecting\n");
 				up(&hub->khubd_sem);
-				usb_hub_disconnect(dev);
+				hub_start_disconnect(dev);
 				continue;
 			}
 
@@ -1004,18 +1045,18 @@
 		}
 
 		for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
-			ret = usb_hub_port_status(dev, i, &portstatus, &portchange);
+			ret = hub_port_status(dev, i, &portstatus, &portchange);
 			if (ret < 0) {
 				continue;
 			}
 
 			if (portchange & USB_PORT_STAT_C_CONNECTION) {
-				usb_hub_port_connect_change(hub, i, portstatus, portchange);
+				hub_port_connect_change(hub, i, portstatus, portchange);
 			} else if (portchange & USB_PORT_STAT_C_ENABLE) {
 				dev_dbg (hubdev (dev),
 					"port %d enable change, status %x\n",
 					i + 1, portstatus);
-				usb_clear_port_feature(dev,
+				clear_port_feature(dev,
 					i + 1, USB_PORT_FEAT_C_ENABLE);
 
 				/*
@@ -1032,7 +1073,7 @@
 					    "disabled by hub (EMI?), "
 					    "re-enabling...",
 						i + 1);
-					usb_hub_port_connect_change(hub,
+					hub_port_connect_change(hub,
 						i, portstatus, portchange);
 				}
 			}
@@ -1041,7 +1082,7 @@
 				dev_dbg (&hub->intf->dev,
 					"suspend change on port %d\n",
 					i + 1);
-				usb_clear_port_feature(dev,
+				clear_port_feature(dev,
 					i + 1,  USB_PORT_FEAT_C_SUSPEND);
 			}
 			
@@ -1049,35 +1090,33 @@
 				dev_err (&hub->intf->dev,
 					"over-current change on port %d\n",
 					i + 1);
-				usb_clear_port_feature(dev,
+				clear_port_feature(dev,
 					i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
-				usb_hub_power_on(hub);
+				hub_power_on(hub);
 			}
 
 			if (portchange & USB_PORT_STAT_C_RESET) {
 				dev_dbg (&hub->intf->dev,
 					"reset change on port %d\n",
 					i + 1);
-				usb_clear_port_feature(dev,
+				clear_port_feature(dev,
 					i + 1, USB_PORT_FEAT_C_RESET);
 			}
 		} /* end for i */
 
 		/* deal with hub status changes */
-		if (usb_get_hub_status(dev, &hubsts) < 0)
+		if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
 			dev_err (&hub->intf->dev, "get_hub_status failed\n");
 		else {
-			hubstatus = le16_to_cpup(&hubsts.wHubStatus);
-			hubchange = le16_to_cpup(&hubsts.wHubChange);
 			if (hubchange & HUB_CHANGE_LOCAL_POWER) {
 				dev_dbg (&hub->intf->dev, "power change\n");
-				usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
+				clear_hub_feature(dev, C_HUB_LOCAL_POWER);
 			}
 			if (hubchange & HUB_CHANGE_OVERCURRENT) {
 				dev_dbg (&hub->intf->dev, "overcurrent change\n");
 				wait_ms(500);	/* Cool down */
-				usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
-                        	usb_hub_power_on(hub);
+				clear_hub_feature(dev, C_HUB_OVER_CURRENT);
+                        	hub_power_on(hub);
 			}
 		}
 		up(&hub->khubd_sem);
@@ -1086,7 +1125,7 @@
 	spin_unlock_irqrestore(&hub_event_lock, flags);
 }
 
-static int usb_hub_thread(void *__hub)
+static int hub_thread(void *__hub)
 {
 	/*
 	 * This thread doesn't need any user-level access,
@@ -1098,13 +1137,13 @@
 
 	/* Send me a signal to get me die (for debugging) */
 	do {
-		usb_hub_events();
+		hub_events();
 		wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
 		if (current->flags & PF_FREEZE)
 			refrigerator(PF_IOTHREAD);
 	} while (!signal_pending(current));
 
-	dbg("usb_hub_thread exiting");
+	dbg("hub_thread exiting");
 	complete_and_exit(&khubd_exited, 0);
 }
 
@@ -1139,7 +1178,7 @@
 		return -1;
 	}
 
-	pid = kernel_thread(usb_hub_thread, NULL,
+	pid = kernel_thread(hub_thread, NULL,
 		CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	if (pid >= 0) {
 		khubd_pid = pid;
@@ -1149,7 +1188,7 @@
 
 	/* Fall through if kernel_thread failed */
 	usb_deregister(&hub_driver);
-	err("failed to start usb_hub_thread");
+	err("failed to start hub_thread");
 
 	return -1;
 }
@@ -1212,8 +1251,8 @@
 	down(&usb_address0_sem);
 
 	/* Send a reset to the device */
-	if (usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
-		usb_hub_port_disable(parent, port);
+	if (hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
+		hub_port_disable(parent, port);
 		up(&usb_address0_sem);
 		kfree(descriptor);
 		return(-ENODEV);
@@ -1223,7 +1262,7 @@
 	ret = usb_set_address(dev);
 	if (ret < 0) {
 		err("USB device not accepting new address (error=%d)", ret);
-		usb_hub_port_disable(parent, port);
+		hub_port_disable(parent, port);
 		up(&usb_address0_sem);
 		kfree(descriptor);
 		return ret;
diff -urN linux-2.5.70-bk15/drivers/usb/core/hub.h linux-2.5.70-bk16/drivers/usb/core/hub.h
--- linux-2.5.70-bk15/drivers/usb/core/hub.h	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/core/hub.h	2003-06-11 04:48:08.000000000 -0700
@@ -174,7 +174,12 @@
 	struct urb		*urb;		/* for interrupt polling pipe */
 
 	/* buffer for urb ... 1 bit each for hub and children, rounded up */
-	char			buffer[(USB_MAXCHILDREN + 1 + 7) / 8];
+	char			(*buffer)[(USB_MAXCHILDREN + 1 + 7) / 8];
+	dma_addr_t		buffer_dma;	/* DMA address for buffer */
+	union {
+		struct usb_hub_status	hub;
+		struct usb_port_status	port;
+	}			*status;	/* buffer for status reports */
 
 	int			error;		/* last reported error */
 	int			nerrors;	/* track consecutive errors */
diff -urN linux-2.5.70-bk15/drivers/usb/core/inode.c linux-2.5.70-bk16/drivers/usb/core/inode.c
--- linux-2.5.70-bk15/drivers/usb/core/inode.c	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/core/inode.c	2003-06-11 04:48:08.000000000 -0700
@@ -282,13 +282,13 @@
 
 
 /* default file operations */
-static ssize_t default_read_file (struct file *file, char *buf,
+static ssize_t default_read_file (struct file *file, char __user *buf,
 				  size_t count, loff_t *ppos)
 {
 	return 0;
 }
 
-static ssize_t default_write_file (struct file *file, const char *buf,
+static ssize_t default_write_file (struct file *file, const char __user *buf,
 				   size_t count, loff_t *ppos)
 {
 	return count;
diff -urN linux-2.5.70-bk15/drivers/usb/gadget/net2280.c linux-2.5.70-bk16/drivers/usb/gadget/net2280.c
--- linux-2.5.70-bk15/drivers/usb/gadget/net2280.c	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/gadget/net2280.c	2003-06-11 04:48:08.000000000 -0700
@@ -20,10 +20,12 @@
  * short OUT transfers happen.)  Drivers can use the req->no_interrupt
  * hint to completely eliminate some IRQs, if a later IRQ is guaranteed
  * and DMA chaining is enabled.
+ *
+ * Note that almost all the errata workarounds here are only needed for
+ * rev1 chips.  Rev1a silicon (0110) fixes almost all of them.
  */
 
-// #define NET2280_DMA_OUT_WORKAROUND
-// #define USE_DMA_CHAINING
+#define USE_DMA_CHAINING
 
 
 /*
@@ -180,6 +182,13 @@
 		 * kicking in the "toggle-irrelevant" mode.
 		 */
 		tmp = USB_ENDPOINT_XFER_BULK;
+	} else if (tmp == USB_ENDPOINT_XFER_BULK) {
+		/* catch some particularly blatant driver bugs */
+		if ((dev->gadget.speed == USB_SPEED_HIGH
+					&& max != 512)
+				|| (dev->gadget.speed == USB_SPEED_FULL
+					&& max > 64))
+			return -ERANGE;
 	}
 	ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0;
 	tmp <<= ENDPOINT_TYPE;
@@ -252,9 +261,6 @@
 		udelay (1);
 		usec--;
 	} while (usec > 0);
-#ifdef DEBUG
-	if (done == 0) dump_stack (); 		/* ignore out_flush timeout */
-#endif
 	return -ETIMEDOUT;
 }
 
@@ -917,6 +923,8 @@
 					 */
 					if (read_fifo (ep, req)) {
 						done (ep, req, 0);
+						if (ep->num == 0)
+							allow_status (ep);
 						/* don't queue it */
 						req = 0;
 					} else
@@ -1194,9 +1202,12 @@
 	VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
 
 	/* set/clear, then synch memory views with the device */
-	if (value)
-		set_halt (ep);
-	else
+	if (value) {
+		if (ep->num == 0)
+			ep->dev->protocol_stall = 1;
+		else
+			set_halt (ep);
+	} else
 		clear_halt (ep);
 	(void) readl (&ep->regs->ep_rsp);
 
@@ -2042,7 +2053,8 @@
 			 * can decide to stall ep0 after that done() returns,
 			 * from non-irq context
 			 */
-			allow_status (ep);
+			if (!ep->stopped)
+				allow_status (ep);
 			req = 0;
 		} else {
 			if (!list_empty (&ep->queue) && !ep->stopped)
diff -urN linux-2.5.70-bk15/drivers/usb/host/ohci-q.c linux-2.5.70-bk16/drivers/usb/host/ohci-q.c
--- linux-2.5.70-bk15/drivers/usb/host/ohci-q.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/host/ohci-q.c	2003-06-11 04:48:08.000000000 -0700
@@ -377,12 +377,8 @@
 		ed->type = type;
 	}
 
-	/* FIXME:  Don't do this without knowing it's safe to clobber this
-	 * state/mode info.  Currently the upper layers don't support such
-	 * guarantees; we're lucky changing config/altsetting is rare.
-	 * The state/mode info also changes during enumeration: set_address
-	 * uses the 'wrong' device address, and ep0 maxpacketsize will often
-	 * improve on the initial value.
+	/* NOTE: only ep0 currently needs this "re"init logic, during
+	 * enumeration (after set_address, or if ep0 maxpacket >8).
 	 */
   	if (ed->state == ED_IDLE) {
 		u32	info;
diff -urN linux-2.5.70-bk15/drivers/usb/image/hpusbscsi.c linux-2.5.70-bk16/drivers/usb/image/hpusbscsi.c
--- linux-2.5.70-bk15/drivers/usb/image/hpusbscsi.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/image/hpusbscsi.c	2003-06-11 04:48:08.000000000 -0700
@@ -45,7 +45,7 @@
 	struct usb_host_interface *altsetting =	intf->altsetting;
 	struct hpusbscsi *new;
 	int error = -ENOMEM;
-	int i, result;
+	int i;
 
 	if (altsetting->desc.bNumEndpoints != 3) {
 		printk (KERN_ERR "Wrong number of endpoints\n");
diff -urN linux-2.5.70-bk15/drivers/usb/media/vicam.c linux-2.5.70-bk16/drivers/usb/media/vicam.c
--- linux-2.5.70-bk15/drivers/usb/media/vicam.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/media/vicam.c	2003-06-11 04:48:08.000000000 -0700
@@ -1101,6 +1101,52 @@
 				((struct vicam_camera *)data)->gain);
 }
 
+static int
+vicam_write_proc_shutter(struct file *file, const char *buffer,
+			 unsigned long count, void *data)
+{
+	u16 stmp;
+	char kbuf[8];
+	struct vicam_camera *cam = (struct vicam_camera *) data;
+
+	if (count > 6)
+		return -EINVAL;
+
+	if (copy_from_user(kbuf, buffer, count))
+		return -EFAULT;
+
+	stmp = (u16) simple_strtoul(kbuf, NULL, 10);
+	if (stmp < 4 || stmp > 32000)
+		return -EINVAL;
+
+	cam->shutter_speed = stmp;
+
+	return count;
+}
+
+static int
+vicam_write_proc_gain(struct file *file, const char *buffer,
+		      unsigned long count, void *data)
+{
+	u16 gtmp;
+	char kbuf[8];
+
+	struct vicam_camera *cam = (struct vicam_camera *) data;
+
+	if (count > 4)
+		return -EINVAL;
+
+	if (copy_from_user(kbuf, buffer, count))
+		return -EFAULT;
+
+	gtmp = (u16) simple_strtoul(kbuf, NULL, 10);
+	if (gtmp > 255)
+		return -EINVAL;
+	cam->gain = gtmp;
+
+	return count;
+}
+
 static void
 vicam_create_proc_root(void)
 {
@@ -1142,18 +1188,21 @@
 	if ( !cam->proc_dir )
 		return; // FIXME: We should probably return an error here
 	
-	ent =
-	    create_proc_entry("shutter", S_IFREG | S_IRUGO, cam->proc_dir);
+	ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR,
+				cam->proc_dir);
 	if (ent) {
 		ent->data = cam;
 		ent->read_proc = vicam_read_proc_shutter;
+		ent->write_proc = vicam_write_proc_shutter;
 		ent->size = 64;
 	}
 
-	ent = create_proc_entry("gain", S_IFREG | S_IRUGO , cam->proc_dir);
-	if ( ent ) {
+	ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR,
+				cam->proc_dir);
+	if (ent) {
 		ent->data = cam;
 		ent->read_proc = vicam_read_proc_gain;
+		ent->write_proc = vicam_write_proc_gain;
 		ent->size = 64;
 	}
 }
diff -urN linux-2.5.70-bk15/drivers/usb/net/catc.c linux-2.5.70-bk16/drivers/usb/net/catc.c
--- linux-2.5.70-bk15/drivers/usb/net/catc.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/net/catc.c	2003-06-11 04:48:08.000000000 -0700
@@ -63,6 +63,8 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
+static const char driver_name[] = "catc";
+
 /*
  * Some defines.
  */ 
@@ -677,7 +679,7 @@
         /* get driver info */
         case ETHTOOL_GDRVINFO: {
                 struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-                strncpy(info.driver, SHORT_DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
+                strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
                 strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
 		usb_make_path (catc->usbdev, info.bus_info, sizeof info.bus_info);
                 if (copy_to_user(useraddr, &info, sizeof(info)))
@@ -978,7 +980,7 @@
 
 static struct usb_driver catc_driver = {
 	.owner =	THIS_MODULE,
-	.name =		"catc",
+	.name =		driver_name,
 	.probe =	catc_probe,
 	.disconnect =	catc_disconnect,
 	.id_table =	catc_id_table,
diff -urN linux-2.5.70-bk15/drivers/usb/net/kaweth.c linux-2.5.70-bk16/drivers/usb/net/kaweth.c
--- linux-2.5.70-bk15/drivers/usb/net/kaweth.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/net/kaweth.c	2003-06-11 04:48:08.000000000 -0700
@@ -114,6 +114,8 @@
 MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
 MODULE_LICENSE("GPL");
 
+static const char driver_name[] = "kaweth";
+
 static int kaweth_probe(
 		struct usb_interface *intf,
 		const struct usb_device_id *id	/* from id_table */
@@ -169,7 +171,7 @@
  ****************************************************************/
 static struct usb_driver kaweth_driver = {
 	.owner =	THIS_MODULE,
-	.name =		"kaweth",
+	.name =		driver_name,
 	.probe =	kaweth_probe,
 	.disconnect =	kaweth_disconnect,
 	.id_table =     usb_klsi_table,
@@ -670,7 +672,7 @@
 	switch (ethcmd) {
 	case ETHTOOL_GDRVINFO: {
 		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-		strlcpy(info.driver, "kaweth", sizeof(info.driver));
+		strlcpy(info.driver, driver_name, sizeof(info.driver));
 		if (copy_to_user(useraddr, &info, sizeof(info)))
 			return -EFAULT;
 		return 0;
diff -urN linux-2.5.70-bk15/drivers/usb/net/pegasus.c linux-2.5.70-bk16/drivers/usb/net/pegasus.c
--- linux-2.5.70-bk15/drivers/usb/net/pegasus.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/net/pegasus.c	2003-06-11 04:48:08.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 1999-2002 Petko Manolov (petkan@users.sourceforge.net)
+ *  Copyright (c) 1999-2003 Petko Manolov (petkan@users.sourceforge.net)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -45,7 +45,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.5.10 (2003/04/01)"
+#define DRIVER_VERSION "v0.5.12 (2003/06/06)"
 #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -564,7 +564,14 @@
 		dbg("%s: reset MAC", net->name);
 		pegasus->flags &= ~PEGASUS_RX_BUSY;
 		break;
+	case -EPIPE:		/* stall, or disconnect from TT */
+		/* FIXME schedule work to clear the halt */
+		warn("%s: no rx stall recovery", net->name);
+		return;
 	case -ENOENT:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		dbg("%s: rx unlink, %d", net->name, urb->status);
 		return;
 	default:
 		dbg("%s: RX status %d", net->name, urb->status);
@@ -604,6 +611,9 @@
 	pegasus->stats.rx_packets++;
 	pegasus->stats.rx_bytes += pkt_len;
 
+	if (pegasus->flags & PEGASUS_UNPLUG)
+		return;
+
 	spin_lock(&pegasus->rx_pool_lock);
 	pegasus->rx_skb = pull_skb(pegasus);
 	spin_unlock(&pegasus->rx_pool_lock);
@@ -631,24 +641,24 @@
 static void rx_fixup(unsigned long data)
 {
 	pegasus_t *pegasus;
+	unsigned long flags;
 
 	pegasus = (pegasus_t *) data;
+	if (pegasus->flags & PEGASUS_UNPLUG)
+		return;
 
-	spin_lock_irq(&pegasus->rx_pool_lock);
+	spin_lock_irqsave(&pegasus->rx_pool_lock, flags);
 	fill_skb_pool(pegasus);
-	spin_unlock_irq(&pegasus->rx_pool_lock);
 	if (pegasus->flags & PEGASUS_RX_URB_FAIL)
 		if (pegasus->rx_skb)
 			goto try_again;
 	if (pegasus->rx_skb == NULL) {
-		spin_lock_irq(&pegasus->rx_pool_lock);
 		pegasus->rx_skb = pull_skb(pegasus);
-		spin_unlock_irq(&pegasus->rx_pool_lock);
 	}
 	if (pegasus->rx_skb == NULL) {
 		warn("wow, low on memory");
 		tasklet_schedule(&pegasus->rx_tl);
-		return;
+		goto done;
 	}
 	usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
 			  usb_rcvbulkpipe(pegasus->usb, 1),
@@ -661,23 +671,41 @@
 	} else {
 		pegasus->flags &= ~PEGASUS_RX_URB_FAIL;
 	}
+done:
+	spin_unlock_irqrestore(&pegasus->rx_pool_lock, flags);
 }
 
 static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	pegasus_t *pegasus = urb->context;
+	struct net_device *net = pegasus->net;
 
 	if (!pegasus || !(pegasus->flags & PEGASUS_RUNNING))
 		return;
 
-	if (!netif_device_present(pegasus->net))
+	if (!netif_device_present(net))
 		return;
 
-	if (urb->status)
-		info("%s: TX status %d", pegasus->net->name, urb->status);
+	switch (urb->status) {
+	case -EPIPE:
+		/* FIXME schedule_work() to clear the tx halt */
+		netif_stop_queue(net);
+		warn("%s: no tx stall recovery", net->name);
+		return;
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		dbg("%s: tx unlink, %d", net->name, urb->status);
+		return;
+	default:
+		info("%s: TX status %d", net->name, urb->status);
+		/* FALL THROUGH */
+	case 0:
+		break;
+	}
 
-	pegasus->net->trans_start = jiffies;
-	netif_wake_queue(pegasus->net);
+	net->trans_start = jiffies;
+	netif_wake_queue(net);
 }
 
 static void intr_callback(struct urb *urb, struct pt_regs *regs)
@@ -754,8 +782,16 @@
 			  write_bulk_callback, pegasus);
 	if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) {
 		warn("failed tx_urb %d", res);
-		pegasus->stats.tx_errors++;
-		netif_start_queue(net);
+		switch (res) {
+		case -EPIPE:		/* stall, or disconnect from TT */
+			/* cleanup should already have been scheduled */
+			break;
+		case -ENODEV:		/* disconnect() upcoming */
+			break;
+		default:
+			pegasus->stats.tx_errors++;
+			netif_start_queue(net);
+		}
 	} else {
 		pegasus->stats.tx_packets++;
 		pegasus->stats.tx_bytes += skb->len;
@@ -903,6 +939,7 @@
 	netif_stop_queue(net);
 	if (!(pegasus->flags & PEGASUS_UNPLUG))
 		disable_net_traffic(pegasus);
+	tasklet_kill(&pegasus->rx_tl);
 	unlink_all_urbs(pegasus);
 
 	return 0;
@@ -920,11 +957,15 @@
 	switch (ethcmd) {
 	/* get driver-specific version/etc. info */
 	case ETHTOOL_GDRVINFO:{
-			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-			strlcpy(info.driver, driver_name,
-				sizeof (info.driver));
-			strlcpy(info.version, DRIVER_VERSION,
-				sizeof (info.version));
+			struct ethtool_drvinfo info;
+			memset (&info, 0, sizeof (info));
+			info.cmd = ETHTOOL_GDRVINFO;
+			strncpy(info.driver, driver_name,
+				sizeof (info.driver) - 1);
+			strncpy(info.version, DRIVER_VERSION,
+				sizeof (info.version) - 1);
+			usb_make_path(pegasus->usb, info.bus_info,
+				      sizeof (info.bus_info));
 			if (copy_to_user(useraddr, &info, sizeof (info)))
 				return -EFAULT;
 			return 0;
@@ -993,12 +1034,15 @@
 		return -EFAULT;
 	switch (cmd) {
 	case ETHTOOL_GDRVINFO:{
-			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-			strncpy(info.driver, driver_name, sizeof info.driver);
+			struct ethtool_drvinfo info;
+			memset (&info, 0, sizeof (info));
+			info.cmd = ETHTOOL_GDRVINFO;
+			strncpy(info.driver, driver_name,
+				sizeof (info.driver) - 1);
 			strncpy(info.version, DRIVER_VERSION,
-				ETHTOOL_BUSINFO_LEN);
+				sizeof (info.version) - 1);
 			usb_make_path(pegasus->usb, info.bus_info,
-				      sizeof info.bus_info);
+				      sizeof (info.bus_info));
 			if (copy_to_user(uaddr, &info, sizeof (info)))
 				return -EFAULT;
 			return 0;
@@ -1006,15 +1050,20 @@
 	case ETHTOOL_GSET:{
 			struct ethtool_cmd ecmd;
 			short lpa, bmcr;
+			u8 port;
 
-			memset(&ecmd, 0, sizeof ecmd);
+			memset(&ecmd, 0, sizeof (ecmd));
 			ecmd.supported = (SUPPORTED_10baseT_Half |
 					  SUPPORTED_10baseT_Full |
 					  SUPPORTED_100baseT_Half |
 					  SUPPORTED_100baseT_Full |
 					  SUPPORTED_Autoneg |
 					  SUPPORTED_TP | SUPPORTED_MII);
-			ecmd.port = PORT_TP;
+			get_registers(pegasus, Reg7b, 1, &port);
+			if (port == 0)
+				ecmd.port = PORT_MII;
+			else
+				ecmd.port = PORT_TP;
 			ecmd.transceiver = XCVR_INTERNAL;
 			ecmd.phy_address = pegasus->phy;
 			read_mii_word(pegasus, pegasus->phy, MII_BMCR, &bmcr);
@@ -1132,7 +1181,10 @@
 	set_register(pegasus, Reg1d, 0);
 	set_register(pegasus, Reg7b, 1);
 	mdelay(100);
-	set_register(pegasus, Reg7b, 2);
+	if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
+		set_register(pegasus, Reg7b, 0);
+	else
+		set_register(pegasus, Reg7b, 2);
 
 	set_register(pegasus, 0x83, data);
 	get_registers(pegasus, 0x83, 1, &data);
@@ -1253,7 +1305,6 @@
 	pegasus->flags |= PEGASUS_UNPLUG;
 	unregister_netdev(pegasus->net);
 	usb_put_dev(interface_to_usbdev(intf));
-	unlink_all_urbs(pegasus);
 	free_all_urbs(pegasus);
 	free_skb_pool(pegasus);
 	if (pegasus->rx_skb)
@@ -1263,7 +1314,6 @@
 }
 
 static struct usb_driver pegasus_driver = {
-	.owner = THIS_MODULE,
 	.name = driver_name,
 	.probe = pegasus_probe,
 	.disconnect = pegasus_disconnect,
diff -urN linux-2.5.70-bk15/drivers/usb/net/pegasus.h linux-2.5.70-bk16/drivers/usb/net/pegasus.h
--- linux-2.5.70-bk15/drivers/usb/net/pegasus.h	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/net/pegasus.h	2003-06-11 04:48:08.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2002 Petko Manolov - Petkan (petkan@users.sourceforge.net)
+ * Copyright (c) 1999-2003 Petko Manolov - Petkan (petkan@users.sourceforge.net)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as published
@@ -129,6 +129,7 @@
 #define	VENDOR_ELCON		0x0db7
 #define	VENDOR_ELSA		0x05cc
 #define	VENDOR_HAWKING		0x0e66
+#define	VENDOR_HP		0x03f0
 #define	VENDOR_IODATA		0x04bb
 #define	VENDOR_KINGSTON		0x0951
 #define	VENDOR_LANEED		0x056e
@@ -223,6 +224,8 @@
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
+		DEFAULT_GPIO_RESET | PEGASUS_II )	
 PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
diff -urN linux-2.5.70-bk15/drivers/usb/net/rtl8150.c linux-2.5.70-bk16/drivers/usb/net/rtl8150.c
--- linux-2.5.70-bk15/drivers/usb/net/rtl8150.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/net/rtl8150.c	2003-06-11 04:48:08.000000000 -0700
@@ -113,9 +113,11 @@
 static int rtl8150_probe(struct usb_interface *intf,
 			   const struct usb_device_id *id);
 
+static const char driver_name [] = "rtl8150";
+
 static struct usb_driver rtl8150_driver = {
 	.owner =	THIS_MODULE,
-	.name =		"rtl8150",
+	.name =		driver_name,
 	.probe =	rtl8150_probe,
 	.disconnect =	rtl8150_disconnect,
 	.id_table =	rtl8150_table,
@@ -684,7 +686,7 @@
 	case ETHTOOL_GDRVINFO:{
 		struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
 
-		strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
+		strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
 		strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
 		usb_make_path(dev->udev, info.bus_info, sizeof info.bus_info);
 		if (copy_to_user(uaddr, &info, sizeof(info)))
diff -urN linux-2.5.70-bk15/drivers/usb/storage/transport.c linux-2.5.70-bk16/drivers/usb/storage/transport.c
--- linux-2.5.70-bk15/drivers/usb/storage/transport.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/storage/transport.c	2003-06-11 04:48:08.000000000 -0700
@@ -48,6 +48,7 @@
 #include <linux/config.h>
 #include "transport.h"
 #include "protocol.h"
+#include "scsiglue.h"
 #include "usb.h"
 #include "debug.h"
 
@@ -303,6 +304,11 @@
 		US_DEBUGP("-- device NAKed\n");
 		return USB_STOR_XFER_ERROR;
 
+	/* babble - the device tried to send more than we wanted to read */
+	case -EOVERFLOW:
+		US_DEBUGP("-- Babble\n");
+		return USB_STOR_XFER_LONG;
+
 	/* the transfer was cancelled, presumably by an abort */
 	case -ECONNRESET:
 		US_DEBUGP("-- transfer cancelled\n");
@@ -525,6 +531,12 @@
 		return;
 	}
 
+	/* if the transport provided its own sense data, don't auto-sense */
+	if (result == USB_STOR_TRANSPORT_NO_SENSE) {
+		srb->result = SAM_STAT_CHECK_CONDITION;
+		return;
+	}
+
 	/* Determine if we need to auto-sense
 	 *
 	 * I normally don't use a flag like this, but it's almost impossible
@@ -764,7 +776,7 @@
 					srb->request_buffer, transfer_length,
 					srb->use_sg, &srb->resid);
 		US_DEBUGP("CBI data stage result is 0x%x\n", result);
-		if (result == USB_STOR_XFER_ERROR)
+		if (result > USB_STOR_XFER_STALLED)
 			return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -854,7 +866,7 @@
 					srb->request_buffer, transfer_length,
 					srb->use_sg, &srb->resid);
 		US_DEBUGP("CB data stage result is 0x%x\n", result);
-		if (result == USB_STOR_XFER_ERROR)
+		if (result > USB_STOR_XFER_STALLED)
 			return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -899,6 +911,7 @@
 	struct bulk_cs_wrap bcs;
 	unsigned int transfer_length = srb->request_bufflen;
 	int result;
+	int fake_sense = 0;
 
 	/* set up the command wrapper */
 	bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -936,6 +949,15 @@
 		US_DEBUGP("Bulk data transfer result 0x%x\n", result);
 		if (result == USB_STOR_XFER_ERROR)
 			return USB_STOR_TRANSPORT_ERROR;
+
+		/* If the device tried to send back more data than the
+		 * amount requested, the spec requires us to transfer
+		 * the CSW anyway.  Since there's no point retrying the
+		 * the command, we'll return fake sense data indicating
+		 * Illegal Request, Invalid Field in CDB.
+		 */
+		if (result == USB_STOR_XFER_LONG)
+			fake_sense = 1;
 	}
 
 	/* See flow chart on pg 15 of the Bulk Only Transport spec for
@@ -975,6 +997,14 @@
 	/* based on the status code, we report good or bad */
 	switch (bcs.Status) {
 		case US_BULK_STAT_OK:
+			/* device babbled -- return fake sense data */
+			if (fake_sense) {
+				memcpy(srb->sense_buffer, 
+				       usb_stor_sense_invalidCDB, 
+				       sizeof(usb_stor_sense_invalidCDB));
+				return USB_STOR_TRANSPORT_NO_SENSE;
+			}
+
 			/* command good -- note that data could be short */
 			return USB_STOR_TRANSPORT_GOOD;
 
diff -urN linux-2.5.70-bk15/drivers/usb/storage/transport.h linux-2.5.70-bk16/drivers/usb/storage/transport.h
--- linux-2.5.70-bk15/drivers/usb/storage/transport.h	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/storage/transport.h	2003-06-11 04:48:08.000000000 -0700
@@ -122,7 +122,8 @@
 #define USB_STOR_XFER_GOOD	0	/* good transfer                 */
 #define USB_STOR_XFER_SHORT	1	/* transferred less than expected */
 #define USB_STOR_XFER_STALLED	2	/* endpoint stalled              */
-#define USB_STOR_XFER_ERROR	3	/* transfer died in the middle   */
+#define USB_STOR_XFER_LONG	3	/* device tried to send too much */
+#define USB_STOR_XFER_ERROR	4	/* transfer died in the middle   */
 
 /*
  * Transport return codes
@@ -130,7 +131,8 @@
 
 #define USB_STOR_TRANSPORT_GOOD	   0   /* Transport good, command good	   */
 #define USB_STOR_TRANSPORT_FAILED  1   /* Transport good, command failed   */
-#define USB_STOR_TRANSPORT_ERROR   2   /* Transport bad (i.e. device dead) */
+#define USB_STOR_TRANSPORT_NO_SENSE 2  /* Command failed, no auto-sense    */
+#define USB_STOR_TRANSPORT_ERROR   3   /* Transport bad (i.e. device dead) */
 
 /*
  * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
diff -urN linux-2.5.70-bk15/drivers/usb/storage/usb.c linux-2.5.70-bk16/drivers/usb/storage/usb.c
--- linux-2.5.70-bk15/drivers/usb/storage/usb.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/storage/usb.c	2003-06-11 04:48:08.000000000 -0700
@@ -3,10 +3,11 @@
  * $Id: usb.c,v 1.75 2002/04/22 03:39:43 mdharm Exp $
  *
  * Current development and maintenance by:
- *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ *   (c) 1999-2003 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
  * Developed with the assistance of:
  *   (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
+ *   (c) 2003 Alan Stern (stern@rowland.harvard.edu)
  *
  * Initial work by:
  *   (c) 1999 Michael Gee (michael@linuxspecific.com)
@@ -297,7 +298,7 @@
 
 	/*
 	 * This thread doesn't need any user-level access,
-	 * so get rid of all our resources..
+	 * so get rid of all our resources.
 	 */
 	daemonize("usb-storage");
 
@@ -305,9 +306,6 @@
 
 	unlock_kernel();
 
-	/* set up for wakeups by new commands */
-	init_MUTEX_LOCKED(&us->sema);
-
 	/* signal that we've started the thread */
 	complete(&(us->notify));
 
@@ -366,17 +364,6 @@
 			us->srb->result = DID_BAD_TARGET << 16;
 		}
 
-		/* handle requests for EVPD, which most USB devices do
-		 * not support */
-		else if((us->srb->cmnd[0] == INQUIRY) &&
-				(us->srb->cmnd[1] & 0x1)) {
-				US_DEBUGP("Faking INQUIRY command for EVPD\n");
-				memcpy(us->srb->sense_buffer, 
-				       usb_stor_sense_invalidCDB, 
-				       sizeof(usb_stor_sense_invalidCDB));
-				us->srb->result = SAM_STAT_CHECK_CONDITION;
-		}
-
 		/* Handle those devices which need us to fake 
 		 * their inquiry data */
 		else if ((us->srb->cmnd[0] == INQUIRY) &&
@@ -432,272 +419,60 @@
 	return 0;
 }	
 
-/* Set up the URB and the usb_ctrlrequest.
- * us->dev_semaphore must already be locked.
- * Note that this function assumes that all the data in the us_data
- * structure is current.
- * Returns non-zero on failure, zero on success
- */ 
-static int usb_stor_allocate_urbs(struct us_data *us)
-{
-	/* calculate and store the pipe values */
-	us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0);
-	us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
-	us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
-	us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
-	us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, us->ep_int);
-
-	/* allocate the usb_ctrlrequest for control packets */
-	US_DEBUGP("Allocating usb_ctrlrequest\n");
-	us->dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
-	if (!us->dr) {
-		US_DEBUGP("allocation failed\n");
-		return 1;
-	}
-
-	/* allocate the URB we're going to use */
-	US_DEBUGP("Allocating URB\n");
-	us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!us->current_urb) {
-		US_DEBUGP("allocation failed\n");
-		return 2;
-	}
-
-	US_DEBUGP("Allocating scatter-gather request block\n");
-	us->current_sg = kmalloc(sizeof(*us->current_sg), GFP_KERNEL);
-	if (!us->current_sg) {
-		US_DEBUGP("allocation failed\n");
-		return 5;
-	}
-
-	return 0;	/* success */
-}
-
-/* Deallocate the URB, the usb_ctrlrequest, and the IRQ pipe.
- * us->dev_semaphore must already be locked.
- */
-static void usb_stor_deallocate_urbs(struct us_data *us)
-{
-	/* free the scatter-gather request block */
-	if (us->current_sg) {
-		kfree(us->current_sg);
-		us->current_sg = NULL;
-	}
-
-	/* free up the main URB for this device */
-	if (us->current_urb) {
-		US_DEBUGP("-- releasing main URB\n");
-		usb_free_urb(us->current_urb);
-		us->current_urb = NULL;
-	}
-
-	/* free the usb_ctrlrequest buffer */
-	if (us->dr) {
-		kfree(us->dr);
-		us->dr = NULL;
-	}
-
-	/* mark the device as gone */
-	usb_put_dev(us->pusb_dev);
-	us->pusb_dev = NULL;
-}
+/***********************************************************************
+ * Device probing and disconnecting
+ ***********************************************************************/
 
-/* Probe to see if a new device is actually a SCSI device */
-static int storage_probe(struct usb_interface *intf,
-			 const struct usb_device_id *id)
+/* Get the unusual_devs entries and the string descriptors */
+static void get_device_info(struct us_data *us,
+			struct us_unusual_dev *unusual_dev)
 {
-	struct usb_device *dev = interface_to_usbdev(intf);
-	int ifnum = intf->altsetting->desc.bInterfaceNumber;
-	int i;
-	const int id_index = id - storage_usb_ids; 
-	char mf[USB_STOR_STRING_LEN];		     /* manufacturer */
-	char prod[USB_STOR_STRING_LEN];		     /* product */
-	char serial[USB_STOR_STRING_LEN];	     /* serial number */
-	unsigned int flags;
-	struct us_unusual_dev *unusual_dev;
-	struct us_data *us = NULL;
-	int result;
-
-	/* these are temporary copies -- we test on these, then put them
-	 * in the us-data structure 
-	 */
-	struct usb_endpoint_descriptor *ep_in = NULL;
-	struct usb_endpoint_descriptor *ep_out = NULL;
-	struct usb_endpoint_descriptor *ep_int = NULL;
-	u8 subclass = 0;
-	u8 protocol = 0;
-
-	/* the altsetting on the interface we're probing that matched our
-	 * usb_match_id table
-	 */
-	struct usb_host_interface *altsetting =
-		intf[ifnum].altsetting + intf[ifnum].act_altsetting;
-	US_DEBUGP("act_altsetting is %d\n", intf[ifnum].act_altsetting);
-
-	/* clear the temporary strings */
-	memset(mf, 0, sizeof(mf));
-	memset(prod, 0, sizeof(prod));
-	memset(serial, 0, sizeof(serial));
-
-	/* 
-	 * Can we support this device, either because we know about it
-	 * from our unusual device list, or because it advertises that it's
-	 * compliant to the specification?
-	 *
-	 * id_index is calculated in the declaration to be the index number
-	 * of the match from the usb_device_id table, so we can find the
-	 * corresponding entry in the private table.
-	 */
-	US_DEBUGP("id_index calculated to be: %d\n", id_index);
-	US_DEBUGP("Array length appears to be: %d\n", sizeof(us_unusual_dev_list) / sizeof(us_unusual_dev_list[0]));
-	if (id_index <
-	    sizeof(us_unusual_dev_list) / sizeof(us_unusual_dev_list[0])) {
-		unusual_dev = &us_unusual_dev_list[id_index];
-		if (unusual_dev->vendorName)
-			US_DEBUGP("Vendor: %s\n", unusual_dev->vendorName);
-		if (unusual_dev->productName)
-			US_DEBUGP("Product: %s\n", unusual_dev->productName);
-	} else
-		/* no, we can't support it */
-		return -EIO;
-
-	/* At this point, we know we've got a live one */
-	US_DEBUGP("USB Mass Storage device detected\n");
-
-	/* Determine subclass and protocol, or copy from the interface */
-	subclass = unusual_dev->useProtocol;
-	protocol = unusual_dev->useTransport;
-	flags = unusual_dev->flags;
-
-	/*
-	 * Find the endpoints we need
-	 * We are expecting a minimum of 2 endpoints - in and out (bulk).
-	 * An optional interrupt is OK (necessary for CBI protocol).
-	 * We will ignore any others.
-	 */
-	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
-		struct usb_endpoint_descriptor *ep;
-
-		ep = &altsetting->endpoint[i].desc;
-
-		/* is it an BULK endpoint? */
-		if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-				== USB_ENDPOINT_XFER_BULK) {
-			/* BULK in or out? */
-			if (ep->bEndpointAddress & USB_DIR_IN)
-				ep_in = ep;
-			else
-				ep_out = ep;
-		}
-
-		/* is it an interrupt endpoint? */
-		else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-				== USB_ENDPOINT_XFER_INT) {
-			ep_int = ep;
-		}
-	}
-	US_DEBUGP("Endpoints: In: 0x%p Out: 0x%p Int: 0x%p (Period %d)\n",
-		  ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0);
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
-	if (protocol == US_PR_EUSB_SDDR09 || protocol == US_PR_DPCM_USB) {
-		/* set the configuration -- STALL is an acceptable response here */
-		result = usb_set_configuration(dev, 1);
-
-		US_DEBUGP("Result from usb_set_configuration is %d\n", result);
-		if (result == -EPIPE) {
-			US_DEBUGP("-- stall on control interface\n");
-		} else if (result != 0) {
-			/* it's not a stall, but another error -- time to bail */
-			US_DEBUGP("-- Unknown error.  Rejecting device\n");
-			return -EIO;
-		}
-	}
-#endif
+	struct usb_device *dev = us->pusb_dev;
 
-	/* Do some basic sanity checks, and bail if we find a problem */
-	if (!ep_in || !ep_out || (protocol == US_PR_CBI && !ep_int)) {
-		US_DEBUGP("Endpoint sanity check failed! Rejecting dev.\n");
-		return -EIO;
-	}
+	if (unusual_dev->vendorName)
+		US_DEBUGP("Vendor: %s\n", unusual_dev->vendorName);
+	if (unusual_dev->productName)
+		US_DEBUGP("Product: %s\n", unusual_dev->productName);
 
-	/* At this point, we've decided to try to use the device */
-	usb_get_dev(dev);
+	/* Store the entries */
+	us->unusual_dev = unusual_dev;
+	us->subclass = unusual_dev->useProtocol;
+	us->protocol = unusual_dev->useTransport;
+	us->flags = unusual_dev->flags;
 
-	/* fetch the strings */
+	/* Read the device's string descriptors */
 	if (dev->descriptor.iManufacturer)
 		usb_string(dev, dev->descriptor.iManufacturer, 
-			   mf, sizeof(mf));
+			   us->vendor, sizeof(us->vendor));
 	if (dev->descriptor.iProduct)
 		usb_string(dev, dev->descriptor.iProduct, 
-			   prod, sizeof(prod));
-	if (dev->descriptor.iSerialNumber && !(flags & US_FL_IGNORE_SER))
+			   us->product, sizeof(us->product));
+	if (dev->descriptor.iSerialNumber && !(us->flags & US_FL_IGNORE_SER))
 		usb_string(dev, dev->descriptor.iSerialNumber, 
-			   serial, sizeof(serial));
-
-	/* New device -- allocate memory and initialize */
-	if ((us = (struct us_data *)kmalloc(sizeof(struct us_data), 
-					    GFP_KERNEL)) == NULL) {
-		printk(KERN_WARNING USB_STORAGE "Out of memory\n");
-		usb_put_dev(dev);
-		return -ENOMEM;
-	}
-	memset(us, 0, sizeof(struct us_data));
-
-	/* Initialize the mutexes only when the struct is new */
-	init_completion(&(us->notify));
-	init_MUTEX_LOCKED(&(us->dev_semaphore));
-
-	/* copy over the subclass and protocol data */
-	us->subclass = subclass;
-	us->protocol = protocol;
-	us->flags = flags;
-	us->unusual_dev = unusual_dev;
+			   us->serial, sizeof(us->serial));
 
-	/* copy over the endpoint data */
-	us->ep_in = ep_in->bEndpointAddress & 
-		USB_ENDPOINT_NUMBER_MASK;
-	us->ep_out = ep_out->bEndpointAddress & 
-		USB_ENDPOINT_NUMBER_MASK;
-	if (ep_int) {
-		us->ep_int = ep_int->bEndpointAddress & 
-			USB_ENDPOINT_NUMBER_MASK;
-		us->ep_bInterval = ep_int->bInterval;
-	}
-	else
-		us->ep_int = us->ep_bInterval = 0;
-
-	/* establish the connection to the new device */
-	us->ifnum = ifnum;
-	us->pusb_dev = dev;
-
-	/* copy over the identifiying strings */
-	strncpy(us->vendor, mf, USB_STOR_STRING_LEN);
-	strncpy(us->product, prod, USB_STOR_STRING_LEN);
-	strncpy(us->serial, serial, USB_STOR_STRING_LEN);
+	/* Use the unusual_dev strings if the device didn't provide them */
 	if (strlen(us->vendor) == 0) {
 		if (unusual_dev->vendorName)
 			strncpy(us->vendor, unusual_dev->vendorName,
-				USB_STOR_STRING_LEN);
+				sizeof(us->vendor) - 1);
 		else
-			strncpy(us->vendor, "Unknown",
-				USB_STOR_STRING_LEN);
+			strcpy(us->vendor, "Unknown");
 	}
 	if (strlen(us->product) == 0) {
 		if (unusual_dev->productName)
 			strncpy(us->product, unusual_dev->productName,
-				USB_STOR_STRING_LEN);
+				sizeof(us->product) - 1);
 		else
-			strncpy(us->product, "Unknown",
-				USB_STOR_STRING_LEN);
+			strcpy(us->product, "Unknown");
 	}
 	if (strlen(us->serial) == 0)
-		strncpy(us->serial, "None", USB_STOR_STRING_LEN);
+		strcpy(us->serial, "None");
+}
 
-	/* 
-	 * Set the handler pointers based on the protocol
-	 * Again, this data is persistent across reattachments
-	 */
+/* Get the transport settings */
+static int get_transport(struct us_data *us)
+{
 	switch (us->protocol) {
 	case US_PR_CB:
 		us->transport_name = "Control/Bulk";
@@ -783,15 +558,19 @@
 #endif
 
 	default:
-		/* us->transport_name = "Unknown"; */
-		goto BadDevice;
+		return -EIO;
 	}
 	US_DEBUGP("Transport: %s\n", us->transport_name);
 
 	/* fix for single-lun devices */
 	if (us->flags & US_FL_SINGLE_LUN)
 		us->max_lun = 0;
+	return 0;
+}
 
+/* Get the protocol settings */
+static int get_protocol(struct us_data *us)
+{
 	switch (us->subclass) {
 	case US_SC_RBC:
 		us->protocol_name = "Reduced Block Commands (RBC)";
@@ -834,173 +613,335 @@
 #endif
 
 	default:
-		/* us->protocol_name = "Unknown"; */
-		goto BadDevice;
+		return -EIO;
 	}
 	US_DEBUGP("Protocol: %s\n", us->protocol_name);
+	return 0;
+}
 
-	/* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
-	if (usb_stor_allocate_urbs(us))
-		goto BadDevice;
+/* Get the pipe settings */
+static int get_pipes(struct us_data *us)
+{
+	struct usb_host_interface *altsetting =
+		&us->pusb_intf->altsetting[us->pusb_intf->act_altsetting];
+	int i;
+	struct usb_endpoint_descriptor *ep;
+	struct usb_endpoint_descriptor *ep_in = NULL;
+	struct usb_endpoint_descriptor *ep_out = NULL;
+	struct usb_endpoint_descriptor *ep_int = NULL;
+
+	/*
+	 * Find the endpoints we need.
+	 * We are expecting a minimum of 2 endpoints - in and out (bulk).
+	 * An optional interrupt is OK (necessary for CBI protocol).
+	 * We will ignore any others.
+	 */
+	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
+		ep = &altsetting->endpoint[i].desc;
+
+		/* Is it a BULK endpoint? */
+		if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+				== USB_ENDPOINT_XFER_BULK) {
+			/* BULK in or out? */
+			if (ep->bEndpointAddress & USB_DIR_IN)
+				ep_in = ep;
+			else
+				ep_out = ep;
+		}
+
+		/* Is it an interrupt endpoint? */
+		else if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+				== USB_ENDPOINT_XFER_INT) {
+			ep_int = ep;
+		}
+	}
+	US_DEBUGP("Endpoints: In: 0x%p Out: 0x%p Int: 0x%p (Period %d)\n",
+		  ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0);
+
+	if (!ep_in || !ep_out || (us->protocol == US_PR_CBI && !ep_int)) {
+		US_DEBUGP("Endpoint sanity check failed! Rejecting dev.\n");
+		return -EIO;
+	}
+
+	/* Calculate and store the pipe values */
+	us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0);
+	us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
+	us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev,
+		ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+	us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, 
+		ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+	if (ep_int) {
+		us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev,
+			ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+		us->ep_bInterval = ep_int->bInterval;
+	}
+	return 0;
+}
+
+/* Initialize all the dynamic resources we need */
+static int usb_stor_acquire_resources(struct us_data *us)
+{
+	int p;
+
+	/* Allocate the USB control blocks */
+	US_DEBUGP("Allocating usb_ctrlrequest\n");
+	us->dr = kmalloc(sizeof(*us->dr), GFP_KERNEL);
+	if (!us->dr) {
+		US_DEBUGP("allocation failed\n");
+		return -ENOMEM;
+	}
+
+	US_DEBUGP("Allocating URB\n");
+	us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!us->current_urb) {
+		US_DEBUGP("allocation failed\n");
+		return -ENOMEM;
+	}
+
+	US_DEBUGP("Allocating scatter-gather request block\n");
+	us->current_sg = kmalloc(sizeof(*us->current_sg), GFP_KERNEL);
+	if (!us->current_sg) {
+		US_DEBUGP("allocation failed\n");
+		return -ENOMEM;
+	}
+
+	/* Lock the device while we carry out the next two operations */
+	down(&us->dev_semaphore);
 
 	/* For bulk-only devices, determine the max LUN value */
 	if (us->protocol == US_PR_BULK)
 		us->max_lun = usb_stor_Bulk_max_lun(us);
 
-	/*
-	 * Since this is a new device, we need to generate a scsi 
-	 * host definition, and register with the higher SCSI layers
-	 */
-
 	/* Just before we start our control thread, initialize
 	 * the device if it needs initialization */
-	if (unusual_dev && unusual_dev->initFunction)
-		unusual_dev->initFunction(us);
+	if (us->unusual_dev->initFunction)
+		us->unusual_dev->initFunction(us);
 
-	/* start up our control thread */
+	up(&us->dev_semaphore);
+
+	/* Start up our control thread */
 	atomic_set(&us->sm_state, US_STATE_IDLE);
-	us->pid = kernel_thread(usb_stor_control_thread, us,
-				CLONE_VM);
-	if (us->pid < 0) {
+	p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
+	if (p < 0) {
 		printk(KERN_WARNING USB_STORAGE 
 		       "Unable to start control thread\n");
-		goto BadDevice;
+		return p;
 	}
+	us->pid = p;
 
-	/* wait for the thread to start */
+	/* Wait for the thread to start */
 	wait_for_completion(&(us->notify));
 
-	/* unlock the device pointers */
-	up(&(us->dev_semaphore));
-
-	/* now register	*/
+	/*
+	 * Since this is a new device, we need to register a SCSI
+	 * host definition with the higher SCSI layers.
+	 */
 	us->host = scsi_register(&usb_stor_host_template, sizeof(us));
 	if (!us->host) {
 		printk(KERN_WARNING USB_STORAGE
 			"Unable to register the scsi host\n");
+		return -EBUSY;
+	}
+
+	/* Set the hostdata to prepare for scanning */
+	us->host->hostdata[0] = (unsigned long) us;
 
-		/* tell the control thread to exit */
+	return 0;
+}
+
+/* Dissociate from the USB device */
+static void dissociate_dev(struct us_data *us)
+{
+	US_DEBUGP("-- %s\n", __FUNCTION__);
+	down(&us->dev_semaphore);
+	usb_set_intfdata(us->pusb_intf, NULL);
+	usb_put_dev(us->pusb_dev);
+	us->pusb_dev = NULL;
+	us->pusb_intf = NULL;
+	up(&us->dev_semaphore);
+}
+
+/* Release all our static and dynamic resources */
+void usb_stor_release_resources(struct us_data *us)
+{
+	/*
+	 * The host must already have been removed
+	 * and dissociate_dev() must have been called.
+	 */
+
+	/* Finish the SCSI host removal sequence */
+	if (us->host) {
+		(struct us_data *) us->host->hostdata[0] = NULL;
+		scsi_unregister(us->host);
+	}
+
+	/* Kill the control thread
+	 *
+	 * Enqueue the command, wake up the thread, and wait for 
+	 * notification that it has exited.
+	 */
+	if (us->pid) {
+		US_DEBUGP("-- sending exit command to thread\n");
+		BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE);
 		us->srb = NULL;
-		up(&us->sema);
-		wait_for_completion(&us->notify);
+		up(&(us->sema));
+		wait_for_completion(&(us->notify));
+	}
 
-		/* re-lock the device pointers */
-		down(&us->dev_semaphore);
-		goto BadDevice;
+	/* Call the destructor routine, if it exists */
+	if (us->extra_destructor) {
+		US_DEBUGP("-- calling extra_destructor()\n");
+		us->extra_destructor(us->extra);
+	}
+
+	/* Destroy the extra data */
+	if (us->extra) {
+		kfree(us->extra);
+	}
+
+	/* Free the USB control blocks */
+	if (us->current_sg)
+		kfree(us->current_sg);
+	if (us->current_urb)
+		usb_free_urb(us->current_urb);
+	if (us->dr)
+		kfree(us->dr);
+
+	/* Free the structure itself */
+	kfree(us);
+	US_DEBUGP("-- %s finished\n", __FUNCTION__);
+}
+
+/* Probe to see if we can drive a newly-connected USB device */
+static int storage_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
+{
+	struct us_data *us;
+	const int id_index = id - storage_usb_ids; 
+	int result;
+
+	US_DEBUGP("USB Mass Storage device detected\n");
+	US_DEBUGP("act_altsetting is %d, id_index is %d\n",
+			intf->act_altsetting, id_index);
+
+	/* Allocate the us_data structure and initialize the mutexes */
+	us = (struct us_data *) kmalloc(sizeof(*us), GFP_KERNEL);
+	if (!us) {
+		printk(KERN_WARNING USB_STORAGE "Out of memory\n");
+		return -ENOMEM;
 	}
+	memset(us, 0, sizeof(struct us_data));
+	init_MUTEX(&(us->dev_semaphore));
+	init_MUTEX_LOCKED(&(us->sema));
+	init_completion(&(us->notify));
+
+	/* Fill in the device-related fields */
+	us->pusb_dev = interface_to_usbdev(intf);
+	us->pusb_intf = intf;
+	us->ifnum = intf->altsetting->desc.bInterfaceNumber;
+
+	/* Store our private data in the interface and increment the
+	 * device's reference count */
+	usb_set_intfdata(intf, us);
+	usb_get_dev(us->pusb_dev);
+
+	/*
+	 * Get the unusual_devs entries and the descriptors
+	 *
+	 * id_index is calculated in the declaration to be the index number
+	 * of the match from the usb_device_id table, so we can find the
+	 * corresponding entry in the private table.
+	 */
+	get_device_info(us, &us_unusual_dev_list[id_index]);
 
-	/* set the hostdata to prepare for scanning */
-	us->host->hostdata[0] = (unsigned long)us;
+#ifdef CONFIG_USB_STORAGE_SDDR09
+	if (us->protocol == US_PR_EUSB_SDDR09 ||
+			us->protocol == US_PR_DPCM_USB) {
+		/* set the configuration -- STALL is an acceptable response here */
+		result = usb_set_configuration(us->pusb_dev, 1);
 
-	/* now add the host */
+		US_DEBUGP("Result from usb_set_configuration is %d\n", result);
+		if (result == -EPIPE) {
+			US_DEBUGP("-- stall on control interface\n");
+		} else if (result != 0) {
+			/* it's not a stall, but another error -- time to bail */
+			US_DEBUGP("-- Unknown error.  Rejecting device\n");
+			goto BadDevice;
+		}
+	}
+#endif
+
+	/* Get the transport, protocol, and pipe settings */
+	result = get_transport(us);
+	if (result)
+		goto BadDevice;
+	result = get_protocol(us);
+	if (result)
+		goto BadDevice;
+	result = get_pipes(us);
+	if (result)
+		goto BadDevice;
+
+	/* Acquire all the other resources */
+	result = usb_stor_acquire_resources(us);
+	if (result)
+		goto BadDevice;
+
+	/* Finally, add the host (this does SCSI device scanning) */
 	result = scsi_add_host(us->host, &intf->dev);
 	if (result) {
 		printk(KERN_WARNING USB_STORAGE
 			"Unable to add the scsi host\n");
-
-		/* tell the control thread to exit */
-		us->srb = NULL;
-		up(&us->sema);
-		wait_for_completion(&us->notify);
-
-		/* re-lock the device pointers */
-		down(&us->dev_semaphore);
 		goto BadDevice;
 	}
 
 	printk(KERN_DEBUG 
 	       "WARNING: USB Mass Storage data integrity not assured\n");
 	printk(KERN_DEBUG 
-	       "USB Mass Storage device found at %d\n", dev->devnum);
-
-	/* save a pointer to our structure */
-	usb_set_intfdata(intf, us);
+	       "USB Mass Storage device found at %d\n", us->pusb_dev->devnum);
 	return 0;
 
-	/* we come here if there are any problems */
-	/* us->dev_semaphore must be locked */
+	/* We come here if there are any problems */
 BadDevice:
 	US_DEBUGP("storage_probe() failed\n");
-	usb_stor_deallocate_urbs(us);
-	up(&us->dev_semaphore);
-	kfree(us);
-	return -EIO;
+	dissociate_dev(us);
+	usb_stor_release_resources(us);
+	return result;
 }
 
 /* Handle a disconnect event from the USB core */
 static void storage_disconnect(struct usb_interface *intf)
 {
-	struct us_data *us;
+	struct us_data *us = usb_get_intfdata(intf);
 	struct scsi_device *sdev;
 
 	US_DEBUGP("storage_disconnect() called\n");
 
-	us = usb_get_intfdata(intf);
-	usb_set_intfdata(intf, NULL);
-
-	/* set devices offline -- need host lock for this */
+	/* Set devices offline -- need host lock for this */
 	scsi_lock(us->host);
 	list_for_each_entry(sdev, &us->host->my_devices, siblings)
 		sdev->online = 0;
 	scsi_unlock(us->host);
 
-	/* prevent new USB transfers and stop the current command */
+	/* Prevent new USB transfers and stop the current command */
 	set_bit(US_FLIDX_DISCONNECTING, &us->flags);
 	usb_stor_stop_transport(us);
 
-	/* lock device access -- no need to unlock, as we're going away */
-	down(&(us->dev_semaphore));
+	/* Dissociate from the USB device */
+	dissociate_dev(us);
 
-	/* TODO: somehow, wait for the device to
-	 * be 'idle' (tasklet completion) */
-
-	/* remove the pointer to the data structure we were using */
-	(struct us_data*)us->host->hostdata[0] = NULL;
-
-	/* begin SCSI host removal sequence */
-	if(scsi_remove_host(us->host)) {
-		US_DEBUGP("-- SCSI refused to unregister\n");
+	/* Begin the SCSI host removal sequence */
+	if (scsi_remove_host(us->host)) {
+		US_DEBUGP("-- SCSI refused to remove the host\n");
 		BUG();
 		return;
-	};
-
-	/* finish SCSI host removal sequence */
-	scsi_unregister(us->host);
-
-	/* Kill the control threads
-	 *
-	 * Enqueue the command, wake up the thread, and wait for 
-	 * notification that it has exited.
-	 */
-	US_DEBUGP("-- sending exit command to thread\n");
-	BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE);
-	us->srb = NULL;
-	up(&(us->sema));
-	wait_for_completion(&(us->notify));
-
-	/* free allocated urbs */
-	usb_stor_deallocate_urbs(us);
-
-	/* If there's extra data in the us_data structure then
-	 * free that first */
-	if (us->extra) {
-		/* call the destructor routine, if it exists */
-		if (us->extra_destructor) {
-			US_DEBUGP("-- calling extra_destructor()\n");
-			us->extra_destructor(us->extra);
-		}
-
-		/* destroy the extra data */
-		US_DEBUGP("-- freeing the data structure\n");
-		kfree(us->extra);
 	}
 
-	/* up the semaphore so auto-code-checkers won't complain about
-	 * the down/up imbalance */
-	up(&(us->dev_semaphore));
+	/* TODO: somehow, wait for the device to
+	 * be 'idle' (tasklet completion) */
 
-	/* free the structure itself */
-	kfree (us);
+	/* Release all our other resources */
+	usb_stor_release_resources(us);
 }
 
 /***********************************************************************
diff -urN linux-2.5.70-bk15/drivers/usb/storage/usb.h linux-2.5.70-bk16/drivers/usb/storage/usb.h
--- linux-2.5.70-bk15/drivers/usb/storage/usb.h	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/usb/storage/usb.h	2003-06-11 04:48:08.000000000 -0700
@@ -107,6 +107,7 @@
 	 */
 	struct semaphore	dev_semaphore;	 /* protect pusb_dev */
 	struct usb_device	*pusb_dev;	 /* this usb_device */
+	struct usb_interface	*pusb_intf;	 /* this interface */
 	unsigned long		flags;		 /* from filter initially */
 	unsigned int		send_bulk_pipe;	 /* cached pipe values */
 	unsigned int		recv_bulk_pipe;
@@ -114,7 +115,7 @@
 	unsigned int		recv_ctrl_pipe;
 	unsigned int		recv_intr_pipe;
 
-	/* information about the device -- always good */
+	/* information about the device */
 	char			vendor[USB_STOR_STRING_LEN];
 	char			product[USB_STOR_STRING_LEN];
 	char			serial[USB_STOR_STRING_LEN];
@@ -124,11 +125,7 @@
 	u8			protocol;
 	u8			max_lun;
 
-	/* information about the device -- only good if device is attached */
 	u8			ifnum;		 /* interface number   */
-	u8			ep_in;		 /* bulk in endpoint   */
-	u8			ep_out;		 /* bulk out endpoint  */
-	u8			ep_int;		 /* interrupt endpoint */ 
 	u8			ep_bInterval;	 /* interrupt interval */ 
 
 	/* function pointers for this device */
diff -urN linux-2.5.70-bk15/drivers/video/pm2fb.c linux-2.5.70-bk16/drivers/video/pm2fb.c
--- linux-2.5.70-bk15/drivers/video/pm2fb.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/drivers/video/pm2fb.c	2003-06-11 04:48:08.000000000 -0700
@@ -1186,10 +1186,6 @@
 #endif
 
 	memset(pci, 0, sizeof(struct pm2pci_par));
-	if (!pci_present()) {
-		DPRINTK("no PCI bus found.\n");
-		return 0;
-	}
 	DPRINTK("scanning PCI bus for known chipsets...\n");
 
 	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
diff -urN linux-2.5.70-bk15/fs/devfs/base.c linux-2.5.70-bk16/fs/devfs/base.c
--- linux-2.5.70-bk15/fs/devfs/base.c	2003-06-11 04:47:54.000000000 -0700
+++ linux-2.5.70-bk16/fs/devfs/base.c	2003-06-11 04:48:08.000000000 -0700
@@ -1684,7 +1684,14 @@
 	}
 
 	error = _devfs_append_entry(dir, de, &old);
-	if (error) {
+	if (error == -EEXIST) {
+		/*
+		 * devfs_mk_dir() of an already-existing directory will
+		 * return success.
+		 */
+		error = 0;
+		devfs_put(old);
+	} else if (error) {
 		PRINTK("(%s): could not append to dir: %p \"%s\"\n",
 				buf, dir, dir->name);
 		devfs_put(old);
diff -urN linux-2.5.70-bk15/fs/jfs/jfs_dmap.c linux-2.5.70-bk16/fs/jfs/jfs_dmap.c
--- linux-2.5.70-bk15/fs/jfs/jfs_dmap.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk16/fs/jfs/jfs_dmap.c	2003-06-11 04:48:08.000000000 -0700
@@ -3050,7 +3050,7 @@
  * RETURN VALUES:
  *      none
  */
-void fsDirty()
+void fsDirty(void)
 {
 	printk("fsDirty(): bye-bye\n");
 	assert(0);
diff -urN linux-2.5.70-bk15/fs/jfs/jfs_xtree.c linux-2.5.70-bk16/fs/jfs/jfs_xtree.c
--- linux-2.5.70-bk15/fs/jfs/jfs_xtree.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/fs/jfs/jfs_xtree.c	2003-06-11 04:48:08.000000000 -0700
@@ -4225,8 +4225,7 @@
  *      at the current entry at the current subtree root page
  *
  */
-int xtGather(t)
-btree_t *t;
+int xtGather(btree_t *t)
 {
 	int rc = 0;
 	xtpage_t *p;
diff -urN linux-2.5.70-bk15/fs/nfsd/nfssvc.c linux-2.5.70-bk16/fs/nfsd/nfssvc.c
--- linux-2.5.70-bk15/fs/nfsd/nfssvc.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk16/fs/nfsd/nfssvc.c	2003-06-11 04:48:08.000000000 -0700
@@ -188,6 +188,14 @@
 	list_add(&me.list, &nfsd_list);
 
 	unlock_kernel();
+
+	/*
+	 * We want less throttling in balance_dirty_pages() so that nfs to
+	 * localhost doesn't cause nfsd to lock up due to all the client's
+	 * dirty pages.
+	 */
+	current->flags |= PF_LESS_THROTTLE;
+
 	/*
 	 * The main request loop
 	 */
diff -urN linux-2.5.70-bk15/fs/sysfs/file.c linux-2.5.70-bk16/fs/sysfs/file.c
--- linux-2.5.70-bk15/fs/sysfs/file.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk16/fs/sysfs/file.c	2003-06-11 04:48:08.000000000 -0700
@@ -84,7 +84,7 @@
 	ssize_t count;
 
 	if (!buffer->page)
-		buffer->page = (char *) __get_free_page(GFP_KERNEL);
+		buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
 	if (!buffer->page)
 		return -ENOMEM;
 
@@ -174,7 +174,7 @@
 	int error;
 
 	if (!buffer->page)
-		buffer->page = (char *)__get_free_page(GFP_KERNEL);
+		buffer->page = (char *)get_zeroed_page(GFP_KERNEL);
 	if (!buffer->page)
 		return -ENOMEM;
 
diff -urN linux-2.5.70-bk15/include/asm-alpha/pci.h linux-2.5.70-bk16/include/asm-alpha/pci.h
--- linux-2.5.70-bk15/include/asm-alpha/pci.h	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-alpha/pci.h	2003-06-11 04:48:08.000000000 -0700
@@ -188,13 +188,12 @@
 	/* Nothing to do. */
 }
 
-/* Return the index of the PCI controller for device PDEV. */
-extern int pci_controller_num(struct pci_dev *pdev);
-
 extern void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 			 struct resource *res);
 
+#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
+
 #endif /* __KERNEL__ */
 
 /* Values for the `which' argument to sys_pciconfig_iobase.  */
diff -urN linux-2.5.70-bk15/include/asm-arm/pci.h linux-2.5.70-bk16/include/asm-arm/pci.h
--- linux-2.5.70-bk15/include/asm-arm/pci.h	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-arm/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -128,14 +128,6 @@
  */
 #define pci_dac_dma_supported(pci_dev, mask)	(0)
 
-/*
- * Return the index of the PCI controller for device PDEV.
- */
-static inline int pci_controller_num(struct pci_dev *dev)
-{
-	return 0;
-}
-
 
 #if defined(CONFIG_SA1111) && !defined(CONFIG_PCI)
 /*
diff -urN linux-2.5.70-bk15/include/asm-h8300/pci.h linux-2.5.70-bk16/include/asm-h8300/pci.h
--- linux-2.5.70-bk15/include/asm-h8300/pci.h	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-h8300/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -19,7 +19,4 @@
 	/* We don't do dynamic PCI IRQ allocation */
 }
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_controller_num(PDEV)	(0)
-
 #endif /* _ASM_H8300_PCI_H */
diff -urN linux-2.5.70-bk15/include/asm-i386/mach-bigsmp/mach_apic.h linux-2.5.70-bk16/include/asm-i386/mach-bigsmp/mach_apic.h
--- linux-2.5.70-bk15/include/asm-i386/mach-bigsmp/mach_apic.h	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-i386/mach-bigsmp/mach_apic.h	2003-06-11 04:48:09.000000000 -0700
@@ -22,7 +22,7 @@
 #define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
 static inline unsigned long target_cpus(void)
 { 
-	return ((cpu_online_map < 0xf)?cpu_online_map:0xf);
+	return cpu_online_map;
 }
 #define TARGET_CPUS	(target_cpus())
 
@@ -151,7 +151,7 @@
 			if (apicid_cluster(apicid) != 
 					apicid_cluster(new_apicid)){
 				printk ("%s: Not a valid mask!\n",__FUNCTION__);
-				return TARGET_CPUS;
+				return 0xFF;
 			}
 			apicid = apicid | new_apicid;
 			cpus_found++;
diff -urN linux-2.5.70-bk15/include/asm-i386/mach-numaq/mach_apic.h linux-2.5.70-bk16/include/asm-i386/mach-numaq/mach_apic.h
--- linux-2.5.70-bk15/include/asm-i386/mach-numaq/mach_apic.h	2003-06-11 04:47:55.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-i386/mach-numaq/mach_apic.h	2003-06-11 04:48:09.000000000 -0700
@@ -6,7 +6,7 @@
 
 #define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
 
-#define TARGET_CPUS (0xf)
+#define TARGET_CPUS (~0UL)
 
 #define NO_BALANCE_IRQ (1)
 #define esr_disable (1)
diff -urN linux-2.5.70-bk15/include/asm-i386/mach-summit/mach_apic.h linux-2.5.70-bk16/include/asm-i386/mach-summit/mach_apic.h
--- linux-2.5.70-bk15/include/asm-i386/mach-summit/mach_apic.h	2003-06-11 04:47:55.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-i386/mach-summit/mach_apic.h	2003-06-11 04:48:09.000000000 -0700
@@ -20,7 +20,7 @@
 
 static inline unsigned long target_cpus(void)
 {
-	return XAPIC_DEST_CPUS_MASK;
+	return (~0UL);
 } 
 #define TARGET_CPUS	(target_cpus())
 
@@ -141,7 +141,7 @@
 			if (apicid_cluster(apicid) != 
 					apicid_cluster(new_apicid)){
 				printk ("%s: Not a valid mask!\n",__FUNCTION__);
-				return TARGET_CPUS;
+				return 0xFF;
 			}
 			apicid = apicid | new_apicid;
 			cpus_found++;
diff -urN linux-2.5.70-bk15/include/asm-i386/pci.h linux-2.5.70-bk16/include/asm-i386/pci.h
--- linux-2.5.70-bk15/include/asm-i386/pci.h	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-i386/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -90,12 +90,6 @@
 #define sg_dma_address(sg)	((sg)->dma_address)
 #define sg_dma_len(sg)		((sg)->length)
 
-/* Return the index of the PCI controller for device. */
-static inline int pci_controller_num(struct pci_dev *dev)
-{
-	return 0;
-}
-
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state, int write_combine);
diff -urN linux-2.5.70-bk15/include/asm-i386/pgtable.h linux-2.5.70-bk16/include/asm-i386/pgtable.h
--- linux-2.5.70-bk15/include/asm-i386/pgtable.h	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-i386/pgtable.h	2003-06-11 04:48:09.000000000 -0700
@@ -221,6 +221,13 @@
 static inline void ptep_mkdirty(pte_t *ptep)			{ set_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); }
 
 /*
+ * Macro to mark a page protection value as "uncacheable".  On processors which do not support
+ * it, this is a no-op.
+ */
+#define pgprot_noncached(prot)	((boot_cpu_data.x86 > 3)					  \
+				 ? (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT)) : (prot))
+
+/*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
diff -urN linux-2.5.70-bk15/include/asm-ia64/pci.h linux-2.5.70-bk16/include/asm-ia64/pci.h
--- linux-2.5.70-bk15/include/asm-ia64/pci.h	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-ia64/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -70,9 +70,6 @@
 #define pci_dac_dma_to_offset(dev,dma_addr)		((dma_addr) & ~PAGE_MASK)
 #define pci_dac_dma_sync_single(dev,dma_addr,len,dir)	do { mb(); } while (0)
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_controller_num(PDEV)	(0)
-
 #define sg_dma_len(sg)		((sg)->dma_length)
 #define sg_dma_address(sg)	((sg)->dma_address)
 
@@ -95,7 +92,7 @@
 };
 
 #define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
-#define PCI_SEGMENT(busdev)    (PCI_CONTROLLER(busdev)->segment)
+#define pci_domain_nr(busdev)    (PCI_CONTROLLER(busdev)->segment)
 
 /* generic pci stuff */
 #include <asm-generic/pci.h>
diff -urN linux-2.5.70-bk15/include/asm-m68k/pci.h linux-2.5.70-bk16/include/asm-m68k/pci.h
--- linux-2.5.70-bk15/include/asm-m68k/pci.h	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-m68k/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -45,9 +45,6 @@
 	/* We don't do dynamic PCI IRQ allocation */
 }
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_controller_num(PDEV)	(0)
-
 /* The PCI address space does equal the physical memory
  * address space.  The networking and block device layers use
  * this boolean for bounce buffer decisions.
diff -urN linux-2.5.70-bk15/include/asm-m68k/pgtable.h linux-2.5.70-bk16/include/asm-m68k/pgtable.h
--- linux-2.5.70-bk15/include/asm-m68k/pgtable.h	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-m68k/pgtable.h	2003-06-11 04:48:09.000000000 -0700
@@ -153,6 +153,23 @@
 #ifndef __ASSEMBLY__
 #include <asm-generic/pgtable.h>
 
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+#ifdef SUN3_PAGE_NOCACHE
+# define __SUN3_PAGE_NOCACHE	SUN3_PAGE_NOCACHE
+#else
+# define __SUN3_PAGE_NOCACHE	0
+#endif
+#define pgprot_noncached(prot)							\
+	(MMU_IS_SUN3								\
+	 ? (__pgprot(pgprot_val(prot) | __SUN3_PAGE_NOCACHE))			\
+	 : ((MMU_IS_851 || MMU_IS_030)						\
+	    ? (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE030))			\
+	    : (MMU_IS_040 || MMU_IS_060)					\
+	    ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S))	\
+	    : (prot)))
+
 typedef pte_t *pte_addr_t;
 
 #endif /* !__ASSEMBLY__ */
diff -urN linux-2.5.70-bk15/include/asm-mips/pci.h linux-2.5.70-bk16/include/asm-mips/pci.h
--- linux-2.5.70-bk15/include/asm-mips/pci.h	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-mips/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -237,9 +237,6 @@
 }
 
 
-/* Return the index of the PCI controller for device. */
-#define pci_controller_num(pdev)	(0)
-
 /*
  * These macros should be used after a pci_map_sg call has been done
  * to get bus addresses of each of the SG entries and their lengths.
diff -urN linux-2.5.70-bk15/include/asm-mips64/pci.h linux-2.5.70-bk16/include/asm-mips64/pci.h
--- linux-2.5.70-bk15/include/asm-mips64/pci.h	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-mips64/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -256,11 +256,6 @@
 }
 
 /*
- * Return the index of the PCI controller for device.
- */
-#define pci_controller_num(pdev)	(0)
-
-/*
  * These macros should be used after a pci_map_sg call has been done
  * to get bus addresses of each of the SG entries and their lengths.
  * You should only work with the number of sg entries pci_map_sg
diff -urN linux-2.5.70-bk15/include/asm-parisc/pci.h linux-2.5.70-bk16/include/asm-parisc/pci.h
--- linux-2.5.70-bk15/include/asm-parisc/pci.h	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-parisc/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -180,9 +180,6 @@
 /* Don't support DAC yet. */
 #define pci_dac_dma_supported(pci_dev, mask)   (0)
 
-/* Return the index of the PCI controller for device PDEV. */
-#define	pci_controller_num(PDEV)	(0)
-
 /* export the pci_ DMA API in terms of the dma_ one */
 #include <asm-generic/pci-dma-compat.h>
 
diff -urN linux-2.5.70-bk15/include/asm-ppc/pci-bridge.h linux-2.5.70-bk16/include/asm-ppc/pci-bridge.h
--- linux-2.5.70-bk15/include/asm-ppc/pci-bridge.h	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-ppc/pci-bridge.h	2003-06-11 04:48:09.000000000 -0700
@@ -39,7 +39,7 @@
  * Structure of a PCI controller (host bridge)
  */
 struct pci_controller {
-	int index;			/* used for pci_controller_num */
+	int index;			/* PCI domain number */
 	struct pci_controller *next;
         struct pci_bus *bus;
 	void *arch_data;
diff -urN linux-2.5.70-bk15/include/asm-ppc/pci.h linux-2.5.70-bk16/include/asm-ppc/pci.h
--- linux-2.5.70-bk15/include/asm-ppc/pci.h	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-ppc/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -266,7 +266,7 @@
 }
 
 /* Return the index of the PCI controller for device PDEV. */
-extern int pci_controller_num(struct pci_dev *pdev);
+#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
 /* Map a range of PCI memory or I/O space for a device into user space */
 int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
diff -urN linux-2.5.70-bk15/include/asm-ppc/pgtable.h linux-2.5.70-bk16/include/asm-ppc/pgtable.h
--- linux-2.5.70-bk15/include/asm-ppc/pgtable.h	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-ppc/pgtable.h	2003-06-11 04:48:09.000000000 -0700
@@ -478,6 +478,11 @@
 	pte_update(ptep, 0, _PAGE_DIRTY);
 }
 
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+#define pgprot_noncached(prot)	(__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
+
 #define pte_same(A,B)	(((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
 
 #define pmd_page_kernel(pmd)	\
diff -urN linux-2.5.70-bk15/include/asm-ppc64/pci.h linux-2.5.70-bk16/include/asm-ppc64/pci.h
--- linux-2.5.70-bk15/include/asm-ppc64/pci.h	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-ppc64/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -86,8 +86,7 @@
 	return 1;
 }
 
-/* Return the index of the PCI controller for device PDEV. */
-extern int pci_controller_num(struct pci_dev *pdev);
+extern int pci_domain_nr(struct pci_bus *bus);
 
 struct vm_area_struct;
 /* Map a range of PCI memory or I/O space for a device into user space */
diff -urN linux-2.5.70-bk15/include/asm-ppc64/pgtable.h linux-2.5.70-bk16/include/asm-ppc64/pgtable.h
--- linux-2.5.70-bk15/include/asm-ppc64/pgtable.h	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-ppc64/pgtable.h	2003-06-11 04:48:09.000000000 -0700
@@ -303,6 +303,11 @@
 	pte_update(ptep, 0, _PAGE_DIRTY);
 }
 
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+#define pgprot_noncached(prot)	(__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
+
 #define pte_same(A,B)	(((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
 
 /*
diff -urN linux-2.5.70-bk15/include/asm-s390/pgtable.h linux-2.5.70-bk16/include/asm-s390/pgtable.h
--- linux-2.5.70-bk15/include/asm-s390/pgtable.h	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-s390/pgtable.h	2003-06-11 04:48:09.000000000 -0700
@@ -212,8 +212,7 @@
 #define _PAGE_INVALID   0x400          /* HW invalid                       */
 
 /* Software bits in the page table entry */
-#define _PAGE_MKCLEAN   0x002
-#define _PAGE_ISCLEAN   0x004
+#define _PAGE_ISCLEAN   0x002
 
 /* Mask and four different kinds of invalid pages. */
 #define _PAGE_INVALID_MASK	0x601
@@ -320,15 +319,6 @@
  */
 extern inline void set_pte(pte_t *pteptr, pte_t pteval)
 {
-	if ((pte_val(pteval) & (_PAGE_MKCLEAN|_PAGE_INVALID))
-	    == _PAGE_MKCLEAN) 
-	{
-		pte_val(pteval) &= ~_PAGE_MKCLEAN;
-               
-		asm volatile ("sske %0,%1" 
-				: : "d" (0), "a" (pte_val(pteval)));
-	}
-
 	*pteptr = pteval;
 }
 
@@ -501,7 +491,7 @@
 	 * sske instruction is slow. It is faster to let the
 	 * next instruction set the dirty bit.
 	 */
-	pte_val(pte) &= ~(_PAGE_MKCLEAN | _PAGE_ISCLEAN);
+	pte_val(pte) &= ~ _PAGE_ISCLEAN;
 	return pte;
 }
 
@@ -582,30 +572,23 @@
 	pgprot_t __pgprot = (pgprot);					  \
 	unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);  \
 	pte_t __pte = mk_pte_phys(__physpage, __pgprot);                  \
-	                                                                  \
-	if (!(pgprot_val(__pgprot) & _PAGE_ISCLEAN)) {			  \
-		int __users = !!PagePrivate(__page) + !!__page->mapping;  \
-		if (__users + page_count(__page) == 1)                    \
-			pte_val(__pte) |= _PAGE_MKCLEAN;                  \
-	}								  \
 	__pte;                                                            \
 })
 
 #define pfn_pte(pfn, pgprot)                                              \
 ({                                                                        \
-	struct page *__page = mem_map+(pfn);                              \
 	pgprot_t __pgprot = (pgprot);					  \
 	unsigned long __physpage = __pa((pfn) << PAGE_SHIFT);             \
 	pte_t __pte = mk_pte_phys(__physpage, __pgprot);                  \
-	                                                                  \
-	if (!(pgprot_val(__pgprot) & _PAGE_ISCLEAN)) {			  \
-		int __users = !!PagePrivate(__page) + !!__page->mapping;  \
-		if (__users + page_count(__page) == 1)                    \
-			pte_val(__pte) |= _PAGE_MKCLEAN;                  \
-	}								  \
 	__pte;                                                            \
 })
 
+#define arch_set_page_uptodate(__page)					  \
+	do {								  \
+		asm volatile ("sske %0,%1" : : "d" (0),			  \
+			      "a" (__pa((__page-mem_map) << PAGE_SHIFT)));\
+	} while (0)
+
 #ifdef __s390x__
 
 #define pfn_pmd(pfn, pgprot)                                              \
diff -urN linux-2.5.70-bk15/include/asm-sh/pci.h linux-2.5.70-bk16/include/asm-sh/pci.h
--- linux-2.5.70-bk15/include/asm-sh/pci.h	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-sh/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -226,9 +226,6 @@
  */
 #define pci_dac_dma_supported(pci_dev, mask) (0)
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_controller_num(PDEV)	(0)
-
 /* These macros should be used after a pci_map_sg call has been done
  * to get bus addresses of each of the SG entries and their lengths.
  * You should only work with the number of sg entries pci_map_sg
diff -urN linux-2.5.70-bk15/include/asm-sparc/pci.h linux-2.5.70-bk16/include/asm-sparc/pci.h
--- linux-2.5.70-bk15/include/asm-sparc/pci.h	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-sparc/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -132,9 +132,6 @@
 
 #define pci_dac_dma_supported(dev, mask)	(0)
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_controller_num(PDEV)	(0)
-
 #endif /* __KERNEL__ */
 
 /* generic pci stuff */
diff -urN linux-2.5.70-bk15/include/asm-sparc64/parport.h linux-2.5.70-bk16/include/asm-sparc64/parport.h
--- linux-2.5.70-bk15/include/asm-sparc64/parport.h	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-sparc64/parport.h	2003-06-11 04:48:09.000000000 -0700
@@ -121,9 +121,6 @@
 	struct linux_ebus_device *edev;
 	int count = 0;
 
-	if (!pci_present())
-		return 0;
-
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
 			if (ebus_ecpp_p(edev)) {
diff -urN linux-2.5.70-bk15/include/asm-sparc64/pci.h linux-2.5.70-bk16/include/asm-sparc64/pci.h
--- linux-2.5.70-bk15/include/asm-sparc64/pci.h	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-sparc64/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -189,7 +189,7 @@
 
 /* Return the index of the PCI controller for device PDEV. */
 
-extern int pci_controller_num(struct pci_dev *pdev);
+extern int pci_domain_nr(struct pci_bus *bus);
 
 /* Platform support for /proc/bus/pci/X/Y mmap()s. */
 
diff -urN linux-2.5.70-bk15/include/asm-v850/rte_cb.h linux-2.5.70-bk16/include/asm-v850/rte_cb.h
--- linux-2.5.70-bk15/include/asm-v850/rte_cb.h	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-v850/rte_cb.h	2003-06-11 04:48:09.000000000 -0700
@@ -54,7 +54,6 @@
    instead, perversely enough, this becomes always true! */
 #define pci_dma_supported(dev, mask)		1
 #define pci_dac_dma_supported(dev, mask)	0
-#define pci_controller_num(dev)			0
 #define pcibios_assign_all_busses()		1
 
 
diff -urN linux-2.5.70-bk15/include/asm-x86_64/pci.h linux-2.5.70-bk16/include/asm-x86_64/pci.h
--- linux-2.5.70-bk15/include/asm-x86_64/pci.h	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-x86_64/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -270,12 +270,6 @@
 #define sg_dma_address(sg)	((sg)->dma_address)
 #define sg_dma_len(sg)		((sg)->length)
 
-/* Return the index of the PCI controller for device. */
-static inline int pci_controller_num(struct pci_dev *dev)
-{
-	return 0;
-}
-
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state, int write_combine);
diff -urN linux-2.5.70-bk15/include/asm-x86_64/pgtable.h linux-2.5.70-bk16/include/asm-x86_64/pgtable.h
--- linux-2.5.70-bk15/include/asm-x86_64/pgtable.h	2003-05-26 18:00:44.000000000 -0700
+++ linux-2.5.70-bk16/include/asm-x86_64/pgtable.h	2003-06-11 04:48:09.000000000 -0700
@@ -265,6 +265,11 @@
 static inline void ptep_set_wrprotect(pte_t *ptep)		{ clear_bit(_PAGE_BIT_RW, ptep); }
 static inline void ptep_mkdirty(pte_t *ptep)			{ set_bit(_PAGE_BIT_DIRTY, ptep); }
 
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+#define pgprot_noncached(prot)	(__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT))
+
 #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) 
 static inline int pmd_large(pmd_t pte) { 
 	return (pmd_val(pte) & __LARGE_PTE) == __LARGE_PTE; 
diff -urN linux-2.5.70-bk15/include/linux/compat_ioctl.h linux-2.5.70-bk16/include/linux/compat_ioctl.h
--- linux-2.5.70-bk15/include/linux/compat_ioctl.h	2003-06-11 04:47:55.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/compat_ioctl.h	2003-06-11 04:48:09.000000000 -0700
@@ -563,27 +563,6 @@
 COMPATIBLE_IOCTL(ATMMPC_CTRL)
 COMPATIBLE_IOCTL(ATMMPC_DATA)
 #endif
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)
-COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)
-COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)
-COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)
-COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
-COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
-#endif /* DRM */
 /* Big W */
 /* WIOC_GETSUPPORT not yet implemented -E */
 COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
diff -urN linux-2.5.70-bk15/include/linux/cpu.h linux-2.5.70-bk16/include/linux/cpu.h
--- linux-2.5.70-bk15/include/linux/cpu.h	2003-06-11 04:47:55.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/cpu.h	2003-06-11 04:48:09.000000000 -0700
@@ -19,7 +19,7 @@
 #ifndef _LINUX_CPU_H_
 #define _LINUX_CPU_H_
 
-#include <linux/device.h>
+#include <linux/sysdev.h>
 #include <linux/node.h>
 #include <asm/semaphore.h>
 
@@ -29,8 +29,6 @@
 };
 
 extern int register_cpu(struct cpu *, int, struct node *);
-extern struct class cpu_class;
-
 struct notifier_block;
 
 #ifdef CONFIG_SMP
@@ -48,6 +46,7 @@
 {
 }
 #endif /* CONFIG_SMP */
+extern struct sysdev_class cpu_sysdev_class;
 
 /* Stop CPUs going up and down. */
 extern struct semaphore cpucontrol;
diff -urN linux-2.5.70-bk15/include/linux/cpufreq.h linux-2.5.70-bk16/include/linux/cpufreq.h
--- linux-2.5.70-bk15/include/linux/cpufreq.h	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/cpufreq.h	2003-06-11 04:48:09.000000000 -0700
@@ -205,10 +205,6 @@
 int cpufreq_set_policy(struct cpufreq_policy *policy);
 int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
 
-#ifdef CONFIG_PM
-int cpufreq_restore(void);
-#endif
-
 /* the proc_intf.c needs this */
 int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
 
diff -urN linux-2.5.70-bk15/include/linux/dcache.h linux-2.5.70-bk16/include/linux/dcache.h
--- linux-2.5.70-bk15/include/linux/dcache.h	2003-05-26 18:01:01.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/dcache.h	2003-06-11 04:48:09.000000000 -0700
@@ -175,7 +175,7 @@
 static inline void __d_drop(struct dentry *dentry)
 {
 	dentry->d_vfs_flags |= DCACHE_UNHASHED;
-	hlist_del_rcu(&dentry->d_hash);
+	hlist_del_rcu_init(&dentry->d_hash);
 }
 
 static inline void d_drop(struct dentry *dentry)
diff -urN linux-2.5.70-bk15/include/linux/device.h linux-2.5.70-bk16/include/linux/device.h
--- linux-2.5.70-bk15/include/linux/device.h	2003-06-11 04:47:55.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/device.h	2003-06-11 04:48:09.000000000 -0700
@@ -351,30 +351,6 @@
 extern struct device * get_device(struct device * dev);
 extern void put_device(struct device * dev);
 
-/* drivers/base/sys.c */
-
-struct sys_root {
-	u32		id;
-	struct device 	dev;
-	struct device	sysdev;
-};
-
-extern int sys_register_root(struct sys_root *);
-extern void sys_unregister_root(struct sys_root *);
-
-
-struct sys_device {
-	char		* name;
-	u32		id;
-	struct sys_root	* root;
-	struct device	dev;
-	struct class_device class_dev;
-};
-
-extern int sys_device_register(struct sys_device *);
-extern void sys_device_unregister(struct sys_device *);
-
-extern struct bus_type system_bus_type;
 
 /* drivers/base/platform.c */
 
diff -urN linux-2.5.70-bk15/include/linux/isapnp.h linux-2.5.70-bk16/include/linux/isapnp.h
--- linux-2.5.70-bk15/include/linux/isapnp.h	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/isapnp.h	2003-06-11 04:48:09.000000000 -0700
@@ -115,8 +115,8 @@
 int isapnp_proc_init(void);
 int isapnp_proc_done(void);
 #else
-static inline isapnp_proc_init(void) { return 0; }
-static inline isapnp_proc_done(void) { return 0; }
+static inline int isapnp_proc_init(void) { return 0; }
+static inline int isapnp_proc_done(void) { return 0; }
 #endif
 
 /* init/main.c */
diff -urN linux-2.5.70-bk15/include/linux/kobject.h linux-2.5.70-bk16/include/linux/kobject.h
--- linux-2.5.70-bk15/include/linux/kobject.h	2003-06-11 04:47:56.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/kobject.h	2003-06-11 04:48:09.000000000 -0700
@@ -118,6 +118,14 @@
 extern struct kobject * kset_find_obj(struct kset *, const char *);
 
 
+/**
+ * Use this when initializing an embedded kset with no other 
+ * fields to initialize.
+ */
+#define set_kset_name(str)	.kset = { .kobj = { .name = str } }
+
+
+
 struct subsystem {
 	struct kset		kset;
 	struct rw_semaphore	rwsem;
diff -urN linux-2.5.70-bk15/include/linux/list.h linux-2.5.70-bk16/include/linux/list.h
--- linux-2.5.70-bk15/include/linux/list.h	2003-06-11 04:47:56.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/list.h	2003-06-11 04:48:09.000000000 -0700
@@ -8,6 +8,14 @@
 #include <asm/system.h>
 
 /*
+ * These are non-NULL pointers that will result in page faults
+ * under normal circumstances, used to verify that nobody uses
+ * non-initialized list entries.
+ */
+#define LIST_POISON1  ((void *) 0x00100100)
+#define LIST_POISON2  ((void *) 0x00200200)
+
+/*
  * Simple doubly linked list implementation.
  *
  * Some of the internal functions ("__xxx") are useful when
@@ -137,7 +145,10 @@
 static inline void list_del(struct list_head *entry)
 {
 	__list_del(entry->prev, entry->next);
+	entry->next = LIST_POISON1;
+	entry->prev = LIST_POISON2;
 }
+
 /**
  * list_del_rcu - deletes entry from list without re-initialization
  * @entry: the element to delete from the list.
@@ -148,6 +159,8 @@
 static inline void list_del_rcu(struct list_head *entry)
 {
 	__list_del(entry->prev, entry->next);
+	entry->next = LIST_POISON1;
+	entry->prev = LIST_POISON2;
 }
 
 /**
@@ -297,6 +310,20 @@
 		     prefetch(pos->member.next))
 
 /**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:	the type * to use as a loop counter.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)			\
+	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
+		     prefetch(pos->member.prev);			\
+	     &pos->member != (head); 					\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member),	\
+		     prefetch(pos->member.prev))
+
+
+/**
  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
  * @pos:	the type * to use as a loop counter.
  * @n:		another type * to use as temporary storage
@@ -399,8 +426,9 @@
 
 static __inline__ void hlist_del(struct hlist_node *n)
 {
-	if (n->pprev)
-		__hlist_del(n);
+	__hlist_del(n);
+	n->next = LIST_POISON1;
+	n->pprev = LIST_POISON2;
 }
 
 #define hlist_del_rcu hlist_del  /* list_del_rcu is identical too? */
@@ -413,6 +441,8 @@
 	}
 }  
 
+#define hlist_del_rcu_init hlist_del_init
+
 static __inline__ void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 
 { 
 	struct hlist_node *first = h->first;
diff -urN linux-2.5.70-bk15/include/linux/node.h linux-2.5.70-bk16/include/linux/node.h
--- linux-2.5.70-bk15/include/linux/node.h	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/node.h	2003-06-11 04:48:09.000000000 -0700
@@ -19,11 +19,11 @@
 #ifndef _LINUX_NODE_H_
 #define _LINUX_NODE_H_
 
-#include <linux/device.h>
+#include <linux/sysdev.h>
 
 struct node {
 	unsigned long cpumap;	/* Bitmap of CPUs on the Node */
-	struct sys_root sysroot;
+	struct sys_device	sysdev;
 };
 
 extern int register_node(struct node *, int, struct node *);
diff -urN linux-2.5.70-bk15/include/linux/page-flags.h linux-2.5.70-bk16/include/linux/page-flags.h
--- linux-2.5.70-bk15/include/linux/page-flags.h	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/page-flags.h	2003-06-11 04:48:09.000000000 -0700
@@ -7,6 +7,7 @@
 
 #include <linux/percpu.h>
 #include <linux/cache.h>
+#include <asm/pgtable.h>
 
 /*
  * Various page->flags bits:
@@ -158,8 +159,16 @@
 #define ClearPageReferenced(page)	clear_bit(PG_referenced, &(page)->flags)
 #define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
 
+#ifndef arch_set_page_uptodate
+#define arch_set_page_uptodate(page) do { } while (0)
+#endif
+
 #define PageUptodate(page)	test_bit(PG_uptodate, &(page)->flags)
-#define SetPageUptodate(page)	set_bit(PG_uptodate, &(page)->flags)
+#define SetPageUptodate(page) \
+	do {								\
+		arch_set_page_uptodate(page);				\
+		set_bit(PG_uptodate, &(page)->flags);			\
+	} while (0)
 #define ClearPageUptodate(page)	clear_bit(PG_uptodate, &(page)->flags)
 
 #define PageDirty(page)		test_bit(PG_dirty, &(page)->flags)
diff -urN linux-2.5.70-bk15/include/linux/pci.h linux-2.5.70-bk16/include/linux/pci.h
--- linux-2.5.70-bk15/include/linux/pci.h	2003-06-11 04:47:56.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/pci.h	2003-06-11 04:48:09.000000000 -0700
@@ -525,10 +525,6 @@
 extern struct list_head pci_root_buses;	/* list of all known PCI buses */
 extern struct list_head pci_devices;	/* list of all devices */
 
-#define pci_for_each_bus(bus) \
-	for(bus = pci_bus_b(pci_root_buses.next); bus != pci_bus_b(&pci_root_buses); bus = pci_bus_b(bus->node.next))
-
-int pci_present(void);
 void pcibios_fixup_bus(struct pci_bus *);
 int pcibios_enable_device(struct pci_dev *, int mask);
 char *pcibios_setup (char *str);
@@ -568,6 +564,7 @@
 struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from);
 struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
 int pci_find_capability (struct pci_dev *dev, int cap);
+struct pci_bus * pci_find_next_bus(const struct pci_bus *from);
 
 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);
@@ -669,8 +666,6 @@
  */
 
 #ifndef CONFIG_PCI
-static inline int pci_present(void) { return 0; }
-
 #define _PCI_NOP(o,s,t) \
 	static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \
 		{ return PCIBIOS_FUNC_NOT_SUPPORTED; }
@@ -805,5 +800,15 @@
 #define PCIPCI_VSFX		16
 #define PCIPCI_ALIMAGIK		32
 
+/*
+ * PCI domain support.  Sometimes called PCI segment (eg by ACPI),
+ * a PCI domain is defined to be a set of PCI busses which share
+ * configuration space.
+ */
+
+#ifndef CONFIG_PCI_DOMAINS
+static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* LINUX_PCI_H */
diff -urN linux-2.5.70-bk15/include/linux/sched.h linux-2.5.70-bk16/include/linux/sched.h
--- linux-2.5.70-bk15/include/linux/sched.h	2003-06-11 04:47:56.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/sched.h	2003-06-11 04:48:09.000000000 -0700
@@ -475,6 +475,7 @@
 #define PF_FSTRANS	0x00020000	/* inside a filesystem transaction */
 #define PF_KSWAPD	0x00040000	/* I am kswapd */
 #define PF_SWAPOFF	0x00080000	/* I am in swapoff */
+#define PF_LESS_THROTTLE 0x01000000	/* Throttle me less: I clena memory */
 
 #ifdef CONFIG_SMP
 extern void set_cpus_allowed(task_t *p, unsigned long new_mask);
diff -urN linux-2.5.70-bk15/include/linux/slab.h linux-2.5.70-bk16/include/linux/slab.h
--- linux-2.5.70-bk15/include/linux/slab.h	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/slab.h	2003-06-11 04:48:09.000000000 -0700
@@ -62,7 +62,38 @@
 extern void kmem_cache_free(kmem_cache_t *, void *);
 extern unsigned int kmem_cache_size(kmem_cache_t *);
 
-extern void *kmalloc(size_t, int);
+/* Size description struct for general caches. */
+struct cache_sizes {
+	size_t		 cs_size;
+	kmem_cache_t	*cs_cachep;
+	kmem_cache_t	*cs_dmacachep;
+};
+extern struct cache_sizes malloc_sizes[];
+extern void *__kmalloc(size_t, int);
+
+static inline void *kmalloc(size_t size, int flags)
+{
+	if (__builtin_constant_p(size)) {
+		int i = 0;
+#define CACHE(x) \
+		if (size <= x) \
+			goto found; \
+		else \
+			i++;
+#include "kmalloc_sizes.h"
+#undef CACHE
+		{
+			extern void __you_cannot_kmalloc_that_much(void);
+			__you_cannot_kmalloc_that_much();
+		}
+found:
+		return kmem_cache_alloc((flags & GFP_DMA) ?
+			malloc_sizes[i].cs_dmacachep :
+			malloc_sizes[i].cs_cachep, flags);
+	}
+	return __kmalloc(size, flags);
+}
+
 extern void kfree(const void *);
 extern unsigned int ksize(const void *);
 
diff -urN linux-2.5.70-bk15/include/linux/sysdev.h linux-2.5.70-bk16/include/linux/sysdev.h
--- linux-2.5.70-bk15/include/linux/sysdev.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk16/include/linux/sysdev.h	2003-06-11 04:48:09.000000000 -0700
@@ -0,0 +1,98 @@
+/**
+ * System devices follow a slightly different driver model. 
+ * They don't need to do dynammic driver binding, can't be probed, 
+ * and don't reside on any type of peripheral bus. 
+ * So, we represent and treat them a little differently.
+ * 
+ * We still have a notion of a driver for a system device, because we still
+ * want to perform basic operations on these devices. 
+ *
+ * We also support auxillary drivers binding to devices of a certain class.
+ * 
+ * This allows configurable drivers to register themselves for devices of
+ * a certain type. And, it allows class definitions to reside in generic
+ * code while arch-specific code can register specific drivers.
+ *
+ * Auxillary drivers registered with a NULL cls are registered as drivers
+ * for all system devices, and get notification calls for each device. 
+ */
+
+
+#ifndef _SYSDEV_H_
+#define _SYSDEV_H_
+
+#include <linux/kobject.h>
+
+
+struct sys_device;
+
+struct sysdev_class {
+	struct list_head	drivers;
+
+	/* Default operations for these types of devices */
+	int	(*shutdown)(struct sys_device *);
+	int	(*save)(struct sys_device *, u32 state);
+	int	(*suspend)(struct sys_device *, u32 state);
+	int	(*resume)(struct sys_device *);
+	int	(*restore)(struct sys_device *);
+	struct kset		kset;
+};
+
+
+extern int sysdev_class_register(struct sysdev_class *);
+extern void sysdev_class_unregister(struct sysdev_class *);
+
+
+/**
+ * Auxillary system device drivers.
+ */
+
+struct sysdev_driver {
+	struct list_head	entry;
+	int	(*add)(struct sys_device *);
+	int	(*remove)(struct sys_device *);
+	int	(*shutdown)(struct sys_device *);
+	int	(*save)(struct sys_device *, u32 state);
+	int	(*suspend)(struct sys_device *, u32 state);
+	int	(*resume)(struct sys_device *);
+	int	(*restore)(struct sys_device *);
+};
+
+
+extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *);
+extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *);
+
+
+/**
+ * sys_devices can be simplified a lot from regular devices, because they're
+ * simply not as versatile. 
+ */
+
+struct sys_device {
+	u32		id;
+	struct sysdev_class	* cls;
+	struct kobject		kobj;
+};
+
+extern int sys_device_register(struct sys_device *);
+extern void sys_device_unregister(struct sys_device *);
+
+
+struct sysdev_attribute { 
+	struct attribute	attr;
+	ssize_t (*show)(struct sys_device *, char *);
+	ssize_t (*store)(struct sys_device *, const char *, size_t);
+};
+
+
+#define SYSDEV_ATTR(_name,_mode,_show,_store) 		\
+struct sysdev_attribute attr_##_name = { 			\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
+	.show	= _show,					\
+	.store	= _store,					\
+};
+
+extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
+extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
+
+#endif /* _SYSDEV_H_ */
diff -urN linux-2.5.70-bk15/include/linux/usb.h linux-2.5.70-bk16/include/linux/usb.h
--- linux-2.5.70-bk15/include/linux/usb.h	2003-06-11 04:47:56.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/usb.h	2003-06-11 04:48:09.000000000 -0700
@@ -136,7 +136,7 @@
 
 static inline void usb_set_intfdata (struct usb_interface *intf, void *data)
 {
-	return dev_set_drvdata (&intf->dev, data);
+	dev_set_drvdata(&intf->dev, data);
 }
 
 /* USB_DT_CONFIG: Configuration descriptor information.
diff -urN linux-2.5.70-bk15/include/linux/usbdevice_fs.h linux-2.5.70-bk16/include/linux/usbdevice_fs.h
--- linux-2.5.70-bk15/include/linux/usbdevice_fs.h	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk16/include/linux/usbdevice_fs.h	2003-06-11 04:48:09.000000000 -0700
@@ -46,14 +46,14 @@
 	__u16 wIndex;
 	__u16 wLength;
 	__u32 timeout;  /* in milliseconds */
- 	void *data;
+ 	void __user *data;
 };
 
 struct usbdevfs_bulktransfer {
 	unsigned int ep;
 	unsigned int len;
 	unsigned int timeout; /* in milliseconds */
-	void *data;
+	void __user *data;
 };
 
 struct usbdevfs_setinterface {
@@ -97,7 +97,7 @@
 	unsigned char endpoint;
 	int status;
 	unsigned int flags;
-	void *buffer;
+	void __user *buffer;
 	int buffer_length;
 	int actual_length;
 	int start_frame;
@@ -113,7 +113,7 @@
 	int	ifno;		/* interface 0..N ; negative numbers reserved */
 	int	ioctl_code;	/* MUST encode size + direction of data so the
 				 * macros in <asm/ioctl.h> give correct values */
-	void	*data;		/* param buffer (in, or out) */
+	void __user *data;	/* param buffer (in, or out) */
 };
 
 /* You can do most things with hubs just through control messages,
diff -urN linux-2.5.70-bk15/include/sound/sndmagic.h linux-2.5.70-bk16/include/sound/sndmagic.h
--- linux-2.5.70-bk15/include/sound/sndmagic.h	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/include/sound/sndmagic.h	2003-06-11 04:48:10.000000000 -0700
@@ -155,6 +155,7 @@
 #define snd_card_dummy_t_magic			0xa15a2501
 #define snd_card_dummy_pcm_t_magic		0xa15a2502
 #define opl3_t_magic				0xa15a2601
+#define opl4_t_magic				0xa15a2602
 #define snd_seq_dummy_port_t_magic		0xa15a2701
 #define ice1712_t_magic				0xa15a2801
 #define ad1816a_t_magic				0xa15a2901
@@ -193,10 +194,9 @@
 #define snd_usb_midi_in_endpoint_t_magic	0xa15a3f03
 #define ak4117_t_magic				0xa15a4000
 #define psic_t_magic				0xa15a4100
-#define opl4_t_magic				0xa15a2602
 #define vx_core_t_magic				0xa15a4110
 #define vx_pipe_t_magic				0xa15a4112
-
+#define azf3328_t_magic				0xa15a4200
 
 #else
 
diff -urN linux-2.5.70-bk15/include/sound/version.h linux-2.5.70-bk16/include/sound/version.h
--- linux-2.5.70-bk15/include/sound/version.h	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/include/sound/version.h	2003-06-11 04:48:10.000000000 -0700
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
 #define CONFIG_SND_VERSION "0.9.4"
-#define CONFIG_SND_DATE " (Fri Jun 06 09:23:03 2003 UTC)"
+#define CONFIG_SND_DATE " (Mon Jun 09 12:01:18 2003 UTC)"
diff -urN linux-2.5.70-bk15/kernel/cpufreq.c linux-2.5.70-bk16/kernel/cpufreq.c
--- linux-2.5.70-bk15/kernel/cpufreq.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/kernel/cpufreq.c	2003-06-11 04:48:10.000000000 -0700
@@ -49,8 +49,6 @@
 static LIST_HEAD(cpufreq_governor_list);
 static DECLARE_MUTEX		(cpufreq_governor_sem);
 
-static struct class_interface cpufreq_interface;
-
 static int cpufreq_cpu_get(unsigned int cpu)
 {
 	if (cpu >= NR_CPUS)
@@ -113,24 +111,8 @@
 EXPORT_SYMBOL_GPL(cpufreq_parse_governor);
 
 
-/* forward declarations */
-static int cpufreq_add_dev (struct class_device * dev);
-static void cpufreq_remove_dev (struct class_device * dev);
-
 /* drivers/base/cpu.c */
-extern struct device_class cpu_devclass;
-
-static struct class_interface cpufreq_interface = {
-        .class =	&cpu_class,
-        .add =		&cpufreq_add_dev,
-        .remove =	&cpufreq_remove_dev,
-};
-
-static inline int to_cpu_nr (struct class_device *dev)
-{
-	struct sys_device * cpu_sys_dev = container_of(dev->dev, struct sys_device, dev);
-	return (cpu_sys_dev->id);
-}
+extern struct sysdev_class cpu_sysdev_class;
 
 
 /**
@@ -331,9 +313,9 @@
  *
  * Adds the cpufreq interface for a CPU device. 
  */
-static int cpufreq_add_dev (struct class_device * class_dev)
+static int cpufreq_add_dev (struct sys_device * sys_dev)
 {
-	unsigned int cpu = to_cpu_nr(class_dev);
+	unsigned int cpu = sys_dev->id;
 	int ret = 0;
 	struct cpufreq_policy new_policy;
 	struct cpufreq_policy *policy;
@@ -358,14 +340,12 @@
 	memcpy(&new_policy, 
 	       policy, 
 	       sizeof(struct cpufreq_policy));
-	class_set_devdata(class_dev, policy);
 	up(&cpufreq_driver_sem);
 
 	init_MUTEX(&policy->lock);
 	/* prepare interface data */
-	policy->kobj.parent = &class_dev->kobj;
+	policy->kobj.parent = &sys_dev->kobj;
 	policy->kobj.ktype = &ktype_cpufreq;
-//	policy->dev = dev->dev;
 	strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN);
 
 	ret = kobject_register(&policy->kobj);
@@ -396,12 +376,12 @@
  *
  * Removes the cpufreq interface for a CPU device.
  */
-static void cpufreq_remove_dev (struct class_device * class_dev)
+static int cpufreq_remove_dev (struct sys_device * sys_dev)
 {
-	unsigned int cpu = to_cpu_nr(class_dev);
+	unsigned int cpu = sys_dev->id;
 
 	if (!kobject_get(&cpufreq_driver->policy[cpu].kobj))
-		return;
+		return -EFAULT;
 
 	down(&cpufreq_driver_sem);
 	if ((cpufreq_driver->target) && 
@@ -421,9 +401,17 @@
 
 	up(&cpufreq_driver_sem);
 	kobject_put(&cpufreq_driver->policy[cpu].kobj);
-	return;
+	return 0;
 }
 
+static int cpufreq_restore(struct sys_device *);
+
+static struct sysdev_driver cpufreq_sysdev_driver = {
+	.add		= cpufreq_add_dev,
+	.remove		= cpufreq_remove_dev,
+	.restore	= cpufreq_restore,
+};
+
 
 /*********************************************************************
  *                     NOTIFIER LISTS INTERFACE                      *
@@ -843,7 +831,7 @@
 
 	memset(cpufreq_driver->policy, 0, NR_CPUS * sizeof(struct cpufreq_policy));
 
-	return class_interface_register(&cpufreq_interface);
+	return sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver);
 }
 EXPORT_SYMBOL_GPL(cpufreq_register_driver);
 
@@ -861,7 +849,7 @@
 	if (!cpufreq_driver || (driver != cpufreq_driver))
 		return -EINVAL;
 
-	class_interface_unregister(&cpufreq_interface);
+	sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
 
 	down(&cpufreq_driver_sem);
 	kfree(cpufreq_driver->policy);
@@ -874,41 +862,34 @@
 
 
 #ifdef CONFIG_PM
+
 /**
  *	cpufreq_restore - restore the CPU clock frequency after resume
  *
  *	Restore the CPU clock frequency so that our idea of the current
  *	frequency reflects the actual hardware.
  */
-int cpufreq_restore(void)
+static int cpufreq_restore(struct sys_device * sysdev)
 {
-	struct cpufreq_policy policy;
-	unsigned int i;
+	int cpu = sysdev->id;
 	unsigned int ret = 0;
+	struct cpufreq_policy policy;
 
-	if (in_interrupt())
-		panic("cpufreq_restore() called from interrupt context!");
-
-	if (!try_module_get(cpufreq_driver->owner))
-		goto error_out;
-
-	for (i=0;i<NR_CPUS;i++) {
-		if (!cpu_online(i) || !cpufreq_cpu_get(i))
-			continue;
-
+	if (cpu_online(cpu) && cpufreq_cpu_get(cpu)) {
 		down(&cpufreq_driver_sem);
-		memcpy(&policy, &cpufreq_driver->policy[i], sizeof(struct cpufreq_policy));
+		memcpy(&policy, &cpufreq_driver->policy[cpu], 
+		       sizeof(struct cpufreq_policy));
 		up(&cpufreq_driver_sem);
-		ret += cpufreq_set_policy(&policy);
-
-		cpufreq_cpu_put(i);
+		ret = cpufreq_set_policy(&policy);
+		cpufreq_cpu_put(cpu);
 	}
 
-	module_put(cpufreq_driver->owner);
- error_out:
 	return ret;
 }
-EXPORT_SYMBOL_GPL(cpufreq_restore);
+
 #else
-#define cpufreq_restore() do {} while (0)
+static int cpufreq_restore(struct sys_device * sysdev)
+{
+	return 0;
+}
 #endif /* CONFIG_PM */
diff -urN linux-2.5.70-bk15/kernel/ksyms.c linux-2.5.70-bk16/kernel/ksyms.c
--- linux-2.5.70-bk15/kernel/ksyms.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/kernel/ksyms.c	2003-06-11 04:48:10.000000000 -0700
@@ -95,7 +95,8 @@
 EXPORT_SYMBOL(kmem_cache_size);
 EXPORT_SYMBOL(set_shrinker);
 EXPORT_SYMBOL(remove_shrinker);
-EXPORT_SYMBOL(kmalloc);
+EXPORT_SYMBOL(malloc_sizes);
+EXPORT_SYMBOL(__kmalloc);
 EXPORT_SYMBOL(kfree);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(__alloc_percpu);
diff -urN linux-2.5.70-bk15/kernel/module.c linux-2.5.70-bk16/kernel/module.c
--- linux-2.5.70-bk15/kernel/module.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/kernel/module.c	2003-06-11 04:48:10.000000000 -0700
@@ -1366,7 +1366,7 @@
 	long arglen;
 	struct module *mod;
 	long err = 0;
-	void *ptr = NULL; /* Stops spurious gcc uninitialized warning */
+	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
 
 	DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
 	       umod, len, uargs);
@@ -1496,13 +1496,14 @@
 
 	if (pcpuindex) {
 		/* We have a special allocation for this section. */
-		mod->percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
-					      sechdrs[pcpuindex].sh_addralign);
-		if (!mod->percpu) {
+		percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
+					 sechdrs[pcpuindex].sh_addralign);
+		if (!percpu) {
 			err = -ENOMEM;
 			goto free_mod;
 		}
 		sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
+		mod->percpu = percpu;
 	}
 
 	/* Determine total sizes, and put offsets in sh_entsize.  For now
@@ -1643,8 +1644,8 @@
  free_core:
 	module_free(mod, mod->module_core);
  free_percpu:
-	if (mod->percpu)
-		percpu_modfree(mod->percpu);
+	if (percpu)
+		percpu_modfree(percpu);
  free_mod:
 	kfree(args);
  free_hdr:
diff -urN linux-2.5.70-bk15/kernel/sched.c linux-2.5.70-bk16/kernel/sched.c
--- linux-2.5.70-bk15/kernel/sched.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/kernel/sched.c	2003-06-11 04:48:10.000000000 -0700
@@ -1108,7 +1108,7 @@
 #endif
 		if (!(j % IDLE_REBALANCE_TICK)) {
 			spin_lock(&this_rq->lock);
-			load_balance(this_rq, 0, cpu_to_node_mask(this_cpu));
+			load_balance(this_rq, idle, cpu_to_node_mask(this_cpu));
 			spin_unlock(&this_rq->lock);
 		}
 		return;
diff -urN linux-2.5.70-bk15/mm/page-writeback.c linux-2.5.70-bk16/mm/page-writeback.c
--- linux-2.5.70-bk15/mm/page-writeback.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/mm/page-writeback.c	2003-06-11 04:48:10.000000000 -0700
@@ -104,11 +104,13 @@
  * clamping level.
  */
 static void
-get_dirty_limits(struct page_state *ps, long *background, long *dirty)
+get_dirty_limits(struct page_state *ps, long *pbackground, long *pdirty)
 {
 	int background_ratio;		/* Percentages */
 	int dirty_ratio;
 	int unmapped_ratio;
+	long background;
+	long dirty;
 
 	get_page_state(ps);
 
@@ -125,8 +127,14 @@
 	if (background_ratio >= dirty_ratio)
 		background_ratio = dirty_ratio / 2;
 
-	*background = (background_ratio * total_pages) / 100;
-	*dirty = (dirty_ratio * total_pages) / 100;
+	background = (background_ratio * total_pages) / 100;
+	dirty = (dirty_ratio * total_pages) / 100;
+	if (current->flags & PF_LESS_THROTTLE) {
+		background += background / 4;
+		dirty += dirty / 4;
+	}
+	*pbackground = background;
+	*pdirty = dirty;
 }
 
 /*
diff -urN linux-2.5.70-bk15/mm/page_alloc.c linux-2.5.70-bk16/mm/page_alloc.c
--- linux-2.5.70-bk15/mm/page_alloc.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/mm/page_alloc.c	2003-06-11 04:48:10.000000000 -0700
@@ -898,7 +898,7 @@
 
 	val->totalram = pgdat->node_size;
 	val->freeram = nr_free_pages_pgdat(pgdat);
-	val->totalhigh = pgdat->node_zones[ZONE_HIGHMEM].spanned_pages;
+	val->totalhigh = pgdat->node_zones[ZONE_HIGHMEM].present_pages;
 	val->freehigh = pgdat->node_zones[ZONE_HIGHMEM].free_pages;
 	val->mem_unit = PAGE_SIZE;
 }
@@ -1152,8 +1152,11 @@
 	for (i = 0; i < MAX_NR_ZONES; i++)
 		size += zones_size[i];
 	size = LONG_ALIGN((size + 7) >> 3);
-	pgdat->valid_addr_bitmap = (unsigned long *)alloc_bootmem_node(pgdat, size);
-	memset(pgdat->valid_addr_bitmap, 0, size);
+	if (size) {
+		pgdat->valid_addr_bitmap = 
+			(unsigned long *)alloc_bootmem_node(pgdat, size);
+		memset(pgdat->valid_addr_bitmap, 0, size);
+	}
 }
 
 /*
diff -urN linux-2.5.70-bk15/mm/slab.c linux-2.5.70-bk16/mm/slab.c
--- linux-2.5.70-bk15/mm/slab.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/mm/slab.c	2003-06-11 04:48:10.000000000 -0700
@@ -385,11 +385,7 @@
 #define	GET_PAGE_SLAB(pg)     ((struct slab *)(pg)->list.prev)
 
 /* These are the default caches for kmalloc. Custom caches can have other sizes. */
-static struct cache_sizes {
-	size_t		 cs_size;
-	kmem_cache_t	*cs_cachep;
-	kmem_cache_t	*cs_dmacachep;
-} malloc_sizes[] = {
+struct cache_sizes malloc_sizes[] = {
 #define CACHE(x) { .cs_size = (x) },
 #include <linux/kmalloc_sizes.h>
 	{ 0, }
@@ -1967,7 +1963,7 @@
  * platforms.  For example, on i386, it means that the memory must come
  * from the first 16MB.
  */
-void * kmalloc (size_t size, int flags)
+void * __kmalloc (size_t size, int flags)
 {
 	struct cache_sizes *csizep = malloc_sizes;
 
diff -urN linux-2.5.70-bk15/sound/core/Kconfig linux-2.5.70-bk16/sound/core/Kconfig
--- linux-2.5.70-bk15/sound/core/Kconfig	2003-05-26 18:00:44.000000000 -0700
+++ linux-2.5.70-bk16/sound/core/Kconfig	2003-06-11 04:48:11.000000000 -0700
@@ -41,7 +41,7 @@
 	bool "OSS Sequencer API"
 	depends on SND_OSSEMUL && SND_SEQUENCER
 	help
-	  Say 'Y' or 'M' to enable OSS sequencer emulation (both /dev/sequencer and
+	  Say 'Y' to enable OSS sequencer emulation (both /dev/sequencer and
 	  /dev/music interfaces).
 
 config SND_RTCTIMER
diff -urN linux-2.5.70-bk15/sound/isa/cs423x/cs4236_lib.c linux-2.5.70-bk16/sound/isa/cs423x/cs4236_lib.c
--- linux-2.5.70-bk15/sound/isa/cs423x/cs4236_lib.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk16/sound/isa/cs423x/cs4236_lib.c	2003-06-11 04:48:11.000000000 -0700
@@ -284,7 +284,7 @@
 		return err;
 
 	if (!(chip->hardware & CS4231_HW_CS4236B_MASK)) {
-	        snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%lx\n",chip->hardware);
+	        snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware);
 		snd_device_free(card, chip);
 		return -ENODEV;
 	}
diff -urN linux-2.5.70-bk15/sound/isa/gus/interwave.c linux-2.5.70-bk16/sound/isa/gus/interwave.c
--- linux-2.5.70-bk15/sound/isa/gus/interwave.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/isa/gus/interwave.c	2003-06-11 04:48:11.000000000 -0700
@@ -757,7 +757,7 @@
 
 	if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT, "InterWave", (void *)iwcard)) {
 		snd_card_free(card);
-		snd_printk("unable to grab IRQ %d\n", irq);
+		snd_printk("unable to grab IRQ %d\n", xirq);
 		return -EBUSY;
 	}
 	iwcard->irq = xirq;
diff -urN linux-2.5.70-bk15/sound/oss/cmpci.c linux-2.5.70-bk16/sound/oss/cmpci.c
--- linux-2.5.70-bk15/sound/oss/cmpci.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/cmpci.c	2003-06-11 04:48:11.000000000 -0700
@@ -3139,10 +3139,6 @@
 	struct pci_dev *pcidev = NULL;
 	int index = 0;
 
-#ifdef CONFIG_PCI
-	if (!pci_present())   /* No PCI bus in this machine! */
-#endif
-		return -ENODEV;
 	printk(KERN_INFO "cmpci: version $Revision: 5.64 $ time " __TIME__ " " __DATE__ "\n");
 
 	while (index < NR_DEVICE && (
diff -urN linux-2.5.70-bk15/sound/oss/cs4281/cs4281m.c linux-2.5.70-bk16/sound/oss/cs4281/cs4281m.c
--- linux-2.5.70-bk15/sound/oss/cs4281/cs4281m.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/cs4281/cs4281m.c	2003-06-11 04:48:11.000000000 -0700
@@ -4484,11 +4484,6 @@
 	int rtn = 0;
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
 		"cs4281: cs4281_init_module()+ \n"));
-	if (!pci_present()) {	/* No PCI bus in this machine! */
-		CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
-			"cs4281: cs4281_init_module()- no pci bus found\n"));
-		return -ENODEV;
-	}
 	printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " "
 	       __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION,
 	       CS4281_ARCH);
diff -urN linux-2.5.70-bk15/sound/oss/cs46xx.c linux-2.5.70-bk16/sound/oss/cs46xx.c
--- linux-2.5.70-bk15/sound/oss/cs46xx.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/cs46xx.c	2003-06-11 04:48:11.000000000 -0700
@@ -5725,11 +5725,6 @@
 	int rtn = 0;
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
 		"cs46xx: cs46xx_init_module()+ \n"));
-	if (!pci_present()) {	/* No PCI bus in this machine! */
-		CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
-			"cs46xx: cs46xx_init_module()- no pci bus found\n"));
-		return -ENODEV;
-	}
 	rtn = pci_module_init(&cs46xx_pci_driver);
 
 	if(rtn == -ENODEV)
diff -urN linux-2.5.70-bk15/sound/oss/es1370.c linux-2.5.70-bk16/sound/oss/es1370.c
--- linux-2.5.70-bk15/sound/oss/es1370.c	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/es1370.c	2003-06-11 04:48:11.000000000 -0700
@@ -2739,8 +2739,6 @@
 
 static int __init init_es1370(void)
 {
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
 	printk(KERN_INFO "es1370: version v0.38 time " __TIME__ " " __DATE__ "\n");
 	return pci_module_init(&es1370_driver);
 }
diff -urN linux-2.5.70-bk15/sound/oss/es1371.c linux-2.5.70-bk16/sound/oss/es1371.c
--- linux-2.5.70-bk15/sound/oss/es1371.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/es1371.c	2003-06-11 04:48:11.000000000 -0700
@@ -3043,8 +3043,6 @@
 
 static int __init init_es1371(void)
 {
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
 	printk(KERN_INFO PFX "version v0.32 time " __TIME__ " " __DATE__ "\n");
 	return pci_module_init(&es1371_driver);
 }
diff -urN linux-2.5.70-bk15/sound/oss/esssolo1.c linux-2.5.70-bk16/sound/oss/esssolo1.c
--- linux-2.5.70-bk15/sound/oss/esssolo1.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/esssolo1.c	2003-06-11 04:48:11.000000000 -0700
@@ -2459,8 +2459,6 @@
 
 static int __init init_solo1(void)
 {
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
 	printk(KERN_INFO "solo1: version v0.20 time " __TIME__ " " __DATE__ "\n");
 	if (!pci_register_driver(&solo1_driver)) {
 		pci_unregister_driver(&solo1_driver);
diff -urN linux-2.5.70-bk15/sound/oss/i810_audio.c linux-2.5.70-bk16/sound/oss/i810_audio.c
--- linux-2.5.70-bk15/sound/oss/i810_audio.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/i810_audio.c	2003-06-11 04:48:11.000000000 -0700
@@ -3449,9 +3449,6 @@
 
 static int __init i810_init_module (void)
 {
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
-
 	printk(KERN_INFO "Intel 810 + AC97 Audio, version "
 	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
 
diff -urN linux-2.5.70-bk15/sound/oss/ite8172.c linux-2.5.70-bk16/sound/oss/ite8172.c
--- linux-2.5.70-bk15/sound/oss/ite8172.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/ite8172.c	2003-06-11 04:48:11.000000000 -0700
@@ -1940,8 +1940,6 @@
 
 static int __init init_it8172(void)
 {
-    if (!pci_present())   /* No PCI bus in this machine! */
-	return -ENODEV;
     printk("version v0.26 time " __TIME__ " " __DATE__ "\n");
     return pci_module_init(&it8172_driver);
 }
diff -urN linux-2.5.70-bk15/sound/oss/maestro3.c linux-2.5.70-bk16/sound/oss/maestro3.c
--- linux-2.5.70-bk15/sound/oss/maestro3.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/maestro3.c	2003-06-11 04:48:11.000000000 -0700
@@ -2936,9 +2936,6 @@
 
 static int __init m3_init_module(void)
 {
-    if (!pci_present())   /* No PCI bus in this machine! */
-        return -ENODEV;
-
     printk(KERN_INFO PFX "version " DRIVER_VERSION " built at " __TIME__ " " __DATE__ "\n");
 
     if (register_reboot_notifier(&m3_reboot_nb)) {
diff -urN linux-2.5.70-bk15/sound/oss/nec_vrc5477.c linux-2.5.70-bk16/sound/oss/nec_vrc5477.c
--- linux-2.5.70-bk15/sound/oss/nec_vrc5477.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/nec_vrc5477.c	2003-06-11 04:48:11.000000000 -0700
@@ -2002,8 +2002,6 @@
 
 static int __init init_vrc5477_ac97(void)
 {
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
 	printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n");
 	return pci_module_init(&vrc5477_ac97_driver);
 }
diff -urN linux-2.5.70-bk15/sound/oss/rme96xx.c linux-2.5.70-bk16/sound/oss/rme96xx.c
--- linux-2.5.70-bk15/sound/oss/rme96xx.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/rme96xx.c	2003-06-11 04:48:11.000000000 -0700
@@ -1093,9 +1093,6 @@
 
 static int __init init_rme96xx(void)
 {
-  
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
 	printk(KERN_INFO RME_MESS" version "RMEVERSION" time " __TIME__ " " __DATE__ "\n");
 	devices = ((devices-1) & RME96xx_MASK_DEVS) + 1;
 	printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices);
diff -urN linux-2.5.70-bk15/sound/oss/skeleton.c linux-2.5.70-bk16/sound/oss/skeleton.c
--- linux-2.5.70-bk15/sound/oss/skeleton.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/skeleton.c	2003-06-11 04:48:11.000000000 -0700
@@ -159,10 +159,6 @@
 	struct pci_dev *pcidev=NULL;
 	int count=0;
 		
-	if(!pci_present())
-		return -ENODEV;
-	
-		
 	while((pcidev = pci_find_device(PCI_VENDOR_MYIDENT, PCI_DEVICE_ID_MYIDENT_MYCARD1, pcidev))!=NULL)
 	{
 		if (pci_enable_device(pcidev))
diff -urN linux-2.5.70-bk15/sound/oss/sonicvibes.c linux-2.5.70-bk16/sound/oss/sonicvibes.c
--- linux-2.5.70-bk15/sound/oss/sonicvibes.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/sonicvibes.c	2003-06-11 04:48:11.000000000 -0700
@@ -2723,8 +2723,6 @@
  
 static int __init init_sonicvibes(void)
 {
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
 	printk(KERN_INFO "sv: version v0.31 time " __TIME__ " " __DATE__ "\n");
 #if 0
 	if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
diff -urN linux-2.5.70-bk15/sound/oss/trident.c linux-2.5.70-bk16/sound/oss/trident.c
--- linux-2.5.70-bk15/sound/oss/trident.c	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk16/sound/oss/trident.c	2003-06-11 04:48:11.000000000 -0700
@@ -4385,9 +4385,6 @@
 
 static int __init trident_init_module (void)
 {
-	if (!pci_present())   /* No PCI bus in this machine! */
-		return -ENODEV;
-
 	printk(KERN_INFO "Trident 4DWave/SiS 7018/ALi 5451,Tvia CyberPro "
 	       "5050 PCI Audio, version " DRIVER_VERSION ", " 
 	       __TIME__ " " __DATE__ "\n");
diff -urN linux-2.5.70-bk15/sound/pci/ac97/ac97_patch.c linux-2.5.70-bk16/sound/pci/ac97/ac97_patch.c
--- linux-2.5.70-bk15/sound/pci/ac97/ac97_patch.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/pci/ac97/ac97_patch.c	2003-06-11 04:48:11.000000000 -0700
@@ -370,18 +370,17 @@
 	unsigned short val;
 	int spdif = 0;
 
-	/* FIXME: set the above 1 if we can detect the chip rev.E correctly.
+	/* FIXME: set the below 1 if we can detect the chip rev.E correctly.
 	 *        this is used for switching mic and center/lfe, which needs
 	 *        resetting GPIO0 level on the older revision.
 	 */
 	ac97->spec.dev_flags = 0;
 
-	/* check spdif */
-	if (ac97->spec.dev_flags) {
-		val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
-		if (val & AC97_EA_SPCV)
-			spdif = 1;
-	}
+	/* check spdif (should be only on rev.E) */
+	val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
+	if (val & AC97_EA_SPCV)
+		spdif = 1;
+
 	if (spdif) {
 		/* enable spdif in */
 		snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK,
diff -urN linux-2.5.70-bk15/sound/pci/emu10k1/emufx.c linux-2.5.70-bk16/sound/pci/emu10k1/emufx.c
--- linux-2.5.70-bk15/sound/pci/emu10k1/emufx.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/pci/emu10k1/emufx.c	2003-06-11 04:48:11.000000000 -0700
@@ -1012,7 +1012,6 @@
 		ctl = snd_emu10k1_look_for_ctl(emu, &id);
 		snd_runtime_check(ctl == NULL, continue);
 		snd_ctl_remove(emu->card, ctl->kcontrol);
-		list_del(&ctl->list);
 	}
 }
 
diff -urN linux-2.5.70-bk15/sound/pci/ice1712/Makefile linux-2.5.70-bk16/sound/pci/ice1712/Makefile
--- linux-2.5.70-bk15/sound/pci/ice1712/Makefile	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/pci/ice1712/Makefile	2003-06-11 04:48:11.000000000 -0700
@@ -3,9 +3,10 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o ak4xxx.o
-snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o ak4xxx.o
+snd-ice17xx-ak4xxx-objs := ak4xxx.o
+snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
+snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o
 
 # Toplevel Module Dependency
-obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o
-obj-$(CONFIG_SND_ICE1724) += snd-ice1724.o
+obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
+obj-$(CONFIG_SND_ICE1724) += snd-ice1724.o snd-ice17xx-ak4xxx.o
diff -urN linux-2.5.70-bk15/sound/pci/ice1712/ak4xxx.c linux-2.5.70-bk16/sound/pci/ice1712/ak4xxx.c
--- linux-2.5.70-bk15/sound/pci/ice1712/ak4xxx.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/pci/ice1712/ak4xxx.c	2003-06-11 04:48:11.000000000 -0700
@@ -168,3 +168,7 @@
 	}
 	return 0;
 }
+
+EXPORT_SYMBOL(snd_ice1712_akm4xxx_init);
+EXPORT_SYMBOL(snd_ice1712_akm4xxx_free);
+EXPORT_SYMBOL(snd_ice1712_akm4xxx_build_controls);
diff -urN linux-2.5.70-bk15/sound/pcmcia/vx/Makefile linux-2.5.70-bk16/sound/pcmcia/vx/Makefile
--- linux-2.5.70-bk15/sound/pcmcia/vx/Makefile	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/pcmcia/vx/Makefile	2003-06-11 04:48:11.000000000 -0700
@@ -3,8 +3,9 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-vxpocket-objs := vxpocket.o vx_entry.o vxp_ops.o vxp_mixer.o
-snd-vxp440-objs := vxpocket.o vx_entry.o vxp_ops.o vxp_mixer.o
+snd-vx-cs-objs := vx_entry.o vxp_ops.o vxp_mixer.o
+snd-vxpocket-objs := vxpocket.o
+snd-vxp440-objs := vxp440.o
 
-obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o
-obj-$(CONFIG_SND_VXP440) += snd-vxp440.o
+obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o snd-vx-cs.o
+obj-$(CONFIG_SND_VXP440) += snd-vxp440.o snd-vx-cs.o
diff -urN linux-2.5.70-bk15/sound/pcmcia/vx/vx_entry.c linux-2.5.70-bk16/sound/pcmcia/vx/vx_entry.c
--- linux-2.5.70-bk15/sound/pcmcia/vx/vx_entry.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/pcmcia/vx/vx_entry.c	2003-06-11 04:48:11.000000000 -0700
@@ -371,10 +371,6 @@
 	return 0;
 }
 
-/* we link this module statically with the card modules
- * due to the pcmcia symbol problems...
- */
-#if 0
 /*
  * exported stuffs
  */
@@ -382,4 +378,3 @@
 EXPORT_SYMBOL(snd_vxpocket_attach);
 EXPORT_SYMBOL(snd_vxpocket_detach);
 EXPORT_SYMBOL(snd_vxpocket_detach_all);
-#endif
diff -urN linux-2.5.70-bk15/sound/pcmcia/vx/vxpocket.c linux-2.5.70-bk16/sound/pcmcia/vx/vxpocket.c
--- linux-2.5.70-bk15/sound/pcmcia/vx/vxpocket.c	2003-06-11 04:47:57.000000000 -0700
+++ linux-2.5.70-bk16/sound/pcmcia/vx/vxpocket.c	2003-06-11 04:48:11.000000000 -0700
@@ -34,7 +34,6 @@
 #include <sound/core.h>
 #include <pcmcia/version.h>
 #include "vxpocket.h"
-#define SNDRV_GET_ID
 #include <sound/initval.h>
 
 /*
@@ -81,7 +80,6 @@
  */
 
 #ifdef COMPILE_VXP440
-static dev_info_t dev_info = "snd-vxp440";
 
 /* 1 DSP, 1 sync UER, 1 sync World Clock (NIY) */
 /* SMPTE (NIY) */
@@ -92,9 +90,9 @@
 
 #define NUM_CODECS	2
 #define CARD_TYPE	VX_TYPE_VXP440
+#define DEV_INFO	"snd-vxp440"
 
 #else
-static dev_info_t dev_info = "snd-vxpocket";
 
 /* 1 DSP, 1 sync UER */
 /* 1 programmable clock (NIY) */
@@ -104,8 +102,11 @@
 
 #define NUM_CODECS	1
 #define CARD_TYPE	VX_TYPE_VXPOCKET
+#define DEV_INFO	"snd-vxpocket"
+
 #endif
 
+static dev_info_t dev_info = DEV_INFO;
 
 static struct snd_vx_hardware vxp_hw = {
 	.name = CARD_NAME,
@@ -146,28 +147,28 @@
 	snd_vxpocket_detach(&hw_entry, link);
 }
 
-
 /*
  * Module entry points
  */
 
+static struct pcmcia_driver vxp_cs_driver = {
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= DEV_INFO,
+	},
+	.attach		= vxp_attach,
+	.detach		= vxp_detach
+};
+
 static int __init init_vxpocket(void)
 {
-	servinfo_t serv;
-
-	CardServices(GetCardServicesInfo, &serv);
-	if (serv.Revision != CS_RELEASE_CODE) {
-		printk(KERN_WARNING "init_vxpocket: Card Services release does not match (%x != %x)!\n", serv.Revision, CS_RELEASE_CODE);
-		return -1;
-	}
-	register_pccard_driver(&dev_info, vxp_attach, vxp_detach);
-	return 0;
+	return pcmcia_register_driver(&vxp_cs_driver);
 }
 
 static void __exit exit_vxpocket(void)
 {
-        unregister_pccard_driver(&dev_info);
-        snd_vxpocket_detach_all(&hw_entry);
+	pcmcia_unregister_driver(&vxp_cs_driver);
+	snd_vxpocket_detach_all(&hw_entry);
 }
 
 module_init(init_vxpocket);
