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

diff -urN linux-2.5.72-bk2/Documentation/firmware_class/README linux-2.5.72-bk3/Documentation/firmware_class/README
--- linux-2.5.72-bk2/Documentation/firmware_class/README	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.72-bk3/Documentation/firmware_class/README	2003-06-20 04:48:10.000000000 -0700
@@ -0,0 +1,58 @@
+
+ request_firmware() hotplug interface:
+ ------------------------------------
+	Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
+
+ Why:
+ ---
+
+ Today, the most extended way to use firmware in the Linux kernel is linking
+ it statically in a header file. Which has political and technical issues:
+
+  1) Some firmware is not legal to redistribute.
+  2) The firmware occupies memory permanently, even though it often is just
+     used once.
+  3) Some people, like the Debian crowd, don't consider some firmware free
+     enough and remove entire drivers (e.g.: keyspan).
+
+ about in-kernel persistence:
+ ---------------------------
+ Under some circumstances, as explained below, it would be interesting to keep
+ firmware images in non-swappable kernel memory or even in the kernel image
+ (probably within initramfs).
+
+ Note that this functionality has not been implemented.
+
+ - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
+ 
+	- If the device that needs the firmware is needed to access the
+	  filesystem. When upon some error the device has to be reset and the
+	  firmware reloaded, it won't be possible to get it from userspace.
+	  e.g.:
+		- A diskless client with a network card that needs firmware.
+		- The filesystem is stored in a disk behind an scsi device
+		  that needs firmware.
+	- Replacing buggy DSDT/SSDT ACPI tables on boot.
+	  Note: this would require the persistent objects to be included
+	  within the kernel image, probably within initramfs.
+	  
+   And the same device can be needed to access the filesystem or not depending
+   on the setup, so I think that the choice on what firmware to make
+   persistent should be left to userspace.
+
+ - Why register_firmware()+__init can be useful:
+ 	- For boot devices needing firmware.
+	- To make the transition easier:
+		The firmware can be declared __init and register_firmware()
+		called on module_init. Then the firmware is warranted to be
+		there even if "firmware hotplug userspace" is not there yet or
+		it doesn't yet provide the needed firmware.
+		Once the firmware is widely available in userspace, it can be
+		removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
+
+	In either case, if firmware hotplug support is there, it can move the
+	firmware out of kernel memory into the real filesystem for later
+	usage.
+
+	Note: If persistence is implemented on top of initramfs,
+	register_firmware() may not be appropriate.
diff -urN linux-2.5.72-bk2/Documentation/firmware_class/firmware_sample_driver.c linux-2.5.72-bk3/Documentation/firmware_class/firmware_sample_driver.c
--- linux-2.5.72-bk2/Documentation/firmware_class/firmware_sample_driver.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.72-bk3/Documentation/firmware_class/firmware_sample_driver.c	2003-06-20 04:48:10.000000000 -0700
@@ -0,0 +1,126 @@
+/*
+ * firmware_sample_driver.c -
+ *
+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ *
+ * Sample code on how to use request_firmware() from drivers.
+ *
+ * Note that register_firmware() is currently useless.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include "linux/firmware.h"
+
+#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+char __init inkernel_firmware[] = "let's say that this is firmware\n";
+#endif
+
+static struct device ghost_device = {
+	.name      = "Ghost Device",
+	.bus_id    = "ghost0",
+};
+
+
+static void sample_firmware_load(char *firmware, int size)
+{
+	u8 buf[size+1];
+	memcpy(buf, firmware, size);
+	buf[size] = '\0';
+	printk("firmware_sample_driver: firmware: %s\n", buf);
+}
+
+static void sample_probe_default(void)
+{
+	/* uses the default method to get the firmware */
+        const struct firmware *fw_entry;
+	printk("firmware_sample_driver: a ghost device got inserted :)\n");
+
+        if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0)
+	{
+		printk(KERN_ERR
+		       "firmware_sample_driver: Firmware not available\n");
+		return;
+	}
+	
+	sample_firmware_load(fw_entry->data, fw_entry->size);
+
+	release_firmware(fw_entry);
+
+	/* finish setting up the device */
+}
+static void sample_probe_specific(void)
+{
+	/* Uses some specific hotplug support to get the firmware from
+	 * userspace  directly into the hardware, or via some sysfs file */
+
+	/* NOTE: This currently doesn't work */
+
+	printk("firmware_sample_driver: a ghost device got inserted :)\n");
+
+        if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0)
+	{
+		printk(KERN_ERR
+		       "firmware_sample_driver: Firmware load failed\n");
+		return;
+	}
+	
+	/* request_firmware blocks until userspace finished, so at
+	 * this point the firmware should be already in the device */
+
+	/* finish setting up the device */
+}
+static void sample_probe_async_cont(const struct firmware *fw, void *context)
+{
+	if(!fw){
+		printk(KERN_ERR
+		       "firmware_sample_driver: firmware load failed\n");
+		return;
+	}
+
+	printk("firmware_sample_driver: device pointer \"%s\"\n",
+	       (char *)context);
+	sample_firmware_load(fw->data, fw->size);
+}
+static void sample_probe_async(void)
+{
+	/* Let's say that I can't sleep */
+	int error;
+	error = request_firmware_nowait (THIS_MODULE,
+					 "sample_driver_fw", &ghost_device,
+					 "my device pointer",
+					 sample_probe_async_cont);
+	if(error){
+		printk(KERN_ERR 
+		       "firmware_sample_driver:"
+		       " request_firmware_nowait failed\n");
+	}
+}
+
+static int sample_init(void)
+{
+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+	register_firmware("sample_driver_fw", inkernel_firmware,
+			  sizeof(inkernel_firmware));
+#endif
+	device_initialize(&ghost_device);
+	/* since there is no real hardware insertion I just call the
+	 * sample probe functions here */
+	sample_probe_specific();
+	sample_probe_default();
+	sample_probe_async();
+	return 0;
+}
+static void __exit sample_exit(void)
+{
+}
+
+module_init (sample_init);
+module_exit (sample_exit);
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.5.72-bk2/Documentation/firmware_class/firmware_sample_firmware_class.c linux-2.5.72-bk3/Documentation/firmware_class/firmware_sample_firmware_class.c
--- linux-2.5.72-bk2/Documentation/firmware_class/firmware_sample_firmware_class.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.72-bk3/Documentation/firmware_class/firmware_sample_firmware_class.c	2003-06-20 04:48:10.000000000 -0700
@@ -0,0 +1,205 @@
+/*
+ * firmware_sample_firmware_class.c -
+ *
+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ *
+ * NOTE: This is just a probe of concept, if you think that your driver would
+ * be well served by this mechanism please contact me first.
+ *
+ * DON'T USE THIS CODE AS IS
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <asm/hardirq.h>
+
+#include "linux/firmware.h"
+
+MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
+MODULE_DESCRIPTION("Hackish sample for using firmware class directly");
+MODULE_LICENSE("GPL");
+
+static inline struct class_device *to_class_dev(struct kobject *obj)
+{
+	return container_of(obj,struct class_device,kobj);
+}
+static inline
+struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
+{
+	return container_of(_attr,struct class_device_attribute,attr);
+}
+
+int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+
+struct firmware_priv {
+	char fw_id[FIRMWARE_NAME_MAX];
+	s32 loading:2;
+	u32 abort:1;
+};
+
+extern struct class firmware_class;
+
+static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf)
+{
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+	return sprintf(buf, "%d\n", fw_priv->loading);
+}
+static ssize_t firmware_loading_store(struct class_device *class_dev,
+				      const char *buf, size_t count)
+{
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+	int prev_loading = fw_priv->loading;
+
+	fw_priv->loading = simple_strtol(buf, NULL, 10);
+	
+	switch(fw_priv->loading){
+	case -1:
+		/* abort load an panic */
+		break;
+	case 1:
+		/* setup load */
+		break;
+	case 0:
+		if(prev_loading==1){
+			/* finish load and get the device back to working
+			 * state */
+		}
+		break;
+	}
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(loading, 0644,
+			 firmware_loading_show, firmware_loading_store);
+
+static ssize_t firmware_data_read(struct kobject *kobj,
+				  char *buffer, loff_t offset, size_t count)
+{
+	struct class_device *class_dev = to_class_dev(kobj);
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+	/* read from the devices firmware memory */
+
+	return count;
+}
+static ssize_t firmware_data_write(struct kobject *kobj,
+				   char *buffer, loff_t offset, size_t count)
+{
+	struct class_device *class_dev = to_class_dev(kobj);
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+	/* write to the devices firmware memory */
+
+	return count;
+}
+static struct bin_attribute firmware_attr_data = {
+	.attr = {.name = "data", .mode = 0644},
+	.size = 0,
+	.read = firmware_data_read,
+	.write = firmware_data_write,
+};
+static int fw_setup_class_device(struct class_device *class_dev,
+				 const char *fw_name,
+				 struct device *device)
+{
+	int retval = 0;
+	struct firmware_priv *fw_priv = kmalloc(sizeof(struct firmware_priv),
+						GFP_KERNEL);
+
+	if(!fw_priv){
+		retval = -ENOMEM;
+		goto out;
+	}
+	memset(fw_priv, 0, sizeof(*fw_priv));
+	memset(class_dev, 0, sizeof(*class_dev));
+
+	strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX);
+	fw_priv->fw_id[FIRMWARE_NAME_MAX-1] = '\0';
+
+	strncpy(class_dev->class_id, device->bus_id, BUS_ID_SIZE);
+	class_dev->class_id[BUS_ID_SIZE-1] = '\0';
+	class_dev->dev = device;
+
+	class_dev->class = &firmware_class,
+	class_set_devdata(class_dev, fw_priv);
+	retval = class_device_register(class_dev);
+	if (retval){
+		printk(KERN_ERR "%s: class_device_register failed\n",
+		       __FUNCTION__);
+		goto error_free_fw_priv;
+	}
+
+	retval = sysfs_create_bin_file(&class_dev->kobj, &firmware_attr_data);
+	if (retval){
+		printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
+		       __FUNCTION__);
+		goto error_unreg_class_dev;
+	}
+
+	retval = class_device_create_file(class_dev,
+					  &class_device_attr_loading);
+	if (retval){
+		printk(KERN_ERR "%s: class_device_create_file failed\n",
+		       __FUNCTION__);
+		goto error_remove_data;
+	}
+
+	goto out;
+	
+error_remove_data:
+	sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data);
+error_unreg_class_dev:
+	class_device_unregister(class_dev);
+error_free_fw_priv:
+	kfree(fw_priv);
+out:
+	return retval;
+}
+static void fw_remove_class_device(struct class_device *class_dev)
+{
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+	class_device_remove_file(class_dev, &class_device_attr_loading);
+	sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data);
+	class_device_unregister(class_dev);
+}
+
+static struct class_device *class_dev;
+
+static struct device my_device = {
+	.name      = "Sample Device",
+	.bus_id    = "my_dev0",
+};
+
+static int __init firmware_sample_init(void)
+{
+	int error;
+
+	device_initialize(&my_device);
+	class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+	if(!class_dev)
+		return -ENOMEM;
+
+	error = fw_setup_class_device(class_dev, "my_firmware_image",
+				      &my_device);
+	if(error){
+		kfree(class_dev);
+		return error;
+	}
+        return 0;
+
+}
+static void __exit firmware_sample_exit(void)
+{
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+	fw_remove_class_device(class_dev);
+	kfree(fw_priv);
+	kfree(class_dev);
+}
+module_init(firmware_sample_init);
+module_exit(firmware_sample_exit);
+
diff -urN linux-2.5.72-bk2/Documentation/firmware_class/hotplug-script linux-2.5.72-bk3/Documentation/firmware_class/hotplug-script
--- linux-2.5.72-bk2/Documentation/firmware_class/hotplug-script	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.72-bk3/Documentation/firmware_class/hotplug-script	2003-06-20 04:48:10.000000000 -0700
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# Simple hotplug script sample:
+# 
+# Both $DEVPATH and $FIRMWARE are already provided in the environment.
+
+HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
+
+echo 1 > /sysfs/$DEVPATH/loading
+cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data
+echo 0 > /sysfs/$DEVPATH/loading
+
+# To cancel the load in case of error:
+#
+#	echo -1 > /sysfs/$DEVPATH/loading
+#
diff -urN linux-2.5.72-bk2/Documentation/kobject.txt linux-2.5.72-bk3/Documentation/kobject.txt
--- linux-2.5.72-bk2/Documentation/kobject.txt	2003-06-16 21:19:46.000000000 -0700
+++ linux-2.5.72-bk3/Documentation/kobject.txt	2003-06-20 04:48:10.000000000 -0700
@@ -5,15 +5,8 @@
 Updated: 3 June 2003
 
 
-Copyright (c)  Patrick Mochel
-Copyright (c)  Open Source Development Labs
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.2
-or any later version published by the Free Software Foundation;
-with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-A copy of the license is included in the section entitled "GNU
-Free Documentation License".
-
+Copyright (c)  2003 Patrick Mochel
+Copyright (c)  2003 Open Source Development Labs
 
 
 0. Introduction
diff -urN linux-2.5.72-bk2/Makefile linux-2.5.72-bk3/Makefile
--- linux-2.5.72-bk2/Makefile	2003-06-20 04:48:04.000000000 -0700
+++ linux-2.5.72-bk3/Makefile	2003-06-20 04:48:10.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 72
-EXTRAVERSION = -bk2
+EXTRAVERSION = -bk3
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.72-bk2/arch/alpha/Kconfig linux-2.5.72-bk3/arch/alpha/Kconfig
--- linux-2.5.72-bk2/arch/alpha/Kconfig	2003-06-20 04:48:04.000000000 -0700
+++ linux-2.5.72-bk3/arch/alpha/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -653,6 +653,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/pnp/Kconfig"
diff -urN linux-2.5.72-bk2/arch/alpha/kernel/alpha_ksyms.c linux-2.5.72-bk3/arch/alpha/kernel/alpha_ksyms.c
--- linux-2.5.72-bk2/arch/alpha/kernel/alpha_ksyms.c	2003-06-16 21:19:40.000000000 -0700
+++ linux-2.5.72-bk3/arch/alpha/kernel/alpha_ksyms.c	2003-06-20 04:48:10.000000000 -0700
@@ -156,7 +156,7 @@
 EXPORT_SYMBOL(sys_write);
 EXPORT_SYMBOL(sys_read);
 EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(__kernel_execve);
+EXPORT_SYMBOL(execve);
 EXPORT_SYMBOL(sys_setsid);
 EXPORT_SYMBOL(sys_wait4);
 
diff -urN linux-2.5.72-bk2/arch/alpha/kernel/entry.S linux-2.5.72-bk3/arch/alpha/kernel/entry.S
--- linux-2.5.72-bk2/arch/alpha/kernel/entry.S	2003-06-16 21:19:37.000000000 -0700
+++ linux-2.5.72-bk3/arch/alpha/kernel/entry.S	2003-06-20 04:48:10.000000000 -0700
@@ -606,7 +606,8 @@
 	.globl	kernel_thread
 	.ent	kernel_thread
 kernel_thread:
-	ldgp	$gp, 0($27)	/* we can be called from a module */
+	/* We can be called from a module.  */
+	ldgp	$gp, 0($27)
 	.prologue 1
 	subq	$sp, SP_OFF+6*8, $sp
 	br	$1, 2f		/* load start address */
@@ -654,26 +655,56 @@
 .end kernel_thread
 
 /*
- * __kernel_execve(path, argv, envp, regs)
+ * execve(path, argv, envp)
  */
 	.align	4
-	.globl	__kernel_execve
-	.ent	__kernel_execve
-__kernel_execve:
-	ldgp	$gp, 0($27)	/* we can be called from modules.  */
-	subq	$sp, 16, $sp
-	.frame	$sp, 16, $26, 0
+	.globl	execve
+	.ent	execve
+execve:
+	/* We can be called from a module.  */
+	ldgp	$gp, 0($27)
+	lda	$sp, -(32+SIZEOF_PT_REGS+8)($sp)
+	.frame	$sp, 32+SIZEOF_PT_REGS+8, $26, 0
 	stq	$26, 0($sp)
-	stq	$19, 8($sp)
+	stq	$16, 8($sp)
+	stq	$17, 16($sp)
+	stq	$18, 24($sp)
 	.prologue 1
-	jsr	$26, do_execve
-	bne	$0, 1f		/* error! */
-	ldq	$sp, 8($sp)
+
+	lda	$16, 32($sp)
+	lda	$17, 0
+	lda	$18, SIZEOF_PT_REGS
+	bsr	$26, memset		!samegp
+
+	/* Avoid the HAE being gratuitously wrong, which would cause us
+	   to do the whole turn off interrupts thing and restore it.  */
+	ldq	$2, alpha_mv+HAE_CACHE
+	stq	$2, 152+32($sp)
+
+	ldq	$16, 8($sp)
+	ldq	$17, 16($sp)
+	ldq	$18, 24($sp)
+	lda	$19, 32($sp)
+	bsr	$26, do_execve		!samegp
+
+	ldq	$26, 0($sp)
+	bne	$0, 1f			/* error! */
+
+	/* Move the temporary pt_regs struct from its current location
+	   to the top of the kernel stack frame.  See copy_thread for
+	   details for a normal process.  */
+	lda	$16, 0x4000 - SIZEOF_PT_REGS($8)
+	lda	$17, 32($sp)
+	lda	$18, SIZEOF_PT_REGS
+	bsr	$26, memmove		!samegp
+
+	/* Take that over as our new stack frame and visit userland!  */
+	lda	$sp, 0x4000 - SIZEOF_PT_REGS($8)
 	br	$31, ret_from_sys_call
-1:	ldq	$26, 0($sp)
-	addq	$sp, 16, $sp
+
+1:	lda	$sp, 32+SIZEOF_PT_REGS+8($sp)
 	ret
-.end __kernel_execve
+.end execve
 
 
 /*
diff -urN linux-2.5.72-bk2/arch/alpha/kernel/srmcons.c linux-2.5.72-bk3/arch/alpha/kernel/srmcons.c
--- linux-2.5.72-bk2/arch/alpha/kernel/srmcons.c	2003-06-16 21:20:22.000000000 -0700
+++ linux-2.5.72-bk3/arch/alpha/kernel/srmcons.c	2003-06-20 04:48:10.000000000 -0700
@@ -291,6 +291,7 @@
 		driver->type = TTY_DRIVER_TYPE_SYSTEM;
 		driver->subtype = SYSTEM_TYPE_SYSCONS;
 		driver->init_termios = tty_std_termios;
+		tty_set_operations(driver, &srmcons_ops);
 		err = tty_register_driver(driver);
 		if (err) {
 			put_tty_driver(driver);
diff -urN linux-2.5.72-bk2/arch/alpha/lib/memmove.S linux-2.5.72-bk3/arch/alpha/lib/memmove.S
--- linux-2.5.72-bk2/arch/alpha/lib/memmove.S	2003-06-16 21:20:01.000000000 -0700
+++ linux-2.5.72-bk3/arch/alpha/lib/memmove.S	2003-06-20 04:48:10.000000000 -0700
@@ -15,15 +15,23 @@
 	.globl bcopy
 	.ent bcopy
 bcopy:
+	ldgp $29, 0($27)
+	.prologue 1
 	mov $16,$0
 	mov $17,$16
 	mov $0,$17
+	br  $31, memmove	!samegp
 	.end bcopy
 
 	.align 4
 	.globl memmove
 	.ent memmove
 memmove:
+	ldgp $29, 0($27)
+	unop
+	nop
+	.prologue 1
+
 	addq $16,$18,$4
 	addq $17,$18,$5
 	cmpule $4,$17,$1		/*  dest + n <= src  */
@@ -32,7 +40,7 @@
 	bis $1,$2,$1
 	mov $16,$0
 	xor $16,$17,$2
-	bne $1,memcpy
+	bne $1,memcpy			!samegp
 
 	and $2,7,$2			/* Test for src/dest co-alignment.  */
 	and $16,7,$1
diff -urN linux-2.5.72-bk2/arch/alpha/oprofile/common.c linux-2.5.72-bk3/arch/alpha/oprofile/common.c
--- linux-2.5.72-bk2/arch/alpha/oprofile/common.c	2003-06-16 21:19:40.000000000 -0700
+++ linux-2.5.72-bk3/arch/alpha/oprofile/common.c	2003-06-20 04:48:10.000000000 -0700
@@ -188,7 +188,7 @@
 }
 
 
-void __exit
+void
 oprofile_arch_exit(void)
 {
 }
diff -urN linux-2.5.72-bk2/arch/arm/Kconfig linux-2.5.72-bk3/arch/arm/Kconfig
--- linux-2.5.72-bk2/arch/arm/Kconfig	2003-06-20 04:48:04.000000000 -0700
+++ linux-2.5.72-bk3/arch/arm/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -703,6 +703,8 @@
 
 source "fs/Kconfig.binfmt"
 
+source "drivers/base/Kconfig"
+
 config PM
 	bool "Power Management support"
 	---help---
diff -urN linux-2.5.72-bk2/arch/arm26/Kconfig linux-2.5.72-bk3/arch/arm26/Kconfig
--- linux-2.5.72-bk2/arch/arm26/Kconfig	2003-06-16 21:20:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/arm26/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -297,6 +297,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/parport/Kconfig"
 
 source "drivers/pnp/Kconfig"
diff -urN linux-2.5.72-bk2/arch/cris/Kconfig linux-2.5.72-bk3/arch/cris/Kconfig
--- linux-2.5.72-bk2/arch/cris/Kconfig	2003-06-20 04:48:04.000000000 -0700
+++ linux-2.5.72-bk3/arch/cris/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -515,6 +515,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 # bring in Etrax built-in drivers
 source "arch/cris/drivers/Kconfig"
 
diff -urN linux-2.5.72-bk2/arch/h8300/Kconfig linux-2.5.72-bk3/arch/h8300/Kconfig
--- linux-2.5.72-bk2/arch/h8300/Kconfig	2003-06-20 04:48:04.000000000 -0700
+++ linux-2.5.72-bk3/arch/h8300/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -145,6 +145,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/ide/Kconfig"
diff -urN linux-2.5.72-bk2/arch/i386/Kconfig linux-2.5.72-bk3/arch/i386/Kconfig
--- linux-2.5.72-bk2/arch/i386/Kconfig	2003-06-20 04:48:04.000000000 -0700
+++ linux-2.5.72-bk3/arch/i386/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -1194,6 +1194,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/parport/Kconfig"
diff -urN linux-2.5.72-bk2/arch/i386/kernel/time.c linux-2.5.72-bk3/arch/i386/kernel/time.c
--- linux-2.5.72-bk2/arch/i386/kernel/time.c	2003-06-16 21:20:01.000000000 -0700
+++ linux-2.5.72-bk3/arch/i386/kernel/time.c	2003-06-20 04:48:10.000000000 -0700
@@ -281,19 +281,19 @@
 	return retval;
 }
 
-static struct sysdev_class rtc_sysclass = {
-	set_kset_name("rtc"),
+static struct sysdev_class pit_sysclass = {
+	set_kset_name("pit"),
 };
 
 /* XXX this driverfs stuff should probably go elsewhere later -john */
 static struct sys_device device_i8253 = {
-	.id		= 0,
-	.cls	= &rtc_sysclass,
+	.id	= 0,
+	.cls	= &pit_sysclass,
 };
 
 static int time_init_device(void)
 {
-	int error = sysdev_class_register(&rtc_sysclass);
+	int error = sysdev_class_register(&pit_sysclass);
 	if (!error)
 		error = sys_device_register(&device_i8253);
 	return error;
diff -urN linux-2.5.72-bk2/arch/ia64/Kconfig linux-2.5.72-bk3/arch/ia64/Kconfig
--- linux-2.5.72-bk2/arch/ia64/Kconfig	2003-06-20 04:48:04.000000000 -0700
+++ linux-2.5.72-bk3/arch/ia64/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -534,6 +534,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 if !IA64_HP_SIM
 
 source "drivers/mtd/Kconfig"
diff -urN linux-2.5.72-bk2/arch/m68k/Kconfig linux-2.5.72-bk3/arch/m68k/Kconfig
--- linux-2.5.72-bk2/arch/m68k/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/m68k/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -573,6 +573,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/block/Kconfig"
diff -urN linux-2.5.72-bk2/arch/m68knommu/Kconfig linux-2.5.72-bk3/arch/m68knommu/Kconfig
--- linux-2.5.72-bk2/arch/m68knommu/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/m68knommu/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -515,6 +515,8 @@
 endmenu
 
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/parport/Kconfig"
diff -urN linux-2.5.72-bk2/arch/mips/Kconfig linux-2.5.72-bk3/arch/mips/Kconfig
--- linux-2.5.72-bk2/arch/mips/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/mips/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -744,6 +744,8 @@
 source "drivers/pnp/Kconfig"
 endif
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/parport/Kconfig"
diff -urN linux-2.5.72-bk2/arch/mips64/Kconfig linux-2.5.72-bk3/arch/mips64/Kconfig
--- linux-2.5.72-bk2/arch/mips64/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/mips64/Kconfig	2003-06-20 04:48:10.000000000 -0700
@@ -361,6 +361,8 @@
 
 source "drivers/pci/Kconfig"
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/parport/Kconfig"
diff -urN linux-2.5.72-bk2/arch/parisc/Kconfig linux-2.5.72-bk3/arch/parisc/Kconfig
--- linux-2.5.72-bk2/arch/parisc/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/parisc/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -170,6 +170,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 # source "drivers/mtd/Kconfig"
 
 source "drivers/parport/Kconfig"
diff -urN linux-2.5.72-bk2/arch/ppc/Kconfig linux-2.5.72-bk3/arch/ppc/Kconfig
--- linux-2.5.72-bk2/arch/ppc/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/ppc/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -1163,6 +1163,8 @@
 	depends on ADVANCED_OPTIONS && 8xx
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/pnp/Kconfig"
diff -urN linux-2.5.72-bk2/arch/ppc64/Kconfig linux-2.5.72-bk3/arch/ppc64/Kconfig
--- linux-2.5.72-bk2/arch/ppc64/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/ppc64/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -241,6 +241,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/parport/Kconfig"
diff -urN linux-2.5.72-bk2/arch/s390/Kconfig linux-2.5.72-bk3/arch/s390/Kconfig
--- linux-2.5.72-bk2/arch/s390/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/s390/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -229,6 +229,8 @@
 	bool
 	default n
 
+source "drivers/base/Kconfig"
+
 menu "SCSI support"
 
 config SCSI
diff -urN linux-2.5.72-bk2/arch/sh/Kconfig linux-2.5.72-bk3/arch/sh/Kconfig
--- linux-2.5.72-bk2/arch/sh/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/sh/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -767,6 +767,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/parport/Kconfig"
diff -urN linux-2.5.72-bk2/arch/sparc/Kconfig linux-2.5.72-bk3/arch/sparc/Kconfig
--- linux-2.5.72-bk2/arch/sparc/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/sparc/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -319,6 +319,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/video/Kconfig"
 
 source "drivers/mtd/Kconfig"
diff -urN linux-2.5.72-bk2/arch/sparc64/Kconfig linux-2.5.72-bk3/arch/sparc64/Kconfig
--- linux-2.5.72-bk2/arch/sparc64/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/sparc64/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -521,6 +521,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/video/Kconfig"
 
 source "drivers/serial/Kconfig"
diff -urN linux-2.5.72-bk2/arch/um/Kconfig linux-2.5.72-bk3/arch/um/Kconfig
--- linux-2.5.72-bk2/arch/um/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/um/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -171,6 +171,8 @@
 
 source "init/Kconfig"
 
+source "drivers/base/Kconfig"
+
 source "arch/um/Kconfig_char"
 
 source "arch/um/Kconfig_block"
diff -urN linux-2.5.72-bk2/arch/v850/Kconfig linux-2.5.72-bk3/arch/v850/Kconfig
--- linux-2.5.72-bk2/arch/v850/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/v850/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -249,6 +249,8 @@
 
 #############################################################################
 
+source "drivers/base/Kconfig"
+
 source drivers/mtd/Kconfig
 
 source drivers/parport/Kconfig
diff -urN linux-2.5.72-bk2/arch/x86_64/Kconfig linux-2.5.72-bk3/arch/x86_64/Kconfig
--- linux-2.5.72-bk2/arch/x86_64/Kconfig	2003-06-20 04:48:05.000000000 -0700
+++ linux-2.5.72-bk3/arch/x86_64/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -397,6 +397,8 @@
 
 endmenu
 
+source "drivers/base/Kconfig"
+
 source "drivers/mtd/Kconfig"
 
 source "drivers/parport/Kconfig"
diff -urN linux-2.5.72-bk2/drivers/base/Kconfig linux-2.5.72-bk3/drivers/base/Kconfig
--- linux-2.5.72-bk2/drivers/base/Kconfig	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.72-bk3/drivers/base/Kconfig	2003-06-20 04:48:11.000000000 -0700
@@ -0,0 +1,10 @@
+menu "Generic Driver Options"
+
+config FW_LOADER
+	tristate "Hotplug firmware loading support"
+	---help---
+	  This option is provided for the case where no in-kernel-tree modules
+	  require hotplug firmware loading support, but a module built outside
+	  the kernel tree does.
+
+endmenu
diff -urN linux-2.5.72-bk2/drivers/base/Makefile linux-2.5.72-bk3/drivers/base/Makefile
--- linux-2.5.72-bk2/drivers/base/Makefile	2003-06-16 21:20:21.000000000 -0700
+++ linux-2.5.72-bk3/drivers/base/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -3,4 +3,5 @@
 obj-y			:= core.o sys.o interface.o power.o bus.o \
 			   driver.o class.o platform.o \
 			   cpu.o firmware.o init.o map.o
+obj-$(CONFIG_FW_LOADER)	+= firmware_class.o
 obj-$(CONFIG_NUMA)	+= node.o  memblk.o
diff -urN linux-2.5.72-bk2/drivers/base/firmware_class.c linux-2.5.72-bk3/drivers/base/firmware_class.c
--- linux-2.5.72-bk2/drivers/base/firmware_class.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.72-bk3/drivers/base/firmware_class.c	2003-06-20 04:48:11.000000000 -0700
@@ -0,0 +1,505 @@
+/*
+ * firmware_class.c - Multi purpose firmware loading support
+ *
+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ *
+ * Please see Documentation/firmware_class/ for more information.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/vmalloc.h>
+#include <asm/hardirq.h>
+
+#include <linux/firmware.h>
+#include "base.h"
+
+MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
+MODULE_DESCRIPTION("Multi purpose firmware loading support");
+MODULE_LICENSE("GPL");
+
+static int loading_timeout = 10;	/* In seconds */
+
+struct firmware_priv {
+	char fw_id[FIRMWARE_NAME_MAX];
+	struct completion completion;
+	struct bin_attribute attr_data;
+	struct firmware *fw;
+	int loading;
+	int abort;
+	int alloc_size;
+	struct timer_list timeout;
+};
+
+static ssize_t
+firmware_timeout_show(struct class *class, char *buf)
+{
+	return sprintf(buf, "%d\n", loading_timeout);
+}
+
+/**
+ * firmware_timeout_store:
+ * Description:
+ *	Sets the number of seconds to wait for the firmware.  Once
+ *	this expires an error will be return to the driver and no
+ *	firmware will be provided.
+ *
+ *	Note: zero means 'wait for ever'
+ *  
+ **/
+static ssize_t
+firmware_timeout_store(struct class *class, const char *buf, size_t count)
+{
+	loading_timeout = simple_strtol(buf, NULL, 10);
+	return count;
+}
+
+static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
+
+static void  fw_class_dev_release(struct class_device *class_dev);
+int firmware_class_hotplug(struct class_device *dev, char **envp,
+			   int num_envp, char *buffer, int buffer_size);
+
+static struct class firmware_class = {
+	.name		= "firmware",
+	.hotplug	= firmware_class_hotplug,
+	.release	= fw_class_dev_release,
+};
+
+int
+firmware_class_hotplug(struct class_device *class_dev, char **envp,
+		       int num_envp, char *buffer, int buffer_size)
+{
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+	int i = 0;
+	char *scratch = buffer;
+
+	if (buffer_size < (FIRMWARE_NAME_MAX + 10))
+		return -ENOMEM;
+	if (num_envp < 1)
+		return -ENOMEM;
+
+	envp[i++] = scratch;
+	scratch += sprintf(scratch, "FIRMWARE=%s", fw_priv->fw_id) + 1;
+	return 0;
+}
+
+static ssize_t
+firmware_loading_show(struct class_device *class_dev, char *buf)
+{
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+	return sprintf(buf, "%d\n", fw_priv->loading);
+}
+
+/**
+ * firmware_loading_store: - loading control file
+ * Description:
+ *	The relevant values are: 
+ *
+ *	 1: Start a load, discarding any previous partial load.
+ *	 0: Conclude the load and handle the data to the driver code.
+ *	-1: Conclude the load with an error and discard any written data.
+ **/
+static ssize_t
+firmware_loading_store(struct class_device *class_dev,
+		       const char *buf, size_t count)
+{
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+	int prev_loading = fw_priv->loading;
+
+	fw_priv->loading = simple_strtol(buf, NULL, 10);
+
+	switch (fw_priv->loading) {
+	case -1:
+		fw_priv->abort = 1;
+		wmb();
+		complete(&fw_priv->completion);
+		break;
+	case 1:
+		kfree(fw_priv->fw->data);
+		fw_priv->fw->data = NULL;
+		fw_priv->fw->size = 0;
+		fw_priv->alloc_size = 0;
+		break;
+	case 0:
+		if (prev_loading == 1)
+			complete(&fw_priv->completion);
+		break;
+	}
+
+	return count;
+}
+
+static CLASS_DEVICE_ATTR(loading, 0644,
+			firmware_loading_show, firmware_loading_store);
+
+static ssize_t
+firmware_data_read(struct kobject *kobj,
+		   char *buffer, loff_t offset, size_t count)
+{
+	struct class_device *class_dev = to_class_dev(kobj);
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+	struct firmware *fw = fw_priv->fw;
+
+	if (offset > fw->size)
+		return 0;
+	if (offset + count > fw->size)
+		count = fw->size - offset;
+
+	memcpy(buffer, fw->data + offset, count);
+	return count;
+}
+static int
+fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
+{
+	u8 *new_data;
+
+	if (min_size <= fw_priv->alloc_size)
+		return 0;
+
+	new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE);
+	if (!new_data) {
+		printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
+		/* Make sure that we don't keep incomplete data */
+		fw_priv->abort = 1;
+		return -ENOMEM;
+	}
+	fw_priv->alloc_size += PAGE_SIZE;
+	if (fw_priv->fw->data) {
+		memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
+		vfree(fw_priv->fw->data);
+	}
+	fw_priv->fw->data = new_data;
+	BUG_ON(min_size > fw_priv->alloc_size);
+	return 0;
+}
+
+/**
+ * firmware_data_write:
+ *
+ * Description:
+ *
+ *	Data written to the 'data' attribute will be later handled to
+ *	the driver as a firmware image.
+ **/
+static ssize_t
+firmware_data_write(struct kobject *kobj,
+		    char *buffer, loff_t offset, size_t count)
+{
+	struct class_device *class_dev = to_class_dev(kobj);
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+	struct firmware *fw = fw_priv->fw;
+	int retval;
+
+	retval = fw_realloc_buffer(fw_priv, offset + count);
+	if (retval)
+		return retval;
+
+	memcpy(fw->data + offset, buffer, count);
+
+	fw->size = max_t(size_t, offset + count, fw->size);
+
+	return count;
+}
+static struct bin_attribute firmware_attr_data_tmpl = {
+	.attr = {.name = "data", .mode = 0644},
+	.size = 0,
+	.read = firmware_data_read,
+	.write = firmware_data_write,
+};
+
+static void
+fw_class_dev_release(struct class_device *class_dev)
+{
+	kfree(class_dev);
+}
+
+static void
+firmware_class_timeout(u_long data)
+{
+	struct firmware_priv *fw_priv = (struct firmware_priv *) data;
+	fw_priv->abort = 1;
+	wmb();
+	complete(&fw_priv->completion);
+}
+
+static inline void
+fw_setup_class_device_id(struct class_device *class_dev, struct device *dev)
+{
+	/* XXX warning we should watch out for name collisions */
+	strncpy(class_dev->class_id, dev->bus_id, BUS_ID_SIZE);
+	class_dev->class_id[BUS_ID_SIZE - 1] = '\0';
+}
+static int
+fw_setup_class_device(struct class_device **class_dev_p,
+		      const char *fw_name, struct device *device)
+{
+	int retval = 0;
+	struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
+						GFP_KERNEL);
+	struct class_device *class_dev = kmalloc(sizeof (struct class_device),
+						 GFP_KERNEL);
+
+	if (!fw_priv || !class_dev) {
+		retval = -ENOMEM;
+		goto error_kfree;
+	}
+	memset(fw_priv, 0, sizeof (*fw_priv));
+	memset(class_dev, 0, sizeof (*class_dev));
+
+	init_completion(&fw_priv->completion);
+	memcpy(&fw_priv->attr_data, &firmware_attr_data_tmpl,
+	       sizeof (firmware_attr_data_tmpl));
+
+	strncpy(&fw_priv->fw_id[0], fw_name, FIRMWARE_NAME_MAX);
+	fw_priv->fw_id[FIRMWARE_NAME_MAX - 1] = '\0';
+
+	fw_setup_class_device_id(class_dev, device);
+	class_dev->dev = device;
+
+	fw_priv->timeout.function = firmware_class_timeout;
+	fw_priv->timeout.data = (u_long) fw_priv;
+	init_timer(&fw_priv->timeout);
+
+	class_dev->class = &firmware_class;
+	class_set_devdata(class_dev, fw_priv);
+	retval = class_device_register(class_dev);
+	if (retval) {
+		printk(KERN_ERR "%s: class_device_register failed\n",
+		       __FUNCTION__);
+		goto error_kfree;
+	}
+
+	retval = sysfs_create_bin_file(&class_dev->kobj, &fw_priv->attr_data);
+	if (retval) {
+		printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
+		       __FUNCTION__);
+		goto error_unreg_class_dev;
+	}
+
+	retval = class_device_create_file(class_dev,
+					  &class_device_attr_loading);
+	if (retval) {
+		printk(KERN_ERR "%s: class_device_create_file failed\n",
+		       __FUNCTION__);
+		goto error_remove_data;
+	}
+
+	fw_priv->fw = kmalloc(sizeof (struct firmware), GFP_KERNEL);
+	if (!fw_priv->fw) {
+		printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
+		       __FUNCTION__);
+		retval = -ENOMEM;
+		goto error_remove_loading;
+	}
+	memset(fw_priv->fw, 0, sizeof (*fw_priv->fw));
+
+	goto out;
+
+error_remove_loading:
+	class_device_remove_file(class_dev, &class_device_attr_loading);
+error_remove_data:
+	sysfs_remove_bin_file(&class_dev->kobj, &fw_priv->attr_data);
+error_unreg_class_dev:
+	class_device_unregister(class_dev);
+error_kfree:
+	kfree(fw_priv);
+	kfree(class_dev);
+	*class_dev_p = NULL;
+out:
+	*class_dev_p = class_dev;
+	return retval;
+}
+static void
+fw_remove_class_device(struct class_device *class_dev)
+{
+	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
+
+	class_device_remove_file(class_dev, &class_device_attr_loading);
+	sysfs_remove_bin_file(&class_dev->kobj, &fw_priv->attr_data);
+	class_device_unregister(class_dev);
+}
+
+/** 
+ * request_firmware: - request firmware to hotplug and wait for it
+ * Description:
+ *	@firmware will be used to return a firmware image by the name
+ *	of @name for device @device.
+ *
+ *	Should be called from user context where sleeping is allowed.
+ *
+ *	@name will be use as $FIRMWARE in the hotplug environment and
+ *	should be distinctive enough not to be confused with any other
+ *	firmware image for this or any other device.
+ **/
+int
+request_firmware(const struct firmware **firmware, const char *name,
+		 struct device *device)
+{
+	struct class_device *class_dev;
+	struct firmware_priv *fw_priv;
+	int retval;
+
+	if (!firmware)
+		return -EINVAL;
+
+	*firmware = NULL;
+
+	retval = fw_setup_class_device(&class_dev, name, device);
+	if (retval)
+		goto out;
+
+	fw_priv = class_get_devdata(class_dev);
+
+	if (loading_timeout) {
+		fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
+		add_timer(&fw_priv->timeout);
+	}
+
+	wait_for_completion(&fw_priv->completion);
+
+	del_timer(&fw_priv->timeout);
+	fw_remove_class_device(class_dev);
+
+	if (fw_priv->fw->size && !fw_priv->abort) {
+		*firmware = fw_priv->fw;
+	} else {
+		retval = -ENOENT;
+		vfree(fw_priv->fw->data);
+		kfree(fw_priv->fw);
+	}
+	kfree(fw_priv);
+out:
+	return retval;
+}
+
+/**
+ * release_firmware: - release the resource associated with a firmware image
+ **/
+void
+release_firmware(const struct firmware *fw)
+{
+	if (fw) {
+		vfree(fw->data);
+		kfree(fw);
+	}
+}
+
+/**
+ * register_firmware: - provide a firmware image for later usage
+ * 
+ * Description:
+ *	Make sure that @data will be available by requesting firmware @name.
+ *
+ *	Note: This will not be possible until some kind of persistence
+ *	is available.
+ **/
+void
+register_firmware(const char *name, const u8 *data, size_t size)
+{
+	/* This is meaningless without firmware caching, so until we
+	 * decide if firmware caching is reasonable just leave it as a
+	 * noop */
+}
+
+/* Async support */
+struct firmware_work {
+	struct work_struct work;
+	struct module *module;
+	const char *name;
+	struct device *device;
+	void *context;
+	void (*cont)(const struct firmware *fw, void *context);
+};
+
+static void
+request_firmware_work_func(void *arg)
+{
+	struct firmware_work *fw_work = arg;
+	const struct firmware *fw;
+	if (!arg)
+		return;
+	request_firmware(&fw, fw_work->name, fw_work->device);
+	fw_work->cont(fw, fw_work->context);
+	release_firmware(fw);
+	module_put(fw_work->module);
+	kfree(fw_work);
+}
+
+/**
+ * request_firmware_nowait:
+ *
+ * Description:
+ *	Asynchronous variant of request_firmware() for contexts where
+ *	it is not possible to sleep.
+ *
+ *	@cont will be called asynchronously when the firmware request is over.
+ *
+ *	@context will be passed over to @cont.
+ *
+ *	@fw may be %NULL if firmware request fails.
+ *
+ **/
+int
+request_firmware_nowait(
+	struct module *module,
+	const char *name, struct device *device, void *context,
+	void (*cont)(const struct firmware *fw, void *context))
+{
+	struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
+						GFP_ATOMIC);
+	if (!fw_work)
+		return -ENOMEM;
+	if (!try_module_get(module)) {
+		kfree(fw_work);
+		return -EFAULT;
+	}
+
+	*fw_work = (struct firmware_work) {
+		.module = module,
+		.name = name,
+		.device = device,
+		.context = context,
+		.cont = cont,
+	};
+	INIT_WORK(&fw_work->work, request_firmware_work_func, fw_work);
+
+	schedule_work(&fw_work->work);
+	return 0;
+}
+
+static int __init
+firmware_class_init(void)
+{
+	int error;
+	error = class_register(&firmware_class);
+	if (error) {
+		printk(KERN_ERR "%s: class_register failed\n", __FUNCTION__);
+	}
+	error = class_create_file(&firmware_class, &class_attr_timeout);
+	if (error) {
+		printk(KERN_ERR "%s: class_create_file failed\n",
+		       __FUNCTION__);
+		class_unregister(&firmware_class);
+	}
+	return error;
+
+}
+static void __exit
+firmware_class_exit(void)
+{
+	class_remove_file(&firmware_class, &class_attr_timeout);
+	class_unregister(&firmware_class);
+}
+
+module_init(firmware_class_init);
+module_exit(firmware_class_exit);
+
+EXPORT_SYMBOL(release_firmware);
+EXPORT_SYMBOL(request_firmware);
+EXPORT_SYMBOL(request_firmware_nowait);
+EXPORT_SYMBOL(register_firmware);
+EXPORT_SYMBOL(firmware_class);
diff -urN linux-2.5.72-bk2/drivers/base/sys.c linux-2.5.72-bk3/drivers/base/sys.c
--- linux-2.5.72-bk2/drivers/base/sys.c	2003-06-16 21:19:37.000000000 -0700
+++ linux-2.5.72-bk3/drivers/base/sys.c	2003-06-20 04:48:11.000000000 -0700
@@ -74,6 +74,8 @@
 	sysfs_remove_file(&s->kobj,&a->attr);
 }
 
+EXPORT_SYMBOL(sysdev_create_file);
+EXPORT_SYMBOL(sysdev_remove_file);
 
 /* 
  * declare system_subsys 
@@ -171,6 +173,9 @@
 	/* Make sure the kset is set */
 	sysdev->kobj.kset = &cls->kset;
 
+	/* But make sure we point to the right type for sysfs translation */
+	sysdev->kobj.ktype = &ktype_sysdev;
+
 	/* set the kobject name */
 	snprintf(sysdev->kobj.name,KOBJ_NAME_LEN,"%s%d",
 		 cls->kset.kobj.name,sysdev->id);
@@ -218,9 +223,6 @@
 		if (drv->remove)
 			drv->remove(sysdev);
 	}
-
-	list_del_init(&sysdev->entry);
-
 	up_write(&system_subsys.rwsem);
 
 	kobject_unregister(&sysdev->kobj);
diff -urN linux-2.5.72-bk2/drivers/isdn/act2000/Makefile linux-2.5.72-bk3/drivers/isdn/act2000/Makefile
--- linux-2.5.72-bk2/drivers/isdn/act2000/Makefile	2003-06-16 21:20:07.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/act2000/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -6,4 +6,4 @@
 
 # Multipart objects.
 
-act2000-objs	:= module.o capi.o act2000_isa.o
+act2000-y			:= module.o capi.o act2000_isa.o
diff -urN linux-2.5.72-bk2/drivers/isdn/capi/Makefile linux-2.5.72-bk3/drivers/isdn/capi/Makefile
--- linux-2.5.72-bk2/drivers/isdn/capi/Makefile	2003-06-16 21:20:01.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/capi/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -13,4 +13,3 @@
 
 kernelcapi-y				:= kcapi.o capiutil.o capilib.o
 kernelcapi-$(CONFIG_PROC_FS)		+= kcapi_proc.o
-kernelcapi-objs				:= $(kernelcapi-y)
diff -urN linux-2.5.72-bk2/drivers/isdn/divert/Makefile linux-2.5.72-bk3/drivers/isdn/divert/Makefile
--- linux-2.5.72-bk2/drivers/isdn/divert/Makefile	2003-06-16 21:20:19.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/divert/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -6,4 +6,4 @@
 
 # Multipart objects.
 
-dss1_divert-objs	:= isdn_divert.o divert_procfs.o divert_init.o
+dss1_divert-y			:= isdn_divert.o divert_procfs.o divert_init.o
diff -urN linux-2.5.72-bk2/drivers/isdn/eicon/Makefile linux-2.5.72-bk3/drivers/isdn/eicon/Makefile
--- linux-2.5.72-bk2/drivers/isdn/eicon/Makefile	2003-06-16 21:19:47.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/eicon/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -7,15 +7,13 @@
 
 # Multipart objects.
 
-eicon-objs	:= eicon_mod.o eicon_isa.o eicon_pci.o eicon_idi.o \
-		   eicon_io.o
-divas-objs	:= common.o idi.o bri.o pri.o log.o xlog.o kprintf.o fpga.o \
-		   fourbri.o lincfg.o linchr.o linsys.o linio.o Divas_mod.o
+eicon-y					:= eicon_mod.o eicon_isa.o eicon_pci.o \
+					   eicon_idi.o eicon_io.o
+eicon-$(CONFIG_ISDN_DRV_EICON_PCI)	+= common.o idi.o bri.o pri.o log.o \
+		   			   xlog.o kprintf.o fpga.o fourbri.o lincfg.o \
+					   linchr.o linsys.o linio.o
 
-# Optional parts of multipart objects.
+divas-y					:= common.o idi.o bri.o pri.o log.o xlog.o \
+					   kprintf.o fpga.o fourbri.o lincfg.o \
+					   linchr.o linsys.o linio.o Divas_mod.o
 
-eicon-objs-$(CONFIG_ISDN_DRV_EICON_PCI) += common.o idi.o bri.o pri.o log.o \
-		   xlog.o kprintf.o fpga.o fourbri.o lincfg.o linchr.o \
-		   linsys.o linio.o
-
-eicon-objs 	+= $(eicon-objs-y)
diff -urN linux-2.5.72-bk2/drivers/isdn/eicon/eicon_isa.c linux-2.5.72-bk3/drivers/isdn/eicon/eicon_isa.c
--- linux-2.5.72-bk2/drivers/isdn/eicon/eicon_isa.c	2003-06-16 21:19:41.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/eicon/eicon_isa.c	2003-06-20 04:48:11.000000000 -0700
@@ -123,7 +123,7 @@
 int
 eicon_isa_bootload(eicon_isa_card *card, eicon_isa_codebuf *cb) {
 	int	tmp;
-	int               timeout;
+	unsigned long     timeout;
 	eicon_isa_codebuf cbuf;
 	unsigned char     *code;
 	eicon_isa_boot    *boot;
@@ -300,7 +300,7 @@
 eicon_isa_load(eicon_isa_card *card, eicon_isa_codebuf *cb) {
 	eicon_isa_boot    *boot;
 	int               tmp;
-	int               timeout;
+	unsigned long     timeout;
 	int 		  j;
 	eicon_isa_codebuf cbuf;
 	unsigned char     *code;
diff -urN linux-2.5.72-bk2/drivers/isdn/hardware/avm/b1pci.c linux-2.5.72-bk3/drivers/isdn/hardware/avm/b1pci.c
--- linux-2.5.72-bk2/drivers/isdn/hardware/avm/b1pci.c	2003-06-16 21:19:39.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/hardware/avm/b1pci.c	2003-06-20 04:48:11.000000000 -0700
@@ -111,7 +111,7 @@
 	cinfo->capi_ctrl.procinfo      = b1pci_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	cinfo->capi_ctrl.owner = THIS_MODULE;
+	cinfo->capi_ctrl.owner         = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
@@ -239,6 +239,7 @@
 		goto err_unmap;
 	}
 
+	cinfo->capi_ctrl.owner         = THIS_MODULE;
 	cinfo->capi_ctrl.driver_name   = "b1pciv4";
 	cinfo->capi_ctrl.driverdata    = cinfo;
 	cinfo->capi_ctrl.register_appl = b1dma_register_appl;
@@ -249,7 +250,6 @@
 	cinfo->capi_ctrl.procinfo      = b1pciv4_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
diff -urN linux-2.5.72-bk2/drivers/isdn/hardware/avm/b1pcmcia.c linux-2.5.72-bk3/drivers/isdn/hardware/avm/b1pcmcia.c
--- linux-2.5.72-bk2/drivers/isdn/hardware/avm/b1pcmcia.c	2003-06-16 21:19:37.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/hardware/avm/b1pcmcia.c	2003-06-20 04:48:11.000000000 -0700
@@ -95,6 +95,7 @@
 	b1_reset(card->port);
 	b1_getrevision(card);
 
+	cinfo->capi_ctrl.owner         = THIS_MODULE;
 	cinfo->capi_ctrl.driver_name   = "b1pcmcia";
 	cinfo->capi_ctrl.driverdata    = cinfo;
 	cinfo->capi_ctrl.register_appl = b1_register_appl;
@@ -105,7 +106,6 @@
 	cinfo->capi_ctrl.procinfo      = b1pcmcia_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
diff -urN linux-2.5.72-bk2/drivers/isdn/hardware/avm/t1pci.c linux-2.5.72-bk3/drivers/isdn/hardware/avm/t1pci.c
--- linux-2.5.72-bk2/drivers/isdn/hardware/avm/t1pci.c	2003-06-16 21:19:41.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/hardware/avm/t1pci.c	2003-06-20 04:48:11.000000000 -0700
@@ -109,6 +109,7 @@
 		goto err_unmap;
 	}
 
+	cinfo->capi_ctrl.owner         = THIS_MODULE;
 	cinfo->capi_ctrl.driver_name   = "t1pci";
 	cinfo->capi_ctrl.driverdata    = cinfo;
 	cinfo->capi_ctrl.register_appl = b1dma_register_appl;
@@ -119,7 +120,6 @@
 	cinfo->capi_ctrl.procinfo      = t1pci_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
diff -urN linux-2.5.72-bk2/drivers/isdn/hardware/eicon/Makefile linux-2.5.72-bk3/drivers/isdn/hardware/eicon/Makefile
--- linux-2.5.72-bk2/drivers/isdn/hardware/eicon/Makefile	2003-06-16 21:20:21.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/hardware/eicon/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -1,24 +1,24 @@
 # Makefile for the Eicon DIVA ISDN drivers.
 
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DIVAS)		+= divadidd.o divas.o
+obj-$(CONFIG_ISDN_DIVAS_MAINT)		+= diva_mnt.o
+obj-$(CONFIG_ISDN_DIVAS_USERIDI)	+= diva_idi.o
+obj-$(CONFIG_ISDN_DIVAS_DIVACAPI)	+= divacapi.o
+
 # Multipart objects. 
 
-divas-objs      := divasmain.o divasfunc.o di.o io.o istream.o diva.o dlist.o divasproc.o diva_dma.o
-divacapi-objs   := capimain.o capifunc.o message.o capidtmf.o
-divadidd-objs   := diva_didd.o diddfunc.o dadapter.o
-diva_mnt-objs   := divamnt.o mntfunc.o debug.o maintidi.o
-diva_idi-objs   := divasi.o idifunc.o um_idi.o dqueue.o dlist.o
-
-# Optional parts of multipart objects.
-
-divas-objs-$(CONFIG_ISDN_DIVAS_BRIPCI)  += os_bri.o  s_bri.o
-divas-objs-$(CONFIG_ISDN_DIVAS_4BRIPCI) += os_4bri.o s_4bri.o
-divas-objs-$(CONFIG_ISDN_DIVAS_PRIPCI)  += os_pri.o  s_pri.o
+divas-y					:= divasmain.o divasfunc.o di.o io.o istream.o \
+					   diva.o dlist.o divasproc.o diva_dma.o
+divas-$(CONFIG_ISDN_DIVAS_BRIPCI)	+= os_bri.o  s_bri.o
+divas-$(CONFIG_ISDN_DIVAS_4BRIPCI)	+= os_4bri.o s_4bri.o
+divas-$(CONFIG_ISDN_DIVAS_PRIPCI)	+= os_pri.o  s_pri.o
 
-divas-objs += $(sort $(divas-objs-y))
+divacapi-y				:= capimain.o capifunc.o message.o capidtmf.o
 
-# Each configuration option enables a list of files.
+divadidd-y				:= diva_didd.o diddfunc.o dadapter.o
+
+diva_mnt-y				:= divamnt.o mntfunc.o debug.o maintidi.o
 
-obj-$(CONFIG_ISDN_DIVAS)               += divadidd.o divas.o
-obj-$(CONFIG_ISDN_DIVAS_MAINT)         += diva_mnt.o
-obj-$(CONFIG_ISDN_DIVAS_USERIDI)       += diva_idi.o
-obj-$(CONFIG_ISDN_DIVAS_DIVACAPI)      += divacapi.o
+diva_idi-y				:= divasi.o idifunc.o um_idi.o dqueue.o dlist.o
diff -urN linux-2.5.72-bk2/drivers/isdn/hisax/Makefile linux-2.5.72-bk3/drivers/isdn/hisax/Makefile
--- linux-2.5.72-bk2/drivers/isdn/hisax/Makefile	2003-06-16 21:19:59.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/hisax/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -17,47 +17,45 @@
 
 # Multipart objects.
 
-hisax_st5481-objs := st5481_init.o st5481_usb.o st5481_d.o st5481_b.o \
-		     st5481_hdlc.o
-hisax-objs	  := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
-		     lmgr.o q931.o callc.o fsm.o cert.o
+hisax_st5481-y 				:= st5481_init.o st5481_usb.o st5481_d.o \
+					   st5481_b.o st5481_hdlc.o
 
-# Optional parts of multipart objects.
-hisax-objs-$(CONFIG_HISAX_EURO) += l3dss1.o
-hisax-objs-$(CONFIG_HISAX_NI1) += l3ni1.o
-hisax-objs-$(CONFIG_HISAX_1TR6) += l3_1tr6.o
-
-hisax-objs-$(CONFIG_HISAX_16_0) += teles0.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_16_3) += teles3.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_TELESPCI) += telespci.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_S0BOX) += s0box.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.o
-hisax-objs-$(CONFIG_HISAX_ELSA) += elsa.o isac.o arcofi.o hscx.o ipac.o
-hisax-objs-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o ipac.o ipacx.o 
-hisax-objs-$(CONFIG_HISAX_ASUSCOM) += asuscom.o isac.o arcofi.o hscx.o ipac.o
-hisax-objs-$(CONFIG_HISAX_TELEINT) += teleint.o isac.o arcofi.o hfc_2bs0.o
-hisax-objs-$(CONFIG_HISAX_SEDLBAUER) += sedlbauer.o isac.o arcofi.o hscx.o ipac.o isar.o
-hisax-objs-$(CONFIG_HISAX_SPORTSTER) += sportster.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_MIC) += mic.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_NETJET) += nj_s.o netjet.o isac.o arcofi.o
-hisax-objs-$(CONFIG_HISAX_NETJET_U) += nj_u.o netjet.o icc.o
-hisax-objs-$(CONFIG_HISAX_HFCS) += hfcscard.o hfc_2bds0.o
-hisax-objs-$(CONFIG_HISAX_HFC_PCI) += hfc_pci.o
-hisax-objs-$(CONFIG_HISAX_HFC_SX) += hfc_sx.o
-hisax-objs-$(CONFIG_HISAX_NICCY) += niccy.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_ISURF) += isurf.o isac.o arcofi.o isar.o
-hisax-objs-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o isac.o arcofi.o hscx.o
-hisax-objs-$(CONFIG_HISAX_BKM_A4T) += bkm_a4t.o isac.o arcofi.o jade.o
-hisax-objs-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o isac.o arcofi.o hscx.o ipac.o
-hisax-objs-$(CONFIG_HISAX_GAZEL) += gazel.o isac.o arcofi.o hscx.o ipac.o
-hisax-objs-$(CONFIG_HISAX_W6692) += w6692.o
-hisax-objs-$(CONFIG_HISAX_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o
-#hisax-objs-$(CONFIG_HISAX_TESTEMU) += testemu.o
-
-hisax-objs += $(hisax-objs-y)
+hisax-y	  				:= config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
+		     			   lmgr.o q931.o callc.o fsm.o cert.o
+hisax-$(CONFIG_HISAX_EURO)		+= l3dss1.o
+hisax-$(CONFIG_HISAX_NI1)		+= l3ni1.o
+hisax-$(CONFIG_HISAX_1TR6)		+= l3_1tr6.o
+
+hisax-$(CONFIG_HISAX_16_0)		+= teles0.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_16_3)		+= teles3.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_TELESPCI)		+= telespci.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_S0BOX)		+= s0box.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_AVM_A1)		+= avm_a1.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_AVM_A1_PCMCIA)	+= avm_a1p.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_FRITZPCI)		+= avm_pci.o isac.o arcofi.o
+hisax-$(CONFIG_HISAX_ELSA)		+= elsa.o isac.o arcofi.o hscx.o ipac.o
+hisax-$(CONFIG_HISAX_IX1MICROR2)	+= ix1_micro.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_DIEHLDIVA)		+= diva.o isac.o arcofi.o hscx.o ipac.o ipacx.o 
+hisax-$(CONFIG_HISAX_ASUSCOM)		+= asuscom.o isac.o arcofi.o hscx.o ipac.o
+hisax-$(CONFIG_HISAX_TELEINT)		+= teleint.o isac.o arcofi.o hfc_2bs0.o
+hisax-$(CONFIG_HISAX_SEDLBAUER)		+= sedlbauer.o isac.o arcofi.o hscx.o ipac.o \
+					   isar.o
+hisax-$(CONFIG_HISAX_SPORTSTER)		+= sportster.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_MIC)		+= mic.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_NETJET)		+= nj_s.o netjet.o isac.o arcofi.o
+hisax-$(CONFIG_HISAX_NETJET_U)		+= nj_u.o netjet.o icc.o
+hisax-$(CONFIG_HISAX_HFCS)		+= hfcscard.o hfc_2bds0.o
+hisax-$(CONFIG_HISAX_HFC_PCI)		+= hfc_pci.o
+hisax-$(CONFIG_HISAX_HFC_SX)		+= hfc_sx.o
+hisax-$(CONFIG_HISAX_NICCY)		+= niccy.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_ISURF)		+= isurf.o isac.o arcofi.o isar.o
+hisax-$(CONFIG_HISAX_HSTSAPHIR)		+= saphir.o isac.o arcofi.o hscx.o
+hisax-$(CONFIG_HISAX_BKM_A4T)		+= bkm_a4t.o isac.o arcofi.o jade.o
+hisax-$(CONFIG_HISAX_SCT_QUADRO)	+= bkm_a8.o isac.o arcofi.o hscx.o ipac.o
+hisax-$(CONFIG_HISAX_GAZEL)		+= gazel.o isac.o arcofi.o hscx.o ipac.o
+hisax-$(CONFIG_HISAX_W6692)		+= w6692.o
+hisax-$(CONFIG_HISAX_ENTERNOW_PCI)	+= enternow_pci.o amd7930_fn.o
+#hisax-$(CONFIG_HISAX_TESTEMU)		+= testemu.o
 
 CERT := $(shell cd $(src); md5sum -c md5sums.asc > /dev/null 2> /dev/null ;echo $$?)
 CFLAGS_cert.o := -DCERTIFICATION=$(CERT)
diff -urN linux-2.5.72-bk2/drivers/isdn/hisax/avma1_cs.c linux-2.5.72-bk3/drivers/isdn/hisax/avma1_cs.c
--- linux-2.5.72-bk2/drivers/isdn/hisax/avma1_cs.c	2003-06-16 21:20:07.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/hisax/avma1_cs.c	2003-06-20 04:48:11.000000000 -0700
@@ -153,6 +153,8 @@
 
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+    if (!link)
+	return NULL;
     memset(link, 0, sizeof(struct dev_link_t));
     link->release.function = &avma1cs_release;
     link->release.data = (u_long)link;
@@ -186,6 +188,10 @@
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+    if (!local) {
+	kfree(link);
+	return NULL;
+    }
     memset(local, 0, sizeof(local_info_t));
     link->priv = local;
     
diff -urN linux-2.5.72-bk2/drivers/isdn/hysdn/Makefile linux-2.5.72-bk3/drivers/isdn/hysdn/Makefile
--- linux-2.5.72-bk2/drivers/isdn/hysdn/Makefile	2003-06-16 21:20:28.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/hysdn/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -2,15 +2,10 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_HYSDN)	+= hysdn.o
+obj-$(CONFIG_HYSDN)		+= hysdn.o
 
 # Multipart objects.
 
-hysdn-objs	:= hysdn_procconf.o hysdn_proclog.o boardergo.o hysdn_boot.o \
-		   hysdn_sched.o hysdn_net.o hysdn_init.o
-
-# Optional parts of multipart objects.
-
-hysdn-objs-$(CONFIG_HYSDN_CAPI) += hycapi.o
-
-hysdn-objs 	+= $(hysdn-objs-y)
+hysdn-y				:= hysdn_procconf.o hysdn_proclog.o boardergo.o \
+				   hysdn_boot.o hysdn_sched.o hysdn_net.o hysdn_init.o
+hysdn-$(CONFIG_HYSDN_CAPI)	+= hycapi.o
diff -urN linux-2.5.72-bk2/drivers/isdn/hysdn/hysdn_proclog.c linux-2.5.72-bk3/drivers/isdn/hysdn/hysdn_proclog.c
--- linux-2.5.72-bk2/drivers/isdn/hysdn/hysdn_proclog.c	2003-06-16 21:19:41.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/hysdn/hysdn_proclog.c	2003-06-20 04:48:11.000000000 -0700
@@ -98,7 +98,8 @@
 {
 	struct log_data *ib;
 	struct procdata *pd = card->proclog;
-	int i, flags;
+	int i;
+	unsigned long flags;
 
 	if (!pd)
 		return;
@@ -300,7 +301,8 @@
 	struct log_data *inf;
 	struct procdata *pd;
 	hysdn_card *card;
-	int flags, retval = 0;
+	int retval = 0;
+	unsigned long flags;
 
 
 	lock_kernel();
diff -urN linux-2.5.72-bk2/drivers/isdn/i4l/Makefile linux-2.5.72-bk3/drivers/isdn/i4l/Makefile
--- linux-2.5.72-bk2/drivers/isdn/i4l/Makefile	2003-06-16 21:19:47.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/i4l/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -2,25 +2,18 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_ISDN)			+= isdn.o
-obj-$(CONFIG_ISDN_PPP_BSDCOMP)		+= isdn_bsdcomp.o
+obj-$(CONFIG_ISDN)		+= isdn.o
+obj-$(CONFIG_ISDN_PPP_BSDCOMP)	+= isdn_bsdcomp.o
 
 # Multipart objects.
 
-isdn-objs				:= isdn_net_lib.o \
-					   isdn_fsm.o \
-					   isdn_tty.o isdn_v110.o \
-					   isdn_common.o \
-
-# Optional parts of multipart objects.
-
-isdn-objs-$(CONFIG_ISDN_NET_SIMPLE)	+= isdn_net.o
-isdn-objs-$(CONFIG_ISDN_NET_CISCO)	+= isdn_ciscohdlck.o
-isdn-objs-$(CONFIG_ISDN_PPP)		+= isdn_ppp.o isdn_ppp_ccp.o
-isdn-objs-$(CONFIG_ISDN_PPP_VJ)		+= isdn_ppp_vj.o
-isdn-objs-$(CONFIG_ISDN_MPP)		+= isdn_ppp_mp.o
-isdn-objs-$(CONFIG_ISDN_X25)		+= isdn_concap.o isdn_x25iface.o
-isdn-objs-$(CONFIG_ISDN_AUDIO)		+= isdn_audio.o
-isdn-objs-$(CONFIG_ISDN_TTY_FAX)	+= isdn_ttyfax.o
-
-isdn-objs				+= $(isdn-objs-y)
+isdn-y				:= isdn_net_lib.o isdn_fsm.o isdn_tty.o \
+				   isdn_v110.o isdn_common.o
+isdn-$(CONFIG_ISDN_NET_SIMPLE)	+= isdn_net.o
+isdn-$(CONFIG_ISDN_NET_CISCO)	+= isdn_ciscohdlck.o
+isdn-$(CONFIG_ISDN_PPP)		+= isdn_ppp.o isdn_ppp_ccp.o
+isdn-$(CONFIG_ISDN_PPP_VJ)	+= isdn_ppp_vj.o
+isdn-$(CONFIG_ISDN_MPP)		+= isdn_ppp_mp.o
+isdn-$(CONFIG_ISDN_X25)		+= isdn_concap.o isdn_x25iface.o
+isdn-$(CONFIG_ISDN_AUDIO)	+= isdn_audio.o
+isdn-$(CONFIG_ISDN_TTY_FAX)	+= isdn_ttyfax.o
diff -urN linux-2.5.72-bk2/drivers/isdn/i4l/isdn_bsdcomp.c linux-2.5.72-bk3/drivers/isdn/i4l/isdn_bsdcomp.c
--- linux-2.5.72-bk2/drivers/isdn/i4l/isdn_bsdcomp.c	2003-06-16 21:20:22.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/i4l/isdn_bsdcomp.c	2003-06-20 04:48:11.000000000 -0700
@@ -300,7 +300,6 @@
 		 * Finally release the structure itself.
 		 */
 		kfree (db);
-		MOD_DEC_USE_COUNT;
 	}
 }
 
@@ -355,8 +354,6 @@
 		return NULL;
 	}
 
-	MOD_INC_USE_COUNT;
-
 	/*
 	 * If this is the compression buffer then there is no length data.
 	 * For decompression, the length information is needed as well.
@@ -907,6 +904,7 @@
  *************************************************************/
 
 static struct isdn_ppp_compressor ippp_bsd_compress = {
+	.owner          = THIS_MODULE,
 	.num            = CI_BSD_COMPRESS,
 	.alloc          = bsd_alloc,
 	.free           = bsd_free,
diff -urN linux-2.5.72-bk2/drivers/isdn/i4l/isdn_ppp_ccp.c linux-2.5.72-bk3/drivers/isdn/i4l/isdn_ppp_ccp.c
--- linux-2.5.72-bk2/drivers/isdn/i4l/isdn_ppp_ccp.c	2003-06-16 21:19:58.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/i4l/isdn_ppp_ccp.c	2003-06-20 04:48:11.000000000 -0700
@@ -259,11 +259,14 @@
 {
 	int id;
 
-	if (ccp->comp_stat)
+	if (ccp->comp_stat) {
 		ccp->compressor->free(ccp->comp_stat);
-	if (ccp->decomp_stat)
+		module_put(ccp->compressor->owner);
+	}
+	if (ccp->decomp_stat) {
 		ccp->decompressor->free(ccp->decomp_stat);
-
+		module_put(ccp->decompressor->owner);
+	}
 	for (id = 0; id < 256; id++) {
 		if (ccp->reset->rs[id])
 			ippp_ccp_reset_free_state(ccp, id);
@@ -553,13 +556,14 @@
 	}
 }
 
-static struct isdn_ppp_compressor *ipc_head = NULL;
+static LIST_HEAD(ipc_head);
+static spinlock_t ipc_head_lock;
 
 int
 ippp_ccp_set_compressor(struct ippp_ccp *ccp, int unit,
 			struct isdn_ppp_comp_data *data)
 {
-	struct isdn_ppp_compressor *ipc = ipc_head;
+	struct isdn_ppp_compressor *ipc;
 	int ret;
 	void *stat;
 	int num = data->num;
@@ -568,34 +572,48 @@
 		printk(KERN_DEBUG "[%d] Set %scompressor type %d\n", unit,
 		       data->flags & IPPP_COMP_FLAG_XMIT ? "" : "de", num);
 
-	for (ipc = ipc_head; ipc; ipc = ipc->next) {
-		if (ipc->num != num)
-			continue;
-		
-		stat = ipc->alloc(data);
-		if (!stat) {
-			printk(KERN_ERR "Can't alloc (de)compression!\n");
-			break;
-		}
-		ret = ipc->init(stat, data, unit, 0);
-		if(!ret) {
-			printk(KERN_ERR "Can't init (de)compression!\n");
-			ipc->free(stat);
-			break;
+	spin_lock(&ipc_head_lock);
+	list_for_each_entry(ipc, &ipc_head, list) {
+		if (ipc->num == num &&
+		    try_module_get(ipc->owner))
+			goto found;
+	}
+	spin_unlock(&ipc_head_lock);
+	return -EINVAL;
+
+ found:
+	spin_unlock(&ipc_head_lock);
+
+	stat = ipc->alloc(data);
+	if (!stat) {
+		printk(KERN_ERR "Can't alloc (de)compression!\n");
+		goto err;
+	}
+	ret = ipc->init(stat, data, unit, 0);
+	if(!ret) {
+		printk(KERN_ERR "Can't init (de)compression!\n");
+		ipc->free(stat);
+		goto err;
+	}
+	if (data->flags & IPPP_COMP_FLAG_XMIT) {
+		if (ccp->comp_stat) {
+			ccp->compressor->free(ccp->comp_stat);
+			module_put(ccp->compressor->owner);
 		}
-		if (data->flags & IPPP_COMP_FLAG_XMIT) {
-			if (ccp->comp_stat)
-				ccp->compressor->free(ccp->comp_stat);
 			ccp->comp_stat = stat;
 			ccp->compressor = ipc;
-		} else {
-			if (ccp->decomp_stat)
-				ccp->decompressor->free(ccp->decomp_stat);
-			ccp->decomp_stat = stat;
-			ccp->decompressor = ipc;
+	} else {
+		if (ccp->decomp_stat) {
+			ccp->decompressor->free(ccp->decomp_stat);
+			module_put(ccp->decompressor->owner);
 		}
-		return 0;
+		ccp->decomp_stat = stat;
+		ccp->decompressor = ipc;
 	}
+	return 0;
+
+ err:
+	module_put(ipc->owner);
 	return -EINVAL;
 }
 
@@ -606,36 +624,34 @@
 	int i, j;
 
 	memset(protos, 0, sizeof(unsigned long) * 8);
-	for (ipc = ipc_head; ipc; ipc = ipc->next) {
+
+	spin_lock(&ipc_head_lock);
+	list_for_each_entry(ipc, &ipc_head, list) {
 		j = ipc->num / (sizeof(long)*8);
 		i = ipc->num % (sizeof(long)*8);
 		if (j < 8)
 			protos[j] |= 1 << i;
 	}
+	spin_unlock(&ipc_head_lock);
 }
 
 int
 isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
 {
-	ipc->next = ipc_head;
-	ipc->prev = NULL;
-	if (ipc_head) {
-		ipc_head->prev = ipc;
-	}
-	ipc_head = ipc;
+	spin_lock(&ipc_head_lock);
+	list_add_tail(&ipc->list, &ipc_head);
+	spin_unlock(&ipc_head_lock);
+
 	return 0;
 }
 
 int
 isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
 {
-	if (ipc->prev)
-		ipc->prev->next = ipc->next;
-	else
-		ipc_head = ipc->next;
-	if (ipc->next)
-		ipc->next->prev = ipc->prev;
-	ipc->prev = ipc->next = NULL;
+	spin_lock(&ipc_head_lock);
+	list_del(&ipc->list);
+	spin_unlock(&ipc_head_lock);
+
 	return 0;
 }
 
diff -urN linux-2.5.72-bk2/drivers/isdn/i4l/isdn_tty.c linux-2.5.72-bk3/drivers/isdn/i4l/isdn_tty.c
--- linux-2.5.72-bk2/drivers/isdn/i4l/isdn_tty.c	2003-06-16 21:20:19.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/i4l/isdn_tty.c	2003-06-20 04:48:11.000000000 -0700
@@ -1983,7 +1983,7 @@
 	memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
 	memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);
 	if (dev->profd)
-		group_send_sig_info(SIGIO, SEND_SIG_PRIV, dev->profd);
+		kill_pg_info(SIGIO, SEND_SIG_PRIV, dev->profd->pgrp);
 }
 
 static struct tty_operations modem_ops = {
@@ -2095,11 +2095,10 @@
 #endif
 		kfree(info->xmit_buf - 4);
 	}
- err_unregister_tty:
-	tty_unregister_driver(&isdn_mdm->tty_modem);
+	tty_unregister_driver(m->tty_modem);
  err:
-	put_tty_driver(&isdn_mdm->tty_modem);
-	isdn_mdm->tty_modem = NULL;
+	put_tty_driver(m->tty_modem);
+	m->tty_modem = NULL;
 	return retval;
 }
 
@@ -2118,9 +2117,9 @@
 #endif
 		kfree(info->xmit_buf - 4);
 	}
-	tty_unregister_driver(&isdn_mdm->tty_modem);
-	put_tty_driver(&isdn_mdm->tty_modem);
-	isdn_mdm->tty_modem = NULL;
+	tty_unregister_driver(isdn_mdm.tty_modem);
+	put_tty_driver(isdn_mdm.tty_modem);
+	isdn_mdm.tty_modem = NULL;
 }
 
 /*
diff -urN linux-2.5.72-bk2/drivers/isdn/i4l/isdn_ttyfax.c linux-2.5.72-bk3/drivers/isdn/i4l/isdn_ttyfax.c
--- linux-2.5.72-bk2/drivers/isdn/i4l/isdn_ttyfax.c	2003-06-16 21:19:39.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/i4l/isdn_ttyfax.c	2003-06-20 04:48:11.000000000 -0700
@@ -303,7 +303,7 @@
 	isdn_ctrl c;
 	int par;
 	struct isdn_slot *slot;
-	long flags;
+	unsigned long flags;
 
 	for (c.parm.aux.cmd = 0; c.parm.aux.cmd < 7; c.parm.aux.cmd++)
 		if (!strncmp(p[0], cmd[c.parm.aux.cmd], 2))
diff -urN linux-2.5.72-bk2/drivers/isdn/isdnloop/Makefile linux-2.5.72-bk3/drivers/isdn/isdnloop/Makefile
--- linux-2.5.72-bk2/drivers/isdn/isdnloop/Makefile	2003-06-16 21:19:39.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/isdnloop/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -1,6 +1,4 @@
-#
 # Makefile for the isdnloop ISDN device driver
-#
 
 # Each configuration option enables a list of files.
 
diff -urN linux-2.5.72-bk2/drivers/isdn/pcbit/Makefile linux-2.5.72-bk3/drivers/isdn/pcbit/Makefile
--- linux-2.5.72-bk2/drivers/isdn/pcbit/Makefile	2003-06-16 21:20:22.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/pcbit/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -6,4 +6,4 @@
 
 # Multipart objects.
 
-pcbit-objs	:= module.o edss1.o drv.o layer2.o capi.o callbacks.o
+pcbit-y				:= module.o edss1.o drv.o layer2.o capi.o callbacks.o
diff -urN linux-2.5.72-bk2/drivers/isdn/sc/Makefile linux-2.5.72-bk3/drivers/isdn/sc/Makefile
--- linux-2.5.72-bk2/drivers/isdn/sc/Makefile	2003-06-16 21:19:46.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/sc/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -6,5 +6,5 @@
 
 # Multipart objects.
 
-sc-objs		:= shmem.o init.o debug.o packet.o command.o event.o \
-		   ioctl.o interrupt.o message.o timer.o	
+sc-y				:= shmem.o init.o debug.o packet.o command.o event.o \
+		   		   ioctl.o interrupt.o message.o timer.o	
diff -urN linux-2.5.72-bk2/drivers/isdn/tpam/Makefile linux-2.5.72-bk3/drivers/isdn/tpam/Makefile
--- linux-2.5.72-bk2/drivers/isdn/tpam/Makefile	2003-06-16 21:19:39.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/tpam/Makefile	2003-06-20 04:48:11.000000000 -0700
@@ -6,5 +6,6 @@
 
 # Multipart objects.
 
-tpam-objs	:= tpam_main.o tpam_nco.o tpam_memory.o tpam_commands.o \
-		   tpam_queues.o tpam_hdlc.o tpam_crcpc.o
+tpam-y				:= tpam_main.o tpam_nco.o tpam_memory.o \
+				   tpam_commands.o tpam_queues.o tpam_hdlc.o \
+				   tpam_crcpc.o
diff -urN linux-2.5.72-bk2/drivers/isdn/tpam/tpam_queues.c linux-2.5.72-bk3/drivers/isdn/tpam/tpam_queues.c
--- linux-2.5.72-bk2/drivers/isdn/tpam/tpam_queues.c	2003-06-16 21:19:39.000000000 -0700
+++ linux-2.5.72-bk3/drivers/isdn/tpam/tpam_queues.c	2003-06-20 04:48:11.000000000 -0700
@@ -145,6 +145,7 @@
 		do {
 			hpic = readl(card->bar0 + TPAM_HPIC_REGISTER);
 			if (waiting_too_long++ > 0xfffffff) {
+				kfree_skb(skb); 
 				spin_unlock(&card->lock);
 				printk(KERN_ERR "TurboPAM(tpam_irq): "
 						"waiting too long...\n");
diff -urN linux-2.5.72-bk2/drivers/net/myri_sbus.c linux-2.5.72-bk3/drivers/net/myri_sbus.c
--- linux-2.5.72-bk2/drivers/net/myri_sbus.c	2003-06-16 21:19:40.000000000 -0700
+++ linux-2.5.72-bk3/drivers/net/myri_sbus.c	2003-06-20 04:48:11.000000000 -0700
@@ -766,10 +766,14 @@
 int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh)
 {
 	unsigned short type = hh->hh_type;
-	unsigned char *pad = (unsigned char *) hh->hh_data;
-	struct ethhdr *eth = (struct ethhdr *) (pad + MYRI_PAD_LEN);
+	unsigned char *pad;
+	struct ethhdr *eth;
 	struct net_device *dev = neigh->dev;
 
+	pad = ((unsigned char *) hh->hh_data) +
+		HH_DATA_OFF(sizeof(*eth) + MYRI_PAD_LEN);
+	eth = (struct ethhdr *) (pad + MYRI_PAD_LEN);
+
 	if (type == __constant_htons(ETH_P_802_3))
 		return -1;
 
@@ -788,7 +792,8 @@
 /* Called by Address Resolution module to notify changes in address. */
 void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
 {
-	memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len);
+	memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
+	       haddr, dev->addr_len);
 }
 
 static int myri_change_mtu(struct net_device *dev, int new_mtu)
diff -urN linux-2.5.72-bk2/drivers/net/plip.c linux-2.5.72-bk3/drivers/net/plip.c
--- linux-2.5.72-bk2/drivers/net/plip.c	2003-06-16 21:20:27.000000000 -0700
+++ linux-2.5.72-bk3/drivers/net/plip.c	2003-06-20 04:48:11.000000000 -0700
@@ -1078,7 +1078,10 @@
 	
 	if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0)
 	{
-		struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2);
+		struct ethhdr *eth;
+
+		eth = (struct ethhdr*)(((u8*)hh->hh_data) +
+				       HH_DATA_OFF(sizeof(*eth)));
 		plip_rewrite_address (neigh->dev, eth);
 	}
 	
diff -urN linux-2.5.72-bk2/drivers/net/pppoe.c linux-2.5.72-bk3/drivers/net/pppoe.c
--- linux-2.5.72-bk2/drivers/net/pppoe.c	2003-06-16 21:20:06.000000000 -0700
+++ linux-2.5.72-bk3/drivers/net/pppoe.c	2003-06-20 04:48:11.000000000 -0700
@@ -1061,6 +1061,7 @@
 }
 
 static struct file_operations pppoe_seq_fops = {
+	.owner		= THIS_MODULE,
 	.open		= pppoe_seq_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
diff -urN linux-2.5.72-bk2/drivers/pnp/base.h linux-2.5.72-bk3/drivers/pnp/base.h
--- linux-2.5.72-bk2/drivers/pnp/base.h	2003-06-16 21:19:42.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/base.h	2003-06-20 04:48:11.000000000 -0700
@@ -4,29 +4,11 @@
 int pnp_interface_attach_device(struct pnp_dev *dev);
 void pnp_name_device(struct pnp_dev *dev);
 void pnp_fixup_device(struct pnp_dev *dev);
-void pnp_free_resources(struct pnp_resources *resources);
+void pnp_free_option(struct pnp_option *option);
 int __pnp_add_device(struct pnp_dev *dev);
 void __pnp_remove_device(struct pnp_dev *dev);
 
-/* resource conflict types */
-#define CONFLICT_TYPE_NONE	0x0000	/* there are no conflicts, other than those in the link */
-#define CONFLICT_TYPE_RESERVED	0x0001	/* the resource requested was reserved */
-#define CONFLICT_TYPE_IN_USE	0x0002	/* there is a conflict because the resource is in use */
-#define CONFLICT_TYPE_PCI	0x0004	/* there is a conflict with a pci device */
-#define CONFLICT_TYPE_INVALID	0x0008	/* the resource requested is invalid */
-#define CONFLICT_TYPE_INTERNAL	0x0010	/* resources within the device conflict with each ohter */
-#define CONFLICT_TYPE_PNP_WARM	0x0020	/* there is a conflict with a pnp device that is active */
-#define CONFLICT_TYPE_PNP_COLD	0x0040	/* there is a conflict with a pnp device that is disabled */
-
-/* conflict search modes */
-#define SEARCH_WARM 1	/* check for conflicts with active devices */
-#define SEARCH_COLD 0	/* check for conflicts with disabled devices */
-
-struct pnp_dev * pnp_check_port_conflicts(struct pnp_dev * dev, int idx, int mode);
 int pnp_check_port(struct pnp_dev * dev, int idx);
-struct pnp_dev * pnp_check_mem_conflicts(struct pnp_dev * dev, int idx, int mode);
 int pnp_check_mem(struct pnp_dev * dev, int idx);
-struct pnp_dev * pnp_check_irq_conflicts(struct pnp_dev * dev, int idx, int mode);
 int pnp_check_irq(struct pnp_dev * dev, int idx);
-struct pnp_dev * pnp_check_dma_conflicts(struct pnp_dev * dev, int idx, int mode);
 int pnp_check_dma(struct pnp_dev * dev, int idx);
diff -urN linux-2.5.72-bk2/drivers/pnp/core.c linux-2.5.72-bk3/drivers/pnp/core.c
--- linux-2.5.72-bk2/drivers/pnp/core.c	2003-06-16 21:19:42.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/core.c	2003-06-20 04:48:11.000000000 -0700
@@ -104,8 +104,8 @@
 static void pnp_release_device(struct device *dmdev)
 {
 	struct pnp_dev * dev = to_pnp_dev(dmdev);
-	if (dev->possible)
-		pnp_free_resources(dev->possible);
+	pnp_free_option(dev->independent);
+	pnp_free_option(dev->dependent);
 	pnp_free_ids(dev);
 	kfree(dev);
 }
@@ -122,7 +122,7 @@
 	list_add_tail(&dev->global_list, &pnp_global);
 	list_add_tail(&dev->protocol_list, &dev->protocol->devices);
 	spin_unlock(&pnp_lock);
-	pnp_auto_config_dev(dev);
+
 	ret = device_register(&dev->dev);
 	if (ret == 0)
 		pnp_interface_attach_device(dev);
diff -urN linux-2.5.72-bk2/drivers/pnp/interface.c linux-2.5.72-bk3/drivers/pnp/interface.c
--- linux-2.5.72-bk2/drivers/pnp/interface.c	2003-06-16 21:19:41.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/interface.c	2003-06-20 04:48:11.000000000 -0700
@@ -168,7 +168,8 @@
 	pnp_printf(buffer, ", %s\n", s);
 }
 
-static void pnp_print_resources(pnp_info_buffer_t *buffer, char *space, struct pnp_resources *res, int dep)
+static void pnp_print_option(pnp_info_buffer_t *buffer, char *space,
+			     struct pnp_option *option, int dep)
 {
 	char *s;
 	struct pnp_port *port;
@@ -176,49 +177,55 @@
 	struct pnp_dma *dma;
 	struct pnp_mem *mem;
 
-	switch (res->priority) {
-	case PNP_RES_PRIORITY_PREFERRED:
-		s = "preferred";
-		break;
-	case PNP_RES_PRIORITY_ACCEPTABLE:
-		s = "acceptable";
-		break;
-	case PNP_RES_PRIORITY_FUNCTIONAL:
-		s = "functional";
-		break;
-	default:
-		s = "invalid";
-	}
-	if (dep > 0)
+	if (dep) {
+		switch (option->priority) {
+			case PNP_RES_PRIORITY_PREFERRED:
+			s = "preferred";
+			break;
+			case PNP_RES_PRIORITY_ACCEPTABLE:
+			s = "acceptable";
+			break;
+			case PNP_RES_PRIORITY_FUNCTIONAL:
+			s = "functional";
+			break;
+			default:
+			s = "invalid";
+		}
 		pnp_printf(buffer, "Dependent: %02i - Priority %s\n",dep, s);
-	for (port = res->port; port; port = port->next)
+	}
+
+	for (port = option->port; port; port = port->next)
 		pnp_print_port(buffer, space, port);
-	for (irq = res->irq; irq; irq = irq->next)
+	for (irq = option->irq; irq; irq = irq->next)
 		pnp_print_irq(buffer, space, irq);
-	for (dma = res->dma; dma; dma = dma->next)
+	for (dma = option->dma; dma; dma = dma->next)
 		pnp_print_dma(buffer, space, dma);
-	for (mem = res->mem; mem; mem = mem->next)
+	for (mem = option->mem; mem; mem = mem->next)
 		pnp_print_mem(buffer, space, mem);
 }
 
-static ssize_t pnp_show_possible_resources(struct device *dmdev, char *buf)
+
+static ssize_t pnp_show_options(struct device *dmdev, char *buf)
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
-	struct pnp_resources * res = dev->possible;
-	int ret, dep = 0;
+	struct pnp_option * independent = dev->independent;
+	struct pnp_option * dependent = dev->dependent;
+	int ret, dep = 1;
+
 	pnp_info_buffer_t *buffer = (pnp_info_buffer_t *)
 				 pnp_alloc(sizeof(pnp_info_buffer_t));
 	if (!buffer)
 		return -ENOMEM;
+
 	buffer->len = PAGE_SIZE;
 	buffer->buffer = buf;
 	buffer->curr = buffer->buffer;
-	while (res){
-		if (dep == 0)
-			pnp_print_resources(buffer, "", res, dep);
-		else
-			pnp_print_resources(buffer, "   ", res, dep);
-		res = res->dep;
+	if (independent)
+		pnp_print_option(buffer, "", independent, 0);
+
+	while (dependent){
+		pnp_print_option(buffer, "   ", dependent, dep);
+		dependent = dependent->next;
 		dep++;
 	}
 	ret = (buffer->curr - buf);
@@ -226,97 +233,8 @@
 	return ret;
 }
 
-static DEVICE_ATTR(possible,S_IRUGO,pnp_show_possible_resources,NULL);
-
-static void pnp_print_conflict_node(pnp_info_buffer_t *buffer, struct pnp_dev * dev)
-{
-	if (!dev)
-		return;
-	pnp_printf(buffer, "'%s'.\n", dev->dev.bus_id);
-}
-
-static void pnp_print_conflict_desc(pnp_info_buffer_t *buffer, int conflict)
-{
-	if (!conflict)
-		return;
-	pnp_printf(buffer, "  Conflict Detected: %2x - ", conflict);
-	switch (conflict) {
-	case CONFLICT_TYPE_RESERVED:
-		pnp_printf(buffer, "manually reserved.\n");
-		break;
-
-	case CONFLICT_TYPE_IN_USE:
-		pnp_printf(buffer, "currently in use.\n");
-		break;
-
-	case CONFLICT_TYPE_PCI:
-		pnp_printf(buffer, "PCI device.\n");
-		break;
-
-	case CONFLICT_TYPE_INVALID:
-		pnp_printf(buffer, "invalid.\n");
-		break;
-
-	case CONFLICT_TYPE_INTERNAL:
-		pnp_printf(buffer, "another resource on this device.\n");
-		break;
-
-	case CONFLICT_TYPE_PNP_WARM:
-		pnp_printf(buffer, "active PnP device ");
-		break;
-
-	case CONFLICT_TYPE_PNP_COLD:
-		pnp_printf(buffer, "disabled PnP device ");
-		break;
-	default:
-		pnp_printf(buffer, "Unknown conflict.\n");
-		break;
-	}
-}
+static DEVICE_ATTR(options,S_IRUGO,pnp_show_options,NULL);
 
-static void pnp_print_conflict(pnp_info_buffer_t *buffer, struct pnp_dev * dev, int idx, int type)
-{
-	struct pnp_dev * cdev, * wdev = NULL;
-	int conflict;
-	switch (type) {
-	case IORESOURCE_IO:
-		conflict = pnp_check_port(dev, idx);
-		if (conflict == CONFLICT_TYPE_PNP_WARM)
-			wdev = pnp_check_port_conflicts(dev, idx, SEARCH_WARM);
-		cdev = pnp_check_port_conflicts(dev, idx, SEARCH_COLD);
-		break;
-	case IORESOURCE_MEM:
-		conflict = pnp_check_mem(dev, idx);
-		if (conflict == CONFLICT_TYPE_PNP_WARM)
-			wdev = pnp_check_mem_conflicts(dev, idx, SEARCH_WARM);
-		cdev = pnp_check_mem_conflicts(dev, idx, SEARCH_COLD);
-		break;
-	case IORESOURCE_IRQ:
-		conflict = pnp_check_irq(dev, idx);
-		if (conflict == CONFLICT_TYPE_PNP_WARM)
-			wdev = pnp_check_irq_conflicts(dev, idx, SEARCH_WARM);
-		cdev = pnp_check_irq_conflicts(dev, idx, SEARCH_COLD);
-		break;
-	case IORESOURCE_DMA:
-		conflict = pnp_check_dma(dev, idx);
-		if (conflict == CONFLICT_TYPE_PNP_WARM)
-			wdev = pnp_check_dma_conflicts(dev, idx, SEARCH_WARM);
-		cdev = pnp_check_dma_conflicts(dev, idx, SEARCH_COLD);
-		break;
-	default:
-		return;
-	}
-
-	pnp_print_conflict_desc(buffer, conflict);
-
-	if (wdev)
-		pnp_print_conflict_node(buffer, wdev);
-
-	if (cdev) {
-		pnp_print_conflict_desc(buffer, CONFLICT_TYPE_PNP_COLD);
-		pnp_print_conflict_node(buffer, cdev);
-	}
-}
 
 static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
 {
@@ -332,12 +250,6 @@
 	buffer->buffer = buf;
 	buffer->curr = buffer->buffer;
 
-	pnp_printf(buffer,"mode = ");
-	if (dev->config_mode & PNP_CONFIG_MANUAL)
-		pnp_printf(buffer,"manual\n");
-	else
-		pnp_printf(buffer,"auto\n");
-
 	pnp_printf(buffer,"state = ");
 	if (dev->active)
 		pnp_printf(buffer,"active\n");
@@ -350,7 +262,6 @@
 			pnp_printf(buffer," 0x%lx-0x%lx \n",
 						pnp_port_start(dev, i),
 						pnp_port_end(dev, i));
-			pnp_print_conflict(buffer, dev, i, IORESOURCE_IO);
 		}
 	}
 	for (i = 0; i < PNP_MAX_MEM; i++) {
@@ -359,21 +270,18 @@
 			pnp_printf(buffer," 0x%lx-0x%lx \n",
 						pnp_mem_start(dev, i),
 						pnp_mem_end(dev, i));
-			pnp_print_conflict(buffer, dev, i, IORESOURCE_MEM);
 		}
 	}
 	for (i = 0; i < PNP_MAX_IRQ; i++) {
 		if (pnp_irq_valid(dev, i)) {
 			pnp_printf(buffer,"irq");
 			pnp_printf(buffer," %ld \n", pnp_irq(dev, i));
-			pnp_print_conflict(buffer, dev, i, IORESOURCE_IRQ);
 		}
 	}
 	for (i = 0; i < PNP_MAX_DMA; i++) {
 		if (pnp_dma_valid(dev, i)) {
 			pnp_printf(buffer,"dma");
 			pnp_printf(buffer," %ld \n", pnp_dma(dev, i));
-			pnp_print_conflict(buffer, dev, i, IORESOURCE_DMA);
 		}
 	}
 	ret = (buffer->curr - buf);
@@ -381,7 +289,7 @@
 	return ret;
 }
 
-extern int pnp_resolve_conflicts(struct pnp_dev *dev);
+extern struct semaphore pnp_res_mutex;
 
 static ssize_t
 pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count)
@@ -390,6 +298,12 @@
 	char	*buf = (void *)ubuf;
 	int	retval = 0;
 
+	if (dev->status & PNP_ATTACHED) {
+		retval = -EBUSY;
+		pnp_info("Device %s cannot be configured because it is in use.", dev->dev.bus_id);
+		goto done;
+	}
+
 	while (isspace(*buf))
 		++buf;
 	if (!strnicmp(buf,"disable",7)) {
@@ -400,41 +314,30 @@
 		retval = pnp_activate_dev(dev);
 		goto done;
 	}
-	if (!strnicmp(buf,"reset",5)) {
-		if (!dev->active)
-			goto done;
-		retval = pnp_disable_dev(dev);
-		if (retval)
+	if (!strnicmp(buf,"fill",4)) {
+		if (dev->active)
 			goto done;
-		retval = pnp_activate_dev(dev);
+		retval = pnp_auto_config_dev(dev);
 		goto done;
 	}
 	if (!strnicmp(buf,"auto",4)) {
 		if (dev->active)
 			goto done;
+		pnp_init_resources(&dev->res);
 		retval = pnp_auto_config_dev(dev);
 		goto done;
 	}
 	if (!strnicmp(buf,"clear",5)) {
 		if (dev->active)
 			goto done;
-		spin_lock(&pnp_lock);
-		dev->config_mode = PNP_CONFIG_MANUAL;
-		pnp_init_resource_table(&dev->res);
-		if (dev->rule)
-			dev->rule->depnum = 0;
-		spin_unlock(&pnp_lock);
-		goto done;
-	}
-	if (!strnicmp(buf,"resolve",7)) {
-		retval = pnp_resolve_conflicts(dev);
+		pnp_init_resources(&dev->res);
 		goto done;
 	}
 	if (!strnicmp(buf,"get",3)) {
-		spin_lock(&pnp_lock);
+		down(&pnp_res_mutex);
 		if (pnp_can_read(dev))
 			dev->protocol->get(dev, &dev->res);
-		spin_unlock(&pnp_lock);
+		up(&pnp_res_mutex);
 		goto done;
 	}
 	if (!strnicmp(buf,"set",3)) {
@@ -442,9 +345,8 @@
 		if (dev->active)
 			goto done;
 		buf += 3;
-		spin_lock(&pnp_lock);
-		dev->config_mode = PNP_CONFIG_MANUAL;
-		pnp_init_resource_table(&dev->res);
+		pnp_init_resources(&dev->res);
+		down(&pnp_res_mutex);
 		while (1) {
 			while (isspace(*buf))
 				++buf;
@@ -514,7 +416,7 @@
 			}
 			break;
 		}
-		spin_unlock(&pnp_lock);
+		up(&pnp_res_mutex);
 		goto done;
 	}
  done:
@@ -543,7 +445,7 @@
 
 int pnp_interface_attach_device(struct pnp_dev *dev)
 {
-	device_create_file(&dev->dev,&dev_attr_possible);
+	device_create_file(&dev->dev,&dev_attr_options);
 	device_create_file(&dev->dev,&dev_attr_resources);
 	device_create_file(&dev->dev,&dev_attr_id);
 	return 0;
diff -urN linux-2.5.72-bk2/drivers/pnp/isapnp/core.c linux-2.5.72-bk3/drivers/pnp/isapnp/core.c
--- linux-2.5.72-bk2/drivers/pnp/isapnp/core.c	2003-06-16 21:20:02.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/isapnp/core.c	2003-06-20 04:48:11.000000000 -0700
@@ -31,6 +31,7 @@
  *  2002-06-06  Made the use of dma channel 0 configurable
  *              Gerald Teschl <gerald.teschl@univie.ac.at>
  *  2002-10-06  Ported to PnP Layer - Adam Belay <ambx1@neo.rr.com>
+ *  2003-08-11	Resource Management Updates - Adam Belay <ambx1@neo.rr.com>
  */
 
 #include <linux/config.h>
@@ -54,7 +55,6 @@
 int isapnp_disable;			/* Disable ISA PnP */
 int isapnp_rdp;				/* Read Data Port */
 int isapnp_reset = 1;			/* reset all PnP cards (deactivate) */
-int isapnp_skip_pci_scan;		/* skip PCI resource scanning */
 int isapnp_verbose = 1;			/* verbose mode */
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -66,8 +66,6 @@
 MODULE_PARM(isapnp_reset, "i");
 MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
 MODULE_PARM(isapnp_allow_dma0, "i");
-MODULE_PARM(isapnp_skip_pci_scan, "i");
-MODULE_PARM_DESC(isapnp_skip_pci_scan, "ISA Plug & Play skip PCI resource scanning");
 MODULE_PARM(isapnp_verbose, "i");
 MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
 MODULE_LICENSE("GPL");
@@ -460,6 +458,7 @@
 	dev->capabilities |= PNP_READ;
 	dev->capabilities |= PNP_WRITE;
 	dev->capabilities |= PNP_DISABLE;
+	pnp_init_resources(&dev->res);
 	return dev;
 }
 
@@ -468,8 +467,8 @@
  *  Add IRQ resource to resources list.
  */
 
-static void __init isapnp_add_irq_resource(struct pnp_dev *dev,
-                                               int depnum, int size)
+static void __init isapnp_parse_irq_resource(struct pnp_option *option,
+					       int size)
 {
 	unsigned char tmp[3];
 	struct pnp_irq *irq;
@@ -483,7 +482,7 @@
 		irq->flags = tmp[2];
 	else
 		irq->flags = IORESOURCE_IRQ_HIGHEDGE;
-	pnp_add_irq_resource(dev, depnum, irq);
+	pnp_register_irq_resource(option, irq);
 	return;
 }
 
@@ -491,8 +490,8 @@
  *  Add DMA resource to resources list.
  */
 
-static void __init isapnp_add_dma_resource(struct pnp_dev *dev,
-                                    	       int depnum, int size)
+static void __init isapnp_parse_dma_resource(struct pnp_option *option,
+                                    	       int size)
 {
 	unsigned char tmp[2];
 	struct pnp_dma *dma;
@@ -503,7 +502,7 @@
 		return;
 	dma->map = tmp[0];
 	dma->flags = tmp[1];
-	pnp_add_dma_resource(dev, depnum, dma);
+	pnp_register_dma_resource(option, dma);
 	return;
 }
 
@@ -511,8 +510,8 @@
  *  Add port resource to resources list.
  */
 
-static void __init isapnp_add_port_resource(struct pnp_dev *dev,
-						int depnum, int size)
+static void __init isapnp_parse_port_resource(struct pnp_option *option,
+						int size)
 {
 	unsigned char tmp[7];
 	struct pnp_port *port;
@@ -526,7 +525,7 @@
 	port->align = tmp[5];
 	port->size = tmp[6];
 	port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
-	pnp_add_port_resource(dev,depnum,port);
+	pnp_register_port_resource(option,port);
 	return;
 }
 
@@ -534,8 +533,8 @@
  *  Add fixed port resource to resources list.
  */
 
-static void __init isapnp_add_fixed_port_resource(struct pnp_dev *dev,
-						      int depnum, int size)
+static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
+						      int size)
 {
 	unsigned char tmp[3];
 	struct pnp_port *port;
@@ -548,7 +547,7 @@
 	port->size = tmp[2];
 	port->align = 0;
 	port->flags = PNP_PORT_FLAG_FIXED;
-	pnp_add_port_resource(dev,depnum,port);
+	pnp_register_port_resource(option,port);
 	return;
 }
 
@@ -556,8 +555,8 @@
  *  Add memory resource to resources list.
  */
 
-static void __init isapnp_add_mem_resource(struct pnp_dev *dev,
-					       int depnum, int size)
+static void __init isapnp_parse_mem_resource(struct pnp_option *option,
+					       int size)
 {
 	unsigned char tmp[9];
 	struct pnp_mem *mem;
@@ -571,7 +570,7 @@
 	mem->align = (tmp[6] << 8) | tmp[5];
 	mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
 	mem->flags = tmp[0];
-	pnp_add_mem_resource(dev,depnum,mem);
+	pnp_register_mem_resource(option,mem);
 	return;
 }
 
@@ -579,8 +578,8 @@
  *  Add 32-bit memory resource to resources list.
  */
 
-static void __init isapnp_add_mem32_resource(struct pnp_dev *dev,
-						 int depnum, int size)
+static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
+						 int size)
 {
 	unsigned char tmp[17];
 	struct pnp_mem *mem;
@@ -594,15 +593,15 @@
 	mem->align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
 	mem->size = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
 	mem->flags = tmp[0];
-	pnp_add_mem_resource(dev,depnum,mem);
+	pnp_register_mem_resource(option,mem);
 }
 
 /*
  *  Add 32-bit fixed memory resource to resources list.
  */
 
-static void __init isapnp_add_fixed_mem32_resource(struct pnp_dev *dev,
-						       int depnum, int size)
+static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
+						       int size)
 {
 	unsigned char tmp[9];
 	struct pnp_mem *mem;
@@ -615,14 +614,14 @@
 	mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
 	mem->align = 0;
 	mem->flags = tmp[0];
-	pnp_add_mem_resource(dev,depnum,mem);
+	pnp_register_mem_resource(option,mem);
 }
 
 /*
  *  Parse card name for ISA PnP device.
  */ 
- 
-static void __init 
+
+static void __init
 isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
 {
 	if (name[0] == '\0') {
@@ -634,7 +633,7 @@
 		/* clean whitespace from end of string */
 		while (size1 > 0  &&  name[--size1] == ' ')
 			name[size1] = '\0';
-	}	
+	}
 }
 
 /*
@@ -644,14 +643,17 @@
 static int __init isapnp_create_device(struct pnp_card *card,
 				       unsigned short size)
 {
-	int number = 0, skip = 0, depnum = 0, dependent = 0, compat = 0;
+	int number = 0, skip = 0, priority = 0, compat = 0;
 	unsigned char type, tmp[17];
+	struct pnp_option *option;
 	struct pnp_dev *dev;
 	if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
 		return 1;
-	if (pnp_build_resource(dev, 0) == NULL)
+	option = pnp_register_independent_option(dev);
+	if (!option)
 		return 1;
 	pnp_add_card_device(card,dev);
+
 	while (1) {
 		if (isapnp_read_tag(&type, &size)<0)
 			return 1;
@@ -662,15 +664,16 @@
 			if (size >= 5 && size <= 6) {
 				if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
 					return 1;
-				pnp_build_resource(dev,0);
-				pnp_add_card_device(card,dev);
 				size = 0;
 				skip = 0;
+				option = pnp_register_independent_option(dev);
+				if (!option)
+					return 1;
+				pnp_add_card_device(card,dev);
 			} else {
 				skip = 1;
 			}
-			dependent = 0;
-			depnum = 0;
+			priority = 0;
 			compat = 0;
 			break;
 		case _STAG_COMPATDEVID:
@@ -684,43 +687,43 @@
 		case _STAG_IRQ:
 			if (size < 2 || size > 3)
 				goto __skip;
-			isapnp_add_irq_resource(dev, depnum, size);
+			isapnp_parse_irq_resource(option, size);
 			size = 0;
 			break;
 		case _STAG_DMA:
 			if (size != 2)
 				goto __skip;
-			isapnp_add_dma_resource(dev, depnum, size);
+			isapnp_parse_dma_resource(option, size);
 			size = 0;
 			break;
 		case _STAG_STARTDEP:
 			if (size > 1)
 				goto __skip;
-			dependent = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+			priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
 			if (size > 0) {
 				isapnp_peek(tmp, size);
-				dependent = 0x100 | tmp[0];
+				priority = 0x100 | tmp[0];
 				size = 0;
 			}
-			pnp_build_resource(dev,dependent);
-			depnum = pnp_get_max_depnum(dev);
+			option = pnp_register_dependent_option(dev,priority);
+			if (!option)
+				return 1;
 			break;
 		case _STAG_ENDDEP:
 			if (size != 0)
 				goto __skip;
-			dependent = 0;
-			depnum = 0;
+			priority = 0;
 			break;
 		case _STAG_IOPORT:
 			if (size != 7)
 				goto __skip;
-			isapnp_add_port_resource(dev, depnum, size);
+			isapnp_parse_port_resource(option, size);
 			size = 0;
 			break;
 		case _STAG_FIXEDIO:
 			if (size != 3)
 				goto __skip;
-			isapnp_add_fixed_port_resource(dev, depnum, size);
+			isapnp_parse_fixed_port_resource(option, size);
 			size = 0;
 			break;
 		case _STAG_VENDOR:
@@ -728,7 +731,7 @@
 		case _LTAG_MEMRANGE:
 			if (size != 9)
 				goto __skip;
-			isapnp_add_mem_resource(dev, depnum, size);
+			isapnp_parse_mem_resource(option, size);
 			size = 0;
 			break;
 		case _LTAG_ANSISTR:
@@ -743,13 +746,13 @@
 		case _LTAG_MEM32RANGE:
 			if (size != 17)
 				goto __skip;
-			isapnp_add_mem32_resource(dev, depnum, size);
+			isapnp_parse_mem32_resource(option, size);
 			size = 0;
 			break;
 		case _LTAG_FIXEDMEM32RANGE:
 			if (size != 9)
 				goto __skip;
-			isapnp_add_fixed_mem32_resource(dev, depnum, size);
+			isapnp_parse_fixed_mem32_resource(option, size);
 			size = 0;
 			break;
 		case _STAG_END:
@@ -859,63 +862,6 @@
 	pnp_add_card_id(id,card);
 }
 
-
-static int isapnp_parse_current_resources(struct pnp_dev *dev, struct pnp_resource_table * res)
-{
-	int tmp, ret;
-	struct pnp_rule_table rule;
-	if (dev->rule)
-		rule = *dev->rule;
-	else {
-		if (!pnp_generate_rule(dev,1,&rule))
-			return -EINVAL;
-	}
-
-	dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
-	if (dev->active) {
-		for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
-			ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
-			if (!ret)
-				continue;
-			res->port_resource[tmp].start = ret;
-			if (rule.port[tmp])
-				res->port_resource[tmp].end = ret + rule.port[tmp]->size - 1;
-			else
-				res->port_resource[tmp].end = ret + 1; /* all we can do is assume 1 :-( */
-			res->port_resource[tmp].flags = IORESOURCE_IO;
-		}
-		for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
-			ret = isapnp_read_dword(ISAPNP_CFG_MEM + (tmp << 3));
-			if (!ret)
-				continue;
-			res->mem_resource[tmp].start = ret;
-			if (rule.mem[tmp])
-				res->mem_resource[tmp].end = ret + rule.mem[tmp]->size - 1;
-			else
-				res->mem_resource[tmp].end = ret + 1; /* all we can do is assume 1 :-( */
-			res->mem_resource[tmp].flags = IORESOURCE_MEM;
-		}
-		for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
-			ret = (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> 8);
-			if (!ret)
-				continue;
-			res->irq_resource[tmp].start = res->irq_resource[tmp].end = ret;
-			res->irq_resource[tmp].flags = IORESOURCE_IRQ;
-		}
-		for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
-			ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
-			if (ret == 4)
-				continue;
-			if (rule.dma[tmp]) { /* some isapnp systems forget to set this to 4 so we have to check */
-				res->dma_resource[tmp].start = res->dma_resource[tmp].end = ret;
-				res->dma_resource[tmp].flags = IORESOURCE_DMA;
-			}
-		}
-	}
-	return 0;
-}
-
-
 /*
  *  Build device list for all present ISA PnP devices.
  */
@@ -925,7 +871,6 @@
 	int csn;
 	unsigned char header[9], checksum;
 	struct pnp_card *card;
-	struct pnp_dev *dev;
 
 	isapnp_wait();
 	isapnp_key();
@@ -959,13 +904,6 @@
 		card->checksum = isapnp_checksum_value;
 		card->protocol = &isapnp_protocol;
 
-		/* read the current resource data */
-		card_for_each_dev(card,dev) {
-			isapnp_device(dev->number);
-		pnp_init_resource_table(&dev->res);
-			isapnp_parse_current_resources(dev, &dev->res);
-		}
-
 		pnp_add_card(card);
 	}
 	isapnp_wait();
@@ -1041,12 +979,50 @@
 EXPORT_SYMBOL(isapnp_wake);
 EXPORT_SYMBOL(isapnp_device);
 
+static int isapnp_read_resources(struct pnp_dev *dev, struct pnp_resource_table *res)
+{
+	int tmp, ret;
+
+	dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
+	if (dev->active) {
+		for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
+			ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
+			if (!ret)
+				continue;
+			res->port_resource[tmp].start = ret;
+			res->port_resource[tmp].flags = IORESOURCE_IO;
+		}
+		for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
+			ret = isapnp_read_dword(ISAPNP_CFG_MEM + (tmp << 3));
+			if (!ret)
+				continue;
+			res->mem_resource[tmp].start = ret;
+			res->mem_resource[tmp].flags = IORESOURCE_MEM;
+		}
+		for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
+			ret = (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> 8);
+			if (!ret)
+				continue;
+			res->irq_resource[tmp].start = res->irq_resource[tmp].end = ret;
+			res->irq_resource[tmp].flags = IORESOURCE_IRQ;
+		}
+		for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
+			ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
+			if (ret == 4)
+				continue;
+			res->dma_resource[tmp].start = res->dma_resource[tmp].end = ret;
+			res->dma_resource[tmp].flags = IORESOURCE_DMA;
+		}
+	}
+	return 0;
+}
+
 static int isapnp_get_resources(struct pnp_dev *dev, struct pnp_resource_table * res)
 {
 	int ret;
-	pnp_init_resource_table(res);
+	pnp_init_resources(res);
 	isapnp_cfg_begin(dev->card->number, dev->number);
-	ret = isapnp_parse_current_resources(dev, res);
+	ret = isapnp_read_resources(dev, res);
 	isapnp_cfg_end();
 	return ret;
 }
@@ -1196,7 +1172,6 @@
 {
 	(void)((get_option(&str,&isapnp_rdp) == 2) &&
 	       (get_option(&str,&isapnp_reset) == 2) &&
-	       (get_option(&str,&isapnp_skip_pci_scan) == 2) &&
 	       (get_option(&str,&isapnp_verbose) == 2));
 	return 1;
 }
diff -urN linux-2.5.72-bk2/drivers/pnp/manager.c linux-2.5.72-bk3/drivers/pnp/manager.c
--- linux-2.5.72-bk2/drivers/pnp/manager.c	2003-06-16 21:20:25.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/manager.c	2003-06-20 04:48:11.000000000 -0700
@@ -1,6 +1,7 @@
 /*
  * manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
  *
+ * based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz>
  * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
  *
  */
@@ -20,549 +21,339 @@
 #include <linux/pnp.h>
 #include "base.h"
 
+DECLARE_MUTEX(pnp_res_mutex);
 
-int pnp_max_moves = 4;
-
-
-static int pnp_next_port(struct pnp_dev * dev, int idx)
+static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
 {
-	struct pnp_port *port;
 	unsigned long *start, *end, *flags;
-	if (!dev || idx < 0 || idx >= PNP_MAX_PORT)
-		return 0;
-	port = dev->rule->port[idx];
-	if (!port)
+
+	if (!dev || !rule)
+		return -EINVAL;
+
+	if (idx >= PNP_MAX_PORT) {
+		pnp_err("More than 4 ports is incompatible with pnp specifications.");
+		/* pretend we were successful so at least the manager won't try again */
+		return 1;
+	}
+
+	/* check if this resource has been manually set, if so skip */
+	if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO))
 		return 1;
 
 	start = &dev->res.port_resource[idx].start;
 	end = &dev->res.port_resource[idx].end;
 	flags = &dev->res.port_resource[idx].flags;
 
-	/* set the initial values if this is the first time */
-	if (*start == 0) {
-		*start = port->min;
-		*end = *start + port->size - 1;
-		*flags = port->flags | IORESOURCE_IO;
-		if (!pnp_check_port(dev, idx))
-			return 1;
-	}
+	/* set the initial values */
+	*start = rule->min;
+	*end = *start + rule->size - 1;
+	*flags = *flags | rule->flags | IORESOURCE_IO;
 
 	/* run through until pnp_check_port is happy */
-	do {
-		*start += port->align;
-		*end = *start + port->size - 1;
-		if (*start > port->max || !port->align)
+	while (!pnp_check_port(dev, idx)) {
+		*start += rule->align;
+		*end = *start + rule->size - 1;
+		if (*start > rule->max || !rule->align)
 			return 0;
-	} while (pnp_check_port(dev, idx));
+	}
 	return 1;
 }
 
-static int pnp_next_mem(struct pnp_dev * dev, int idx)
+static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 {
-	struct pnp_mem *mem;
 	unsigned long *start, *end, *flags;
-	if (!dev || idx < 0 || idx >= PNP_MAX_MEM)
-		return 0;
-	mem = dev->rule->mem[idx];
-	if (!mem)
+
+	if (!dev || !rule)
+		return -EINVAL;
+
+	if (idx >= PNP_MAX_MEM) {
+		pnp_err("More than 8 mems is incompatible with pnp specifications.");
+		/* pretend we were successful so at least the manager won't try again */
+		return 1;
+	}
+
+	/* check if this resource has been manually set, if so skip */
+	if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO))
 		return 1;
 
 	start = &dev->res.mem_resource[idx].start;
 	end = &dev->res.mem_resource[idx].end;
 	flags = &dev->res.mem_resource[idx].flags;
 
-	/* set the initial values if this is the first time */
-	if (*start == 0) {
-		*start = mem->min;
-		*end = *start + mem->size -1;
-		*flags = mem->flags | IORESOURCE_MEM;
-		if (!(mem->flags & IORESOURCE_MEM_WRITEABLE))
-			*flags |= IORESOURCE_READONLY;
-		if (mem->flags & IORESOURCE_MEM_CACHEABLE)
-			*flags |= IORESOURCE_CACHEABLE;
-		if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
-			*flags |= IORESOURCE_RANGELENGTH;
-		if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
-			*flags |= IORESOURCE_SHADOWABLE;
-		if (!pnp_check_mem(dev, idx))
-			return 1;
-	}
+	/* set the initial values */
+	*start = rule->min;
+	*end = *start + rule->size -1;
+	*flags = *flags | rule->flags | IORESOURCE_MEM;
+
+	/* convert pnp flags to standard Linux flags */
+	if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
+		*flags |= IORESOURCE_READONLY;
+	if (rule->flags & IORESOURCE_MEM_CACHEABLE)
+		*flags |= IORESOURCE_CACHEABLE;
+	if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
+		*flags |= IORESOURCE_RANGELENGTH;
+	if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
+		*flags |= IORESOURCE_SHADOWABLE;
 
 	/* run through until pnp_check_mem is happy */
-	do {
-		*start += mem->align;
-		*end = *start + mem->size - 1;
-		if (*start > mem->max || !mem->align)
+	while (!pnp_check_mem(dev, idx)) {
+		*start += rule->align;
+		*end = *start + rule->size - 1;
+		if (*start > rule->max || !rule->align)
 			return 0;
-	} while (pnp_check_mem(dev, idx));
+	}
 	return 1;
 }
 
-static int pnp_next_irq(struct pnp_dev * dev, int idx)
+static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx)
 {
-	struct pnp_irq *irq;
 	unsigned long *start, *end, *flags;
-	int i, mask;
-	if (!dev || idx < 0 || idx >= PNP_MAX_IRQ)
-		return 0;
-	irq = dev->rule->irq[idx];
-	if (!irq)
-		return 1;
+	int i;
 
-	start = &dev->res.irq_resource[idx].start;
-	end = &dev->res.irq_resource[idx].end;
-	flags = &dev->res.irq_resource[idx].flags;
+	/* IRQ priority: this table is good for i386 */
+	static unsigned short xtab[16] = {
+		5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
+	};
 
-	/* set the initial values if this is the first time */
-	if (*start == -1) {
-		*start = *end = 0;
-		*flags = irq->flags | IORESOURCE_IRQ;
-		if (!pnp_check_irq(dev, idx))
-			return 1;
-	}
+	if (!dev || !rule)
+		return -EINVAL;
 
-	mask = irq->map;
-	for (i = *start + 1; i < 16; i++)
-	{
-		if(mask>>i & 0x01) {
-			*start = *end = i;
-			if(!pnp_check_irq(dev, idx))
-				return 1;
-		}
+	if (idx >= PNP_MAX_IRQ) {
+		pnp_err("More than 2 irqs is incompatible with pnp specifications.");
+		/* pretend we were successful so at least the manager won't try again */
+		return 1;
 	}
-	return 0;
-}
 
-static int pnp_next_dma(struct pnp_dev * dev, int idx)
-{
-	struct pnp_dma *dma;
-	unsigned long *start, *end, *flags;
-	int i, mask;
-	if (!dev || idx < 0 || idx >= PNP_MAX_DMA)
-		return -EINVAL;
-	dma = dev->rule->dma[idx];
-	if (!dma)
+	/* check if this resource has been manually set, if so skip */
+	if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO))
 		return 1;
 
-	start = &dev->res.dma_resource[idx].start;
-	end = &dev->res.dma_resource[idx].end;
-	flags = &dev->res.dma_resource[idx].flags;
+	start = &dev->res.irq_resource[idx].start;
+	end = &dev->res.irq_resource[idx].end;
+	flags = &dev->res.irq_resource[idx].flags;
 
-	/* set the initial values if this is the first time */
-	if (*start == -1) {
-		*start = *end = 0;
-		*flags = dma->flags | IORESOURCE_DMA;
-		if (!pnp_check_dma(dev, idx))
-			return 1;
-	}
+	/* set the initial values */
+	*flags = *flags | rule->flags | IORESOURCE_IRQ;
 
-	mask = dma->map;
-	for (i = *start + 1; i < 8; i++)
-	{
-		if(mask>>i & 0x01) {
-			*start = *end = i;
-			if(!pnp_check_dma(dev, idx))
+	for (i = 0; i < 16; i++) {
+		if(rule->map & (1<<xtab[i])) {
+			*start = *end = xtab[i];
+			if(pnp_check_irq(dev, idx))
 				return 1;
 		}
 	}
 	return 0;
 }
 
-static int pnp_next_rule(struct pnp_dev *dev)
-{
-	int depnum = dev->rule->depnum;
-        int max = pnp_get_max_depnum(dev);
-	int priority = PNP_RES_PRIORITY_PREFERRED;
-
-	if (depnum < 0)
-		return 0;
-
-	if (max == 0) {
-		if (pnp_generate_rule(dev, 0, dev->rule)) {
-			dev->rule->depnum = -1;
-			return 1;
-		}
-	}
-
-	if(depnum > 0) {
-		struct pnp_resources * res = pnp_find_resources(dev, depnum);
-		priority = res->priority;
-	}
-
-	for (; priority <= PNP_RES_PRIORITY_FUNCTIONAL; priority++, depnum = 0) {
-		depnum += 1;
-		for (; depnum <= max; depnum++) {
-			struct pnp_resources * res = pnp_find_resources(dev, depnum);
-			if (res->priority == priority) {
-				if(pnp_generate_rule(dev, depnum, dev->rule)) {
-					dev->rule->depnum = depnum;
-					return 1;
-				}
-			}
-		}
-	}
-	return 0;
-}
-
-struct pnp_change {
-	struct list_head change_list;
-	struct list_head changes;
-	struct pnp_resource_table res_bak;
-	struct pnp_rule_table rule_bak;
-	struct pnp_dev * dev;
-};
-
-static void pnp_free_changes(struct pnp_change * parent)
-{
-	struct list_head * pos, * temp;
-	list_for_each_safe(pos, temp, &parent->changes) {
-		struct pnp_change * change = list_entry(pos, struct pnp_change, change_list);
-		list_del(&change->change_list);
-		kfree(change);
-	}
-}
-
-static void pnp_undo_changes(struct pnp_change * parent)
-{
-	struct list_head * pos, * temp;
-	list_for_each_safe(pos, temp, &parent->changes) {
-		struct pnp_change * change = list_entry(pos, struct pnp_change, change_list);
-		*change->dev->rule = change->rule_bak;
-		change->dev->res = change->res_bak;
-		list_del(&change->change_list);
-		kfree(change);
-	}
-}
-
-static struct pnp_change * pnp_add_change(struct pnp_change * parent, struct pnp_dev * dev)
-{
-	struct pnp_change * change = pnp_alloc(sizeof(struct pnp_change));
-	if (!change)
-		return NULL;
-	change->res_bak = dev->res;
-	change->rule_bak = *dev->rule;
-	change->dev = dev;
-	INIT_LIST_HEAD(&change->changes);
-	if (parent)
-		list_add(&change->change_list, &parent->changes);
-	return change;
-}
-
-static void pnp_commit_changes(struct pnp_change * parent, struct pnp_change * change)
-{
-	/* check if it's the root change */
-	if (!parent)
-		return;
-	if (!list_empty(&change->changes))
-		list_splice_init(&change->changes, &parent->changes);
-}
-
-static int pnp_next_config(struct pnp_dev * dev, int move, struct pnp_change * parent);
-
-static int pnp_next_request(struct pnp_dev * dev, int move, struct pnp_change * parent, struct pnp_change * change)
+static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
 {
+	unsigned long *start, *end, *flags;
 	int i;
-	struct pnp_dev * cdev;
 
-	for (i = 0; i < PNP_MAX_PORT; i++) {
-		if (dev->res.port_resource[i].start == 0
-		 || pnp_check_port_conflicts(dev,i,SEARCH_WARM)) {
-			if (!pnp_next_port(dev,i))
-				return 0;
-		}
-		do {
-			cdev = pnp_check_port_conflicts(dev,i,SEARCH_COLD);
-			if (cdev && (!move || !pnp_next_config(cdev,move,change))) {
-				pnp_undo_changes(change);
-				if (!pnp_next_port(dev,i))
-					return 0;
-			}
-		} while (cdev);
-		pnp_commit_changes(parent, change);
-	}
-	for (i = 0; i < PNP_MAX_MEM; i++) {
-		if (dev->res.mem_resource[i].start == 0
-		 || pnp_check_mem_conflicts(dev,i,SEARCH_WARM)) {
-			if (!pnp_next_mem(dev,i))
-				return 0;
-		}
-		do {
-			cdev = pnp_check_mem_conflicts(dev,i,SEARCH_COLD);
-			if (cdev && (!move || !pnp_next_config(cdev,move,change))) {
-				pnp_undo_changes(change);
-				if (!pnp_next_mem(dev,i))
-					return 0;
-			}
-		} while (cdev);
-		pnp_commit_changes(parent, change);
-	}
-	for (i = 0; i < PNP_MAX_IRQ; i++) {
-		if (dev->res.irq_resource[i].start == -1
-		 || pnp_check_irq_conflicts(dev,i,SEARCH_WARM)) {
-			if (!pnp_next_irq(dev,i))
-				return 0;
-		}
-		do {
-			cdev = pnp_check_irq_conflicts(dev,i,SEARCH_COLD);
-			if (cdev && (!move || !pnp_next_config(cdev,move,change))) {
-				pnp_undo_changes(change);
-				if (!pnp_next_irq(dev,i))
-					return 0;
-			}
-		} while (cdev);
-		pnp_commit_changes(parent, change);
-	}
-	for (i = 0; i < PNP_MAX_DMA; i++) {
-		if (dev->res.dma_resource[i].start == -1
-		 || pnp_check_dma_conflicts(dev,i,SEARCH_WARM)) {
-			if (!pnp_next_dma(dev,i))
-				return 0;
-		}
-		do {
-			cdev = pnp_check_dma_conflicts(dev,i,SEARCH_COLD);
-			if (cdev && (!move || !pnp_next_config(cdev,move,change))) {
-				pnp_undo_changes(change);
-				if (!pnp_next_dma(dev,i))
-					return 0;
-			}
-		} while (cdev);
-		pnp_commit_changes(parent, change);
-	}
-	return 1;
-}
-
-static int pnp_next_config(struct pnp_dev * dev, int move, struct pnp_change * parent)
-{
-	struct pnp_change * change;
-	move--;
-	if (!dev->rule)
-		return 0;
-	change = pnp_add_change(parent,dev);
-	if (!change)
-		return 0;
-	if (!pnp_can_configure(dev))
-		goto fail;
-	if (!dev->rule->depnum) {
-		if (!pnp_next_rule(dev))
-			goto fail;
-	}
-	while (!pnp_next_request(dev, move, parent, change)) {
-		if(!pnp_next_rule(dev))
-			goto fail;
-		pnp_init_resource_table(&dev->res);
-	}
-	if (!parent) {
-		pnp_free_changes(change);
-		kfree(change);
-	}
-	return 1;
+	/* DMA priority: this table is good for i386 */
+	static unsigned short xtab[8] = {
+		1, 3, 5, 6, 7, 0, 2, 4
+	};
 
-fail:
-	if (!parent)
-		kfree(change);
-	return 0;
-}
+	if (!dev || !rule)
+		return -EINVAL;
 
-/* this advanced algorithm will shuffle other configs to make room and ensure that the most possible devices have configs */
-static int pnp_advanced_config(struct pnp_dev * dev)
-{
-	int move;
-	/* if the device cannot be configured skip it */
-	if (!pnp_can_configure(dev))
+	if (idx >= PNP_MAX_DMA) {
+		pnp_err("More than 2 dmas is incompatible with pnp specifications.");
+		/* pretend we were successful so at least the manager won't try again */
 		return 1;
-	if (!dev->rule) {
-		dev->rule = pnp_alloc(sizeof(struct pnp_rule_table));
-		if (!dev->rule)
-			return -ENOMEM;
-	}
-
-	spin_lock(&pnp_lock);
-	for (move = 1; move <= pnp_max_moves; move++) {
-		dev->rule->depnum = 0;
-		pnp_init_resource_table(&dev->res);
-		if (pnp_next_config(dev,move,NULL)) {
-			spin_unlock(&pnp_lock);
-			return 1;
-		}
 	}
 
-	pnp_init_resource_table(&dev->res);
-	dev->rule->depnum = 0;
-	spin_unlock(&pnp_lock);
-	pnp_err("res: Unable to resolve resource conflicts for the device '%s', some devices may not be usable.", dev->dev.bus_id);
-	return 0;
-}
+	/* check if this resource has been manually set, if so skip */
+	if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO))
+		return 1;
 
-int pnp_resolve_conflicts(struct pnp_dev *dev)
-{
-	int i;
-	struct pnp_dev * cdev;
+	start = &dev->res.dma_resource[idx].start;
+	end = &dev->res.dma_resource[idx].end;
+	flags = &dev->res.dma_resource[idx].flags;
 
-	for (i = 0; i < PNP_MAX_PORT; i++)
-	{
-		do {
-			cdev = pnp_check_port_conflicts(dev,i,SEARCH_COLD);
-			if (cdev)
-				pnp_advanced_config(cdev);
-		} while (cdev);
-	}
-	for (i = 0; i < PNP_MAX_MEM; i++)
-	{
-		do {
-			cdev = pnp_check_mem_conflicts(dev,i,SEARCH_COLD);
-			if (cdev)
-				pnp_advanced_config(cdev);
-		} while (cdev);
-	}
-	for (i = 0; i < PNP_MAX_IRQ; i++)
-	{
-		do {
-			cdev = pnp_check_irq_conflicts(dev,i,SEARCH_COLD);
-			if (cdev)
-				pnp_advanced_config(cdev);
-		} while (cdev);
-	}
-	for (i = 0; i < PNP_MAX_DMA; i++)
-	{
-		do {
-			cdev = pnp_check_dma_conflicts(dev,i,SEARCH_COLD);
-			if (cdev)
-				pnp_advanced_config(cdev);
-		} while (cdev);
-	}
-	return 1;
-}
+	/* set the initial values */
+	*flags = *flags | rule->flags | IORESOURCE_DMA;
 
-/* this is a much faster algorithm but it may not leave resources for other devices to use */
-static int pnp_simple_config(struct pnp_dev * dev)
-{
-	int i;
-	spin_lock(&pnp_lock);
-	if (dev->active) {
-		spin_unlock(&pnp_lock);
-		return 1;
-	}
-	if (!dev->rule) {
-		dev->rule = pnp_alloc(sizeof(struct pnp_rule_table));
-		if (!dev->rule) {
-			spin_unlock(&pnp_lock);
-			return -ENOMEM;
-		}
-	}
-	dev->rule->depnum = 0;
-	pnp_init_resource_table(&dev->res);
-	while (pnp_next_rule(dev)) {
-		for (i = 0; i < PNP_MAX_PORT; i++) {
-			if (!pnp_next_port(dev,i))
-				continue;
-		}
-		for (i = 0; i < PNP_MAX_MEM; i++) {
-			if (!pnp_next_mem(dev,i))
-				continue;
-		}
-		for (i = 0; i < PNP_MAX_IRQ; i++) {
-			if (!pnp_next_irq(dev,i))
-				continue;
-		}
-		for (i = 0; i < PNP_MAX_DMA; i++) {
-			if (!pnp_next_dma(dev,i))
-				continue;
+	for (i = 0; i < 8; i++) {
+		if(rule->map & (1<<xtab[i])) {
+			*start = *end = xtab[i];
+			if(pnp_check_dma(dev, idx))
+				return 1;
 		}
-		goto done;
 	}
-	pnp_init_resource_table(&dev->res);
-	dev->rule->depnum = 0;
-	spin_unlock(&pnp_lock);
 	return 0;
-
-done:
-	pnp_resolve_conflicts(dev);	/* this is required or we will break the advanced configs */
-	return 1;
 }
 
-static int pnp_compare_resources(struct pnp_resource_table * resa, struct pnp_resource_table * resb)
+/**
+ * pnp_init_resources - Resets a resource table to default values.
+ * @table: pointer to the desired resource table
+ *
+ */
+void pnp_init_resources(struct pnp_resource_table *table)
 {
 	int idx;
+	down(&pnp_res_mutex);
 	for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
-		if (resa->irq_resource[idx].start != resb->irq_resource[idx].start)
-			return 1;
+		table->irq_resource[idx].name = NULL;
+		table->irq_resource[idx].start = -1;
+		table->irq_resource[idx].end = -1;
+		table->irq_resource[idx].flags = IORESOURCE_AUTO;
 	}
 	for (idx = 0; idx < PNP_MAX_DMA; idx++) {
-		if (resa->dma_resource[idx].start != resb->dma_resource[idx].start)
-			return 1;
+		table->dma_resource[idx].name = NULL;
+		table->dma_resource[idx].start = -1;
+		table->dma_resource[idx].end = -1;
+		table->dma_resource[idx].flags = IORESOURCE_AUTO;
 	}
 	for (idx = 0; idx < PNP_MAX_PORT; idx++) {
-		if (resa->port_resource[idx].start != resb->port_resource[idx].start)
-			return 1;
-		if (resa->port_resource[idx].end != resb->port_resource[idx].end)
-			return 1;
+		table->port_resource[idx].name = NULL;
+		table->port_resource[idx].start = 0;
+		table->port_resource[idx].end = 0;
+		table->port_resource[idx].flags = IORESOURCE_AUTO;
 	}
 	for (idx = 0; idx < PNP_MAX_MEM; idx++) {
-		if (resa->mem_resource[idx].start != resb->mem_resource[idx].start)
-			return 1;
-		if (resa->mem_resource[idx].end != resb->mem_resource[idx].end)
-			return 1;
+		table->mem_resource[idx].name = NULL;
+		table->mem_resource[idx].start = 0;
+		table->mem_resource[idx].end = 0;
+		table->mem_resource[idx].flags = IORESOURCE_AUTO;
 	}
-	return 0;
+	up(&pnp_res_mutex);
 }
 
-
-/*
- * PnP Device Resource Management
- */
-
 /**
- * pnp_auto_config_dev - determines the best possible resource configuration based on available information
- * @dev: pointer to the desired device
+ * pnp_clean_resources - clears resources that were not manually set
+ * @res - the resources to clean
  *
  */
-
-int pnp_auto_config_dev(struct pnp_dev *dev)
-{
-	int error;
-	if(!dev)
-		return -EINVAL;
-
-	dev->config_mode = PNP_CONFIG_AUTO;
-
-	if(dev->active)
-		error = pnp_resolve_conflicts(dev);
-	else
-		error = pnp_advanced_config(dev);
-	return error;
-}
-
-static void pnp_process_manual_resources(struct pnp_resource_table * ctab, struct pnp_resource_table * ntab)
+static void pnp_clean_resources(struct pnp_resource_table * res)
 {
 	int idx;
 	for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
-		if (ntab->irq_resource[idx].flags & IORESOURCE_AUTO)
+		if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO))
 			continue;
-		ctab->irq_resource[idx].start = ntab->irq_resource[idx].start;
-		ctab->irq_resource[idx].end = ntab->irq_resource[idx].end;
-		ctab->irq_resource[idx].flags = ntab->irq_resource[idx].flags;
+		res->irq_resource[idx].start = -1;
+		res->irq_resource[idx].end = -1;
+		res->irq_resource[idx].flags = IORESOURCE_AUTO;
 	}
 	for (idx = 0; idx < PNP_MAX_DMA; idx++) {
-		if (ntab->dma_resource[idx].flags & IORESOURCE_AUTO)
+		if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO))
 			continue;
-		ctab->dma_resource[idx].start = ntab->dma_resource[idx].start;
-		ctab->dma_resource[idx].end = ntab->dma_resource[idx].end;
-		ctab->dma_resource[idx].flags = ntab->dma_resource[idx].flags;
+		res->dma_resource[idx].start = -1;
+		res->dma_resource[idx].end = -1;
+		res->dma_resource[idx].flags = IORESOURCE_AUTO;
 	}
 	for (idx = 0; idx < PNP_MAX_PORT; idx++) {
-		if (ntab->port_resource[idx].flags & IORESOURCE_AUTO)
+		if (!(res->port_resource[idx].flags & IORESOURCE_AUTO))
 			continue;
-		ctab->port_resource[idx].start = ntab->port_resource[idx].start;
-		ctab->port_resource[idx].end = ntab->port_resource[idx].end;
-		ctab->port_resource[idx].flags = ntab->port_resource[idx].flags;
+		res->port_resource[idx].start = 0;
+		res->port_resource[idx].end = 0;
+		res->port_resource[idx].flags = IORESOURCE_AUTO;
 	}
 	for (idx = 0; idx < PNP_MAX_MEM; idx++) {
-		if (ntab->irq_resource[idx].flags & IORESOURCE_AUTO)
+		if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO))
 			continue;
-		ctab->irq_resource[idx].start = ntab->mem_resource[idx].start;
-		ctab->irq_resource[idx].end = ntab->mem_resource[idx].end;
-		ctab->irq_resource[idx].flags = ntab->mem_resource[idx].flags;
+		res->mem_resource[idx].start = 0;
+		res->mem_resource[idx].end = 0;
+		res->mem_resource[idx].flags = IORESOURCE_AUTO;
+	}
+}
+
+/**
+ * pnp_assign_resources - assigns resources to the device based on the specified dependent number
+ * @dev: pointer to the desired device
+ * @depnum: the dependent function number
+ *
+ * Only set depnum to 0 if the device does not have dependent options.
+ */
+int pnp_assign_resources(struct pnp_dev *dev, int depnum)
+{
+	struct pnp_port *port;
+	struct pnp_mem *mem;
+	struct pnp_irq *irq;
+	struct pnp_dma *dma;
+	int nport = 0, nmem = 0, nirq = 0, ndma = 0;
+
+	if (!pnp_can_configure(dev))
+		return -ENODEV;
+
+	down(&pnp_res_mutex);
+	pnp_clean_resources(&dev->res); /* start with a fresh slate */
+	if (dev->independent) {
+		port = dev->independent->port;
+		mem = dev->independent->mem;
+		irq = dev->independent->irq;
+		dma = dev->independent->dma;
+		while (port) {
+			if (!pnp_assign_port(dev, port, nport))
+				goto fail;
+			nport++;
+			port = port->next;
+		}
+		while (mem) {
+			if (!pnp_assign_mem(dev, mem, nmem))
+				goto fail;
+			nmem++;
+			mem = mem->next;
+		}
+		while (irq) {
+			if (!pnp_assign_irq(dev, irq, nirq))
+				goto fail;
+			nirq++;
+			irq = irq->next;
+		}
+		while (dma) {
+			if (!pnp_assign_dma(dev, dma, ndma))
+				goto fail;
+			ndma++;
+			dma = dma->next;
+		}
 	}
+
+	if (depnum) {
+		struct pnp_option *dep;
+		int i;
+		for (i=1,dep=dev->dependent; i<depnum; i++, dep=dep->next)
+			if(!dep)
+				goto fail;
+		port =dep->port;
+		mem = dep->mem;
+		irq = dep->irq;
+		dma = dep->dma;
+		while (port) {
+			if (!pnp_assign_port(dev, port, nport))
+				goto fail;
+			nport++;
+			port = port->next;
+		}
+		while (mem) {
+			if (!pnp_assign_mem(dev, mem, nmem))
+				goto fail;
+			nmem++;
+			mem = mem->next;
+		}
+		while (irq) {
+			if (!pnp_assign_irq(dev, irq, nirq))
+				goto fail;
+			nirq++;
+			irq = irq->next;
+		}
+		while (dma) {
+			if (!pnp_assign_dma(dev, dma, ndma))
+				goto fail;
+			ndma++;
+			dma = dma->next;
+		}
+	} else if (dev->dependent)
+		goto fail;
+
+	up(&pnp_res_mutex);
+	return 1;
+
+fail:
+	pnp_clean_resources(&dev->res);
+	up(&pnp_res_mutex);
+	return 0;
 }
 
 /**
@@ -572,22 +363,21 @@
  *
  * This function can be used by drivers that want to manually set thier resources.
  */
-
 int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res, int mode)
 {
 	int i;
 	struct pnp_resource_table * bak;
 	if (!dev || !res)
 		return -EINVAL;
-	if (dev->active)
-		return -EBUSY;
+	if (!pnp_can_configure(dev))
+		return -ENODEV;
 	bak = pnp_alloc(sizeof(struct pnp_resource_table));
 	if (!bak)
 		return -ENOMEM;
 	*bak = dev->res;
 
-	spin_lock(&pnp_lock);
-	pnp_process_manual_resources(&dev->res, res);
+	down(&pnp_res_mutex);
+	dev->res = *res;
 	if (!(mode & PNP_CONFIG_FORCE)) {
 		for (i = 0; i < PNP_MAX_PORT; i++) {
 			if(pnp_check_port(dev,i))
@@ -606,27 +396,64 @@
 				goto fail;
 		}
 	}
-	dev->config_mode = PNP_CONFIG_MANUAL;
-	spin_unlock(&pnp_lock);
+	up(&pnp_res_mutex);
 
-	pnp_resolve_conflicts(dev);
+	pnp_auto_config_dev(dev);
 	kfree(bak);
 	return 0;
 
 fail:
 	dev->res = *bak;
-	spin_unlock(&pnp_lock);
+	up(&pnp_res_mutex);
 	kfree(bak);
 	return -EINVAL;
 }
 
 /**
- * pnp_activate_dev - activates a PnP device for use
+ * pnp_auto_config_dev - automatically assigns resources to a device
  * @dev: pointer to the desired device
  *
- * finds the best resource configuration and then informs the correct pnp protocol
  */
+int pnp_auto_config_dev(struct pnp_dev *dev)
+{
+	struct pnp_option *dep;
+	int i = 1;
+
+	if(!dev)
+		return -EINVAL;
+
+	if(!pnp_can_configure(dev)) {
+		pnp_info("Device %s does not support resource configuration.", dev->dev.bus_id);
+		return -ENODEV;
+	}
+
+	if (!dev->dependent) {
+		if (pnp_assign_resources(dev, 0))
+			return 1;
+		else
+			return 0;
+	}
+
+	dep = dev->dependent;
+	do {
+		if (pnp_assign_resources(dev, i))
+			return 1;
 
+		/* if this dependent resource failed, try the next one */
+		dep = dep->next;
+		i++;
+	} while (dep);
+
+	pnp_err("Unable to assign resources to device %s.", dev->dev.bus_id);
+	return 0;
+}
+
+/**
+ * pnp_activate_dev - activates a PnP device for use
+ * @dev: pointer to the desired device
+ *
+ * does not validate or set resources so be careful.
+ */
 int pnp_activate_dev(struct pnp_dev *dev)
 {
 	if (!dev)
@@ -634,55 +461,25 @@
 	if (dev->active) {
 		return 0; /* the device is already active */
 	}
-	/* If this condition is true, advanced configuration failed, we need to get this device up and running
-	 * so we use the simple config engine which ignores cold conflicts, this of course may lead to new failures */
-	if (!pnp_is_active(dev)) {
-		if (!pnp_simple_config(dev)) {
-			pnp_err("res: Unable to resolve resource conflicts for the device '%s'.", dev->dev.bus_id);
-			goto fail;
-		}
-	}
 
-	spin_lock(&pnp_lock);	/* we lock just in case the device is being configured during this call */
-	dev->active = 1;
-	spin_unlock(&pnp_lock); /* once the device is claimed active we know it won't be configured so we can unlock */
+	/* ensure resources are allocated */
+	if (!pnp_auto_config_dev(dev))
+		return -EBUSY;
 
-	if (dev->config_mode & PNP_CONFIG_INVALID) {
-		pnp_info("res: Unable to activate the PnP device '%s' because its resource configuration is invalid.", dev->dev.bus_id);
-		goto fail;
-	}
-	if (dev->status != PNP_READY && dev->status != PNP_ATTACHED){
-		pnp_err("res: Activation failed because the PnP device '%s' is busy.", dev->dev.bus_id);
-		goto fail;
-	}
 	if (!pnp_can_write(dev)) {
-		pnp_info("res: Unable to activate the PnP device '%s' because this feature is not supported.", dev->dev.bus_id);
-		goto fail;
+		pnp_info("Device %s does not supported activation.", dev->dev.bus_id);
+		return -EINVAL;
 	}
+
 	if (dev->protocol->set(dev, &dev->res)<0) {
-		pnp_err("res: The protocol '%s' reports that activating the PnP device '%s' has failed.", dev->protocol->name, dev->dev.bus_id);
-		goto fail;
-	}
-	if (pnp_can_read(dev)) {
-		struct pnp_resource_table * res = pnp_alloc(sizeof(struct pnp_resource_table));
-		if (!res)
-			goto fail;
-		dev->protocol->get(dev, res);
-		if (pnp_compare_resources(&dev->res, res)) /* if this happens we may be in big trouble but it's best just to continue */
-			pnp_err("res: The resources requested do not match those set for the PnP device '%s'.", dev->dev.bus_id);
-		kfree(res);
-	} else
-		dev->active = pnp_is_active(dev);
-	pnp_dbg("res: the device '%s' has been activated.", dev->dev.bus_id);
-	if (dev->rule) {
-		kfree(dev->rule);
-		dev->rule = NULL;
+		pnp_err("Failed to activate device %s.", dev->dev.bus_id);
+		return -EIO;
 	}
-	return 0;
 
-fail:
-	dev->active = 0; /* fixes incorrect active state */
-	return -EINVAL;
+	dev->active = 1;
+	pnp_info("Device %s activated.", dev->dev.bus_id);
+
+	return 1;
 }
 
 /**
@@ -691,7 +488,6 @@
  *
  * inform the correct pnp protocol so that resources can be used by other devices
  */
-
 int pnp_disable_dev(struct pnp_dev *dev)
 {
         if (!dev)
@@ -699,21 +495,25 @@
 	if (!dev->active) {
 		return 0; /* the device is already disabled */
 	}
-	if (dev->status != PNP_READY){
-		pnp_info("res: Disable failed becuase the PnP device '%s' is busy.", dev->dev.bus_id);
-		return -EINVAL;
-	}
+
 	if (!pnp_can_disable(dev)) {
-		pnp_info("res: Unable to disable the PnP device '%s' because this feature is not supported.", dev->dev.bus_id);
+		pnp_info("Device %s does not supported disabling.", dev->dev.bus_id);
 		return -EINVAL;
 	}
 	if (dev->protocol->disable(dev)<0) {
-		pnp_err("res: The protocol '%s' reports that disabling the PnP device '%s' has failed.", dev->protocol->name, dev->dev.bus_id);
-		return -1;
+		pnp_err("Failed to disable device %s.", dev->dev.bus_id);
+		return -EIO;
 	}
-	dev->active = 0; /* just in case the protocol doesn't do this */
-	pnp_dbg("res: the device '%s' has been disabled.", dev->dev.bus_id);
-	return 0;
+
+	dev->active = 0;
+	pnp_info("Device %s disabled.", dev->dev.bus_id);
+
+	/* release the resources so that other devices can use them */
+	down(&pnp_res_mutex);
+	pnp_clean_resources(&dev->res);
+	up(&pnp_res_mutex);
+
+	return 1;
 }
 
 /**
@@ -723,7 +523,6 @@
  * @size: size of region
  *
  */
-
 void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size)
 {
 	if (resource == NULL)
@@ -734,19 +533,10 @@
 }
 
 
-EXPORT_SYMBOL(pnp_auto_config_dev);
+EXPORT_SYMBOL(pnp_assign_resources);
 EXPORT_SYMBOL(pnp_manual_config_dev);
+EXPORT_SYMBOL(pnp_auto_config_dev);
 EXPORT_SYMBOL(pnp_activate_dev);
 EXPORT_SYMBOL(pnp_disable_dev);
 EXPORT_SYMBOL(pnp_resource_change);
-
-
-/* format is: pnp_max_moves=num */
-
-static int __init pnp_setup_max_moves(char *str)
-{
-	get_option(&str,&pnp_max_moves);
-	return 1;
-}
-
-__setup("pnp_max_moves=", pnp_setup_max_moves);
+EXPORT_SYMBOL(pnp_init_resources);
diff -urN linux-2.5.72-bk2/drivers/pnp/pnpbios/core.c linux-2.5.72-bk3/drivers/pnp/pnpbios/core.c
--- linux-2.5.72-bk2/drivers/pnp/pnpbios/core.c	2003-06-16 21:19:39.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/pnpbios/core.c	2003-06-20 04:48:11.000000000 -0700
@@ -935,6 +935,10 @@
 		dev->capabilities |= PNP_REMOVABLE;
 	dev->protocol = &pnpbios_protocol;
 
+	/* clear out the damaged flags */
+	if (!dev->active)
+		pnp_init_resources(&dev->res);
+
 	pnp_add_device(dev);
 	pnpbios_interface_attach_device(node);
 
diff -urN linux-2.5.72-bk2/drivers/pnp/quirks.c linux-2.5.72-bk3/drivers/pnp/quirks.c
--- linux-2.5.72-bk2/drivers/pnp/quirks.c	2003-06-16 21:20:21.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/quirks.c	2003-06-20 04:48:11.000000000 -0700
@@ -30,7 +30,7 @@
 static void quirk_awe32_resources(struct pnp_dev *dev)
 {
 	struct pnp_port *port, *port2, *port3;
-	struct pnp_resources *res = dev->possible->dep;
+	struct pnp_option *res = dev->dependent;
 
 	/*
 	 * Unfortunately the isapnp_add_port_resource is too tightly bound
@@ -38,7 +38,7 @@
 	 * two extra ports (at offset 0x400 and 0x800 from the one given) by
 	 * hand.
 	 */
-	for ( ; res ; res = res->dep ) {
+	for ( ; res ; res = res->next ) {
 		port2 = pnp_alloc(sizeof(struct pnp_port));
 		if (!port2)
 			return;
@@ -62,9 +62,9 @@
 
 static void quirk_cmi8330_resources(struct pnp_dev *dev)
 {
-	struct pnp_resources *res = dev->possible->dep;
+	struct pnp_option *res = dev->dependent;
 
-	for ( ; res ; res = res->dep ) {
+	for ( ; res ; res = res->next ) {
 
 		struct pnp_irq *irq;
 		struct pnp_dma *dma;
@@ -82,7 +82,7 @@
 static void quirk_sb16audio_resources(struct pnp_dev *dev)
 {
 	struct pnp_port *port;
-	struct pnp_resources *res = dev->possible->dep;
+	struct pnp_option *res = dev->dependent;
 	int    changed = 0;
 
 	/*
@@ -91,7 +91,7 @@
 	 * auto-configured.
 	 */
 
-	for( ; res ; res = res->dep ) {
+	for( ; res ; res = res->next ) {
 		port = res->port;
 		if(!port)
 			continue;
@@ -118,11 +118,11 @@
 	 * doesn't allow a DMA channel of 0, afflicted card is an
 	 * OPL3Sax where x=4.
 	 */
-	struct pnp_resources *res;
+	struct pnp_option *res;
 	int max;
-	res = dev->possible;
+	res = dev->dependent;
 	max = 0;
-	for (res = res->dep; res; res = res->dep) {
+	for (; res; res = res->next) {
 		if (res->dma->map > max)
 			max = res->dma->map;
 	}
diff -urN linux-2.5.72-bk2/drivers/pnp/resource.c linux-2.5.72-bk3/drivers/pnp/resource.c
--- linux-2.5.72-bk2/drivers/pnp/resource.c	2003-06-16 21:20:05.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/resource.c	2003-06-20 04:48:11.000000000 -0700
@@ -10,18 +10,19 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/pci.h>
 #include <linux/kernel.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
+#include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 
 #include <linux/pnp.h>
 #include "base.h"
 
-int pnp_allow_dma0 = -1;		        /* allow dma 0 during auto activation: -1=off (:default), 0=off (set by user), 1=on */
+int pnp_allow_dma0 = -1;		        /* allow dma 0 during auto activation:
+						 * -1=off (:default), 0=off (set by user), 1=on */
 int pnp_skip_pci_scan;				/* skip PCI resource scanning */
 int pnp_reserve_irq[16] = { [0 ... 15] = -1 };	/* reserve (don't use) some IRQ */
 int pnp_reserve_dma[8] = { [0 ... 7] = -1 };	/* reserve (don't use) some DMA */
@@ -30,88 +31,75 @@
 
 
 /*
- * possible resource registration
+ * option registration
  */
 
-struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent)
+static struct pnp_option * pnp_build_option(int priority)
 {
-	struct pnp_resources *res, *ptr, *ptra;
+	struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option));
 
-	res = pnp_alloc(sizeof(struct pnp_resources));
-	if (!res)
+	/* check if pnp_alloc ran out of memory */
+	if (!option)
 		return NULL;
-	ptr = dev->possible;
-	if (ptr) { /* add to another list */
-		ptra = ptr->dep;
-		while (ptra && ptra->dep)
-			ptra = ptra->dep;
-		if (!ptra)
-			ptr->dep = res;
-		else
-			ptra->dep = res;
-	} else
-		dev->possible = res;
-	if (dependent) {
-		res->priority = dependent & 0xff;
-		if (res->priority > PNP_RES_PRIORITY_FUNCTIONAL)
-			res->priority = PNP_RES_PRIORITY_INVALID;
-	} else
-		res->priority = PNP_RES_PRIORITY_PREFERRED;
-	return res;
+
+	option->priority = priority & 0xff;
+	/* make sure the priority is valid */
+	if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
+		option->priority = PNP_RES_PRIORITY_INVALID;
+
+	return option;
 }
 
-struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum)
+struct pnp_option * pnp_register_independent_option(struct pnp_dev *dev)
 {
-	int i;
-	struct pnp_resources *res;
+	struct pnp_option *option;
 	if (!dev)
 		return NULL;
-	res = dev->possible;
-	if (!res)
-		return NULL;
-	for (i = 0; i < depnum; i++)
-	{
-		if (res->dep)
-			res = res->dep;
-		else
-			return NULL;
-	}
-	return res;
+
+	option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
+
+	/* this should never happen but if it does we'll try to continue */
+	if (dev->independent)
+		pnp_err("independent resource already registered");
+	dev->independent = option;
+	return option;
 }
 
-int pnp_get_max_depnum(struct pnp_dev *dev)
+struct pnp_option * pnp_register_dependent_option(struct pnp_dev *dev, int priority)
 {
-	int num = 0;
-	struct pnp_resources *res;
+	struct pnp_option *option;
 	if (!dev)
-		return -EINVAL;
-	res = dev->possible;
-	if (!res)
-		return -EINVAL;
-	while (res->dep){
-		res = res->dep;
-		num++;
-	}
-	return num;
+		return NULL;
+
+	option = pnp_build_option(priority);
+
+	if (dev->dependent) {
+		struct pnp_option *parent = dev->dependent;
+		while (parent->next)
+			parent = parent->next;
+		parent->next = option;
+	} else
+		dev->dependent = option;
+	return option;
 }
 
-int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data)
+int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data)
 {
 	int i;
-	struct pnp_resources *res;
 	struct pnp_irq *ptr;
-	res = pnp_find_resources(dev,depnum);
-	if (!res)
+	if (!option)
 		return -EINVAL;
 	if (!data)
 		return -EINVAL;
-	ptr = res->irq;
+
+	ptr = option->irq;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
 	if (ptr)
 		ptr->next = data;
 	else
-		res->irq = data;
+		option->irq = data;
+
 #ifdef CONFIG_PCI
 	for (i=0; i<16; i++)
 		if (data->map & (1<<i))
@@ -120,60 +108,59 @@
 	return 0;
 }
 
-int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_dma *data)
+int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data)
 {
-	struct pnp_resources *res;
 	struct pnp_dma *ptr;
-	res = pnp_find_resources(dev,depnum);
-	if (!res)
+	if (!option)
 		return -EINVAL;
 	if (!data)
 		return -EINVAL;
-	ptr = res->dma;
+
+	ptr = option->dma;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
 	if (ptr)
 		ptr->next = data;
 	else
-		res->dma = data;
+		option->dma = data;
+
 	return 0;
 }
 
-int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_port *data)
+int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data)
 {
-	struct pnp_resources *res;
 	struct pnp_port *ptr;
-	res = pnp_find_resources(dev,depnum);
-	if (!res)
+	if (!option)
 		return -EINVAL;
 	if (!data)
 		return -EINVAL;
-	ptr = res->port;
+
+	ptr = option->port;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
 	if (ptr)
 		ptr->next = data;
 	else
-		res->port = data;
+		option->port = data;
+
 	return 0;
 }
 
-int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_mem *data)
+int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data)
 {
-	struct pnp_resources *res;
 	struct pnp_mem *ptr;
-	res = pnp_find_resources(dev,depnum);
-	if (!res)
+	if (!option)
 		return -EINVAL;
 	if (!data)
 		return -EINVAL;
-	ptr = res->mem;
+
+	ptr = option->mem;
 	while (ptr && ptr->next)
 		ptr = ptr->next;
 	if (ptr)
 		ptr->next = data;
 	else
-		res->mem = data;
+		option->mem = data;
 	return 0;
 }
 
@@ -221,18 +208,18 @@
 	}
 }
 
-void pnp_free_resources(struct pnp_resources *resources)
+void pnp_free_option(struct pnp_option *option)
 {
-	struct pnp_resources *next;
+	struct pnp_option *next;
 
-	while (resources) {
-		next = resources->dep;
-		pnp_free_port(resources->port);
-		pnp_free_irq(resources->irq);
-		pnp_free_dma(resources->dma);
-		pnp_free_mem(resources->mem);
-		kfree(resources);
-		resources = next;
+	while (option) {
+		next = option->next;
+		pnp_free_port(option->port);
+		pnp_free_irq(option->irq);
+		pnp_free_dma(option->dma);
+		pnp_free_mem(option->mem);
+		kfree(option);
+		option = next;
 	}
 }
 
@@ -253,50 +240,23 @@
  (*(enda) >= *(startb) && *(enda) <= *(endb)) || \
  (*(starta) < *(startb) && *(enda) > *(endb)))
 
-struct pnp_dev * pnp_check_port_conflicts(struct pnp_dev * dev, int idx, int mode)
-{
-	int tmp;
-	unsigned long *port, *end, *tport, *tend;
-	struct pnp_dev *tdev;
-	port = &dev->res.port_resource[idx].start;
-	end = &dev->res.port_resource[idx].end;
-
-	/* if the resource doesn't exist, don't complain about it */
-	if (dev->res.port_resource[idx].start == 0)
-		return NULL;
-
-	/* check for cold conflicts */
-	pnp_for_each_dev(tdev) {
-		/* Is the device configurable? */
-		if (tdev == dev || (mode ? !tdev->active : tdev->active))
-			continue;
-		for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
-			if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) {
-				tport = &tdev->res.port_resource[tmp].start;
-				tend = &tdev->res.port_resource[tmp].end;
-				if (ranged_conflict(port,end,tport,tend))
-					return tdev;
-			}
-		}
-	}
-	return NULL;
-}
-
 int pnp_check_port(struct pnp_dev * dev, int idx)
 {
 	int tmp;
+	struct pnp_dev *tdev;
 	unsigned long *port, *end, *tport, *tend;
 	port = &dev->res.port_resource[idx].start;
 	end = &dev->res.port_resource[idx].end;
 
 	/* if the resource doesn't exist, don't complain about it */
 	if (dev->res.port_resource[idx].start == 0)
-		return 0;
+		return 1;
 
-	/* check if the resource is already in use, skip if the device is active because it itself may be in use */
+	/* check if the resource is already in use, skip if the
+	 * device is active because it itself may be in use */
 	if(!dev->active) {
-		if (check_region(*port, length(port,end)))
-			return CONFLICT_TYPE_IN_USE;
+		if (__check_region(&ioport_resource, *port, length(port,end)))
+			return 0;
 	}
 
 	/* check if the resource is reserved */
@@ -304,7 +264,7 @@
 		int rport = pnp_reserve_io[tmp << 1];
 		int rend = pnp_reserve_io[(tmp << 1) + 1] + rport - 1;
 		if (ranged_conflict(port,end,&rport,&rend))
-			return CONFLICT_TYPE_RESERVED;
+			return 0;
 	}
 
 	/* check for internal conflicts */
@@ -313,61 +273,44 @@
 			tport = &dev->res.port_resource[tmp].start;
 			tend = &dev->res.port_resource[tmp].end;
 			if (ranged_conflict(port,end,tport,tend))
-				return CONFLICT_TYPE_INTERNAL;
+				return 0;
 		}
 	}
 
-	/* check for warm conflicts */
-	if (pnp_check_port_conflicts(dev, idx, SEARCH_WARM))
-		return CONFLICT_TYPE_PNP_WARM;
-
-	return 0;
-}
-
-struct pnp_dev * pnp_check_mem_conflicts(struct pnp_dev * dev, int idx, int mode)
-{
-	int tmp;
-	unsigned long *addr, *end, *taddr, *tend;
-	struct pnp_dev *tdev;
-	addr = &dev->res.mem_resource[idx].start;
-	end = &dev->res.mem_resource[idx].end;
-
-	/* if the resource doesn't exist, don't complain about it */
-	if (dev->res.mem_resource[idx].start == 0)
-		return NULL;
-
-	/* check for cold conflicts */
+	/* check for conflicts with other pnp devices */
 	pnp_for_each_dev(tdev) {
-		/* Is the device configurable? */
-		if (tdev == dev || (mode ? !tdev->active : tdev->active))
+		if (tdev == dev)
 			continue;
-		for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
-			if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
-				taddr = &tdev->res.mem_resource[tmp].start;
-				tend = &tdev->res.mem_resource[tmp].end;
-				if (ranged_conflict(addr,end,taddr,tend))
-					return tdev;
+		for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
+			if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) {
+				tport = &tdev->res.port_resource[tmp].start;
+				tend = &tdev->res.port_resource[tmp].end;
+				if (ranged_conflict(port,end,tport,tend))
+					return 0;
 			}
 		}
 	}
-	return NULL;
+
+	return 1;
 }
 
 int pnp_check_mem(struct pnp_dev * dev, int idx)
 {
 	int tmp;
+	struct pnp_dev *tdev;
 	unsigned long *addr, *end, *taddr, *tend;
 	addr = &dev->res.mem_resource[idx].start;
 	end = &dev->res.mem_resource[idx].end;
 
 	/* if the resource doesn't exist, don't complain about it */
 	if (dev->res.mem_resource[idx].start == 0)
-		return 0;
+		return 1;
 
-	/* check if the resource is already in use, skip if the device is active because it itself may be in use */
+	/* check if the resource is already in use, skip if the
+	 * device is active because it itself may be in use */
 	if(!dev->active) {
-		if (__check_region(&iomem_resource, *addr, length(addr,end)))
-			return CONFLICT_TYPE_IN_USE;
+		if (check_mem_region(*addr, length(addr,end)))
+			return 0;
 	}
 
 	/* check if the resource is reserved */
@@ -375,7 +318,7 @@
 		int raddr = pnp_reserve_mem[tmp << 1];
 		int rend = pnp_reserve_mem[(tmp << 1) + 1] + raddr - 1;
 		if (ranged_conflict(addr,end,&raddr,&rend))
-			return CONFLICT_TYPE_RESERVED;
+			return 0;
 	}
 
 	/* check for internal conflicts */
@@ -384,40 +327,25 @@
 			taddr = &dev->res.mem_resource[tmp].start;
 			tend = &dev->res.mem_resource[tmp].end;
 			if (ranged_conflict(addr,end,taddr,tend))
-				return CONFLICT_TYPE_INTERNAL;
+				return 0;
 		}
 	}
 
-	/* check for warm conflicts */
-	if (pnp_check_mem_conflicts(dev, idx, SEARCH_WARM))
-		return CONFLICT_TYPE_PNP_WARM;
-
-	return 0;
-}
-
-struct pnp_dev * pnp_check_irq_conflicts(struct pnp_dev * dev, int idx, int mode)
-{
-	int tmp;
-	struct pnp_dev * tdev;
-	unsigned long * irq = &dev->res.irq_resource[idx].start;
-
-	/* if the resource doesn't exist, don't complain about it */
-	if (dev->res.irq_resource[idx].start == -1)
-		return NULL;
-
-	/* check for cold conflicts */
+	/* check for conflicts with other pnp devices */
 	pnp_for_each_dev(tdev) {
-		/* Is the device configurable? */
-		if (tdev == dev || (mode ? !tdev->active : tdev->active))
+		if (tdev == dev)
 			continue;
-		for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
-			if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
-				if ((tdev->res.irq_resource[tmp].start == *irq))
-					return tdev;
+		for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
+			if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
+				taddr = &tdev->res.mem_resource[tmp].start;
+				tend = &tdev->res.mem_resource[tmp].end;
+				if (ranged_conflict(addr,end,taddr,tend))
+					return 0;
 			}
 		}
 	}
-	return NULL;
+
+	return 1;
 }
 
 static irqreturn_t pnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
@@ -428,27 +356,28 @@
 int pnp_check_irq(struct pnp_dev * dev, int idx)
 {
 	int tmp;
+	struct pnp_dev *tdev;
 	unsigned long * irq = &dev->res.irq_resource[idx].start;
 
 	/* if the resource doesn't exist, don't complain about it */
 	if (dev->res.irq_resource[idx].start == -1)
-		return 0;
+		return 1;
 
 	/* check if the resource is valid */
 	if (*irq < 0 || *irq > 15)
-		return CONFLICT_TYPE_INVALID;
+		return 0;
 
 	/* check if the resource is reserved */
 	for (tmp = 0; tmp < 16; tmp++) {
 		if (pnp_reserve_irq[tmp] == *irq)
-			return CONFLICT_TYPE_RESERVED;
+			return 0;
 	}
 
 	/* check for internal conflicts */
 	for (tmp = 0; tmp < PNP_MAX_IRQ && tmp != idx; tmp++) {
 		if (dev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
 			if (dev->res.irq_resource[tmp].start == *irq)
-				return CONFLICT_TYPE_INTERNAL;
+				return 0;
 		}
 	}
 
@@ -458,233 +387,94 @@
 		struct pci_dev * pci = NULL;
 		while ((pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci)) != NULL) {
 			if (pci->irq == *irq)
-				return CONFLICT_TYPE_PCI;
+				return 0;
 		}
 	}
 #endif
 
-	/* check if the resource is already in use, skip if the device is active because it itself may be in use */
+	/* check if the resource is already in use, skip if the
+	 * device is active because it itself may be in use */
 	if(!dev->active) {
 		if (request_irq(*irq, pnp_test_handler, SA_INTERRUPT, "pnp", NULL))
-			return CONFLICT_TYPE_IN_USE;
+			return 0;
 		free_irq(*irq, NULL);
 	}
 
-	/* check for warm conflicts */
-	if (pnp_check_irq_conflicts(dev, idx, SEARCH_WARM))
-		return CONFLICT_TYPE_PNP_WARM;
-
-	return 0;
-}
-
-
-struct pnp_dev * pnp_check_dma_conflicts(struct pnp_dev * dev, int idx, int mode)
-{
-	int tmp;
-	struct pnp_dev * tdev;
-	unsigned long * dma = &dev->res.dma_resource[idx].start;
-
-	/* if the resource doesn't exist, don't complain about it */
-	if (dev->res.dma_resource[idx].start == -1)
-		return NULL;
-
-	/* check for cold conflicts */
+	/* check for conflicts with other pnp devices */
 	pnp_for_each_dev(tdev) {
-		/* Is the device configurable? */
-		if (tdev == dev || (mode ? !tdev->active : tdev->active))
+		if (tdev == dev)
 			continue;
-		for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
-			if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
-				if ((tdev->res.dma_resource[tmp].start == *dma))
-					return tdev;
+		for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
+			if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) {
+				if ((tdev->res.irq_resource[tmp].start == *irq))
+					return 0;
 			}
 		}
 	}
-	return NULL;
+
+	return 1;
 }
 
 int pnp_check_dma(struct pnp_dev * dev, int idx)
 {
 	int tmp, mindma = 1;
+	struct pnp_dev *tdev;
 	unsigned long * dma = &dev->res.dma_resource[idx].start;
 
 	/* if the resource doesn't exist, don't complain about it */
 	if (dev->res.dma_resource[idx].start == -1)
-		return 0;
+		return 1;
 
 	/* check if the resource is valid */
 	if (pnp_allow_dma0 == 1)
 		mindma = 0;
 	if (*dma < mindma || *dma == 4 || *dma > 7)
-		return CONFLICT_TYPE_INVALID;
+		return 0;
 
 	/* check if the resource is reserved */
 	for (tmp = 0; tmp < 8; tmp++) {
 		if (pnp_reserve_dma[tmp] == *dma)
-			return CONFLICT_TYPE_RESERVED;
+			return 0;
 	}
 
 	/* check for internal conflicts */
 	for (tmp = 0; tmp < PNP_MAX_DMA && tmp != idx; tmp++) {
 		if (dev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
 			if (dev->res.dma_resource[tmp].start == *dma)
-				return CONFLICT_TYPE_INTERNAL;
+				return 0;
 		}
 	}
 
-	/* check if the resource is already in use, skip if the device is active because it itself may be in use */
+	/* check if the resource is already in use, skip if the
+	 * device is active because it itself may be in use */
 	if(!dev->active) {
 		if (request_dma(*dma, "pnp"))
-			return CONFLICT_TYPE_IN_USE;
+			return 0;
 		free_dma(*dma);
 	}
 
-	/* check for warm conflicts */
-	if (pnp_check_dma_conflicts(dev, idx, SEARCH_WARM))
-		return CONFLICT_TYPE_PNP_WARM;
-	return 0;
-}
-
-
-/**
- * pnp_init_resource_table - Resets a resource table to default values.
- * @table: pointer to the desired resource table
- *
- */
-
-void pnp_init_resource_table(struct pnp_resource_table *table)
-{
-	int idx;
-	for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
-		table->irq_resource[idx].name = NULL;
-		table->irq_resource[idx].start = -1;
-		table->irq_resource[idx].end = -1;
-		table->irq_resource[idx].flags = IORESOURCE_AUTO;
-	}
-	for (idx = 0; idx < PNP_MAX_DMA; idx++) {
-		table->dma_resource[idx].name = NULL;
-		table->dma_resource[idx].start = -1;
-		table->dma_resource[idx].end = -1;
-		table->dma_resource[idx].flags = IORESOURCE_AUTO;
-	}
-	for (idx = 0; idx < PNP_MAX_PORT; idx++) {
-		table->port_resource[idx].name = NULL;
-		table->port_resource[idx].start = 0;
-		table->port_resource[idx].end = 0;
-		table->port_resource[idx].flags = IORESOURCE_AUTO;
-	}
-	for (idx = 0; idx < PNP_MAX_MEM; idx++) {
-		table->mem_resource[idx].name = NULL;
-		table->mem_resource[idx].start = 0;
-		table->mem_resource[idx].end = 0;
-		table->mem_resource[idx].flags = IORESOURCE_AUTO;
-	}
-}
-
-
-/**
- * pnp_generate_rule - Creates a rule table structure based on depnum and device.
- * @dev: pointer to the desired device
- * @depnum: dependent function, if not valid will return an error
- * @rule: pointer to a rule structure to record data to
- *
- */
-
-int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table * rule)
-{
-	int nport = 0, nirq = 0, ndma = 0, nmem = 0;
-	struct pnp_resources * res;
-	struct pnp_port * port;
-	struct pnp_mem * mem;
-	struct pnp_irq * irq;
-	struct pnp_dma * dma;
-
-	if (depnum < 0 || !rule)
-		return -EINVAL;
-
-	/* independent */
-	res = pnp_find_resources(dev, 0);
-	if (!res)
-		return -ENODEV;
-	port = res->port;
-	mem = res->mem;
-	irq = res->irq;
-	dma = res->dma;
-	while (port){
-		rule->port[nport] = port;
-		nport++;
-		port = port->next;
-	}
-	while (mem){
-		rule->mem[nmem] = mem;
-		nmem++;
-		mem = mem->next;
-	}
-	while (irq){
-		rule->irq[nirq] = irq;
-		nirq++;
-		irq = irq->next;
-	}
-	while (dma){
-		rule->dma[ndma] = dma;
-		ndma++;
-		dma = dma->next;
+	/* check for conflicts with other pnp devices */
+	pnp_for_each_dev(tdev) {
+		if (tdev == dev)
+			continue;
+		for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
+			if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) {
+				if ((tdev->res.dma_resource[tmp].start == *dma))
+					return 0;
+			}
+		}
 	}
 
-	/* dependent */
-	if (depnum == 0)
-		return 1;
-	res = pnp_find_resources(dev, depnum);
-	if (!res)
-		return -ENODEV;
-	port = res->port;
-	mem = res->mem;
-	irq = res->irq;
-	dma = res->dma;
-	while (port){
-		rule->port[nport] = port;
-		nport++;
-		port = port->next;
-	}
-	while (mem){
-		rule->mem[nmem] = mem;
-		nmem++;
-		mem = mem->next;
-	}
-
-	while (irq){
-		rule->irq[nirq] = irq;
-		nirq++;
-		irq = irq->next;
-	}
-	while (dma){
-		rule->dma[ndma] = dma;
-		ndma++;
-		dma = dma->next;
-	}
-
-	/* clear the remaining values */
-	for (; nport < PNP_MAX_PORT; nport++)
-		rule->port[nport] = NULL;
-	for (; nmem < PNP_MAX_MEM; nmem++)
-		rule->mem[nmem] = NULL;
-	for (; nirq < PNP_MAX_IRQ; nirq++)
-		rule->irq[nirq] = NULL;
-	for (; ndma < PNP_MAX_DMA; ndma++)
-		rule->dma[ndma] = NULL;
 	return 1;
 }
 
 
-EXPORT_SYMBOL(pnp_build_resource);
-EXPORT_SYMBOL(pnp_find_resources);
-EXPORT_SYMBOL(pnp_get_max_depnum);
-EXPORT_SYMBOL(pnp_add_irq_resource);
-EXPORT_SYMBOL(pnp_add_dma_resource);
-EXPORT_SYMBOL(pnp_add_port_resource);
-EXPORT_SYMBOL(pnp_add_mem_resource);
-EXPORT_SYMBOL(pnp_init_resource_table);
-EXPORT_SYMBOL(pnp_generate_rule);
+EXPORT_SYMBOL(pnp_register_dependent_option);
+EXPORT_SYMBOL(pnp_register_independent_option);
+EXPORT_SYMBOL(pnp_register_irq_resource);
+EXPORT_SYMBOL(pnp_register_dma_resource);
+EXPORT_SYMBOL(pnp_register_port_resource);
+EXPORT_SYMBOL(pnp_register_mem_resource);
 
 
 /* format is: allowdma0 */
diff -urN linux-2.5.72-bk2/drivers/pnp/support.c linux-2.5.72-bk3/drivers/pnp/support.c
--- linux-2.5.72-bk2/drivers/pnp/support.c	2003-06-16 21:19:42.000000000 -0700
+++ linux-2.5.72-bk3/drivers/pnp/support.c	2003-06-20 04:48:11.000000000 -0700
@@ -1,7 +1,7 @@
 /*
  * support.c - provides standard pnp functions for the use of pnp protocol drivers,
  *
- * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
+ * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
  *
  * Resource parsing functions are based on those in the linux pnpbios driver.
  * Copyright Christian Schmidt, Tom Lees, David Hinds, Alan Cox, Thomas Hood,
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/ctype.h>
 
 #ifdef CONFIG_PNP_DEBUG
 	#define DEBUG
@@ -122,7 +123,7 @@
 		return NULL;
 
 	/* Blank the resource table values */
-	pnp_init_resource_table(res);
+	pnp_init_resources(res);
 
 	while ((char *)p < (char *)end) {
 
@@ -250,51 +251,51 @@
  * Possible resource reading functions *
  */
 
-static void possible_mem(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_mem(unsigned char *p, int size, struct pnp_option *option)
 {
 	struct pnp_mem * mem;
 	mem = pnp_alloc(sizeof(struct pnp_mem));
 	if (!mem)
 		return;
-	mem->min = ((p[3] << 8) | p[2]) << 8;
-	mem->max = ((p[5] << 8) | p[4]) << 8;
-	mem->align = (p[7] << 8) | p[6];
-	mem->size = ((p[9] << 8) | p[8]) << 8;
-	mem->flags = p[1];
-	pnp_add_mem_resource(dev,depnum,mem);
+	mem->min = ((p[5] << 8) | p[4]) << 8;
+	mem->max = ((p[7] << 8) | p[6]) << 8;
+	mem->align = (p[9] << 8) | p[8];
+	mem->size = ((p[11] << 8) | p[10]) << 8;
+	mem->flags = p[3];
+	pnp_register_mem_resource(option,mem);
 	return;
 }
 
-static void possible_mem32(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_mem32(unsigned char *p, int size, struct pnp_option *option)
 {
 	struct pnp_mem * mem;
 	mem = pnp_alloc(sizeof(struct pnp_mem));
 	if (!mem)
 		return;
-	mem->min = (p[5] << 24) | (p[4] << 16) | (p[3] << 8) | p[2];
-	mem->max = (p[9] << 24) | (p[8] << 16) | (p[7] << 8) | p[6];
-	mem->align = (p[13] << 24) | (p[12] << 16) | (p[11] << 8) | p[10];
-	mem->size = (p[17] << 24) | (p[16] << 16) | (p[15] << 8) | p[14];
-	mem->flags = p[1];
-	pnp_add_mem_resource(dev,depnum,mem);
+	mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
+	mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
+	mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
+	mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
+	mem->flags = p[3];
+	pnp_register_mem_resource(option,mem);
 	return;
 }
 
-static void possible_fixed_mem32(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_fixed_mem32(unsigned char *p, int size, struct pnp_option *option)
 {
 	struct pnp_mem * mem;
 	mem = pnp_alloc(sizeof(struct pnp_mem));
 	if (!mem)
 		return;
-	mem->min = mem->max = (p[5] << 24) | (p[4] << 16) | (p[3] << 8) | p[2];
-	mem->size = (p[9] << 24) | (p[8] << 16) | (p[7] << 8) | p[6];
+	mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
+	mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
 	mem->align = 0;
-	mem->flags = p[1];
-	pnp_add_mem_resource(dev,depnum,mem);
+	mem->flags = p[3];
+	pnp_register_mem_resource(option,mem);
 	return;
 }
 
-static void possible_irq(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_irq(unsigned char *p, int size, struct pnp_option *option)
 {
 	struct pnp_irq * irq;
 	irq = pnp_alloc(sizeof(struct pnp_irq));
@@ -303,11 +304,13 @@
 	irq->map = (p[2] << 8) | p[1];
 	if (size > 2)
 		irq->flags = p[3];
-	pnp_add_irq_resource(dev,depnum,irq);
+	else
+		irq->flags = IORESOURCE_IRQ_HIGHEDGE;
+	pnp_register_irq_resource(option,irq);
 	return;
 }
 
-static void possible_dma(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_dma(unsigned char *p, int size, struct pnp_option *option)
 {
 	struct pnp_dma * dma;
 	dma = pnp_alloc(sizeof(struct pnp_dma));
@@ -315,11 +318,11 @@
 		return;
 	dma->map = p[1];
 	dma->flags = p[2];
-	pnp_add_dma_resource(dev,depnum,dma);
+	pnp_register_dma_resource(option,dma);
 	return;
 }
 
-static void possible_port(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_port(unsigned char *p, int size, struct pnp_option *option)
 {
 	struct pnp_port * port;
 	port = pnp_alloc(sizeof(struct pnp_port));
@@ -330,11 +333,11 @@
 	port->align = p[6];
 	port->size = p[7];
 	port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
-	pnp_add_port_resource(dev,depnum,port);
+	pnp_register_port_resource(option,port);
 	return;
 }
 
-static void possible_fixed_port(unsigned char *p, int size, int depnum, struct pnp_dev *dev)
+static void possible_fixed_port(unsigned char *p, int size, struct pnp_option *option)
 {
 	struct pnp_port * port;
 	port = pnp_alloc(sizeof(struct pnp_port));
@@ -344,7 +347,7 @@
 	port->size = p[3];
 	port->align = 0;
 	port->flags = PNP_PORT_FLAG_FIXED;
-	pnp_add_port_resource(dev,depnum,port);
+	pnp_register_port_resource(option,port);
 	return;
 }
 
@@ -358,12 +361,14 @@
 
 unsigned char * pnp_parse_possible_resources(unsigned char * p, unsigned char * end, struct pnp_dev *dev)
 {
-	int len, depnum = 0, dependent = 0;
+	int len, priority = 0;
+	struct pnp_option *option;
 
 	if (!p)
 		return NULL;
 
-	if (pnp_build_resource(dev, 0) == NULL)
+	option = pnp_register_independent_option(dev);
+	if (!option)
 		return NULL;
 
 	while ((char *)p < (char *)end) {
@@ -375,21 +380,21 @@
 			{
 				if (len != 9)
 					goto lrg_err;
-				possible_mem(p,len,depnum,dev);
+				possible_mem(p,len,option);
 				break;
 			}
 			case LARGE_TAG_MEM32:
 			{
 				if (len != 17)
 					goto lrg_err;
-				possible_mem32(p,len,depnum,dev);
+				possible_mem32(p,len,option);
 				break;
 			}
 			case LARGE_TAG_FIXEDMEM32:
 			{
 				if (len != 9)
 					goto lrg_err;
-				possible_fixed_mem32(p,len,depnum,dev);
+				possible_fixed_mem32(p,len,option);
 				break;
 			}
 			default: /* an unkown tag */
@@ -410,46 +415,46 @@
 		{
 			if (len < 2 || len > 3)
 				goto sm_err;
-			possible_irq(p,len,depnum,dev);
+			possible_irq(p,len,option);
 			break;
 		}
 		case SMALL_TAG_DMA:
 		{
 			if (len != 2)
 				goto sm_err;
-			possible_dma(p,len,depnum,dev);
+			possible_dma(p,len,option);
 			break;
 		}
 		case SMALL_TAG_STARTDEP:
 		{
 			if (len > 1)
 				goto sm_err;
-			dependent = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
+			priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
 			if (len > 0)
-				dependent = 0x100 | p[1];
-			pnp_build_resource(dev,dependent);
-			depnum = pnp_get_max_depnum(dev);
+				priority = 0x100 | p[1];
+			option = pnp_register_dependent_option(dev, priority);
+			if (!option)
+				return NULL;
 			break;
 		}
 		case SMALL_TAG_ENDDEP:
 		{
 			if (len != 0)
 				goto sm_err;
-			depnum = 0;
 			break;
 		}
 		case SMALL_TAG_PORT:
 		{
 			if (len != 7)
 				goto sm_err;
-			possible_port(p,len,depnum,dev);
+			possible_port(p,len,option);
 			break;
 		}
 		case SMALL_TAG_FIXEDPORT:
 		{
 			if (len != 3)
 				goto sm_err;
-			possible_fixed_port(p,len,depnum,dev);
+			possible_fixed_port(p,len,option);
 			break;
 		}
 		case SMALL_TAG_END:
@@ -481,12 +486,12 @@
 {
 	unsigned long base = res->start;
 	unsigned long len = res->end - res->start + 1;
-	p[2] = (base >> 8) & 0xff;
-	p[3] = ((base >> 8) >> 8) & 0xff;
 	p[4] = (base >> 8) & 0xff;
 	p[5] = ((base >> 8) >> 8) & 0xff;
-	p[8] = (len >> 8) & 0xff;
-	p[9] = ((len >> 8) >> 8) & 0xff;
+	p[6] = (base >> 8) & 0xff;
+	p[7] = ((base >> 8) >> 8) & 0xff;
+	p[10] = (len >> 8) & 0xff;
+	p[11] = ((len >> 8) >> 8) & 0xff;
 	return;
 }
 
@@ -494,32 +499,32 @@
 {
 	unsigned long base = res->start;
 	unsigned long len = res->end - res->start + 1;
-	p[2] = base & 0xff;
-	p[3] = (base >> 8) & 0xff;
-	p[4] = (base >> 16) & 0xff;
-	p[5] = (base >> 24) & 0xff;
-	p[6] = base & 0xff;
-	p[7] = (base >> 8) & 0xff;
-	p[8] = (base >> 16) & 0xff;
-	p[9] = (base >> 24) & 0xff;
-	p[14] = len & 0xff;
-	p[15] = (len >> 8) & 0xff;
-	p[16] = (len >> 16) & 0xff;
-	p[17] = (len >> 24) & 0xff;
+	p[4] = base & 0xff;
+	p[5] = (base >> 8) & 0xff;
+	p[6] = (base >> 16) & 0xff;
+	p[7] = (base >> 24) & 0xff;
+	p[8] = base & 0xff;
+	p[9] = (base >> 8) & 0xff;
+	p[10] = (base >> 16) & 0xff;
+	p[11] = (base >> 24) & 0xff;
+	p[16] = len & 0xff;
+	p[17] = (len >> 8) & 0xff;
+	p[18] = (len >> 16) & 0xff;
+	p[19] = (len >> 24) & 0xff;
 	return;
 }
 
 static void write_fixed_mem32(unsigned char *p, struct resource * res)
 {	unsigned long base = res->start;
 	unsigned long len = res->end - res->start + 1;
-	p[2] = base & 0xff;
-	p[3] = (base >> 8) & 0xff;
-	p[4] = (base >> 16) & 0xff;
-	p[5] = (base >> 24) & 0xff;
-	p[6] = len & 0xff;
-	p[7] = (len >> 8) & 0xff;
-	p[8] = (len >> 16) & 0xff;
-	p[9] = (len >> 24) & 0xff;
+	p[4] = base & 0xff;
+	p[5] = (base >> 8) & 0xff;
+	p[6] = (base >> 16) & 0xff;
+	p[7] = (base >> 24) & 0xff;
+	p[8] = len & 0xff;
+	p[9] = (len >> 8) & 0xff;
+	p[10] = (len >> 16) & 0xff;
+	p[11] = (len >> 24) & 0xff;
 	return;
 }
 
@@ -630,7 +635,7 @@
 		{
 			if (len != 2)
 				goto sm_err;
-			write_dma(p, &res->dma_resource[irq]);
+			write_dma(p, &res->dma_resource[dma]);
 			dma++;
 			break;
 		}
diff -urN linux-2.5.72-bk2/drivers/serial/8250_pnp.c linux-2.5.72-bk3/drivers/serial/8250_pnp.c
--- linux-2.5.72-bk2/drivers/serial/8250_pnp.c	2003-06-16 21:19:39.000000000 -0700
+++ linux-2.5.72-bk3/drivers/serial/8250_pnp.c	2003-06-20 04:48:12.000000000 -0700
@@ -315,19 +315,6 @@
 
 MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
 
-static inline void avoid_irq_share(struct pnp_dev *dev)
-{
-	unsigned int map = 0x1FF8;
-	struct pnp_irq *irq;
-	struct pnp_resources *res = dev->possible;
-
-	serial8250_get_irq_map(&map);
-
-	for ( ; res; res = res->dep)
-		for (irq = res->irq; irq; irq = irq->next)
-			irq->map = map;
-}
-
 static char *modem_names[] __devinitdata = {
 	"MODEM", "Modem", "modem", "FAX", "Fax", "fax",
 	"56K", "56k", "K56", "33.6", "28.8", "14.4",
@@ -346,6 +333,29 @@
 	return 0;
 }
 
+static int __devinit check_resources(struct pnp_option *option)
+{
+	struct pnp_option *tmp;
+	if (!option)
+		return 0;
+
+	for (tmp = option; tmp; tmp = tmp->next) {
+		struct pnp_port *port;
+		for (port = tmp->port; port; port = port->next)
+			if ((port->size == 8) &&
+			    ((port->min == 0x2f8) ||
+			     (port->min == 0x3f8) ||
+			     (port->min == 0x2e8) ||
+#ifdef CONFIG_X86_PC9800
+			     (port->min == 0x8b0) ||
+#endif
+			     (port->min == 0x3e8)))
+				return 1;
+	}
+
+	return 0;
+}
+
 /*
  * Given a complete unknown PnP device, try to use some heuristics to
  * detect modems. Currently use such heuristic set:
@@ -357,30 +367,16 @@
  * PnP modems, alternatively we must hardcode all modems in pnp_devices[]
  * table.
  */
-static int serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
+static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
 {
-	struct pnp_resources *res = dev->possible;
-	struct pnp_resources *resa;
-
 	if (!(check_name(dev->dev.name) || (dev->card && check_name(dev->card->dev.name))))
 		return -ENODEV;
 
-	if (!res)
-		return -ENODEV;
+	if (check_resources(dev->independent))
+		return 0;
 
-	for (resa = res->dep; resa; resa = resa->dep) {
-		struct pnp_port *port;
-		for (port = res->port; port; port = port->next)
-			if ((port->size == 8) &&
-			    ((port->min == 0x2f8) ||
-			     (port->min == 0x3f8) ||
-			     (port->min == 0x2e8) ||
-#ifdef CONFIG_X86_PC9800
-			     (port->min == 0x8b0) ||
-#endif
-			     (port->min == 0x3e8)))
-				return 0;
-	}
+	if (check_resources(dev->dependent))
+		return 0;
 
 	return -ENODEV;
 }
@@ -395,8 +391,6 @@
 		if (ret < 0)
 			return ret;
 	}
-	if (flags & SPCI_FL_NO_SHIRQ)
-		avoid_irq_share(dev);
 	memset(&serial_req, 0, sizeof(serial_req));
 	serial_req.irq = pnp_irq(dev,0);
 	serial_req.port = pnp_port_start(dev, 0);
diff -urN linux-2.5.72-bk2/include/asm-alpha/smp.h linux-2.5.72-bk3/include/asm-alpha/smp.h
--- linux-2.5.72-bk2/include/asm-alpha/smp.h	2003-06-16 21:20:23.000000000 -0700
+++ linux-2.5.72-bk3/include/asm-alpha/smp.h	2003-06-20 04:48:12.000000000 -0700
@@ -57,6 +57,15 @@
 	return hweight64(cpu_online_map);
 }
 
+extern inline int
+any_online_cpu(unsigned int mask)
+{
+        if (mask & cpu_online_map)
+                return __ffs(mask & cpu_online_map);
+
+        return -1;
+}
+
 extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu);
 
 #else /* CONFIG_SMP */
diff -urN linux-2.5.72-bk2/include/asm-alpha/unistd.h linux-2.5.72-bk3/include/asm-alpha/unistd.h
--- linux-2.5.72-bk2/include/asm-alpha/unistd.h	2003-06-16 21:20:00.000000000 -0700
+++ linux-2.5.72-bk3/include/asm-alpha/unistd.h	2003-06-20 04:48:12.000000000 -0700
@@ -593,13 +593,7 @@
 	return sys_read(fd, buf, nr);
 }
 
-extern int __kernel_execve(char *, char **, char **, struct pt_regs *);
-static inline long execve(char * file, char ** argvp, char ** envp)
-{
-	struct pt_regs regs;
-	memset(&regs, 0, sizeof(regs));
-	return __kernel_execve(file, argvp, envp, &regs);
-}
+extern long execve(char *, char **, char **);
 
 extern long sys_setsid(void);
 static inline long setsid(void)
diff -urN linux-2.5.72-bk2/include/asm-alpha/xor.h linux-2.5.72-bk3/include/asm-alpha/xor.h
--- linux-2.5.72-bk2/include/asm-alpha/xor.h	2003-06-16 21:20:20.000000000 -0700
+++ linux-2.5.72-bk3/include/asm-alpha/xor.h	2003-06-20 04:48:12.000000000 -0700
@@ -822,19 +822,19 @@
 ");
 
 static struct xor_block_template xor_block_alpha = {
-	name: "alpha",
-	do_2: xor_alpha_2,
-	do_3: xor_alpha_3,
-	do_4: xor_alpha_4,
-	do_5: xor_alpha_5,
+	.name	= "alpha",
+	.do_2	= xor_alpha_2,
+	.do_3	= xor_alpha_3,
+	.do_4	= xor_alpha_4,
+	.do_5	= xor_alpha_5,
 };
 
 static struct xor_block_template xor_block_alpha_prefetch = {
-	name: "alpha prefetch",
-	do_2: xor_alpha_prefetch_2,
-	do_3: xor_alpha_prefetch_3,
-	do_4: xor_alpha_prefetch_4,
-	do_5: xor_alpha_prefetch_5,
+	.name	= "alpha prefetch",
+	.do_2	= xor_alpha_prefetch_2,
+	.do_3	= xor_alpha_prefetch_3,
+	.do_4	= xor_alpha_prefetch_4,
+	.do_5	= xor_alpha_prefetch_5,
 };
 
 /* For grins, also test the generic routines.  */
diff -urN linux-2.5.72-bk2/include/linux/firmware.h linux-2.5.72-bk3/include/linux/firmware.h
--- linux-2.5.72-bk2/include/linux/firmware.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.72-bk3/include/linux/firmware.h	2003-06-20 04:48:12.000000000 -0700
@@ -0,0 +1,19 @@
+#ifndef _LINUX_FIRMWARE_H
+#define _LINUX_FIRMWARE_H
+#include <linux/module.h>
+#include <linux/types.h>
+#define FIRMWARE_NAME_MAX 30 
+struct firmware {
+	size_t size;
+	u8 *data;
+};
+int request_firmware(const struct firmware **fw, const char *name,
+		     struct device *device);
+int request_firmware_nowait(
+	struct module *module,
+	const char *name, struct device *device, void *context,
+	void (*cont)(const struct firmware *fw, void *context));
+
+void release_firmware(const struct firmware *fw);
+void register_firmware(const char *name, const u8 *data, size_t size);
+#endif
diff -urN linux-2.5.72-bk2/include/linux/isdn.h linux-2.5.72-bk3/include/linux/isdn.h
--- linux-2.5.72-bk2/include/linux/isdn.h	2003-06-16 21:20:27.000000000 -0700
+++ linux-2.5.72-bk3/include/linux/isdn.h	2003-06-20 04:48:12.000000000 -0700
@@ -283,7 +283,7 @@
 #endif
 	int          mdmcmdl;                    /* Length of Modem-Commandbuffer      */
 	int          pluscount;                  /* Counter for +++ sequence           */
-	int          lastplus;                   /* Timestamp of last +                */
+	unsigned long lastplus;                  /* Timestamp of last +                */
 	char         mdmcmd[255];                /* Modem-Commandbuffer                */
 	unsigned int charge;                     /* Charge units of current connection */
 } atemu;
diff -urN linux-2.5.72-bk2/include/linux/isdn_ppp.h linux-2.5.72-bk3/include/linux/isdn_ppp.h
--- linux-2.5.72-bk2/include/linux/isdn_ppp.h	2003-06-16 21:19:43.000000000 -0700
+++ linux-2.5.72-bk3/include/linux/isdn_ppp.h	2003-06-20 04:48:12.000000000 -0700
@@ -95,7 +95,8 @@
  * check the original include for more information
  */
 struct isdn_ppp_compressor {
-	struct isdn_ppp_compressor *next, *prev;
+	struct module *owner;
+	struct list_head list;
 	int num; /* CCP compression protocol number */
   
 	void *(*alloc) (struct isdn_ppp_comp_data *);
diff -urN linux-2.5.72-bk2/include/linux/netdevice.h linux-2.5.72-bk3/include/linux/netdevice.h
--- linux-2.5.72-bk2/include/linux/netdevice.h	2003-06-16 21:20:23.000000000 -0700
+++ linux-2.5.72-bk3/include/linux/netdevice.h	2003-06-20 04:48:12.000000000 -0700
@@ -195,8 +195,14 @@
 	int		hh_len;		/* length of header */
 	int		(*hh_output)(struct sk_buff *skb);
 	rwlock_t	hh_lock;
+
 	/* cached hardware header; allow for machine alignment needs.        */
-	unsigned long	hh_data[16/sizeof(unsigned long)];
+#define HH_DATA_MOD	16
+#define HH_DATA_OFF(__len) \
+	(HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1)))
+#define HH_DATA_ALIGN(__len) \
+	(((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
+	unsigned long	hh_data[HH_DATA_ALIGN(LL_MAX_HEADER)];
 };
 
 /* These flag bits are private to the generic network queueing
diff -urN linux-2.5.72-bk2/include/linux/netfilter_arp.h linux-2.5.72-bk3/include/linux/netfilter_arp.h
--- linux-2.5.72-bk2/include/linux/netfilter_arp.h	2003-06-16 21:19:40.000000000 -0700
+++ linux-2.5.72-bk3/include/linux/netfilter_arp.h	2003-06-20 04:48:12.000000000 -0700
@@ -14,6 +14,7 @@
 /* ARP Hooks */
 #define NF_ARP_IN	0
 #define NF_ARP_OUT	1
-#define NF_ARP_NUMHOOKS	2
+#define NF_ARP_FORWARD	2
+#define NF_ARP_NUMHOOKS	3
 
 #endif /* __LINUX_ARP_NETFILTER_H */
diff -urN linux-2.5.72-bk2/include/linux/pci_ids.h linux-2.5.72-bk3/include/linux/pci_ids.h
--- linux-2.5.72-bk2/include/linux/pci_ids.h	2003-06-16 21:20:00.000000000 -0700
+++ linux-2.5.72-bk3/include/linux/pci_ids.h	2003-06-20 04:48:12.000000000 -0700
@@ -602,6 +602,8 @@
 #define PCI_DEVICE_ID_HP_DIVA_TOSCA1	0x1049
 #define PCI_DEVICE_ID_HP_DIVA_TOSCA2	0x104A
 #define PCI_DEVICE_ID_HP_DIVA_MAESTRO	0x104B
+#define PCI_DEVICE_ID_HP_REO_SBA	0x10f0
+#define PCI_DEVICE_ID_HP_REO_IOC	0x10f1
 #define PCI_DEVICE_ID_HP_VISUALIZE_FXE	0x108b
 #define PCI_DEVICE_ID_HP_DIVA_HALFDOME	0x1223
 #define PCI_DEVICE_ID_HP_DIVA_KEYSTONE	0x1226
diff -urN linux-2.5.72-bk2/include/linux/pnp.h linux-2.5.72-bk3/include/linux/pnp.h
--- linux-2.5.72-bk2/include/linux/pnp.h	2003-06-16 21:20:27.000000000 -0700
+++ linux-2.5.72-bk3/include/linux/pnp.h	2003-06-20 04:48:12.000000000 -0700
@@ -102,22 +102,13 @@
 #define PNP_RES_PRIORITY_FUNCTIONAL	2
 #define PNP_RES_PRIORITY_INVALID	65535
 
-struct pnp_resources {
+struct pnp_option {
 	unsigned short priority;	/* priority */
 	struct pnp_port *port;		/* first port */
 	struct pnp_irq *irq;		/* first IRQ */
 	struct pnp_dma *dma;		/* first DMA */
 	struct pnp_mem *mem;		/* first memory resource */
-	struct pnp_dev *dev;		/* parent */
-	struct pnp_resources *dep;	/* dependent resources */
-};
-
-struct pnp_rule_table {
-	int depnum;
-	struct pnp_port *port[PNP_MAX_PORT];
-	struct pnp_irq *irq[PNP_MAX_IRQ];
-	struct pnp_dma *dma[PNP_MAX_DMA];
-	struct pnp_mem *mem[PNP_MAX_MEM];
+	struct pnp_option *next;	/* used to chain dependent resources */
 };
 
 struct pnp_resource_table {
@@ -187,8 +178,6 @@
 struct pnp_dev {
 	struct device dev;		/* Driver Model device interface */
 	unsigned char number;		/* used as an index, must be unique */
-	int active;
-	int capabilities;
 	int status;
 
 	struct list_head global_list;	/* node in global list of devices */
@@ -201,11 +190,13 @@
 	struct pnp_driver * driver;
 	struct pnp_card_link * card_link;
 
-	struct pnp_id		      * id;		/* supported EISA IDs*/
-	struct pnp_resource_table	res;		/* contains the currently chosen resources */
-	struct pnp_resources	      * possible;	/* a list of possible resources */
-	struct pnp_rule_table	      * rule;		/* the current possible resource set */
-	int 				config_mode;	/* flags that determine how the device's resources should be configured */
+	struct pnp_id	* id;	/* supported EISA IDs*/
+
+	int active;
+	int capabilities;
+	struct pnp_option * independent;
+	struct pnp_option * dependent;
+	struct pnp_resource_table res;
 
 	void * protocol_data;		/* Used to store protocol specific data */
 	unsigned short	regs;		/* ISAPnP: supported registers */
@@ -252,11 +243,9 @@
 	void (*quirk_function)(struct pnp_dev *dev);	/* fixup function */
 };
 
-/* config modes */
-#define PNP_CONFIG_AUTO		0x0001	/* Use the Resource Configuration Engine to determine resource settings */
-#define PNP_CONFIG_MANUAL	0x0002	/* the config has been manually specified */
-#define PNP_CONFIG_FORCE	0x0004	/* disables validity checking */
-#define PNP_CONFIG_INVALID	0x0008	/* If this flag is set, the pnp layer will refuse to activate the device */
+/* config parameters */
+#define PNP_CONFIG_NORMAL	0x0001
+#define PNP_CONFIG_FORCE	0x0002	/* disables validity checking */
 
 /* capabilities */
 #define PNP_READ		0x0001
@@ -271,7 +260,7 @@
 				 ((dev)->capabilities & PNP_WRITE))
 #define pnp_can_disable(dev)	(((dev)->protocol) && ((dev)->protocol->disable) && \
 				 ((dev)->capabilities & PNP_DISABLE))
-#define pnp_can_configure(dev)	((!(dev)->active) && ((dev)->config_mode & PNP_CONFIG_AUTO) && \
+#define pnp_can_configure(dev)	((!(dev)->active) && \
 				 ((dev)->capabilities & PNP_CONFIGURABLE))
 
 #ifdef CONFIG_ISAPNP
@@ -383,7 +372,7 @@
 
 #if defined(CONFIG_PNP)
 
-/* core */
+/* device management */
 int pnp_register_protocol(struct pnp_protocol *protocol);
 void pnp_unregister_protocol(struct pnp_protocol *protocol);
 int pnp_add_device(struct pnp_dev *dev);
@@ -392,7 +381,7 @@
 void pnp_device_detach(struct pnp_dev *pnp_dev);
 extern struct list_head pnp_global;
 
-/* card */
+/* multidevice card support */
 int pnp_add_card(struct pnp_card *card);
 void pnp_remove_card(struct pnp_card *card);
 int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
@@ -404,41 +393,35 @@
 void pnp_unregister_card_driver(struct pnp_card_driver * drv);
 extern struct list_head pnp_cards;
 
-/* resource */
-struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent);
-struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum);
-int pnp_get_max_depnum(struct pnp_dev *dev);
-int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data);
-int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_dma *data);
-int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_port *data);
-int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_mem *data);
-void pnp_init_resource_table(struct pnp_resource_table *table);
-int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table * rule);
-
-/* manager */
+/* resource management */
+struct pnp_option * pnp_register_independent_option(struct pnp_dev *dev);
+struct pnp_option * pnp_register_dependent_option(struct pnp_dev *dev, int priority);
+int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data);
+int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data);
+int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data);
+int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data);
+void pnp_init_resources(struct pnp_resource_table *table);
+int pnp_assign_resources(struct pnp_dev *dev, int depnum);
+int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode);
+int pnp_auto_config_dev(struct pnp_dev *dev);
+int pnp_validate_config(struct pnp_dev *dev);
 int pnp_activate_dev(struct pnp_dev *dev);
 int pnp_disable_dev(struct pnp_dev *dev);
 void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size);
-int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode);
-int pnp_auto_config_dev(struct pnp_dev *dev);
-
-/* driver */
-int compare_pnp_id(struct pnp_id * pos, const char * id);
-int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
-int pnp_register_driver(struct pnp_driver *drv);
-void pnp_unregister_driver(struct pnp_driver *drv);
 
-/* support */
+/* protocol helpers */
 int pnp_is_active(struct pnp_dev * dev);
 unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res);
 unsigned char * pnp_parse_possible_resources(unsigned char * p, unsigned char * end, struct pnp_dev * dev);
 unsigned char * pnp_write_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res);
+int compare_pnp_id(struct pnp_id * pos, const char * id);
+int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
+int pnp_register_driver(struct pnp_driver *drv);
+void pnp_unregister_driver(struct pnp_driver *drv);
 
 #else
 
-/* just in case anyone decides to call these without PnP Support Enabled */
-
-/* core */
+/* device management */
 static inline int pnp_register_protocol(struct pnp_protocol *protocol) { return -ENODEV; }
 static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { }
 static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
@@ -447,7 +430,7 @@
 static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
 static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { ; }
 
-/* card */
+/* multidevice card support */
 static inline int pnp_add_card(struct pnp_card *card) { return -ENODEV; }
 static inline void pnp_remove_card(struct pnp_card *card) { ; }
 static inline int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev) { return -ENODEV; }
@@ -458,35 +441,31 @@
 static inline int pnp_register_card_driver(struct pnp_card_driver * drv) { return -ENODEV; }
 static inline void pnp_unregister_card_driver(struct pnp_card_driver * drv) { ; }
 
-/* resource */
-static inline struct pnp_resources * pnp_build_resource(struct pnp_dev *dev, int dependent) { return NULL; }
-static inline struct pnp_resources * pnp_find_resources(struct pnp_dev *dev, int depnum) { return NULL; }
-static inline int pnp_get_max_depnum(struct pnp_dev *dev) { return -ENODEV; }
-static inline int pnp_add_irq_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline int pnp_add_dma_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline int pnp_add_port_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline int pnp_add_mem_resource(struct pnp_dev *dev, int depnum, struct pnp_irq *data) { return -ENODEV; }
-static inline void pnp_init_resource_table(struct pnp_resource_table *table) { ; }
-static inline int pnp_generate_rule(struct pnp_dev * dev, int depnum, struct pnp_rule_table * rule) { return -ENODEV; }
-
-/* manager */
-static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
-static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
-static inline void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) { ; }
+/* resource management */
+static inline struct pnp_option * pnp_register_independent_option(struct pnp_dev *dev) { return NULL; }
+static inline struct pnp_option * pnp_register_dependent_option(struct pnp_dev *dev, int priority) { return NULL; }
+static inline int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) { return -ENODEV; }
+static inline int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { return -ENODEV; }
+static inline int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { return -ENODEV; }
+static inline int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { return -ENODEV; }
+static inline void pnp_init_resources(struct pnp_resource_table *table) { }
+static inline int pnp_assign_resources(struct pnp_dev *dev, int depnum) { return -ENODEV; }
 static inline int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode) { return -ENODEV; }
 static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_validate_config(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) { }
 
-/* driver */
-static inline int compare_pnp_id(struct list_head * id_list, const char * id) { return -ENODEV; }
-static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; }
-static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
-static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; }
-
-/* support */
-static inline int pnp_is_active(struct pnp_dev * dev) { return -ENODEV; }
+/* protocol helpers */
+static inline int pnp_is_active(struct pnp_dev * dev) { return 0; }
 static inline unsigned char * pnp_parse_current_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res) { return NULL; }
 static inline unsigned char * pnp_parse_possible_resources(unsigned char * p, unsigned char * end, struct pnp_dev * dev) { return NULL; }
 static inline unsigned char * pnp_write_resources(unsigned char * p, unsigned char * end, struct pnp_resource_table * res) { return NULL; }
+static inline int compare_pnp_id(struct pnp_id * pos, const char * id) { return -ENODEV; }
+static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
+static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; }
 
 #endif /* CONFIG_PNP */
 
diff -urN linux-2.5.72-bk2/include/linux/skbuff.h linux-2.5.72-bk3/include/linux/skbuff.h
--- linux-2.5.72-bk2/include/linux/skbuff.h	2003-06-20 04:48:06.000000000 -0700
+++ linux-2.5.72-bk3/include/linux/skbuff.h	2003-06-20 04:48:12.000000000 -0700
@@ -803,12 +803,9 @@
 	skb_shinfo(skb)->nr_frags = i+1;
 }
 
-#define SKB_PAGE_ASSERT(skb) do { if (skb_shinfo(skb)->nr_frags) \
-					BUG(); } while (0)
-#define SKB_FRAG_ASSERT(skb) do { if (skb_shinfo(skb)->frag_list) \
-					BUG(); } while (0)
-#define SKB_LINEAR_ASSERT(skb) do { if (skb_is_nonlinear(skb)) \
-					BUG(); } while (0)
+#define SKB_PAGE_ASSERT(skb) 	BUG_ON(skb_shinfo(skb)->nr_frags)
+#define SKB_FRAG_ASSERT(skb) 	BUG_ON(skb_shinfo(skb)->frag_list)
+#define SKB_LINEAR_ASSERT(skb)  BUG_ON(skb_is_nonlinear(skb))
 
 /*
  *	Add data to an sk_buff
@@ -837,7 +834,7 @@
 	SKB_LINEAR_ASSERT(skb);
 	skb->tail += len;
 	skb->len  += len;
-	if (skb->tail>skb->end)
+	if (unlikely(skb->tail>skb->end))
 		skb_over_panic(skb, len, current_text_addr());
 	return tmp;
 }
@@ -862,7 +859,7 @@
 {
 	skb->data -= len;
 	skb->len  += len;
-	if (skb->data<skb->head)
+	if (unlikely(skb->data<skb->head))
 		skb_under_panic(skb, len, current_text_addr());
 	return skb->data;
 }
@@ -870,8 +867,7 @@
 static inline char *__skb_pull(struct sk_buff *skb, unsigned int len)
 {
 	skb->len -= len;
-	if (skb->len < skb->data_len)
-		BUG();
+	BUG_ON(skb->len < skb->data_len);
 	return skb->data += len;
 }
 
@@ -1137,8 +1133,7 @@
 static inline void *kmap_skb_frag(const skb_frag_t *frag)
 {
 #ifdef CONFIG_HIGHMEM
-	if (in_irq())
-		BUG();
+	BUG_ON(in_irq());
 
 	local_bh_disable();
 #endif
@@ -1154,9 +1149,9 @@
 }
 
 #define skb_queue_walk(queue, skb) \
-		for (skb = (queue)->next;			\
+		for (skb = (queue)->next, prefetch(skb->next);	\
 		     (skb != (struct sk_buff *)(queue));	\
-		     skb = skb->next)
+		     skb = skb->next, prefetch(skb->next))
 
 
 extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
diff -urN linux-2.5.72-bk2/include/linux/sysdev.h linux-2.5.72-bk3/include/linux/sysdev.h
--- linux-2.5.72-bk2/include/linux/sysdev.h	2003-06-16 21:20:05.000000000 -0700
+++ linux-2.5.72-bk3/include/linux/sysdev.h	2003-06-20 04:48:12.000000000 -0700
@@ -72,7 +72,6 @@
 	u32		id;
 	struct sysdev_class	* cls;
 	struct kobject		kobj;
-	struct list_head	entry;
 };
 
 extern int sys_device_register(struct sys_device *);
diff -urN linux-2.5.72-bk2/kernel/ksyms.c linux-2.5.72-bk3/kernel/ksyms.c
--- linux-2.5.72-bk2/kernel/ksyms.c	2003-06-20 04:48:06.000000000 -0700
+++ linux-2.5.72-bk3/kernel/ksyms.c	2003-06-20 04:48:12.000000000 -0700
@@ -592,7 +592,6 @@
 /* init task, for moving kthread roots - ought to export a function ?? */
 
 EXPORT_SYMBOL(init_task);
-EXPORT_SYMBOL(init_thread_union);
 
 EXPORT_SYMBOL(tasklist_lock);
 EXPORT_SYMBOL(find_task_by_pid);
diff -urN linux-2.5.72-bk2/lib/kobject.c linux-2.5.72-bk3/lib/kobject.c
--- linux-2.5.72-bk2/lib/kobject.c	2003-06-16 21:20:22.000000000 -0700
+++ linux-2.5.72-bk3/lib/kobject.c	2003-06-20 04:48:12.000000000 -0700
@@ -100,6 +100,9 @@
 
 #define BUFFER_SIZE	1024	/* should be enough memory for the env */
 #define NUM_ENVP	32	/* number of env pointers */
+static unsigned long sequence_num;
+static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
+
 static void kset_hotplug(const char *action, struct kset *kset,
 			 struct kobject *kobj)
 {
@@ -112,6 +115,7 @@
 	int kobj_path_length;
 	char *kobj_path = NULL;
 	char *name = NULL;
+	unsigned long seq;
 
 	/* If the kset has a filter operation, call it. If it returns
 	   failure, no hotplug event is required. */
@@ -152,6 +156,13 @@
 	envp [i++] = scratch;
 	scratch += sprintf(scratch, "ACTION=%s", action) + 1;
 
+	spin_lock(&sequence_lock);
+	seq = sequence_num++;
+	spin_unlock(&sequence_lock);
+
+	envp [i++] = scratch;
+	scratch += sprintf(scratch, "SEQNUM=%ld", seq) + 1;
+
 	kobj_path_length = get_kobj_path_length (kset, kobj);
 	kobj_path = kmalloc (kobj_path_length, GFP_KERNEL);
 	if (!kobj_path)
diff -urN linux-2.5.72-bk2/net/bridge/br_netfilter.c linux-2.5.72-bk3/net/bridge/br_netfilter.c
--- linux-2.5.72-bk2/net/bridge/br_netfilter.c	2003-06-16 21:20:26.000000000 -0700
+++ linux-2.5.72-bk3/net/bridge/br_netfilter.c	2003-06-20 04:48:12.000000000 -0700
@@ -22,6 +22,7 @@
 #include <linux/if_ether.h>
 #include <linux/netfilter_bridge.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_arp.h>
 #include <linux/in_route.h>
 #include <net/ip.h>
 #include <asm/uaccess.h>
@@ -304,31 +305,36 @@
 	return NF_ACCEPT;
 }
 
-
 /* PF_BRIDGE/FORWARD *************************************************/
 static int br_nf_forward_finish(struct sk_buff *skb)
 {
 	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+	struct net_device *in;
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	skb->nf_debug ^= (1 << NF_BR_FORWARD);
 #endif
 
-	if (nf_bridge->mask & BRNF_PKT_TYPE) {
-		skb->pkt_type = PACKET_OTHERHOST;
-		nf_bridge->mask ^= BRNF_PKT_TYPE;
+	if (skb->protocol == __constant_htons(ETH_P_IP)) {
+		in = nf_bridge->physindev;
+		if (nf_bridge->mask & BRNF_PKT_TYPE) {
+			skb->pkt_type = PACKET_OTHERHOST;
+			nf_bridge->mask ^= BRNF_PKT_TYPE;
+		}
+	} else {
+		in = *((struct net_device **)(skb->cb));
 	}
 
-	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, nf_bridge->physindev,
+	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
 			skb->dev, br_forward_finish, 1);
-
 	return 0;
 }
 
-/* This is the 'purely bridged' case.  We pass the packet to
+/* This is the 'purely bridged' case.  For IP, we pass the packet to
  * netfilter with indev and outdev set to the bridge device,
  * but we are still able to filter on the 'real' indev/outdev
- * because of the ipt_physdev.c module.
+ * because of the ipt_physdev.c module. For ARP, indev and outdev are the
+ * bridge ports.
  */
 static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
    const struct net_device *in, const struct net_device *out,
@@ -337,24 +343,33 @@
 	struct sk_buff *skb = *pskb;
 	struct nf_bridge_info *nf_bridge;
 
-	if (skb->protocol != __constant_htons(ETH_P_IP))
+	if (skb->protocol != __constant_htons(ETH_P_IP) &&
+	    skb->protocol != __constant_htons(ETH_P_ARP))
 		return NF_ACCEPT;
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	skb->nf_debug ^= (1 << NF_BR_FORWARD);
 #endif
+	if (skb->protocol == __constant_htons(ETH_P_IP)) {
+		nf_bridge = skb->nf_bridge;
+		if (skb->pkt_type == PACKET_OTHERHOST) {
+			skb->pkt_type = PACKET_HOST;
+			nf_bridge->mask |= BRNF_PKT_TYPE;
+		}
 
-	nf_bridge = skb->nf_bridge;
-	if (skb->pkt_type == PACKET_OTHERHOST) {
-		skb->pkt_type = PACKET_HOST;
-		nf_bridge->mask |= BRNF_PKT_TYPE;
-	}
+		/* The physdev module checks on this */
+		nf_bridge->mask |= BRNF_BRIDGED;
+		nf_bridge->physoutdev = skb->dev;
 
-	nf_bridge->mask |= BRNF_BRIDGED; /* The physdev module checks on this */
-	nf_bridge->physoutdev = skb->dev;
+		NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in),
+			bridge_parent(out), br_nf_forward_finish);
+	} else {
+		struct net_device **d = (struct net_device **)(skb->cb);
 
-	NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(nf_bridge->physindev),
-			bridge_parent(skb->dev), br_nf_forward_finish);
+		*d = (struct net_device *)in;
+		NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
+			(struct net_device *)out, br_nf_forward_finish);
+	}
 
 	return NF_STOLEN;
 }
diff -urN linux-2.5.72-bk2/net/core/flow.c linux-2.5.72-bk3/net/core/flow.c
--- linux-2.5.72-bk2/net/core/flow.c	2003-06-16 21:19:39.000000000 -0700
+++ linux-2.5.72-bk3/net/core/flow.c	2003-06-20 04:48:12.000000000 -0700
@@ -12,7 +12,6 @@
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/interrupt.h>
 #include <linux/smp.h>
 #include <linux/completion.h>
 #include <linux/percpu.h>
@@ -301,7 +300,8 @@
 
 	local_bh_disable();
 	smp_call_function(flow_cache_flush_per_cpu, &info, 1, 0);
-	flow_cache_flush_tasklet((unsigned long)&info);
+	if (test_bit(smp_processor_id(), &info.cpumap))
+		flow_cache_flush_tasklet((unsigned long)&info);
 	local_bh_enable();
 
 	wait_for_completion(&info.completion);
@@ -309,13 +309,11 @@
 	up(&flow_flush_sem);
 }
 
-static void __devinit flow_cache_cpu_online(int cpu)
+static int __devinit flow_cache_cpu_prepare(int cpu)
 {
 	struct tasklet_struct *tasklet;
 	unsigned long order;
 
-	flow_hash_rnd_recalc(cpu) = 1;
-
 	for (order = 0;
 	     (PAGE_SIZE << order) <
 		     (sizeof(struct flow_cache_entry *)*flow_hash_size);
@@ -325,15 +323,28 @@
 	flow_table(cpu) = (struct flow_cache_entry **)
 		__get_free_pages(GFP_KERNEL, order);
 
+	if (!flow_table(cpu))
+		return NOTIFY_BAD;
+
 	memset(flow_table(cpu), 0, PAGE_SIZE << order);
 
+	flow_hash_rnd_recalc(cpu) = 1;
+	flow_count(cpu) = 0;
+
 	tasklet = flow_flush_tasklet(cpu);
 	tasklet_init(tasklet, flow_cache_flush_tasklet, 0);
 
+	return NOTIFY_OK;
+}
+
+static int __devinit flow_cache_cpu_online(int cpu)
+{
 	down(&flow_cache_cpu_sem);
 	set_bit(cpu, &flow_cache_cpu_map);
 	flow_cache_cpu_count++;
 	up(&flow_cache_cpu_sem);
+
+	return NOTIFY_OK;
 }
 
 static int __devinit flow_cache_cpu_notify(struct notifier_block *self,
@@ -342,7 +353,10 @@
 	unsigned long cpu = (unsigned long)cpu;
 	switch (action) {
 	case CPU_UP_PREPARE:
-		flow_cache_cpu_online(cpu);
+		return flow_cache_cpu_prepare(cpu);
+		break;
+	case CPU_ONLINE:
+		return flow_cache_cpu_online(cpu);
 		break;
 	}
 	return NOTIFY_OK;
@@ -354,6 +368,8 @@
 
 static int __init flow_cache_init(void)
 {
+	int i;
+
 	flow_cachep = kmem_cache_create("flow_cache",
 					sizeof(struct flow_cache_entry),
 					0, SLAB_HWCACHE_ALIGN,
@@ -371,8 +387,12 @@
 	flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD;
 	add_timer(&flow_hash_rnd_timer);
 
-	flow_cache_cpu_online(smp_processor_id());
 	register_cpu_notifier(&flow_cache_cpu_nb);
+	for (i = 0; i < NR_CPUS; i++)
+		if (cpu_online(i)) {
+			flow_cache_cpu_prepare(i);
+			flow_cache_cpu_online(i);
+		}
 
 	return 0;
 }
diff -urN linux-2.5.72-bk2/net/ethernet/eth.c linux-2.5.72-bk3/net/ethernet/eth.c
--- linux-2.5.72-bk2/net/ethernet/eth.c	2003-06-16 21:20:02.000000000 -0700
+++ linux-2.5.72-bk3/net/ethernet/eth.c	2003-06-20 04:48:12.000000000 -0700
@@ -216,9 +216,12 @@
 int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
 {
 	unsigned short type = hh->hh_type;
-	struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2);
+	struct ethhdr *eth;
 	struct net_device *dev = neigh->dev;
 
+	eth = (struct ethhdr*)
+		(((u8*)hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
+
 	if (type == __constant_htons(ETH_P_802_3))
 		return -1;
 
@@ -235,5 +238,6 @@
 
 void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
 {
-	memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len);
+	memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
+	       haddr, dev->addr_len);
 }
diff -urN linux-2.5.72-bk2/net/ipv4/ip_output.c linux-2.5.72-bk3/net/ipv4/ip_output.c
--- linux-2.5.72-bk2/net/ipv4/ip_output.c	2003-06-16 21:20:26.000000000 -0700
+++ linux-2.5.72-bk3/net/ipv4/ip_output.c	2003-06-20 04:48:12.000000000 -0700
@@ -193,8 +193,11 @@
 #endif /*CONFIG_NETFILTER_DEBUG*/
 
 	if (hh) {
+		int hh_alen;
+
 		read_lock_bh(&hh->hh_lock);
-  		memcpy(skb->data - 16, hh->hh_data, 16);
+		hh_alen = HH_DATA_ALIGN(hh->hh_len);
+  		memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
 		read_unlock_bh(&hh->hh_lock);
 	        skb_push(skb, hh->hh_len);
 		return hh->hh_output(skb);
diff -urN linux-2.5.72-bk2/net/ipv4/netfilter/arptable_filter.c linux-2.5.72-bk3/net/ipv4/netfilter/arptable_filter.c
--- linux-2.5.72-bk2/net/ipv4/netfilter/arptable_filter.c	2003-06-16 21:19:37.000000000 -0700
+++ linux-2.5.72-bk3/net/ipv4/netfilter/arptable_filter.c	2003-06-20 04:48:12.000000000 -0700
@@ -8,7 +8,8 @@
 #include <linux/module.h>
 #include <linux/netfilter_arp/arp_tables.h>
 
-#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT))
+#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \
+			   (1 << NF_ARP_FORWARD))
 
 /* Standard entry. */
 struct arpt_standard
@@ -32,15 +33,17 @@
 static struct
 {
 	struct arpt_replace repl;
-	struct arpt_standard entries[2];
+	struct arpt_standard entries[3];
 	struct arpt_error term;
 } initial_table __initdata
-= { { "filter", FILTER_VALID_HOOKS, 3,
-      sizeof(struct arpt_standard) * 2 + sizeof(struct arpt_error),
+= { { "filter", FILTER_VALID_HOOKS, 4,
+      sizeof(struct arpt_standard) * 3 + sizeof(struct arpt_error),
       { [NF_ARP_IN] = 0,
-	[NF_ARP_OUT] = sizeof(struct arpt_standard) },
+	[NF_ARP_OUT] = sizeof(struct arpt_standard),
+	[NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), },
       { [NF_ARP_IN] = 0,
-	[NF_ARP_OUT] = sizeof(struct arpt_standard), },
+	[NF_ARP_OUT] = sizeof(struct arpt_standard),
+	[NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), },
       0, NULL, { } },
     {
 	    /* ARP_IN */
@@ -84,6 +87,27 @@
 			    { 0, 0 }, { } },
 		    { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
 		      -NF_ACCEPT - 1 }
+	    },
+	    /* ARP_FORWARD */
+	    {
+		    {
+			    {
+				    { 0 }, { 0 }, { 0 }, { 0 },
+				    0, 0,
+				    { { 0, }, { 0, } },
+				    { { 0, }, { 0, } },
+				    0, 0,
+				    0, 0,
+				    0, 0,
+				    "", "", { 0 }, { 0 },
+				    0, 0
+			    },
+			    sizeof(struct arpt_entry),
+			    sizeof(struct arpt_standard),
+			    0,
+			    { 0, 0 }, { } },
+		    { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
+		      -NF_ACCEPT - 1 }
 	    }
     },
     /* ERROR */
@@ -142,35 +166,34 @@
 		.owner		= THIS_MODULE,
 		.pf		= NF_ARP,
 		.hooknum	= NF_ARP_OUT,
-	}
+	},
+	{
+		.hook		= arpt_hook,
+		.owner		= THIS_MODULE,
+		.pf		= NF_ARP,
+		.hooknum	= NF_ARP_FORWARD,
+	},
 };
 
 static int __init init(void)
 {
-	int ret;
+	int ret, i;
 
 	/* Register table */
 	ret = arpt_register_table(&packet_filter);
 	if (ret < 0)
 		return ret;
 
-	/* Register hooks */
-	ret = nf_register_hook(&arpt_ops[0]);
-	if (ret < 0)
-		goto cleanup_table;
-
-	ret = nf_register_hook(&arpt_ops[1]);
-	if (ret < 0)
-		goto cleanup_hook0;
-
+	for (i = 0; i < ARRAY_SIZE(arpt_ops); i++)
+		if ((ret = nf_register_hook(&arpt_ops[i])) < 0)
+			goto cleanup_hooks;
 	return ret;
 
-cleanup_hook0:
-	nf_unregister_hook(&arpt_ops[0]);
+cleanup_hooks:
+	while (--i >= 0)
+		nf_unregister_hook(&arpt_ops[i]);
 
-cleanup_table:
 	arpt_unregister_table(&packet_filter);
-
 	return ret;
 }
 
@@ -178,7 +201,7 @@
 {
 	unsigned int i;
 
-	for (i = 0; i < sizeof(arpt_ops)/sizeof(struct nf_hook_ops); i++)
+	for (i = 0; i < ARRAY_SIZE(arpt_ops); i++)
 		nf_unregister_hook(&arpt_ops[i]);
 
 	arpt_unregister_table(&packet_filter);
diff -urN linux-2.5.72-bk2/net/ipv4/netfilter/ipt_MIRROR.c linux-2.5.72-bk3/net/ipv4/netfilter/ipt_MIRROR.c
--- linux-2.5.72-bk2/net/ipv4/netfilter/ipt_MIRROR.c	2003-06-16 21:20:27.000000000 -0700
+++ linux-2.5.72-bk3/net/ipv4/netfilter/ipt_MIRROR.c	2003-06-20 04:48:12.000000000 -0700
@@ -90,8 +90,11 @@
 	struct hh_cache *hh = dst->hh;
 
 	if (hh) {
+		int hh_alen;
+
 		read_lock_bh(&hh->hh_lock);
-  		memcpy(skb->data - 16, hh->hh_data, 16);
+		hh_alen = HH_DATA_ALIGN(hh->hh_len);
+  		memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
 		read_unlock_bh(&hh->hh_lock);
 	        skb_push(skb, hh->hh_len);
 		hh->hh_output(skb);
diff -urN linux-2.5.72-bk2/net/ipv6/ip6_output.c linux-2.5.72-bk3/net/ipv6/ip6_output.c
--- linux-2.5.72-bk2/net/ipv6/ip6_output.c	2003-06-16 21:19:40.000000000 -0700
+++ linux-2.5.72-bk3/net/ipv6/ip6_output.c	2003-06-20 04:48:13.000000000 -0700
@@ -76,8 +76,11 @@
 	struct hh_cache *hh = dst->hh;
 
 	if (hh) {
+		int hh_alen;
+
 		read_lock_bh(&hh->hh_lock);
-		memcpy(skb->data - 16, hh->hh_data, 16);
+		hh_alen = HH_DATA_ALIGN(hh->hh_len);
+		memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
 		read_unlock_bh(&hh->hh_lock);
 	        skb_push(skb, hh->hh_len);
 		return hh->hh_output(skb);
diff -urN linux-2.5.72-bk2/net/sched/sch_htb.c linux-2.5.72-bk3/net/sched/sch_htb.c
--- linux-2.5.72-bk2/net/sched/sch_htb.c	2003-06-16 21:20:06.000000000 -0700
+++ linux-2.5.72-bk3/net/sched/sch_htb.c	2003-06-20 04:48:13.000000000 -0700
@@ -9,6 +9,8 @@
  * Authors:	Martin Devera, <devik@cdi.cz>
  *
  * Credits (in time order) for older HTB versions:
+ *              Stef Coene <stef.coene@docum.org>
+ *			HTB support at LARTC mailing list
  *		Ondrej Kraus, <krauso@barr.cz> 
  *			found missing INIT_QDISC(htb)
  *		Vladimir Smelhaus, Aamer Akhter, Bert Hubert
@@ -19,7 +21,7 @@
  *			created test case so that I was able to fix nasty bug
  *		and many others. thanks.
  *
- * $Id: sch_htb.c,v 1.17 2003/01/29 09:22:18 devik Exp devik $
+ * $Id: sch_htb.c,v 1.20 2003/06/18 19:55:49 devik Exp devik $
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -71,7 +73,7 @@
 #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
 #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
 #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
-#define HTB_VER 0x3000a	/* major must be matched with number suplied by TC as version */
+#define HTB_VER 0x3000c	/* major must be matched with number suplied by TC as version */
 
 #if HTB_VER >> 16 != TC_HTB_PROTOVER
 #error "Mismatched sch_htb.c and pkt_sch.h"
@@ -217,6 +219,9 @@
     /* time of nearest event per level (row) */
     unsigned long near_ev_cache[TC_HTB_MAXDEPTH];
 
+    /* cached value of jiffies in dequeue */
+    unsigned long jiffies;
+
     /* whether we hit non-work conserving class during this dequeue; we use */
     int nwc_hit;	/* this to disable mindelay complaint in dequeue */
 
@@ -336,7 +341,7 @@
 static void htb_debug_dump (struct htb_sched *q)
 {
 	int i,p;
-	printk(KERN_DEBUG "htb*g j=%lu\n",jiffies);
+	printk(KERN_DEBUG "htb*g j=%lu lj=%lu\n",jiffies,q->jiffies);
 	/* rows */
 	for (i=TC_HTB_MAXDEPTH-1;i>=0;i--) {
 		printk(KERN_DEBUG "htb*r%d m=%x",i,q->row_mask[i]);
@@ -419,8 +424,8 @@
 	if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit())
 		printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint);
 #endif
-	cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay);
-	if (cl->pq_key == jiffies)
+	cl->pq_key = q->jiffies + PSCHED_US2JIFFIE(delay);
+	if (cl->pq_key == q->jiffies)
 		cl->pq_key++;
 
 	/* update the nearest event cache */
@@ -587,7 +592,7 @@
     long toks;
 
     if ((toks = (cl->ctokens + *diff)) < (
-#ifdef HTB_HYSTERESIS
+#if HTB_HYSTERESIS
 	    cl->cmode != HTB_CANT_SEND ? -cl->cbuffer :
 #endif
        	    0)) {
@@ -595,7 +600,7 @@
 	    return HTB_CANT_SEND;
     }
     if ((toks = (cl->tokens + *diff)) >= (
-#ifdef HTB_HYSTERESIS
+#if HTB_HYSTERESIS
 	    cl->cmode == HTB_CAN_SEND ? -cl->buffer :
 #endif
 	    0))
@@ -798,7 +803,7 @@
 				       cl->classid, diff,
 				       (unsigned long long) q->now,
 				       (unsigned long long) cl->t_c,
-				       jiffies);
+				       q->jiffies);
 			diff = 1000;
 		}
 #endif
@@ -841,6 +846,7 @@
  *
  * Scans event queue for pending events and applies them. Returns jiffies to
  * next pending event (0 for no event in pq).
+ * Note: Aplied are events whose have cl->pq_key <= jiffies.
  */
 static long htb_do_events(struct htb_sched *q,int level)
 {
@@ -855,9 +861,9 @@
 		while (p->rb_left) p = p->rb_left;
 
 		cl = rb_entry(p, struct htb_class, pq_node);
-		if (cl->pq_key - (jiffies+1) < 0x80000000) {
-			HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - jiffies);
-			return cl->pq_key - jiffies;
+		if (cl->pq_key - (q->jiffies+1) < 0x80000000) {
+			HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - q->jiffies);
+			return cl->pq_key - q->jiffies;
 		}
 		htb_safe_rb_erase(p,q->wait_pq+level);
 		diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
@@ -868,7 +874,7 @@
 				       cl->classid, diff,
 				       (unsigned long long) q->now,
 				       (unsigned long long) cl->t_c,
-				       jiffies);
+				       q->jiffies);
 			diff = 1000;
 		}
 #endif
@@ -975,7 +981,8 @@
 			printk(KERN_INFO "HTB delay %ld > 5sec\n", delay);
 		delay = 5*HZ;
 	}
-	mod_timer(&q->timer, jiffies + delay);
+	/* why don't use jiffies here ? because expires can be in past */
+	mod_timer(&q->timer, q->jiffies + delay);
 	sch->flags |= TCQ_F_THROTTLED;
 	sch->stats.overlimits++;
 	HTB_DBG(3,1,"htb_deq t_delay=%ld\n",delay);
@@ -991,6 +998,7 @@
 	int evs_used = 0;
 #endif
 
+	q->jiffies = jiffies;
 	HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue),
 			sch->q.qlen);
 
@@ -1010,14 +1018,14 @@
 		/* common case optimization - skip event handler quickly */
 		int m;
 		long delay;
-		if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) {
+		if (q->jiffies - q->near_ev_cache[level] < 0x80000000 || 0) {
 			delay = htb_do_events(q,level);
-			q->near_ev_cache[level] += delay ? delay : HZ;
+			q->near_ev_cache[level] = q->jiffies + (delay ? delay : HZ);
 #ifdef HTB_DEBUG
 			evs_used++;
 #endif
 		} else
-			delay = q->near_ev_cache[level] - jiffies;	
+			delay = q->near_ev_cache[level] - q->jiffies;	
 		
 		if (delay && min_delay > delay) 
 			min_delay = delay;
@@ -1036,8 +1044,8 @@
 #ifdef HTB_DEBUG
 	if (!q->nwc_hit && min_delay >= 10*HZ && net_ratelimit()) {
 		if (min_delay == LONG_MAX) {
-			printk(KERN_ERR "HTB: dequeue bug (%d), report it please !\n",
-					evs_used);
+			printk(KERN_ERR "HTB: dequeue bug (%d,%lu,%lu), report it please !\n",
+					evs_used,q->jiffies,jiffies);
 			htb_debug_dump(q);
 		} else 
 			printk(KERN_WARNING "HTB: mindelay=%ld, some class has "
@@ -1046,7 +1054,7 @@
 #endif
 	htb_delay_by (sch,min_delay > 5*HZ ? 5*HZ : min_delay);
 fin:
-	HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb);
+	HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,q->jiffies,skb);
 	return skb;
 }
 
@@ -1409,7 +1417,7 @@
 	parent = parentid == TC_H_ROOT ? NULL : htb_find (parentid,sch);
 
 	hopt = RTA_DATA(tb[TCA_HTB_PARMS-1]);
-	HTB_DBG(0,1,"htb_chg cl=%p, clid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum);
+	HTB_DBG(0,1,"htb_chg cl=%p(%X), clid=%X, parid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,classid,parentid,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum);
 	rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB-1]);
 	ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB-1]);
 	if (!rtab || !ctab) goto failure;
