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

diff -urN linux-2.5.69-bk8/Makefile linux-2.5.69-bk9/Makefile
--- linux-2.5.69-bk8/Makefile	2003-05-14 04:43:37.000000000 -0700
+++ linux-2.5.69-bk9/Makefile	2003-05-14 04:43:42.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 69
-EXTRAVERSION = -bk8
+EXTRAVERSION = -bk9
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.69-bk8/arch/i386/kernel/cpu/cpufreq/powernow-k7.c linux-2.5.69-bk9/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
--- linux-2.5.69-bk8/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2003-05-14 04:43:37.000000000 -0700
+++ linux-2.5.69-bk9/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2003-05-14 04:43:42.000000000 -0700
@@ -24,6 +24,7 @@
 #include <asm/msr.h>
 #include <asm/timex.h>
 #include <asm/io.h>
+#include <asm/system.h>
 
 #include "powernow-k7.h"
 
diff -urN linux-2.5.69-bk8/arch/i386/kernel/process.c linux-2.5.69-bk9/arch/i386/kernel/process.c
--- linux-2.5.69-bk8/arch/i386/kernel/process.c	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk9/arch/i386/kernel/process.c	2003-05-14 04:43:42.000000000 -0700
@@ -529,12 +529,12 @@
 	struct task_struct *p;
 	unsigned long clone_flags;
 	unsigned long newsp;
-	int *parent_tidptr, *child_tidptr;
+	int __user *parent_tidptr, *child_tidptr;
 
 	clone_flags = regs.ebx;
 	newsp = regs.ecx;
-	parent_tidptr = (int *)regs.edx;
-	child_tidptr = (int *)regs.edi;
+	parent_tidptr = (int __user *)regs.edx;
+	child_tidptr = (int __user *)regs.edi;
 	if (!newsp)
 		newsp = regs.esp;
 	p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, parent_tidptr, child_tidptr);
diff -urN linux-2.5.69-bk8/arch/i386/lib/usercopy.c linux-2.5.69-bk9/arch/i386/lib/usercopy.c
--- linux-2.5.69-bk8/arch/i386/lib/usercopy.c	2003-05-14 04:43:37.000000000 -0700
+++ linux-2.5.69-bk9/arch/i386/lib/usercopy.c	2003-05-14 04:43:42.000000000 -0700
@@ -12,14 +12,16 @@
 #include <asm/uaccess.h>
 #include <asm/mmx.h>
 
-static inline int movsl_is_ok(const void *a1, const void *a2, unsigned long n)
+static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned long n)
 {
 #ifdef CONFIG_X86_INTEL_USERCOPY
-	if (n >= 64 && (((const long)a1 ^ (const long)a2) & movsl_mask.mask))
+	if (n >= 64 && ((a1 ^ a2) & movsl_mask.mask))
 		return 0;
 #endif
 	return 1;
 }
+#define movsl_is_ok(a1,a2,n) \
+	__movsl_is_ok((unsigned long)(a1),(unsigned long)(a2),(n))
 
 /*
  * Copy a null terminated string from userspace.
@@ -74,7 +76,7 @@
  * and returns @count.
  */
 long
-__strncpy_from_user(char *dst, const char *src, long count)
+__strncpy_from_user(char *dst, const char __user *src, long count)
 {
 	long res;
 	__do_strncpy_from_user(dst, src, count, res);
@@ -100,7 +102,7 @@
  * and returns @count.
  */
 long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
 {
 	long res = -EFAULT;
 	if (access_ok(VERIFY_READ, src, 1))
@@ -145,7 +147,7 @@
  * On success, this will be zero.
  */
 unsigned long
-clear_user(void *to, unsigned long n)
+clear_user(void __user *to, unsigned long n)
 {
 	if (access_ok(VERIFY_WRITE, to, n))
 		__do_clear_user(to, n);
@@ -164,7 +166,7 @@
  * On success, this will be zero.
  */
 unsigned long
-__clear_user(void *to, unsigned long n)
+__clear_user(void __user *to, unsigned long n)
 {
 	__do_clear_user(to, n);
 	return n;
@@ -181,7 +183,7 @@
  * On exception, returns 0.
  * If the string is too long, returns a value greater than @n.
  */
-long strnlen_user(const char *s, long n)
+long strnlen_user(const char __user *s, long n)
 {
 	unsigned long mask = -__addr_ok(s);
 	unsigned long res, tmp;
@@ -484,7 +486,7 @@
 } while (0)
 
 
-unsigned long __copy_to_user_ll(void *to, const void *from, unsigned long n)
+unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n)
 {
 #ifndef CONFIG_X86_WP_WORKS_OK
 	if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
@@ -534,17 +536,17 @@
 	}
 #endif
 	if (movsl_is_ok(to, from, n))
-		__copy_user(to, from, n);
+		__copy_user((void *)to, from, n);
 	else
-		n = __copy_user_intel(to, from, n);
+		n = __copy_user_intel((void *)to, from, n);
 	return n;
 }
 
-unsigned long __copy_from_user_ll(void *to, const void *from, unsigned long n)
+unsigned long __copy_from_user_ll(void *to, const void __user *from, unsigned long n)
 {
 	if (movsl_is_ok(to, from, n))
-		__copy_user_zeroing(to, from, n);
+		__copy_user_zeroing(to, (const void *) from, n);
 	else
-		n = __copy_user_zeroing_intel(to, from, n);
+		n = __copy_user_zeroing_intel(to, (const void *) from, n);
 	return n;
 }
diff -urN linux-2.5.69-bk8/arch/sparc64/defconfig linux-2.5.69-bk9/arch/sparc64/defconfig
--- linux-2.5.69-bk8/arch/sparc64/defconfig	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk9/arch/sparc64/defconfig	2003-05-14 04:43:42.000000000 -0700
@@ -477,7 +477,16 @@
 # CONFIG_SCTP_ADLER32 is not set
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
-# CONFIG_ATM is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_ATM_BR2684_IPFILTER=y
 CONFIG_VLAN_8021Q=m
 CONFIG_LLC=m
 CONFIG_LLC_UI=y
@@ -487,17 +496,24 @@
 # CONFIG_DEV_APPLETALK is not set
 CONFIG_DECNET=m
 CONFIG_DECNET_SIOCGIFCONF=y
-# CONFIG_DECNET_ROUTER is not set
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+
+#
+# DECnet: Netfilter Configuration
+#
+CONFIG_DECNET_NF_GRABULATOR=m
 CONFIG_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
 CONFIG_BRIDGE_EBT_T_NAT=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_LOG=m
-CONFIG_BRIDGE_EBT_IPF=m
-CONFIG_BRIDGE_EBT_ARPF=m
-CONFIG_BRIDGE_EBT_VLANF=m
-CONFIG_BRIDGE_EBT_MARKF=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
 CONFIG_BRIDGE_EBT_SNAT=m
 CONFIG_BRIDGE_EBT_DNAT=m
 CONFIG_BRIDGE_EBT_REDIRECT=m
@@ -517,6 +533,7 @@
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_ATM=y
 CONFIG_NET_SCH_PRIO=m
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
@@ -632,13 +649,14 @@
 # CONFIG_ROADRUNNER is not set
 CONFIG_PLIP=m
 CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_MULTILINK=y
 CONFIG_PPP_FILTER=y
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
 CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
@@ -647,7 +665,19 @@
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_AIRO is not set
+# CONFIG_HERMES is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices (depends on LLC=y)
@@ -663,6 +693,30 @@
 # CONFIG_WAN is not set
 
 #
+# ATM drivers
+#
+CONFIG_ATM_TCP=m
+# CONFIG_ATM_LANAI is not set
+# CONFIG_ATM_ENI is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+# CONFIG_ATM_NICSTAR is not set
+# CONFIG_ATM_IDT77252 is not set
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+CONFIG_ATM_FORE200E_PCA=y
+CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y
+CONFIG_ATM_FORE200E_SBA=y
+CONFIG_ATM_FORE200E_SBA_DEFAULT_FW=y
+CONFIG_ATM_FORE200E_TX_RETRY=16
+CONFIG_ATM_FORE200E_DEBUG=0
+CONFIG_ATM_FORE200E=m
+CONFIG_ATM_HE=m
+CONFIG_ATM_HE_USE_SUNI=y
+
+#
 # Amateur Radio support
 #
 CONFIG_HAMRADIO=y
@@ -759,9 +813,11 @@
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
 CONFIG_EXT3_FS=m
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1127,7 +1183,9 @@
 CONFIG_USB_RIO500=m
 # CONFIG_USB_BRLVGER is not set
 CONFIG_USB_LCD=m
+CONFIG_USB_SPEEDTOUCH=m
 CONFIG_USB_TEST=m
+# CONFIG_USB_GADGET is not set
 
 #
 # Bluetooth support
diff -urN linux-2.5.69-bk8/drivers/atm/he.c linux-2.5.69-bk9/drivers/atm/he.c
--- linux-2.5.69-bk8/drivers/atm/he.c	2003-05-14 04:43:38.000000000 -0700
+++ linux-2.5.69-bk9/drivers/atm/he.c	2003-05-14 04:43:42.000000000 -0700
@@ -128,7 +128,7 @@
 
 #include <linux/atm_he.h>
 
-#define hprintk(fmt,args...)	printk(KERN_ERR DEV_LABEL "%d: " fmt, he_dev->number, ##args)
+#define hprintk(fmt,args...)	printk(KERN_ERR DEV_LABEL "%d: " fmt, he_dev->number , ##args)
 
 #undef DEBUG
 #ifdef DEBUG
diff -urN linux-2.5.69-bk8/drivers/bluetooth/hci_ldisc.c linux-2.5.69-bk9/drivers/bluetooth/hci_ldisc.c
--- linux-2.5.69-bk8/drivers/bluetooth/hci_ldisc.c	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk9/drivers/bluetooth/hci_ldisc.c	2003-05-14 04:43:42.000000000 -0700
@@ -535,6 +535,7 @@
 	hci_uart_ldisc.receive_room= hci_uart_tty_room;
 	hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
 	hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
+	hci_uart_ldisc.owner       = THIS_MODULE;
 
 	if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
 		BT_ERR("HCI line discipline registration failed. (%d)", err);
diff -urN linux-2.5.69-bk8/drivers/char/agp/Makefile linux-2.5.69-bk9/drivers/char/agp/Makefile
--- linux-2.5.69-bk8/drivers/char/agp/Makefile	2003-05-14 04:43:38.000000000 -0700
+++ linux-2.5.69-bk9/drivers/char/agp/Makefile	2003-05-14 04:43:42.000000000 -0700
@@ -1,4 +1,4 @@
-agpgart-y := backend.o frontend.o generic.o generic-3.0.o
+agpgart-y := backend.o frontend.o generic.o isoch.o
 
 obj-$(CONFIG_AGP)		+= agpgart.o
 obj-$(CONFIG_AGP_ALI)		+= ali-agp.o
diff -urN linux-2.5.69-bk8/drivers/char/agp/agp.h linux-2.5.69-bk9/drivers/char/agp/agp.h
--- linux-2.5.69-bk8/drivers/char/agp/agp.h	2003-05-14 04:43:38.000000000 -0700
+++ linux-2.5.69-bk9/drivers/char/agp/agp.h	2003-05-14 04:43:42.000000000 -0700
@@ -139,6 +139,8 @@
 	int max_memory_agp;	/* in number of pages */
 	int aperture_size_idx;
 	int capndx;
+	char major_version;
+	char minor_version;
 };
 
 #define OUTREG64(mmap, addr, val)	__raw_writeq((val), (mmap)+(addr))
@@ -388,27 +390,38 @@
 int agp_num_entries(void);
 u32 agp_collect_device_status(u32 mode, u32 command);
 void agp_device_command(u32 command, int agp_v3);
-int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor);
+int agp_3_0_enable(struct agp_bridge_data *bridge, u32 mode);
+int agp_3_5_enable(struct agp_bridge_data *bridge, u32 mode);
 void global_cache_flush(void);
+void get_agp_version(struct agp_bridge_data *bridge);
 
 /* Standard agp registers */
 #define AGPSTAT			0x4
 #define AGPCMD			0x8
+#define AGPNISTAT		0xc
 #define AGPNEPG			0x16
+#define AGPNICMD		0x20
 
 #define AGP_MAJOR_VERSION_SHIFT	(20)
 #define AGP_MINOR_VERSION_SHIFT	(16)
 
 #define AGPSTAT_RQ_DEPTH	(0xff000000)
 
+#define AGPSTAT_CAL_MASK	(1<<12|1<<11|1<<10)
+#define AGPSTAT_ARQSZ		(1<<15|1<<14|1<<13)
 #define AGPSTAT_ARQSZ_SHIFT	13
 
-#define AGPSTAT_AGP_ENABLE	(1<<8)
 #define AGPSTAT_SBA		(1<<9)
+#define AGPSTAT_AGP_ENABLE	(1<<8)
+#define AGPSTAT_FW		(1<<4)
+#define AGPSTAT_MODE_3_0	(1<<3)
 
 #define AGPSTAT2_1X		(1<<0)
 #define AGPSTAT2_2X		(1<<1)
 #define AGPSTAT2_4X		(1<<2)
-#define AGPSTAT_FW		(1<<4)
+
+#define AGPSTAT3_RSVD		(1<<2)
+#define AGPSTAT3_8X		(1<<1)
+#define AGPSTAT3_4X		(1)
 
 #endif				/* _AGP_BACKEND_PRIV_H */
diff -urN linux-2.5.69-bk8/drivers/char/agp/amd-k8-agp.c linux-2.5.69-bk9/drivers/char/agp/amd-k8-agp.c
--- linux-2.5.69-bk8/drivers/char/agp/amd-k8-agp.c	2003-05-14 04:43:38.000000000 -0700
+++ linux-2.5.69-bk9/drivers/char/agp/amd-k8-agp.c	2003-05-14 04:43:42.000000000 -0700
@@ -253,8 +253,10 @@
 {
 	struct agp_bridge_data *bridge;
 	struct pci_dev *loop_dev;
+	u8 rev_id;
 	u8 cap_ptr;
 	int i = 0;
+	char *revstring="  ";
 
 	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 	if (!cap_ptr)
@@ -266,14 +268,38 @@
 	if (!bridge)
 		return -ENOMEM;
 
+	/* Assume here we have an 8151. (Later this assumption will be fixed). */
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
+	switch (rev_id) {
+		case 0x01:	revstring="A0";
+				break;
+		case 0x02:	revstring="A1";
+				break;
+		case 0x11:	revstring="B0";
+				break;
+		case 0x12:	revstring="B1";
+				break;
+		case 0x13:	revstring="B2";
+				break;
+		default:	revstring="??";
+				break;
+	}
+	printk ("Detected AMD 8151 AGP Bridge rev %s", revstring);
+	/*
+	 * Work around errata.
+	 * Chips before B2 stepping incorrectly reporting v3.5
+	 */
+	if (rev_id < 0x13) {
+		bridge->major_version = 3;
+		bridge->minor_version = 0;
+	}
+
 	bridge->driver = &amd_8151_driver;
 	bridge->dev = pdev;
 	bridge->capndx = cap_ptr;
 
 	/* Fill in the mode register */
-	pci_read_config_dword(pdev,
-			bridge->capndx+PCI_AGP_STATUS,
-			&bridge->mode);
+	pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
 
 	/* cache pci_devs of northbridges. */
 	pci_for_each_dev(loop_dev) {
@@ -290,7 +316,7 @@
 
 	pci_set_drvdata(pdev, bridge);
 	return agp_add_bridge(bridge);
- out_free:
+out_free:
 	agp_put_bridge(bridge);
 	return -ENOMEM;
 }
diff -urN linux-2.5.69-bk8/drivers/char/agp/generic-3.0.c linux-2.5.69-bk9/drivers/char/agp/generic-3.0.c
--- linux-2.5.69-bk8/drivers/char/agp/generic-3.0.c	2003-05-14 04:43:38.000000000 -0700
+++ linux-2.5.69-bk9/drivers/char/agp/generic-3.0.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,537 +0,0 @@
-/*
- * Generic routines for AGP 3.0 compliant bridges.
- */
-
-#include <linux/list.h>
-#include <linux/pci.h>
-#include <linux/agp_backend.h>
-#include <linux/module.h>
-
-#include "agp.h"
-
-/* Generic AGP 3.0 enabling routines */
-
-struct agp_3_0_dev {
-	struct list_head list;
-	u8 capndx;
-	u32 maxbw;
-	struct pci_dev *dev;
-};
-
-static void agp_3_0_dev_list_insert(struct list_head *head, struct list_head *new)
-{
-	struct agp_3_0_dev *cur, *n = list_entry(new, struct agp_3_0_dev, list);
-	struct list_head *pos;
-
-	list_for_each(pos, head) {
-		cur = list_entry(pos, struct agp_3_0_dev, list);
-		if(cur->maxbw > n->maxbw)
-			break;
-	}
-	list_add_tail(new, pos);
-}
-
-static void agp_3_0_dev_list_sort(struct agp_3_0_dev *list, unsigned int ndevs)
-{
-	struct agp_3_0_dev *cur;
-	struct pci_dev *dev;
-	struct list_head *pos, *tmp, *head = &list->list, *start = head->next;
-	u32 nistat;
-
-	INIT_LIST_HEAD(head);
-
-	for(pos = start; pos != head;) {
-		cur = list_entry(pos, struct agp_3_0_dev, list);
-		dev = cur->dev;
-
-		pci_read_config_dword(dev, cur->capndx + 0x0c, &nistat);
-		cur->maxbw = (nistat >> 16) & 0xff;
-
-		tmp = pos;
-		pos = pos->next;
-		agp_3_0_dev_list_insert(head, tmp);
-	}
-}
-
-/* 
- * Initialize all isochronous transfer parameters for an AGP 3.0 
- * node (i.e. a host bridge in combination with the adapters 
- * lying behind it...)
- */
-
-static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
-		struct agp_3_0_dev *dev_list, unsigned int ndevs)
-{
-	/*
-	 * Convenience structure to make the calculations clearer
-	 * here.  The field names come straight from the AGP 3.0 spec.
-	 */
-	struct isoch_data {
-		u32 maxbw;
-		u32 n;
-		u32 y;
-		u32 l;
-		u32 rq;
-		struct agp_3_0_dev *dev;
-	};
-
-	struct pci_dev *td = bridge->dev, *dev;
-	struct list_head *head = &dev_list->list, *pos;
-	struct agp_3_0_dev *cur;
-	struct isoch_data *master, target;
-	unsigned int cdev = 0;
-	u32 mnistat, tnistat, tstatus, mcmd;
-	u16 tnicmd, mnicmd;
-	u8 mcapndx;
-	u32 tot_bw = 0, tot_n = 0, tot_rq = 0, y_max, rq_isoch, rq_async;
-	u32 step, rem, rem_isoch, rem_async;
-	int ret = 0;
-
-	/*
-	 * We'll work with an array of isoch_data's (one for each
-	 * device in dev_list) throughout this function.
-	 */
-	if((master = kmalloc(ndevs * sizeof(*master), GFP_KERNEL)) == NULL) {
-		ret = -ENOMEM;
-		goto get_out;
-	}
-
-	/*
-	 * Sort the device list by maxbw.  We need to do this because the
-	 * spec suggests that the devices with the smallest requirements
-	 * have their resources allocated first, with all remaining resources
-	 * falling to the device with the largest requirement.
-	 *
-	 * We don't exactly do this, we divide target resources by ndevs
-	 * and split them amongst the AGP 3.0 devices.  The remainder of such
-	 * division operations are dropped on the last device, sort of like
-	 * the spec mentions it should be done.
-	 *
-	 * We can't do this sort when we initially construct the dev_list
-	 * because we don't know until this function whether isochronous
-	 * transfers are enabled and consequently whether maxbw will mean
-	 * anything.
-	 */
-	agp_3_0_dev_list_sort(dev_list, ndevs);
-
-	pci_read_config_dword(td, bridge->capndx + 0x0c, &tnistat);
-	pci_read_config_dword(td, bridge->capndx+AGPSTAT, &tstatus);
-
-	/* Extract power-on defaults from the target */
-	target.maxbw = (tnistat >> 16) & 0xff;
-	target.n     = (tnistat >> 8)  & 0xff;
-	target.y     = (tnistat >> 6)  & 0x3;
-	target.l     = (tnistat >> 3)  & 0x7;
-	target.rq    = (tstatus >> 24) & 0xff;
-
-	y_max = target.y;
-
-	/*
-	 * Extract power-on defaults for each device in dev_list.  Along
-	 * the way, calculate the total isochronous bandwidth required
-	 * by these devices and the largest requested payload size.
-	 */
-	list_for_each(pos, head) {
-		cur = list_entry(pos, struct agp_3_0_dev, list);
-		dev = cur->dev;
-
-		mcapndx = cur->capndx;
-
-		pci_read_config_dword(dev, cur->capndx + 0x0c, &mnistat);
-
-		master[cdev].maxbw = (mnistat >> 16) & 0xff;
-		master[cdev].n     = (mnistat >> 8)  & 0xff;
-		master[cdev].y     = (mnistat >> 6)  & 0x3;
-		master[cdev].dev   = cur;
-
-		tot_bw += master[cdev].maxbw;
-		y_max = max(y_max, master[cdev].y);
-
-		cdev++;
-	}
-
-	/* Check if this configuration has any chance of working */
-	if(tot_bw > target.maxbw) {
-		printk(KERN_ERR PFX "isochronous bandwidth required "
-			"by AGP 3.0 devices exceeds that which is supported by "
-			"the AGP 3.0 bridge!\n");
-		ret = -ENODEV;
-		goto free_and_exit;
-	}
-
-	target.y = y_max;
-
-	/*
-	 * Write the calculated payload size into the target's NICMD
-	 * register.  Doing this directly effects the ISOCH_N value
-	 * in the target's NISTAT register, so we need to do this now
-	 * to get an accurate value for ISOCH_N later.
-	 */
-	pci_read_config_word(td, bridge->capndx + 0x20, &tnicmd);
-	tnicmd &= ~(0x3 << 6);
-	tnicmd |= target.y << 6;
-	pci_write_config_word(td, bridge->capndx + 0x20, tnicmd);
-
-	/* Reread the target's ISOCH_N */
-	pci_read_config_dword(td, bridge->capndx + 0x0c, &tnistat);
-	target.n = (tnistat >> 8) & 0xff;
-
-	/* Calculate the minimum ISOCH_N needed by each master */
-	for(cdev = 0; cdev < ndevs; cdev++) {
-		master[cdev].y = target.y;
-		master[cdev].n = master[cdev].maxbw / (master[cdev].y + 1);
-
-		tot_n += master[cdev].n;
-	}
-
-	/* Exit if the minimal ISOCH_N allocation among the masters is more
-	 * than the target can handle. */
-	if(tot_n > target.n) {
-		printk(KERN_ERR PFX "number of isochronous "
-			"transactions per period required by AGP 3.0 devices "
-			"exceeds that which is supported by the AGP 3.0 "
-			"bridge!\n");
-		ret = -ENODEV;
-		goto free_and_exit;
-	}
-
-	/* Calculate left over ISOCH_N capability in the target.  We'll give
-	 * this to the hungriest device (as per the spec) */
-	rem  = target.n - tot_n;
-
-	/* 
-	 * Calculate the minimum isochronous RQ depth needed by each master.
-	 * Along the way, distribute the extra ISOCH_N capability calculated
-	 * above.
-	 */
-	for(cdev = 0; cdev < ndevs; cdev++) {
-		/*
-		 * This is a little subtle.  If ISOCH_Y > 64B, then ISOCH_Y
-		 * byte isochronous writes will be broken into 64B pieces.
-		 * This means we need to budget more RQ depth to account for
-		 * these kind of writes (each isochronous write is actually
-		 * many writes on the AGP bus).
-		 */
-		master[cdev].rq = master[cdev].n;
-		if(master[cdev].y > 0x1) {
-			master[cdev].rq *= (1 << (master[cdev].y - 1));
-		}
-
-		tot_rq += master[cdev].rq;
-
-		if(cdev == ndevs - 1)
-			master[cdev].n += rem;
-	}
-
-	/* Figure the number of isochronous and asynchronous RQ slots the
-	 * target is providing. */
-	rq_isoch = (target.y > 0x1) ? target.n * (1 << (target.y - 1)) : target.n;
-	rq_async = target.rq - rq_isoch;
-
-	/* Exit if the minimal RQ needs of the masters exceeds what the target
-	 * can provide. */
-	if(tot_rq > rq_isoch) {
-		printk(KERN_ERR PFX "number of request queue slots "
-			"required by the isochronous bandwidth requested by "
-			"AGP 3.0 devices exceeds the number provided by the "
-			"AGP 3.0 bridge!\n");
-		ret = -ENODEV;
-		goto free_and_exit;
-	}
-
-	/* Calculate asynchronous RQ capability in the target (per master) as
-	 * well as the total number of leftover isochronous RQ slots. */
-	step      = rq_async / ndevs;
-	rem_async = step + (rq_async % ndevs);
-	rem_isoch = rq_isoch - tot_rq;
-
-	/* Distribute the extra RQ slots calculated above and write our
-	 * isochronous settings out to the actual devices. */
-	for(cdev = 0; cdev < ndevs; cdev++) {
-		cur = master[cdev].dev;
-		dev = cur->dev;
-
-		mcapndx = cur->capndx;
-
-		master[cdev].rq += (cdev == ndevs - 1)
-		              ? (rem_async + rem_isoch) : step;
-
-		pci_read_config_word(dev, cur->capndx + 0x20, &mnicmd);
-		pci_read_config_dword(dev, cur->capndx+AGPCMD, &mcmd);
-
-		mnicmd &= ~(0xff << 8);
-		mnicmd &= ~(0x3  << 6);
-		mcmd   &= ~(0xff << 24);
-
-		mnicmd |= master[cdev].n  << 8;
-		mnicmd |= master[cdev].y  << 6;
-		mcmd   |= master[cdev].rq << 24;
-
-		pci_write_config_dword(dev, cur->capndx+AGPCMD, mcmd);
-		pci_write_config_word(dev, cur->capndx + 0x20, mnicmd);
-	}
-
-free_and_exit:
-	kfree(master);
-
-get_out:
-	return ret;
-}
-
-/*
- * This function basically allocates request queue slots among the
- * AGP 3.0 systems in nonisochronous nodes.  The algorithm is
- * pretty stupid, divide the total number of RQ slots provided by the
- * target by ndevs.  Distribute this many slots to each AGP 3.0 device,
- * giving any left over slots to the last device in dev_list.
- */
-static void agp_3_0_nonisochronous_node_enable(struct agp_bridge_data *bridge,
-		struct agp_3_0_dev *dev_list, unsigned int ndevs)
-{
-	struct agp_3_0_dev *cur;
-	struct list_head *head = &dev_list->list, *pos;
-	u32 tstatus, mcmd;
-	u32 trq, mrq, rem;
-	unsigned int cdev = 0;
-
-	pci_read_config_dword(bridge->dev, bridge->capndx + 0x04, &tstatus);
-
-	trq = (tstatus >> 24) & 0xff;
-	mrq = trq / ndevs;
-
-	rem = mrq + (trq % ndevs);
-
-	for(pos = head->next; cdev < ndevs; cdev++, pos = pos->next) {
-		cur = list_entry(pos, struct agp_3_0_dev, list);
-
-		pci_read_config_dword(cur->dev, cur->capndx+AGPCMD, &mcmd);
-		mcmd &= ~(0xff << 24);
-		mcmd |= ((cdev == ndevs - 1) ? rem : mrq) << 24;
-		pci_write_config_dword(cur->dev, cur->capndx+AGPCMD, mcmd);
-	}
-}
-
-/*
- * Fully configure and enable an AGP 3.0 host bridge and all the devices
- * lying behind it.
- */
-int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor)
-{
-	struct pci_dev *td = bridge->dev, *dev;
-	u8 mcapndx;
-	u32 isoch, arqsz, cal_cycle, tmp, rate;
-	u32 tstatus, tcmd, mcmd, mstatus, ncapid;
-	u32 mmajor, mminor;
-	u16 mpstat;
-	struct agp_3_0_dev *dev_list, *cur;
-	struct list_head *head, *pos;
-	unsigned int ndevs = 0;
-	int ret = 0;
-
-	/* 
-	 * Allocate a head for our AGP 3.0 device list (multiple AGP 3.0
-	 * devices are allowed behind a single bridge). 
-	 */
-	if((dev_list = kmalloc(sizeof(*dev_list), GFP_KERNEL)) == NULL) {
-		ret = -ENOMEM;
-		goto get_out;
-	}
-	head = &dev_list->list;
-	INIT_LIST_HEAD(head);
-
-	/* Find all AGP devices, and add them to dev_list. */
-	pci_for_each_dev(dev) { 
-		mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP);
-		switch ((dev->class >>8) & 0xff00) {
-			case 0x0600:    /* Bridge */
-				/* Skip bridges. We should call this function for each one. */
-				continue;
-
-			case 0x0001:    /* Unclassified device */
-				/* Don't know what this is, but log it for investigation. */
-				if (mcapndx != 0) {
-					printk (KERN_INFO PFX "Wacky, found unclassified AGP device. %x:%x\n",
-						dev->vendor, dev->device);
-				}
-				continue;
-
-			case 0x0300:    /* Display controller */
-			case 0x0400:    /* Multimedia controller */
-				if (mcapndx == 0)
-					continue;
-
-				if((cur = kmalloc(sizeof(*cur), GFP_KERNEL)) == NULL) {
-					ret = -ENOMEM;
-					goto free_and_exit;
-				}
-				cur->dev = dev;
-
-				pos = &cur->list;
-				list_add(pos, head);
-				ndevs++;
-				continue;
-
-			default:
-				continue;
-		}
-	}
-
-	/* Extract some power-on defaults from the target */
-	pci_read_config_dword(td, bridge->capndx + 0x04, &tstatus);
-	isoch     = (tstatus >> 17) & 0x1;
-	arqsz     = (tstatus >> 13) & 0x7;
-	cal_cycle = (tstatus >> 10) & 0x7;
-	rate      = tstatus & 0x7;
-
-	/*
-	 * Take an initial pass through the devices lying behind our host
-	 * bridge.  Make sure each one is actually an AGP 3.0 device, otherwise
-	 * exit with an error message.  Along the way store the AGP 3.0
-	 * cap_ptr for each device, the minimum supported cal_cycle, and the
-	 * minimum supported data rate.
-	 */
-	list_for_each(pos, head) {
-		cur = list_entry(pos, struct agp_3_0_dev, list);
-		dev = cur->dev;
-		
-		pci_read_config_word(dev, PCI_STATUS, &mpstat);
-		if((mpstat & PCI_STATUS_CAP_LIST) == 0)
-			continue;
-
-		pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &mcapndx);
-		if (mcapndx != 0x00) {
-			do {
-				pci_read_config_dword(dev, mcapndx, &ncapid);
-				if ((ncapid & 0xff) != 0x02)
-					mcapndx = (ncapid >> 8) & 0xff;
-			}
-			while (((ncapid & 0xff) != 0x02) && (mcapndx != 0x00));
-		}
-
-		if(mcapndx == 0) {
-			printk(KERN_ERR PFX "woah!  Non-AGP device "
-				"found on the secondary bus of an AGP 3.0 bridge!\n");
-			ret = -ENODEV;
-			goto free_and_exit;
-		}
-
-		mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
-		mminor = (ncapid >> AGP_MINOR_VERSION_SHIFT) & 0xf;
-
-		if(mmajor < 3) {
-			printk(KERN_ERR PFX "woah!  AGP 2.0 device "
-				"found on the secondary bus of an AGP 3.0 "
-				"bridge operating with AGP 3.0 electricals!\n");
-			ret = -ENODEV;
-			goto free_and_exit;
-		}
-
-		cur->capndx = mcapndx;
-
-		pci_read_config_dword(dev, cur->capndx + 0x04, &mstatus);
-
-		if(((mstatus >> 3) & 0x1) == 0) {
-			printk(KERN_ERR PFX "woah!  AGP 3.0 device "
-				"not operating in AGP 3.0 mode found on the "
-				"secondary bus of an AGP 3.0 bridge operating "
-				"with AGP 3.0 electricals!\n");
-			ret = -ENODEV;
-			goto free_and_exit;
-		}
-
-		tmp = (mstatus >> 10) & 0x7;
-		cal_cycle = min(cal_cycle, tmp);
-
-		/* figure the lesser rate */
-		tmp = mstatus & 0x7;
-		if(tmp < rate) 
-			rate = tmp;
-			
-	}		
-
-	/* Turn rate into something we can actually write out to AGPCMD */
-	switch(rate) {
-	case 0x1:
-	case 0x2:
-		break;
-	case 0x3:
-		rate = 0x2;
-		break;
-	default:
-		printk(KERN_ERR PFX "woah!  Bogus AGP rate (%d) "
-			"value found advertised behind an AGP 3.0 bridge!\n", rate);
-		ret = -ENODEV;
-		goto free_and_exit;
-	}
-
-	/*
-	 * Call functions to divide target resources amongst the AGP 3.0
-	 * masters.  This process is dramatically different depending on
-	 * whether isochronous transfers are supported.
-	 */
-	if (isoch) {
-		ret = agp_3_0_isochronous_node_enable(bridge, dev_list, ndevs);
-		if (ret) {
-			printk(KERN_INFO PFX "Something bad happened setting "
-			       "up isochronous xfers.  Falling back to "
-			       "non-isochronous xfer mode.\n");
-		}
-	}
-	agp_3_0_nonisochronous_node_enable(bridge, dev_list, ndevs);
-
-	/*
-	 * Set the calculated minimum supported cal_cycle and minimum
-	 * supported transfer rate in the target's AGPCMD register.
-	 * Also set the AGP_ENABLE bit, effectively 'turning on' the
-	 * target (this has to be done _before_ turning on the masters).
-	 */
-	pci_read_config_dword(td, bridge->capndx+AGPCMD, &tcmd);
-
-	tcmd &= ~(0x7 << 10);
-	tcmd &= ~0x7;
-
-	tcmd |= cal_cycle << 10;
-	tcmd |= 0x1 << 8;
-	tcmd |= rate;
-
-	pci_write_config_dword(td, bridge->capndx+AGPCMD, tcmd);
-
-	/*
-	 * Set the target's advertised arqsz value, the minimum supported
-	 * transfer rate, and the AGP_ENABLE bit in each master's AGPCMD
-	 * register.
-	 */
-	list_for_each(pos, head) {
-		cur = list_entry(pos, struct agp_3_0_dev, list);
-		dev = cur->dev;
-
-		mcapndx = cur->capndx;
-
-		pci_read_config_dword(dev, cur->capndx+AGPCMD, &mcmd);
-
-		mcmd &= ~(0x7 << AGPSTAT_ARQSZ_SHIFT);
-		mcmd &= ~0x7;
-
-		mcmd |= arqsz << 13;
-		mcmd |= AGPSTAT_AGP_ENABLE;
-		mcmd |= rate;
-
-		pci_write_config_dword(dev, cur->capndx+AGPCMD, mcmd);
-	}
-
-free_and_exit:
-	/* Be sure to free the dev_list */
-	for(pos = head->next; pos != head;) {
-		cur = list_entry(pos, struct agp_3_0_dev, list);
-
-		pos = pos->next;
-		kfree(cur);
-	}
-	kfree(dev_list);
-
-get_out:
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(agp_3_0_node_enable);
-
diff -urN linux-2.5.69-bk8/drivers/char/agp/generic.c linux-2.5.69-bk9/drivers/char/agp/generic.c
--- linux-2.5.69-bk8/drivers/char/agp/generic.c	2003-05-14 04:43:38.000000000 -0700
+++ linux-2.5.69-bk9/drivers/char/agp/generic.c	2003-05-14 04:43:42.000000000 -0700
@@ -270,14 +270,16 @@
 int agp_copy_info(agp_kern_info * info)
 {
 	memset(info, 0, sizeof(agp_kern_info));
-	if (agp_bridge->type == NOT_SUPPORTED) {
-		info->chipset = agp_bridge->type;
+	if (!agp_bridge || agp_bridge->type == NOT_SUPPORTED ||
+	    !agp_bridge->version) {
+		info->chipset = NOT_SUPPORTED;
 		return -EIO;
 	}
+
 	info->version.major = agp_bridge->version->major;
 	info->version.minor = agp_bridge->version->minor;
-	info->device = agp_bridge->dev;
 	info->chipset = agp_bridge->type;
+	info->device = agp_bridge->dev;
 	info->mode = agp_bridge->mode;
 	info->aper_base = agp_bridge->gart_bus_addr;
 	info->aper_size = agp_return_size();
@@ -366,60 +368,106 @@
 
 
 /* Generic Agp routines - Start */
+static void agp_v2_parse_one(u32 *mode, u32 *cmd, u32 *tmp)
+{
+	/* disable SBA if it's not supported */
+	if (!((*cmd & AGPSTAT_SBA) && (*tmp & AGPSTAT_SBA) && (*mode & AGPSTAT_SBA)))
+		*cmd &= ~AGPSTAT_SBA;
+
+	/* disable FW if it's not supported */
+	if (!((*cmd & AGPSTAT_FW) && (*tmp & AGPSTAT_FW) && (*mode & AGPSTAT_FW)))
+		*cmd &= ~AGPSTAT_FW;
+
+	/* Set speed */
+	if (!((*cmd & AGPSTAT2_4X) && (*tmp & AGPSTAT2_4X) && (*mode & AGPSTAT2_4X)))
+		*cmd &= ~AGPSTAT2_4X;
+
+	if (!((*cmd & AGPSTAT2_2X) && (*tmp & AGPSTAT2_2X) && (*mode & AGPSTAT2_2X)))
+		*cmd &= ~AGPSTAT2_2X;
+
+	if (!((*cmd & AGPSTAT2_1X) && (*tmp & AGPSTAT2_1X) && (*mode & AGPSTAT2_1X)))
+		*cmd &= ~AGPSTAT2_1X;
 
-u32 agp_collect_device_status(u32 mode, u32 command)
+	/* Now we know what mode it should be, clear out the unwanted bits. */
+	if (*cmd & AGPSTAT2_4X)
+		*cmd &= ~(AGPSTAT2_1X | AGPSTAT2_2X);	/* 4X */
+
+	if (*cmd & AGPSTAT2_2X)
+		*cmd &= ~(AGPSTAT2_1X | AGPSTAT2_4X);	/* 2X */
+
+	if (*cmd & AGPSTAT2_1X)
+		*cmd &= ~(AGPSTAT2_2X | AGPSTAT2_4X);	/* 1Xf */
+}
+
+
+static void agp_v3_parse_one(u32 *mode, u32 *cmd, u32 *tmp)
+{
+	/* ARQSZ - Set the value to the maximum one.
+	 * Don't allow the mode register to override values. */
+	*cmd = ((*cmd & ~AGPSTAT_ARQSZ) |
+		max_t(u32,(*cmd & AGPSTAT_ARQSZ),(*tmp & AGPSTAT_ARQSZ)));
+
+	/* Calibration cycle.
+	 * Don't allow the mode register to override values. */
+	*cmd = ((*cmd & ~AGPSTAT_CAL_MASK) |
+		min_t(u32,(*cmd & AGPSTAT_CAL_MASK),(*tmp & AGPSTAT_CAL_MASK)));
+
+	/* SBA *must* be supported for AGP v3 */
+	*cmd |= AGPSTAT_SBA;
+
+	/* disable FW if it's not supported */
+	if (!((*cmd & AGPSTAT_FW) && (*tmp & AGPSTAT_FW) && (*mode & AGPSTAT_FW)))
+		*cmd &= ~AGPSTAT_FW;
+
+	/* Set speed. */
+	if (!((*cmd & AGPSTAT3_8X) && (*tmp & AGPSTAT3_8X) && (*mode & AGPSTAT3_8X)))
+		*cmd &= ~AGPSTAT3_8X;
+
+	if (!((*cmd & AGPSTAT3_4X) && (*tmp & AGPSTAT3_4X) && (*mode & AGPSTAT3_4X)))
+		*cmd &= ~AGPSTAT3_4X;
+
+	/* Clear out unwanted bits. */
+	if (*cmd & AGPSTAT3_8X)
+		*cmd *= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
+	if (*cmd & AGPSTAT3_4X)
+		*cmd *= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
+}
+
+//FIXME: This doesn't smell right.
+//We need a function we pass an agp_device to.
+u32 agp_collect_device_status(u32 mode, u32 cmd)
 {
 	struct pci_dev *device;
-	u8 agp;
-	u32 scratch; 
+	u8 cap_ptr;
+	u32 tmp;
+	u32 agp3;
 
 	pci_for_each_dev(device) {
-		agp = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (!agp)
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (!cap_ptr)
 			continue;
 
 		/*
 		 * Ok, here we have a AGP device. Disable impossible 
 		 * settings, and adjust the readqueue to the minimum.
 		 */
-		pci_read_config_dword(device, agp + PCI_AGP_STATUS, &scratch);
+		pci_read_config_dword(device, cap_ptr+PCI_AGP_STATUS, &tmp);
 
 		/* adjust RQ depth */
-		command = ((command & ~AGPSTAT_RQ_DEPTH) |
+		cmd = ((cmd & ~AGPSTAT_RQ_DEPTH) |
 		     min_t(u32, (mode & AGPSTAT_RQ_DEPTH),
-			 min_t(u32, (command & AGPSTAT_RQ_DEPTH),
-			     (scratch & AGPSTAT_RQ_DEPTH))));
-
-		/* disable SBA if it's not supported */
-		if (!((command & AGPSTAT_SBA) && (scratch & AGPSTAT_SBA) && (mode & AGPSTAT_SBA)))
-			command &= ~AGPSTAT_SBA;
-
-		/* disable FW if it's not supported */
-		if (!((command & AGPSTAT_FW) && (scratch & AGPSTAT_FW) && (mode & AGPSTAT_FW)))
-			command &= ~AGPSTAT_FW;
-
-		/* Set speed */
-		if (!((command & AGPSTAT2_4X) && (scratch & AGPSTAT2_4X) && (mode & AGPSTAT2_4X)))
-			command &= ~AGPSTAT2_4X;
-
-		if (!((command & AGPSTAT2_2X) && (scratch & AGPSTAT2_2X) && (mode & AGPSTAT2_2X)))
-			command &= ~AGPSTAT2_2X;
+			 min_t(u32, (cmd & AGPSTAT_RQ_DEPTH), (tmp & AGPSTAT_RQ_DEPTH))));
+		
+		pci_read_config_dword(device, cap_ptr+AGPSTAT, &agp3);
 
-		if (!((command & AGPSTAT2_1X) && (scratch & AGPSTAT2_1X) && (mode & AGPSTAT2_1X)))
-			command &= ~AGPSTAT2_1X;
+		/* Check to see if we are operating in 3.0 mode */
+		if (agp3 & AGPSTAT_MODE_3_0) {
+			agp_v3_parse_one(&mode, &cmd, &tmp);
+		} else {
+			agp_v2_parse_one(&mode, &cmd, &tmp);
+		}
 	}
-
-	/* Now we know what mode it should be, clear out the unwanted bits. */
-	if (command & AGPSTAT2_4X)
-		command &= ~(AGPSTAT2_1X | AGPSTAT2_2X);	/* 4X */
-
-	if (command & AGPSTAT2_2X)
-		command &= ~(AGPSTAT2_1X | AGPSTAT2_4X);	/* 2X */
-
-	if (command & AGPSTAT2_1X)
-		command &= ~(AGPSTAT2_2X | AGPSTAT2_4X);	/* 1Xf */
-
-	return command;
+	return cmd;
 }
 EXPORT_SYMBOL(agp_collect_device_status);
 
@@ -446,29 +494,33 @@
 EXPORT_SYMBOL(agp_device_command);
 
 
-void agp_generic_enable(u32 mode)
+void get_agp_version(struct agp_bridge_data *bridge)
 {
-	u32 command, ncapid, major, minor;
+	u32 ncapid;
+
+	/* Exit early if already set by errata workarounds. */
+	if (agp_bridge->major_version != 0)
+		return;
 
 	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx, &ncapid);
-	major = (ncapid >> 20) & 0xf;
-	minor = (ncapid >> 16) & 0xf;
-	printk(KERN_INFO PFX "Found an AGP %d.%d compliant device.\n",major, minor);
+	agp_bridge->major_version = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
+	agp_bridge->minor_version = (ncapid >> AGP_MINOR_VERSION_SHIFT) & 0xf;
+}
+EXPORT_SYMBOL(get_agp_version);
 
-	if(major >= 3) {
-		u32 agp_3_0;
 
-		pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x4, &agp_3_0);
-		/* Check to see if we are operating in 3.0 mode */
-		if((agp_3_0 >> 3) & 0x1) {
-			agp_3_0_node_enable(agp_bridge, mode, minor);
-			return;
-		} else {
-			printk (KERN_INFO PFX "not in AGP 3.0 mode, falling back to 2.x\n");
-		}
-	}
+void agp_generic_enable(u32 mode)
+{
+	u32 command;
+	u32 agp3;
+
+	get_agp_version(agp_bridge);
+
+	printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n",
+				agp_bridge->major_version,
+				agp_bridge->minor_version,
+				agp_bridge->dev->slot_name);
 
-	/* AGP v<3 */
 	pci_read_config_dword(agp_bridge->dev,
 		      agp_bridge->capndx + PCI_AGP_STATUS, &command);
 
@@ -477,7 +529,27 @@
 
 	pci_write_config_dword(agp_bridge->dev,
 		       agp_bridge->capndx + PCI_AGP_COMMAND, command);
-	agp_device_command(command, 0);
+
+	/* Do AGP version specific frobbing. */
+	if(agp_bridge->major_version >= 3) {
+		pci_read_config_dword(agp_bridge->dev,
+			agp_bridge->capndx+AGPSTAT, &agp3);
+
+		/* Check to see if we are operating in 3.0 mode */
+		if (agp3 & AGPSTAT_MODE_3_0) {
+			/* If we have 3.5, we can do the isoch stuff. */
+			if (agp_bridge->minor_version >= 5)
+				agp_3_5_enable(agp_bridge, mode);
+			agp_device_command(command, TRUE);
+			return;
+		} else {
+			printk (KERN_INFO PFX "Device is in legacy mode,"
+				" falling back to 2.x\n");
+		}
+	}
+
+	/* AGP v<3 */
+	agp_device_command(command, FALSE);
 }
 EXPORT_SYMBOL(agp_generic_enable);
 
@@ -831,6 +903,7 @@
 }
 EXPORT_SYMBOL(agp_enable);
 
+
 #ifdef CONFIG_SMP
 static void ipi_handler(void *null)
 {
diff -urN linux-2.5.69-bk8/drivers/char/agp/intel-agp.c linux-2.5.69-bk9/drivers/char/agp/intel-agp.c
--- linux-2.5.69-bk8/drivers/char/agp/intel-agp.c	2003-05-14 04:43:38.000000000 -0700
+++ linux-2.5.69-bk9/drivers/char/agp/intel-agp.c	2003-05-14 04:43:42.000000000 -0700
@@ -1275,8 +1275,6 @@
 	u8 cap_ptr = 0;
 
 	cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
-	if (!cap_ptr)
-		return -ENODEV;
 
 	bridge = agp_alloc_bridge();
 	if (!bridge)
@@ -1417,9 +1415,11 @@
 	printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
 
 	/* Fill in the mode register */
-	pci_read_config_dword(pdev,
-			bridge->capndx+PCI_AGP_STATUS,
-			&bridge->mode);
+	if (cap_ptr) {
+		pci_read_config_dword(pdev,
+				bridge->capndx+PCI_AGP_STATUS,
+				&bridge->mode);
+	}
 
 	pci_set_drvdata(pdev, bridge);
 	return agp_add_bridge(bridge);
diff -urN linux-2.5.69-bk8/drivers/char/agp/isoch.c linux-2.5.69-bk9/drivers/char/agp/isoch.c
--- linux-2.5.69-bk8/drivers/char/agp/isoch.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk9/drivers/char/agp/isoch.c	2003-05-14 04:43:42.000000000 -0700
@@ -0,0 +1,468 @@
+/*
+ * Setup routines for AGP 3.5 compliant bridges.
+ */
+
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/agp_backend.h>
+#include <linux/module.h>
+
+#include "agp.h"
+
+/* Generic AGP 3.5 enabling routines */
+
+struct agp_3_5_dev {
+	struct list_head list;
+	u8 capndx;
+	u32 maxbw;
+	struct pci_dev *dev;
+};
+
+static void agp_3_5_dev_list_insert(struct list_head *head, struct list_head *new)
+{
+	struct agp_3_5_dev *cur, *n = list_entry(new, struct agp_3_5_dev, list);
+	struct list_head *pos;
+
+	list_for_each(pos, head) {
+		cur = list_entry(pos, struct agp_3_5_dev, list);
+		if(cur->maxbw > n->maxbw)
+			break;
+	}
+	list_add_tail(new, pos);
+}
+
+static void agp_3_5_dev_list_sort(struct agp_3_5_dev *list, unsigned int ndevs)
+{
+	struct agp_3_5_dev *cur;
+	struct pci_dev *dev;
+	struct list_head *pos, *tmp, *head = &list->list, *start = head->next;
+	u32 nistat;
+
+	INIT_LIST_HEAD(head);
+
+	for (pos=start; pos!=head; ) {
+		cur = list_entry(pos, struct agp_3_5_dev, list);
+		dev = cur->dev;
+
+		pci_read_config_dword(dev, cur->capndx+AGPNISTAT, &nistat);
+		cur->maxbw = (nistat >> 16) & 0xff;
+
+		tmp = pos;
+		pos = pos->next;
+		agp_3_5_dev_list_insert(head, tmp);
+	}
+}
+
+/* 
+ * Initialize all isochronous transfer parameters for an AGP 3.0 
+ * node (i.e. a host bridge in combination with the adapters 
+ * lying behind it...)
+ */
+
+static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge,
+		struct agp_3_5_dev *dev_list, unsigned int ndevs)
+{
+	/*
+	 * Convenience structure to make the calculations clearer
+	 * here.  The field names come straight from the AGP 3.0 spec.
+	 */
+	struct isoch_data {
+		u32 maxbw;
+		u32 n;
+		u32 y;
+		u32 l;
+		u32 rq;
+		struct agp_3_5_dev *dev;
+	};
+
+	struct pci_dev *td = bridge->dev, *dev;
+	struct list_head *head = &dev_list->list, *pos;
+	struct agp_3_5_dev *cur;
+	struct isoch_data *master, target;
+	unsigned int cdev = 0;
+	u32 mnistat, tnistat, tstatus, mcmd;
+	u16 tnicmd, mnicmd;
+	u8 mcapndx;
+	u32 tot_bw = 0, tot_n = 0, tot_rq = 0, y_max, rq_isoch, rq_async;
+	u32 step, rem, rem_isoch, rem_async;
+	int ret = 0;
+
+	/*
+	 * We'll work with an array of isoch_data's (one for each
+	 * device in dev_list) throughout this function.
+	 */
+	if ((master = kmalloc(ndevs * sizeof(*master), GFP_KERNEL)) == NULL) {
+		ret = -ENOMEM;
+		goto get_out;
+	}
+
+	/*
+	 * Sort the device list by maxbw.  We need to do this because the
+	 * spec suggests that the devices with the smallest requirements
+	 * have their resources allocated first, with all remaining resources
+	 * falling to the device with the largest requirement.
+	 *
+	 * We don't exactly do this, we divide target resources by ndevs
+	 * and split them amongst the AGP 3.0 devices.  The remainder of such
+	 * division operations are dropped on the last device, sort of like
+	 * the spec mentions it should be done.
+	 *
+	 * We can't do this sort when we initially construct the dev_list
+	 * because we don't know until this function whether isochronous
+	 * transfers are enabled and consequently whether maxbw will mean
+	 * anything.
+	 */
+	agp_3_5_dev_list_sort(dev_list, ndevs);
+
+	pci_read_config_dword(td, bridge->capndx+AGPNISTAT, &tnistat);
+	pci_read_config_dword(td, bridge->capndx+AGPSTAT, &tstatus);
+
+	/* Extract power-on defaults from the target */
+	target.maxbw = (tnistat >> 16) & 0xff;
+	target.n     = (tnistat >> 8)  & 0xff;
+	target.y     = (tnistat >> 6)  & 0x3;
+	target.l     = (tnistat >> 3)  & 0x7;
+	target.rq    = (tstatus >> 24) & 0xff;
+
+	y_max = target.y;
+
+	/*
+	 * Extract power-on defaults for each device in dev_list.  Along
+	 * the way, calculate the total isochronous bandwidth required
+	 * by these devices and the largest requested payload size.
+	 */
+	list_for_each(pos, head) {
+		cur = list_entry(pos, struct agp_3_5_dev, list);
+		dev = cur->dev;
+
+		mcapndx = cur->capndx;
+
+		pci_read_config_dword(dev, cur->capndx+AGPNISTAT, &mnistat);
+
+		master[cdev].maxbw = (mnistat >> 16) & 0xff;
+		master[cdev].n     = (mnistat >> 8)  & 0xff;
+		master[cdev].y     = (mnistat >> 6)  & 0x3;
+		master[cdev].dev   = cur;
+
+		tot_bw += master[cdev].maxbw;
+		y_max = max(y_max, master[cdev].y);
+
+		cdev++;
+	}
+
+	/* Check if this configuration has any chance of working */
+	if (tot_bw > target.maxbw) {
+		printk(KERN_ERR PFX "isochronous bandwidth required "
+			"by AGP 3.0 devices exceeds that which is supported by "
+			"the AGP 3.0 bridge!\n");
+		ret = -ENODEV;
+		goto free_and_exit;
+	}
+
+	target.y = y_max;
+
+	/*
+	 * Write the calculated payload size into the target's NICMD
+	 * register.  Doing this directly effects the ISOCH_N value
+	 * in the target's NISTAT register, so we need to do this now
+	 * to get an accurate value for ISOCH_N later.
+	 */
+	pci_read_config_word(td, bridge->capndx+AGPNICMD, &tnicmd);
+	tnicmd &= ~(0x3 << 6);
+	tnicmd |= target.y << 6;
+	pci_write_config_word(td, bridge->capndx+AGPNICMD, tnicmd);
+
+	/* Reread the target's ISOCH_N */
+	pci_read_config_dword(td, bridge->capndx+AGPNISTAT, &tnistat);
+	target.n = (tnistat >> 8) & 0xff;
+
+	/* Calculate the minimum ISOCH_N needed by each master */
+	for (cdev=0; cdev<ndevs; cdev++) {
+		master[cdev].y = target.y;
+		master[cdev].n = master[cdev].maxbw / (master[cdev].y + 1);
+
+		tot_n += master[cdev].n;
+	}
+
+	/* Exit if the minimal ISOCH_N allocation among the masters is more
+	 * than the target can handle. */
+	if (tot_n > target.n) {
+		printk(KERN_ERR PFX "number of isochronous "
+			"transactions per period required by AGP 3.0 devices "
+			"exceeds that which is supported by the AGP 3.0 "
+			"bridge!\n");
+		ret = -ENODEV;
+		goto free_and_exit;
+	}
+
+	/* Calculate left over ISOCH_N capability in the target.  We'll give
+	 * this to the hungriest device (as per the spec) */
+	rem  = target.n - tot_n;
+
+	/* 
+	 * Calculate the minimum isochronous RQ depth needed by each master.
+	 * Along the way, distribute the extra ISOCH_N capability calculated
+	 * above.
+	 */
+	for (cdev=0; cdev<ndevs; cdev++) {
+		/*
+		 * This is a little subtle.  If ISOCH_Y > 64B, then ISOCH_Y
+		 * byte isochronous writes will be broken into 64B pieces.
+		 * This means we need to budget more RQ depth to account for
+		 * these kind of writes (each isochronous write is actually
+		 * many writes on the AGP bus).
+		 */
+		master[cdev].rq = master[cdev].n;
+		if(master[cdev].y > 0x1)
+			master[cdev].rq *= (1 << (master[cdev].y - 1));
+
+		tot_rq += master[cdev].rq;
+
+		if (cdev == ndevs-1)
+			master[cdev].n += rem;
+	}
+
+	/* Figure the number of isochronous and asynchronous RQ slots the
+	 * target is providing. */
+	rq_isoch = (target.y > 0x1) ? target.n * (1 << (target.y - 1)) : target.n;
+	rq_async = target.rq - rq_isoch;
+
+	/* Exit if the minimal RQ needs of the masters exceeds what the target
+	 * can provide. */
+	if (tot_rq > rq_isoch) {
+		printk(KERN_ERR PFX "number of request queue slots "
+			"required by the isochronous bandwidth requested by "
+			"AGP 3.0 devices exceeds the number provided by the "
+			"AGP 3.0 bridge!\n");
+		ret = -ENODEV;
+		goto free_and_exit;
+	}
+
+	/* Calculate asynchronous RQ capability in the target (per master) as
+	 * well as the total number of leftover isochronous RQ slots. */
+	step      = rq_async / ndevs;
+	rem_async = step + (rq_async % ndevs);
+	rem_isoch = rq_isoch - tot_rq;
+
+	/* Distribute the extra RQ slots calculated above and write our
+	 * isochronous settings out to the actual devices. */
+	for (cdev=0; cdev<ndevs; cdev++) {
+		cur = master[cdev].dev;
+		dev = cur->dev;
+
+		mcapndx = cur->capndx;
+
+		master[cdev].rq += (cdev == ndevs - 1)
+		              ? (rem_async + rem_isoch) : step;
+
+		pci_read_config_word(dev, cur->capndx+AGPNICMD, &mnicmd);
+		pci_read_config_dword(dev, cur->capndx+AGPCMD, &mcmd);
+
+		mnicmd &= ~(0xff << 8);
+		mnicmd &= ~(0x3  << 6);
+		mcmd   &= ~(0xff << 24);
+
+		mnicmd |= master[cdev].n  << 8;
+		mnicmd |= master[cdev].y  << 6;
+		mcmd   |= master[cdev].rq << 24;
+
+		pci_write_config_dword(dev, cur->capndx+AGPCMD, mcmd);
+		pci_write_config_word(dev, cur->capndx+AGPNICMD, mnicmd);
+	}
+
+free_and_exit:
+	kfree(master);
+
+get_out:
+	return ret;
+}
+
+/*
+ * This function basically allocates request queue slots among the
+ * AGP 3.0 systems in nonisochronous nodes.  The algorithm is
+ * pretty stupid, divide the total number of RQ slots provided by the
+ * target by ndevs.  Distribute this many slots to each AGP 3.0 device,
+ * giving any left over slots to the last device in dev_list.
+ */
+static void agp_3_5_nonisochronous_node_enable(struct agp_bridge_data *bridge,
+		struct agp_3_5_dev *dev_list, unsigned int ndevs)
+{
+	struct agp_3_5_dev *cur;
+	struct list_head *head = &dev_list->list, *pos;
+	u32 tstatus, mcmd;
+	u32 trq, mrq, rem;
+	unsigned int cdev = 0;
+
+	pci_read_config_dword(bridge->dev, bridge->capndx+AGPSTAT, &tstatus);
+
+	trq = (tstatus >> 24) & 0xff;
+	mrq = trq / ndevs;
+
+	rem = mrq + (trq % ndevs);
+
+	for (pos=head->next; cdev<ndevs; cdev++, pos=pos->next) {
+		cur = list_entry(pos, struct agp_3_5_dev, list);
+
+		pci_read_config_dword(cur->dev, cur->capndx+AGPCMD, &mcmd);
+		mcmd &= ~(0xff << 24);
+		mcmd |= ((cdev == ndevs - 1) ? rem : mrq) << 24;
+		pci_write_config_dword(cur->dev, cur->capndx+AGPCMD, mcmd);
+	}
+}
+
+/*
+ * Fully configure and enable an AGP 3.0 host bridge and all the devices
+ * lying behind it.
+ */
+int agp_3_5_enable(struct agp_bridge_data *bridge, u32 mode)
+{
+	struct pci_dev *td = bridge->dev, *dev;
+	u8 mcapndx;
+	u32 isoch, arqsz;
+	u32 tstatus, mstatus, ncapid;
+	u32 mmajor;
+	u16 mpstat;
+	struct agp_3_5_dev *dev_list, *cur;
+	struct list_head *head, *pos;
+	unsigned int ndevs = 0;
+	int ret = 0;
+
+	/* Extract some power-on defaults from the target */
+	pci_read_config_dword(td, bridge->capndx+AGPSTAT, &tstatus);
+	isoch     = (tstatus >> 17) & 0x1;
+	if (isoch == 0)	/* isoch xfers not available, bail out. */
+		return -ENODEV;
+
+	arqsz     = (tstatus >> 13) & 0x7;
+
+	/* 
+	 * Allocate a head for our AGP 3.5 device list
+	 * (multiple AGP v3 devices are allowed behind a single bridge). 
+	 */
+	if ((dev_list = kmalloc(sizeof(*dev_list), GFP_KERNEL)) == NULL) {
+		ret = -ENOMEM;
+		goto get_out;
+	}
+	head = &dev_list->list;
+	INIT_LIST_HEAD(head);
+
+	/* Find all AGP devices, and add them to dev_list. */
+	pci_for_each_dev(dev) { 
+		mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP);
+		if (mcapndx == 0)
+			continue;
+
+		switch ((dev->class >>8) & 0xff00) {
+			case 0x0600:    /* Bridge */
+				/* Skip bridges. We should call this function for each one. */
+				continue;
+
+			case 0x0001:    /* Unclassified device */
+				/* Don't know what this is, but log it for investigation. */
+				if (mcapndx != 0) {
+					printk (KERN_INFO PFX "Wacky, found unclassified AGP device. %x:%x\n",
+						dev->vendor, dev->device);
+				}
+				continue;
+
+			case 0x0300:    /* Display controller */
+			case 0x0400:    /* Multimedia controller */
+				if((cur = kmalloc(sizeof(*cur), GFP_KERNEL)) == NULL) {
+					ret = -ENOMEM;
+					goto free_and_exit;
+				}
+				cur->dev = dev;
+
+				pos = &cur->list;
+				list_add(pos, head);
+				ndevs++;
+				continue;
+
+			default:
+				continue;
+		}
+	}
+
+	/*
+	 * Take an initial pass through the devices lying behind our host
+	 * bridge.  Make sure each one is actually an AGP 3.0 device, otherwise
+	 * exit with an error message.  Along the way store the AGP 3.0
+	 * cap_ptr for each device
+	 */
+	list_for_each(pos, head) {
+		cur = list_entry(pos, struct agp_3_5_dev, list);
+		dev = cur->dev;
+		
+		pci_read_config_word(dev, PCI_STATUS, &mpstat);
+		if ((mpstat & PCI_STATUS_CAP_LIST) == 0)
+			continue;
+
+		pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &mcapndx);
+		if (mcapndx != 0) {
+			do {
+				pci_read_config_dword(dev, mcapndx, &ncapid);
+				if ((ncapid & 0xff) != 2)
+					mcapndx = (ncapid >> 8) & 0xff;
+			}
+			while (((ncapid & 0xff) != 2) && (mcapndx != 0));
+		}
+
+		if (mcapndx == 0) {
+			printk(KERN_ERR PFX "woah!  Non-AGP device "
+				"found on the secondary bus of an AGP 3.5 bridge!\n");
+			ret = -ENODEV;
+			goto free_and_exit;
+		}
+
+		mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
+		if (mmajor < 3) {
+			printk(KERN_ERR PFX "woah!  AGP 2.0 device "
+				"found on the secondary bus of an AGP 3.5 "
+				"bridge operating with AGP 3.0 electricals!\n");
+			ret = -ENODEV;
+			goto free_and_exit;
+		}
+
+		cur->capndx = mcapndx;
+
+		pci_read_config_dword(dev, cur->capndx+AGPSTAT, &mstatus);
+
+		if (((mstatus >> 3) & 0x1) == 0) {
+			printk(KERN_ERR PFX "woah!  AGP 3.x device "
+				"not operating in AGP 3.x mode found on the "
+				"secondary bus of an AGP 3.5 bridge operating "
+				"with AGP 3.0 electricals!\n");
+			ret = -ENODEV;
+			goto free_and_exit;
+		}
+	}		
+
+	/*
+	 * Call functions to divide target resources amongst the AGP 3.0
+	 * masters.  This process is dramatically different depending on
+	 * whether isochronous transfers are supported.
+	 */
+	if (isoch) {
+		ret = agp_3_5_isochronous_node_enable(bridge, dev_list, ndevs);
+		if (ret) {
+			printk(KERN_INFO PFX "Something bad happened setting "
+			       "up isochronous xfers.  Falling back to "
+			       "non-isochronous xfer mode.\n");
+		}
+	}
+	agp_3_5_nonisochronous_node_enable(bridge, dev_list, ndevs);
+
+free_and_exit:
+	/* Be sure to free the dev_list */
+	for (pos=head->next; pos!=head; ) {
+		cur = list_entry(pos, struct agp_3_5_dev, list);
+
+		pos = pos->next;
+		kfree(cur);
+	}
+	kfree(dev_list);
+
+get_out:
+	return ret;
+}
+
diff -urN linux-2.5.69-bk8/drivers/char/drm/Kconfig linux-2.5.69-bk9/drivers/char/drm/Kconfig
--- linux-2.5.69-bk8/drivers/char/drm/Kconfig	2003-05-04 16:53:40.000000000 -0700
+++ linux-2.5.69-bk9/drivers/char/drm/Kconfig	2003-05-14 04:43:42.000000000 -0700
@@ -49,7 +49,7 @@
 
 config DRM_I810
 	tristate "Intel I810"
-	depends on DRM && AGP
+	depends on DRM && AGP && AGP_INTEL
 	help
 	  Choose this option if you have an Intel I810 graphics card.  If M is
 	  selected, the module will be called i810.  AGP support is required
@@ -57,7 +57,7 @@
 
 config DRM_I830
 	tristate "Intel 830M, 845G, 852GM, 855GM, 865G"
-	depends on DRM && AGP
+	depends on DRM && AGP && AGP_INTEL
 	help
 	  Choose this option if you have a system that has Intel 830M, 845G,
 	  852GM, 855GM or 865G integrated graphics.  If M is selected, the
diff -urN linux-2.5.69-bk8/drivers/char/vt_ioctl.c linux-2.5.69-bk9/drivers/char/vt_ioctl.c
--- linux-2.5.69-bk8/drivers/char/vt_ioctl.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk9/drivers/char/vt_ioctl.c	2003-05-14 04:43:43.000000000 -0700
@@ -869,13 +869,13 @@
 		if (clin > 32)
 			return -EINVAL;
 		    
-		if (vlin)
-			vc->vc_scan_lines = vlin;
-		if (clin)
-			vc->vc_font.height = clin;
-	
-		for (i = 0; i < MAX_NR_CONSOLES; i++)
+		for (i = 0; i < MAX_NR_CONSOLES; i++) {
+			if (vlin)
+				vc_cons[i].d->vc_scan_lines = vlin;
+			if (clin)
+				vc_cons[i].d->vc_font.height = clin;
 			vc_resize(i, cc, ll);
+		}
   		return 0;
 	}
 
diff -urN linux-2.5.69-bk8/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-2.5.69-bk9/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- linux-2.5.69-bk8/drivers/scsi/aic7xxx/aic7xxx_osm.c	2003-05-14 04:43:38.000000000 -0700
+++ linux-2.5.69-bk9/drivers/scsi/aic7xxx/aic7xxx_osm.c	2003-05-14 04:43:44.000000000 -0700
@@ -784,14 +784,18 @@
 static int	   ahc_linux_slave_alloc(Scsi_Device *);
 static int	   ahc_linux_slave_configure(Scsi_Device *);
 static void	   ahc_linux_slave_destroy(Scsi_Device *);
+#if defined(__i386__)
 static int	   ahc_linux_biosparam(struct scsi_device*,
 				       struct block_device*,
 				       sector_t, int[]);
+#endif
 #else
 static void	   ahc_linux_select_queue_depth(struct Scsi_Host *host,
 						Scsi_Device *scsi_devs);
+#if defined(__i386__)
 static int	   ahc_linux_biosparam(Disk *, kdev_t, int[]);
 #endif
+#endif
 static int	   ahc_linux_bus_reset(Scsi_Cmnd *);
 static int	   ahc_linux_dev_reset(Scsi_Cmnd *);
 static int	   ahc_linux_abort(Scsi_Cmnd *);
@@ -1194,6 +1198,7 @@
 /*
  * Return the disk geometry for the given SCSI device.
  */
+#if defined(__i386__)
 static int
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
@@ -1257,6 +1262,7 @@
 	geom[2] = cylinders;
 	return (0);
 }
+#endif
 
 /*
  * Abort the current SCSI command(s).
diff -urN linux-2.5.69-bk8/drivers/video/console/fbcon.c linux-2.5.69-bk9/drivers/video/console/fbcon.c
--- linux-2.5.69-bk8/drivers/video/console/fbcon.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk9/drivers/video/console/fbcon.c	2003-05-14 04:43:45.000000000 -0700
@@ -294,13 +294,16 @@
  *	Maps a virtual console @unit to a frame buffer device
  *	@newidx.
  */
-void set_con2fb_map(int unit, int newidx)
+int set_con2fb_map(int unit, int newidx)
 {
 	struct vc_data *vc = vc_cons[unit].d;
 
+	if (!vc)
+		return -ENODEV;
 	con2fb_map[unit] = newidx;
 	fbcon_is_default = (vc->vc_sw == &fb_con) ? 1 : 0;
 	take_over_console(&fb_con, unit, unit, fbcon_is_default);
+	return 0;
 }
 
 /*
@@ -1047,6 +1050,11 @@
 			cursor.set |= FB_CUR_SETSIZE;
 		}
 
+		if (info->cursor.hot.x || info->cursor.hot.y) {
+			cursor.hot.x = cursor.hot.y = 0;
+			cursor.set |= FB_CUR_SETHOT;
+		}
+
 		if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) {
 			char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
 			int cur_height, size, i = 0;
diff -urN linux-2.5.69-bk8/drivers/video/console/fbcon.h linux-2.5.69-bk9/drivers/video/console/fbcon.h
--- linux-2.5.69-bk8/drivers/video/console/fbcon.h	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk9/drivers/video/console/fbcon.h	2003-05-14 04:43:45.000000000 -0700
@@ -38,7 +38,7 @@
 
 /* drivers/video/console/fbcon.c */
 extern char con2fb_map[MAX_NR_CONSOLES];
-extern void set_con2fb_map(int unit, int newidx);
+extern int set_con2fb_map(int unit, int newidx);
 
     /*
      *  Attribute Decoding
diff -urN linux-2.5.69-bk8/drivers/video/riva/fbdev.c linux-2.5.69-bk9/drivers/video/riva/fbdev.c
--- linux-2.5.69-bk8/drivers/video/riva/fbdev.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk9/drivers/video/riva/fbdev.c	2003-05-14 04:43:45.000000000 -0700
@@ -1469,10 +1469,10 @@
 static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
 	struct riva_par *par = (struct riva_par *) info->par;
-	int i, j, d_idx = 0, s_idx = 0;
 	u8 data[MAX_CURS * MAX_CURS/8];
 	u8 mask[MAX_CURS * MAX_CURS/8];
 	u16 fg, bg;
+	int i;
 
 	par->riva.ShowHideCursor(&par->riva, 0);
 
diff -urN linux-2.5.69-bk8/drivers/video/vesafb.c linux-2.5.69-bk9/drivers/video/vesafb.c
--- linux-2.5.69-bk8/drivers/video/vesafb.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk9/drivers/video/vesafb.c	2003-05-14 04:43:45.000000000 -0700
@@ -215,7 +215,6 @@
 int __init vesafb_init(void)
 {
 	int video_cmap_len;
-	char *edid = 0;
 	int i;
 
 	if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
@@ -300,18 +299,10 @@
 		ypan = 0;
 	}
 
-#ifdef __i386__
-	edid = get_EDID_from_BIOS(0);
-	if (edid)
-		parse_edid(edid, &vesafb_defined);	
-	else		
-#endif
-	{	
-		/* some dummy values for timing to make fbset happy */
-		vesafb_defined.pixclock     = 10000000 / vesafb_defined.xres * 1000 / vesafb_defined.yres;
-		vesafb_defined.left_margin  = (vesafb_defined.xres / 8) & 0xf8;
-		vesafb_defined.hsync_len    = (vesafb_defined.xres / 8) & 0xf8;
-	}
+	/* some dummy values for timing to make fbset happy */
+	vesafb_defined.pixclock     = 10000000 / vesafb_defined.xres * 1000 / vesafb_defined.yres;
+	vesafb_defined.left_margin  = (vesafb_defined.xres / 8) & 0xf8;
+	vesafb_defined.hsync_len    = (vesafb_defined.xres / 8) & 0xf8;
 	
 	if (vesafb_defined.bits_per_pixel > 8) {
 		vesafb_defined.red.offset    = screen_info.red_pos;
diff -urN linux-2.5.69-bk8/fs/block_dev.c linux-2.5.69-bk9/fs/block_dev.c
--- linux-2.5.69-bk8/fs/block_dev.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk9/fs/block_dev.c	2003-05-14 04:43:45.000000000 -0700
@@ -681,18 +681,18 @@
 	return blkdev_put(inode->i_bdev, BDEV_FILE);
 }
 
-static ssize_t blkdev_file_write(struct file *file, const char *buf,
+static ssize_t blkdev_file_write(struct file *file, const char __user *buf,
 				   size_t count, loff_t *ppos)
 {
-	struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
+	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
 
 	return generic_file_write_nolock(file, &local_iov, 1, ppos);
 }
 
-static ssize_t blkdev_file_aio_write(struct kiocb *iocb, const char *buf,
+static ssize_t blkdev_file_aio_write(struct kiocb *iocb, const char __user *buf,
 				   size_t count, loff_t pos)
 {
-	struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
+	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
 
 	return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
 }
diff -urN linux-2.5.69-bk8/fs/fcntl.c linux-2.5.69-bk9/fs/fcntl.c
--- linux-2.5.69-bk8/fs/fcntl.c	2003-05-04 16:53:34.000000000 -0700
+++ linux-2.5.69-bk9/fs/fcntl.c	2003-05-14 04:43:45.000000000 -0700
@@ -305,11 +305,11 @@
 			err = setfl(fd, filp, arg);
 			break;
 		case F_GETLK:
-			err = fcntl_getlk(filp, (struct flock *) arg);
+			err = fcntl_getlk(filp, (struct flock __user *) arg);
 			break;
 		case F_SETLK:
 		case F_SETLKW:
-			err = fcntl_setlk(filp, cmd, (struct flock *) arg);
+			err = fcntl_setlk(filp, cmd, (struct flock __user *) arg);
 			break;
 		case F_GETOWN:
 			/*
@@ -393,11 +393,11 @@
 	
 	switch (cmd) {
 		case F_GETLK64:
-			err = fcntl_getlk64(filp, (struct flock64 *) arg);
+			err = fcntl_getlk64(filp, (struct flock64 __user *) arg);
 			break;
 		case F_SETLK64:
 		case F_SETLKW64:
-			err = fcntl_setlk64(filp, cmd, (struct flock64 *) arg);
+			err = fcntl_setlk64(filp, cmd, (struct flock64 __user *) arg);
 			break;
 		default:
 			err = do_fcntl(fd, cmd, arg, filp);
diff -urN linux-2.5.69-bk8/fs/filesystems.c linux-2.5.69-bk9/fs/filesystems.c
--- linux-2.5.69-bk8/fs/filesystems.c	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk9/fs/filesystems.c	2003-05-14 04:43:45.000000000 -0700
@@ -174,7 +174,7 @@
 		register_fs_subsys(*p);
 }
 
-static int fs_index(const char * __name)
+static int fs_index(const char __user * __name)
 {
 	struct file_system_type * tmp;
 	char * name;
@@ -198,7 +198,7 @@
 	return err;
 }
 
-static int fs_name(unsigned int index, char * buf)
+static int fs_name(unsigned int index, char __user * buf)
 {
 	struct file_system_type * tmp;
 	int len, res;
@@ -239,11 +239,11 @@
 
 	switch (option) {
 		case 1:
-			retval = fs_index((const char *) arg1);
+			retval = fs_index((const char __user *) arg1);
 			break;
 
 		case 2:
-			retval = fs_name(arg1, (char *) arg2);
+			retval = fs_name(arg1, (char __user *) arg2);
 			break;
 
 		case 3:
diff -urN linux-2.5.69-bk8/fs/ioctl.c linux-2.5.69-bk9/fs/ioctl.c
--- linux-2.5.69-bk8/fs/ioctl.c	2003-05-04 16:53:07.000000000 -0700
+++ linux-2.5.69-bk9/fs/ioctl.c	2003-05-14 04:43:45.000000000 -0700
@@ -75,7 +75,7 @@
 			break;
 
 		case FIONBIO:
-			if ((error = get_user(on, (int *)arg)) != 0)
+			if ((error = get_user(on, (int __user *)arg)) != 0)
 				break;
 			flag = O_NONBLOCK;
 #ifdef __sparc__
@@ -90,7 +90,7 @@
 			break;
 
 		case FIOASYNC:
-			if ((error = get_user(on, (int *)arg)) != 0)
+			if ((error = get_user(on, (int __user *)arg)) != 0)
 				break;
 			flag = on ? FASYNC : 0;
 
@@ -114,7 +114,7 @@
 			    S_ISREG(filp->f_dentry->d_inode->i_mode) ||
 			    S_ISLNK(filp->f_dentry->d_inode->i_mode)) {
 				loff_t res = inode_get_bytes(filp->f_dentry->d_inode);
-				error = copy_to_user((loff_t *)arg, &res, sizeof(res)) ? -EFAULT : 0;
+				error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0;
 			}
 			else
 				error = -ENOTTY;
diff -urN linux-2.5.69-bk8/fs/libfs.c linux-2.5.69-bk9/fs/libfs.c
--- linux-2.5.69-bk8/fs/libfs.c	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk9/fs/libfs.c	2003-05-14 04:43:45.000000000 -0700
@@ -157,7 +157,7 @@
 	return 0;
 }
 
-ssize_t generic_read_dir(struct file *filp, char *buf, size_t siz, loff_t *ppos)
+ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
 {
 	return -EISDIR;
 }
diff -urN linux-2.5.69-bk8/fs/locks.c linux-2.5.69-bk9/fs/locks.c
--- linux-2.5.69-bk8/fs/locks.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk9/fs/locks.c	2003-05-14 04:43:45.000000000 -0700
@@ -1342,7 +1342,7 @@
 /* Report the first existing lock that would conflict with l.
  * This implements the F_GETLK command of fcntl().
  */
-int fcntl_getlk(struct file *filp, struct flock *l)
+int fcntl_getlk(struct file *filp, struct flock __user *l)
 {
 	struct file_lock *fl, file_lock;
 	struct flock flock;
@@ -1404,7 +1404,7 @@
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
-int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l)
+int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock __user *l)
 {
 	struct file_lock *file_lock = locks_alloc_lock();
 	struct flock flock;
@@ -1492,7 +1492,7 @@
 /* Report the first existing lock that would conflict with l.
  * This implements the F_GETLK command of fcntl().
  */
-int fcntl_getlk64(struct file *filp, struct flock64 *l)
+int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
 {
 	struct file_lock *fl, file_lock;
 	struct flock64 flock;
@@ -1542,7 +1542,7 @@
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
-int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 *l)
+int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l)
 {
 	struct file_lock *file_lock = locks_alloc_lock();
 	struct flock64 flock;
diff -urN linux-2.5.69-bk8/fs/nfs/symlink.c linux-2.5.69-bk9/fs/nfs/symlink.c
--- linux-2.5.69-bk8/fs/nfs/symlink.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk9/fs/nfs/symlink.c	2003-05-14 04:43:45.000000000 -0700
@@ -75,7 +75,7 @@
 	return (char*)page;
 }
 
-static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
+static int nfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
 {
 	struct inode *inode = dentry->d_inode;
 	struct page *page = NULL;
diff -urN linux-2.5.69-bk8/fs/pipe.c linux-2.5.69-bk9/fs/pipe.c
--- linux-2.5.69-bk8/fs/pipe.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/fs/pipe.c	2003-05-14 04:43:45.000000000 -0700
@@ -44,7 +44,7 @@
 }
 
 static ssize_t
-pipe_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	int do_wakeup;
@@ -126,7 +126,7 @@
 }
 
 static ssize_t
-pipe_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+pipe_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	ssize_t ret;
@@ -216,13 +216,13 @@
 }
 
 static ssize_t
-bad_pipe_r(struct file *filp, char *buf, size_t count, loff_t *ppos)
+bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
 {
 	return -EBADF;
 }
 
 static ssize_t
-bad_pipe_w(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+bad_pipe_w(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
 {
 	return -EBADF;
 }
@@ -233,7 +233,7 @@
 {
 	switch (cmd) {
 		case FIONREAD:
-			return put_user(PIPE_LEN(*pino), (int *)arg);
+			return put_user(PIPE_LEN(*pino), (int __user *)arg);
 		default:
 			return -EINVAL;
 	}
diff -urN linux-2.5.69-bk8/include/linux/fs.h linux-2.5.69-bk9/include/linux/fs.h
--- linux-2.5.69-bk8/include/linux/fs.h	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/include/linux/fs.h	2003-05-14 04:43:45.000000000 -0700
@@ -521,12 +521,12 @@
 
 #include <linux/fcntl.h>
 
-extern int fcntl_getlk(struct file *, struct flock *);
-extern int fcntl_setlk(struct file *, unsigned int, struct flock *);
+extern int fcntl_getlk(struct file *, struct flock __user *);
+extern int fcntl_setlk(struct file *, unsigned int, struct flock __user *);
 
 #if BITS_PER_LONG == 32
-extern int fcntl_getlk64(struct file *, struct flock64 *);
-extern int fcntl_setlk64(struct file *, unsigned int, struct flock64 *);
+extern int fcntl_getlk64(struct file *, struct flock64 __user *);
+extern int fcntl_setlk64(struct file *, unsigned int, struct flock64 __user *);
 #endif
 
 /* fs/locks.c */
@@ -1263,8 +1263,8 @@
 
 extern int vfs_readdir(struct file *, filldir_t, void *);
 
-extern int vfs_stat(char *, struct kstat *);
-extern int vfs_lstat(char *, struct kstat *);
+extern int vfs_stat(char __user *, struct kstat *);
+extern int vfs_lstat(char __user *, struct kstat *);
 extern int vfs_fstat(unsigned int, struct kstat *);
 
 extern struct file_system_type *get_fs_type(const char *name);
@@ -1291,7 +1291,7 @@
 				unsigned offset, unsigned to);
 
 extern struct dentry *simple_lookup(struct inode *, struct dentry *);
-extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *);
+extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
 extern struct file_operations simple_dir_operations;
 extern struct inode_operations simple_dir_inode_operations;
 struct tree_descr { char *name; struct file_operations *ops; int mode; };
diff -urN linux-2.5.69-bk8/include/linux/netfilter_ipv4/compat_firewall.h linux-2.5.69-bk9/include/linux/netfilter_ipv4/compat_firewall.h
--- linux-2.5.69-bk8/include/linux/netfilter_ipv4/compat_firewall.h	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk9/include/linux/netfilter_ipv4/compat_firewall.h	2003-05-14 04:43:45.000000000 -0700
@@ -21,20 +21,20 @@
 {
 	struct firewall_ops *next;
 	int (*fw_forward)(struct firewall_ops *this, int pf,
-			  struct net_device *dev, void *phdr, void *arg,
+			  struct net_device *dev, void *arg,
 			  struct sk_buff **pskb);
 	int (*fw_input)(struct firewall_ops *this, int pf,
-			struct net_device *dev, void *phdr, void *arg,
+			struct net_device *dev, void *arg,
 			struct sk_buff **pskb);
 	int (*fw_output)(struct firewall_ops *this, int pf,
-			 struct net_device *dev, void *phdr, void *arg,
+			 struct net_device *dev, void *arg,
 			 struct sk_buff **pskb);
 	/* These may be NULL. */
 	int (*fw_acct_in)(struct firewall_ops *this, int pf,
-			  struct net_device *dev, void *phdr, void *arg,
+			  struct net_device *dev, void *arg,
 			  struct sk_buff **pskb);
 	int (*fw_acct_out)(struct firewall_ops *this, int pf,
-			   struct net_device *dev, void *phdr, void *arg,
+			   struct net_device *dev, void *arg,
 			   struct sk_buff **pskb);
 };
 
diff -urN linux-2.5.69-bk8/include/linux/netfilter_ipv4/ipfwadm_core.h linux-2.5.69-bk9/include/linux/netfilter_ipv4/ipfwadm_core.h
--- linux-2.5.69-bk8/include/linux/netfilter_ipv4/ipfwadm_core.h	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk9/include/linux/netfilter_ipv4/ipfwadm_core.h	2003-05-14 04:43:45.000000000 -0700
@@ -250,7 +250,7 @@
 
 extern int ip_fw_masq_timeouts(void *user, int len);
 
-extern int ip_fw_chk(struct iphdr *, struct net_device *, __u16 *,
+extern int ip_fw_chk(struct sk_buff **, struct net_device *, __u16 *,
 		     struct ip_fw *, int, int);
 #endif /* KERNEL */
 #endif /* _IP_FW_H */
diff -urN linux-2.5.69-bk8/include/linux/sunrpc/rpc_pipe_fs.h linux-2.5.69-bk9/include/linux/sunrpc/rpc_pipe_fs.h
--- linux-2.5.69-bk8/include/linux/sunrpc/rpc_pipe_fs.h	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk9/include/linux/sunrpc/rpc_pipe_fs.h	2003-05-14 04:43:45.000000000 -0700
@@ -12,8 +12,8 @@
 };
 
 struct rpc_pipe_ops {
-	ssize_t (*upcall)(struct file *, struct rpc_pipe_msg *, char *, size_t);
-	ssize_t (*downcall)(struct file *, const char *, size_t);
+	ssize_t (*upcall)(struct file *, struct rpc_pipe_msg *, char __user *, size_t);
+	ssize_t (*downcall)(struct file *, const char __user *, size_t);
 	void (*destroy_msg)(struct rpc_pipe_msg *);
 };
 
diff -urN linux-2.5.69-bk8/include/net/atmclip.h linux-2.5.69-bk9/include/net/atmclip.h
--- linux-2.5.69-bk8/include/net/atmclip.h	2003-05-04 16:53:40.000000000 -0700
+++ linux-2.5.69-bk9/include/net/atmclip.h	2003-05-14 04:43:45.000000000 -0700
@@ -55,13 +55,22 @@
 };
 
 
-extern struct atm_vcc *atmarpd; /* ugly */
-extern struct neigh_table clip_tbl;
+#ifdef __KERNEL__
+struct atm_clip_ops {
+	int (*clip_create)(int number);
+	int (*clip_mkip)(struct atm_vcc *vcc,int timeout);
+	int (*clip_setentry)(struct atm_vcc *vcc,u32 ip);
+	int (*clip_encap)(struct atm_vcc *vcc,int mode);
+	void (*clip_push)(struct atm_vcc *vcc,struct sk_buff *skb);
+	int (*atm_init_atmarp)(struct atm_vcc *vcc);
+	struct module *owner;
+};
+
+void atm_clip_ops_set(struct atm_clip_ops *);
+int try_atm_clip_ops(void);
 
-int clip_create(int number);
-int clip_mkip(struct atm_vcc *vcc,int timeout);
-int clip_setentry(struct atm_vcc *vcc,u32 ip);
-int clip_encap(struct atm_vcc *vcc,int mode);
-void atm_clip_init(void);
+extern struct neigh_table *clip_tbl_hook;
+extern struct atm_clip_ops *atm_clip_ops;
+#endif
 
 #endif
diff -urN linux-2.5.69-bk8/include/net/bluetooth/l2cap.h linux-2.5.69-bk9/include/net/bluetooth/l2cap.h
--- linux-2.5.69-bk8/include/net/bluetooth/l2cap.h	2003-05-04 16:53:03.000000000 -0700
+++ linux-2.5.69-bk9/include/net/bluetooth/l2cap.h	2003-05-14 04:43:45.000000000 -0700
@@ -231,8 +231,10 @@
 	struct sock 		*prev_c;
 };
 
-#define CONF_REQ_SENT    0x01
-#define CONF_INPUT_DONE  0x02
-#define CONF_OUTPUT_DONE 0x04
+#define L2CAP_CONF_REQ_SENT    0x01
+#define L2CAP_CONF_INPUT_DONE  0x02
+#define L2CAP_CONF_OUTPUT_DONE 0x04
+
+void l2cap_load(void);
 
 #endif /* __L2CAP_H */
diff -urN linux-2.5.69-bk8/include/net/bluetooth/rfcomm.h linux-2.5.69-bk9/include/net/bluetooth/rfcomm.h
--- linux-2.5.69-bk8/include/net/bluetooth/rfcomm.h	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk9/include/net/bluetooth/rfcomm.h	2003-05-14 04:43:45.000000000 -0700
@@ -185,10 +185,11 @@
 	atomic_t      refcnt;
 	u8            dlci;
 	u8            addr;
-
-	uint          mtu;
+	u8            priority;
 	u8            v24_sig;
+	u8            mscex;
 
+	uint          mtu;
 	uint          credits;
 	uint          rx_credits;
 	uint          tx_credits;
@@ -213,6 +214,11 @@
 #define RFCOMM_SCHED_TIMEO  3
 #define RFCOMM_SCHED_WAKEUP 31
 
+/* MSC exchange flags */
+#define RFCOMM_MSCEX_TX     1
+#define RFCOMM_MSCEX_RX     2
+#define RFCOMM_MSCEX_OK     (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
+
 extern struct task_struct *rfcomm_thread;
 extern unsigned long rfcomm_event;
 
diff -urN linux-2.5.69-bk8/include/net/sock.h linux-2.5.69-bk9/include/net/sock.h
--- linux-2.5.69-bk8/include/net/sock.h	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk9/include/net/sock.h	2003-05-14 04:43:45.000000000 -0700
@@ -405,12 +405,12 @@
 extern void			sock_rfree(struct sk_buff *skb);
 
 extern int			sock_setsockopt(struct socket *sock, int level,
-						int op, char *optval,
+						int op, char __user *optval,
 						int optlen);
 
 extern int			sock_getsockopt(struct socket *sock, int level,
-						int op, char *optval, 
-						int *optlen);
+						int op, char __user *optval, 
+						int __user *optlen);
 extern struct sk_buff 		*sock_alloc_send_skb(struct sock *sk,
 						     unsigned long size,
 						     int noblock,
diff -urN linux-2.5.69-bk8/include/sound/seq_kernel.h linux-2.5.69-bk9/include/sound/seq_kernel.h
--- linux-2.5.69-bk8/include/sound/seq_kernel.h	2003-05-04 16:53:42.000000000 -0700
+++ linux-2.5.69-bk9/include/sound/seq_kernel.h	2003-05-14 04:43:45.000000000 -0700
@@ -158,7 +158,7 @@
 extern int snd_seq_delete_kernel_client(int client);
 extern int snd_seq_kernel_client_enqueue(int client, snd_seq_event_t *ev, int atomic, int hop);
 extern int snd_seq_kernel_client_dispatch(int client, snd_seq_event_t *ev, int atomic, int hop);
-extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void *arg);
+extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void __user *arg);
 
 #define SNDRV_SEQ_EXT_MASK	0xc0000000
 #define SNDRV_SEQ_EXT_USRPTR	0x80000000
diff -urN linux-2.5.69-bk8/net/Kconfig linux-2.5.69-bk9/net/Kconfig
--- linux-2.5.69-bk8/net/Kconfig	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/Kconfig	2003-05-14 04:43:45.000000000 -0700
@@ -230,7 +230,7 @@
 	  further details.
 
 config ATM_CLIP
-	bool "Classical IP over ATM (EXPERIMENTAL)"
+	tristate "Classical IP over ATM (EXPERIMENTAL)"
 	depends on ATM && INET
 	help
 	  Classical IP over ATM for PVCs and SVCs, supporting InARP and
diff -urN linux-2.5.69-bk8/net/atm/Makefile linux-2.5.69-bk9/net/atm/Makefile
--- linux-2.5.69-bk8/net/atm/Makefile	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/atm/Makefile	2003-05-14 04:43:45.000000000 -0700
@@ -2,13 +2,15 @@
 # Makefile for the ATM Protocol Families.
 #
 
+atm-y		:= addr.o pvc.o signaling.o svc.o common.o atm_misc.o raw.o resources.o
 mpoa-objs	:= mpc.o mpoa_caches.o mpoa_proc.o
 
-obj-$(CONFIG_ATM) := addr.o pvc.o signaling.o svc.o common.o atm_misc.o raw.o resources.o
-
-obj-$(CONFIG_ATM_CLIP) += clip.o ipcommon.o
-obj-$(CONFIG_ATM_BR2684) += br2684.o ipcommon.o
-obj-$(CONFIG_NET_SCH_ATM) += ipcommon.o
+obj-$(CONFIG_ATM) += atm.o
+obj-$(CONFIG_ATM_CLIP) += clip.o
+atm-$(subst m,y,$(CONFIG_ATM_CLIP)) += ipcommon.o
+obj-$(CONFIG_ATM_BR2684) += br2684.o
+atm-$(subst m,y,$(CONFIG_ATM_BR2684)) += ipcommon.o
+atm-$(subst m,y,$CONFIG_NET_SCH_ATM)) += ipcommon.o
 obj-$(CONFIG_PROC_FS) += proc.o
 
 obj-$(CONFIG_ATM_LANE) += lec.o
diff -urN linux-2.5.69-bk8/net/atm/clip.c linux-2.5.69-bk9/net/atm/clip.c
--- linux-2.5.69-bk8/net/atm/clip.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/atm/clip.c	2003-05-14 04:43:45.000000000 -0700
@@ -7,6 +7,8 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h> /* for UINT_MAX */
+#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/wait.h>
@@ -45,6 +47,7 @@
 
 struct net_device *clip_devs = NULL;
 struct atm_vcc *atmarpd = NULL;
+static struct neigh_table clip_tbl;
 static struct timer_list idle_timer;
 static int start_timer = 1;
 
@@ -187,7 +190,7 @@
 }
 
 
-void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
+static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
 {
 	struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
 
@@ -325,7 +328,7 @@
 }
 
 
-struct neigh_table clip_tbl = {
+static struct neigh_table clip_tbl = {
 	NULL,			/* next */
 	AF_INET,		/* family */
 	sizeof(struct neighbour)+sizeof(struct atmarp_entry), /* entry_size */
@@ -371,7 +374,7 @@
  */
 
 
-int clip_encap(struct atm_vcc *vcc,int mode)
+static int clip_encap(struct atm_vcc *vcc,int mode)
 {
 	CLIP_VCC(vcc)->encap = mode;
 	return 0;
@@ -468,7 +471,7 @@
 }
 
 
-int clip_mkip(struct atm_vcc *vcc,int timeout)
+static int clip_mkip(struct atm_vcc *vcc,int timeout)
 {
 	struct clip_vcc *clip_vcc;
 	struct sk_buff_head copy;
@@ -508,7 +511,7 @@
 }
 
 
-int clip_setentry(struct atm_vcc *vcc,u32 ip)
+static int clip_setentry(struct atm_vcc *vcc,u32 ip)
 {
 	struct neighbour *neigh;
 	struct atmarp_entry *entry;
@@ -581,7 +584,7 @@
 }
 
 
-int clip_create(int number)
+static int clip_create(int number)
 {
 	struct net_device *dev;
 	struct clip_priv *clip_priv;
@@ -701,28 +704,23 @@
 		    "pending\n");
 	skb_queue_purge(&vcc->sk->receive_queue);
 	DPRINTK("(done)\n");
+	module_put(THIS_MODULE);
 }
 
 
 static struct atmdev_ops atmarpd_dev_ops = {
-	.close =atmarpd_close,
+	.close = atmarpd_close
 };
 
 
 static struct atm_dev atmarpd_dev = {
-	&atmarpd_dev_ops,
-	NULL,		/* no PHY */
-	"arpd",		/* type */
-	999,		/* dummy device number */
-	NULL,NULL,	/* pretend not to have any VCCs */
-	NULL,NULL,	/* no data */
-	0,		/* no flags */
-	NULL,		/* no local address */
-	{ 0 }		/* no ESI, no statistics */
+	.ops =			&atmarpd_dev_ops,
+	.type =			"arpd",
+	.number = 		999,
 };
 
 
-int atm_init_atmarp(struct atm_vcc *vcc)
+static int atm_init_atmarp(struct atm_vcc *vcc)
 {
 	struct net_device *dev;
 
@@ -752,10 +750,57 @@
 	return 0;
 }
 
+static struct atm_clip_ops __atm_clip_ops = {
+	.clip_create =		clip_create,
+	.clip_mkip =		clip_mkip,
+	.clip_setentry =	clip_setentry,
+	.clip_encap =		clip_encap,
+	.clip_push =		clip_push,
+	.atm_init_atmarp =	atm_init_atmarp,
+	.owner =		THIS_MODULE
+};
 
-void atm_clip_init(void)
+static int __init atm_clip_init(void)
 {
+	/* we should use neigh_table_init() */
 	clip_tbl.lock = RW_LOCK_UNLOCKED;
 	clip_tbl.kmem_cachep = kmem_cache_create(clip_tbl.id,
 	    clip_tbl.entry_size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+
+	/* so neigh_ifdown() doesn't complain */
+	clip_tbl.proxy_timer.data = 0;
+	clip_tbl.proxy_timer.function = 0;
+	init_timer(&clip_tbl.proxy_timer);
+	skb_queue_head_init(&clip_tbl.proxy_queue);
+
+	clip_tbl_hook = &clip_tbl;
+	atm_clip_ops_set(&__atm_clip_ops);
+
+	return 0;
+}
+
+static void __exit atm_clip_exit(void)
+{
+	struct net_device *dev, *next;
+
+	atm_clip_ops_set(NULL);
+
+	neigh_ifdown(&clip_tbl, NULL);
+	dev = clip_devs;
+	while (dev) {
+		next = PRIV(dev)->next;
+		unregister_netdev(dev);
+		kfree(dev);
+		dev = next;
+	}
+	if (start_timer == 0) del_timer(&idle_timer);
+
+	kmem_cache_destroy(clip_tbl.kmem_cachep);
+
+	clip_tbl_hook = NULL;
 }
+
+module_init(atm_clip_init);
+module_exit(atm_clip_exit);
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.5.69-bk8/net/atm/common.c linux-2.5.69-bk9/net/atm/common.c
--- linux-2.5.69-bk8/net/atm/common.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/atm/common.c	2003-05-14 04:43:45.000000000 -0700
@@ -57,6 +57,36 @@
 #endif
 #endif
 
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+#include <net/atmclip.h>
+struct atm_clip_ops *atm_clip_ops;
+static DECLARE_MUTEX(atm_clip_ops_mutex);
+
+void atm_clip_ops_set(struct atm_clip_ops *hook)
+{
+	down(&atm_clip_ops_mutex);
+	atm_clip_ops = hook;
+	up(&atm_clip_ops_mutex);
+}
+
+int try_atm_clip_ops(void)
+{
+	down(&atm_clip_ops_mutex);
+	if (atm_clip_ops && try_module_get(atm_clip_ops->owner)) {
+		up(&atm_clip_ops_mutex);
+		return 1;
+	}
+	up(&atm_clip_ops_mutex);
+	return 0;
+}
+
+#ifdef CONFIG_ATM_CLIP_MODULE
+EXPORT_SYMBOL(atm_clip_ops);
+EXPORT_SYMBOL(atm_clip_ops_mutex);
+EXPORT_SYMBOL(atm_clip_ops_set);
+#endif
+#endif
+
 #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
 int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
 EXPORT_SYMBOL(pppoatm_ioctl_hook);
@@ -623,39 +653,67 @@
 			if (!error) sock->state = SS_CONNECTED;
 			ret_val = error;
 			goto done;
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 		case SIOCMKCLIP:
-			if (!capable(CAP_NET_ADMIN))
+			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
-			else 
-				ret_val = clip_create(arg);
+				goto done;
+			}
+			if (try_atm_clip_ops()) {
+				ret_val = atm_clip_ops->clip_create(arg);
+				module_put(atm_clip_ops->owner);
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 		case ATMARPD_CTRL:
 			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
 				goto done;
 			}
-			error = atm_init_atmarp(vcc);
-			if (!error) sock->state = SS_CONNECTED;
-			ret_val = error;
+#if defined(CONFIG_ATM_CLIP_MODULE)
+			if (!atm_clip_ops)
+				request_module("clip");
+#endif
+			if (try_atm_clip_ops()) {
+				error = atm_clip_ops->atm_init_atmarp(vcc);
+				if (!error)
+					sock->state = SS_CONNECTED;
+				ret_val = error;
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 		case ATMARP_MKIP:
-			if (!capable(CAP_NET_ADMIN)) 
+			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
-			else 
-				ret_val = clip_mkip(vcc,arg);
+				goto done;
+			}
+			if (try_atm_clip_ops()) {
+				ret_val = atm_clip_ops->clip_mkip(vcc, arg);
+				module_put(atm_clip_ops->owner);
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 		case ATMARP_SETENTRY:
-			if (!capable(CAP_NET_ADMIN)) 
+			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
-			else
-				ret_val = clip_setentry(vcc,arg);
+				goto done;
+			}
+			if (try_atm_clip_ops()) {
+				ret_val = atm_clip_ops->clip_setentry(vcc, arg);
+				module_put(atm_clip_ops->owner);
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 		case ATMARP_ENCAP:
-			if (!capable(CAP_NET_ADMIN)) 
+			if (!capable(CAP_NET_ADMIN)) {
 				ret_val = -EPERM;
-			else
-				ret_val = clip_encap(vcc,arg);
+				goto done;
+			}
+			if (try_atm_clip_ops()) {
+				ret_val = atm_clip_ops->clip_encap(vcc, arg);
+				module_put(atm_clip_ops->owner);
+			} else
+				ret_val = -ENOSYS;
 			goto done;
 #endif
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
diff -urN linux-2.5.69-bk8/net/atm/ipcommon.c linux-2.5.69-bk9/net/atm/ipcommon.c
--- linux-2.5.69-bk8/net/atm/ipcommon.c	2003-05-04 16:53:12.000000000 -0700
+++ linux-2.5.69-bk9/net/atm/ipcommon.c	2003-05-14 04:43:45.000000000 -0700
@@ -67,4 +67,5 @@
 }
 
 
+EXPORT_SYMBOL(llc_oui);
 EXPORT_SYMBOL(skb_migrate);
diff -urN linux-2.5.69-bk8/net/atm/proc.c linux-2.5.69-bk9/net/atm/proc.c
--- linux-2.5.69-bk8/net/atm/proc.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/atm/proc.c	2003-05-14 04:43:45.000000000 -0700
@@ -39,10 +39,9 @@
 #include "common.h" /* atm_proc_init prototype */
 #include "signaling.h" /* to get sigd - ugly too */
 
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 #include <net/atmclip.h>
 #include "ipcommon.h"
-extern void clip_push(struct atm_vcc *vcc,struct sk_buff *skb);
 #endif
 
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
@@ -91,7 +90,7 @@
 }
 
 
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 
 
 static int svc_addr(char *buf,struct sockaddr_atmsvc *addr)
@@ -180,16 +179,21 @@
 	    aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr,
 	    class_name[vcc->qos.rxtp.traffic_class],vcc->qos.txtp.min_pcr,
 	    class_name[vcc->qos.txtp.traffic_class]);
-#ifdef CONFIG_ATM_CLIP
-	if (vcc->push == clip_push) {
-		struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
-		struct net_device *dev;
-
-		dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
-		off += sprintf(buf+off,"CLIP, Itf:%s, Encap:",
-		    dev ? dev->name : "none?");
-		if (clip_vcc->encap) off += sprintf(buf+off,"LLC/SNAP");
-		else off += sprintf(buf+off,"None");
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+	if (try_atm_clip_ops()) {
+		if (vcc->push == atm_clip_ops->clip_push) {
+			struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
+			struct net_device *dev;
+
+			dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
+			off += sprintf(buf+off,"CLIP, Itf:%s, Encap:",
+			    dev ? dev->name : "none?");
+			if (clip_vcc->encap)
+				off += sprintf(buf+off,"LLC/SNAP");
+			else
+				off += sprintf(buf+off,"None");
+		}
+		module_put(atm_clip_ops->owner);
 	}
 #endif
 	strcpy(buf+off,"\n");
@@ -409,7 +413,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 static int atm_arp_info(loff_t pos,char *buf)
 {
 	struct neighbour *n;
@@ -419,28 +423,33 @@
 		return sprintf(buf,"IPitf TypeEncp Idle IP address      "
 		    "ATM address\n");
 	}
+	if (!try_atm_clip_ops())
+		return 0;
 	count = pos;
-	read_lock_bh(&clip_tbl.lock);
+	read_lock_bh(&clip_tbl_hook->lock);
 	for (i = 0; i <= NEIGH_HASHMASK; i++)
-		for (n = clip_tbl.hash_buckets[i]; n; n = n->next) {
+		for (n = clip_tbl_hook->hash_buckets[i]; n; n = n->next) {
 			struct atmarp_entry *entry = NEIGH2ENTRY(n);
 			struct clip_vcc *vcc;
 
 			if (!entry->vccs) {
 				if (--count) continue;
 				atmarp_info(n->dev,entry,NULL,buf);
-				read_unlock_bh(&clip_tbl.lock);
+				read_unlock_bh(&clip_tbl_hook->lock);
+				module_put(atm_clip_ops->owner);
 				return strlen(buf);
 			}
 			for (vcc = entry->vccs; vcc;
 			    vcc = vcc->next) {
 				if (--count) continue;
 				atmarp_info(n->dev,entry,vcc,buf);
-				read_unlock_bh(&clip_tbl.lock);
+				read_unlock_bh(&clip_tbl_hook->lock);
+				module_put(atm_clip_ops->owner);
 				return strlen(buf);
 			}
 		}
-	read_unlock_bh(&clip_tbl.lock);
+	read_unlock_bh(&clip_tbl_hook->lock);
+	module_put(atm_clip_ops->owner);
 	return 0;
 }
 #endif
@@ -612,7 +621,7 @@
 	CREATE_ENTRY(pvc);
 	CREATE_ENTRY(svc);
 	CREATE_ENTRY(vc);
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 	CREATE_ENTRY(arp);
 #endif
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
diff -urN linux-2.5.69-bk8/net/atm/pvc.c linux-2.5.69-bk9/net/atm/pvc.c
--- linux-2.5.69-bk8/net/atm/pvc.c	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk9/net/atm/pvc.c	2003-05-14 04:43:45.000000000 -0700
@@ -7,16 +7,12 @@
 #include <linux/net.h>		/* struct socket, struct proto_ops */
 #include <linux/atm.h>		/* ATM stuff */
 #include <linux/atmdev.h>	/* ATM devices */
-#include <linux/atmclip.h>	/* Classical IP over ATM */
 #include <linux/errno.h>	/* error codes */
 #include <linux/kernel.h>	/* printk */
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
 #include <net/sock.h>		/* for sock_no_* */
-#ifdef CONFIG_ATM_CLIP
-#include <net/atmclip.h>
-#endif
 
 #include "resources.h"		/* devs and vccs */
 #include "common.h"		/* common for PVCs and SVCs */
@@ -129,9 +125,6 @@
 		printk(KERN_ERR "ATMPVC: can't register (%d)",error);
 		return error;
 	}
-#ifdef CONFIG_ATM_CLIP
-	atm_clip_init();
-#endif
 #ifdef CONFIG_PROC_FS
 	error = atm_proc_init();
 	if (error) printk("atm_proc_init fails with %d\n",error);
diff -urN linux-2.5.69-bk8/net/bluetooth/af_bluetooth.c linux-2.5.69-bk9/net/bluetooth/af_bluetooth.c
--- linux-2.5.69-bk8/net/bluetooth/af_bluetooth.c	2003-05-04 16:53:03.000000000 -0700
+++ linux-2.5.69-bk9/net/bluetooth/af_bluetooth.c	2003-05-14 04:43:45.000000000 -0700
@@ -92,6 +92,8 @@
 
 static int bt_sock_create(struct socket *sock, int proto)
 {
+	int err = 0;
+
 	if (proto >= BT_MAX_PROTO)
 		return -EINVAL;
 
@@ -102,11 +104,12 @@
 		request_module(module_name);
 	}
 #endif
-
-	if (!bt_proto[proto])
-		return -ENOENT;
-
-	return bt_proto[proto]->create(sock, proto);
+	err = -EPROTONOSUPPORT;
+	if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
+		err = bt_proto[proto]->create(sock, proto);
+		module_put(bt_proto[proto]->owner);
+	}
+	return err; 
 }
 
 struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio)
diff -urN linux-2.5.69-bk8/net/bluetooth/bnep/core.c linux-2.5.69-bk9/net/bluetooth/bnep/core.c
--- linux-2.5.69-bk8/net/bluetooth/bnep/core.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk9/net/bluetooth/bnep/core.c	2003-05-14 04:43:45.000000000 -0700
@@ -85,14 +85,17 @@
 
 static void __bnep_link_session(struct bnep_session *s)
 {
-	MOD_INC_USE_COUNT;
+	/* It's safe to call __module_get() here because sessions are added
+	   by the socket layer which has to hold the refference to this module.
+	 */
+	__module_get(THIS_MODULE);
 	list_add(&s->list, &bnep_session_list);	
 }
 
 static void __bnep_unlink_session(struct bnep_session *s)
 {
 	list_del(&s->list);
-	MOD_DEC_USE_COUNT;
+	module_put(THIS_MODULE);
 }
 
 static int bnep_send(struct bnep_session *s, void *data, size_t len)
@@ -677,7 +680,9 @@
 
 static int  __init bnep_init_module(void)
 {	
-	char flt[50] = "";	
+	char flt[50] = "";
+
+	l2cap_load();
 
 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
 	strcat(flt, "protocol ");
diff -urN linux-2.5.69-bk8/net/bluetooth/bnep/sock.c linux-2.5.69-bk9/net/bluetooth/bnep/sock.c
--- linux-2.5.69-bk8/net/bluetooth/bnep/sock.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk9/net/bluetooth/bnep/sock.c	2003-05-14 04:43:45.000000000 -0700
@@ -67,8 +67,6 @@
 
 	sock_orphan(sk);
 	sock_put(sk);
-
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -179,13 +177,10 @@
 		return -ENOMEM;
 	sock->ops = &bnep_sock_ops;
 
-	MOD_INC_USE_COUNT;
-
-	sock->state = SS_UNCONNECTED;
+	sock->state  = SS_UNCONNECTED;
 
 	sk->destruct = NULL;
 	sk->protocol = protocol;
-
 	return 0;
 }
 
diff -urN linux-2.5.69-bk8/net/bluetooth/l2cap.c linux-2.5.69-bk9/net/bluetooth/l2cap.c
--- linux-2.5.69-bk8/net/bluetooth/l2cap.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/bluetooth/l2cap.c	2003-05-14 04:43:45.000000000 -0700
@@ -145,8 +145,6 @@
 	conn->chan_list.lock = RW_LOCK_UNLOCKED;
 
 	BT_DBG("hcon %p conn %p", hcon, conn);
-
-	MOD_INC_USE_COUNT;
 	return conn;
 }
 
@@ -173,8 +171,6 @@
 
 	hcon->l2cap_data = NULL;
 	kfree(conn);
-
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -242,8 +238,6 @@
 
 	if (sk->protinfo)
 		kfree(sk->protinfo);
-	
-	MOD_DEC_USE_COUNT;
 }
 
 static void l2cap_sock_cleanup_listen(struct sock *parent)
@@ -356,6 +350,8 @@
 	if (!sk)
 		return NULL;
 
+	sk_set_owner(sk, THIS_MODULE);
+
 	sk->destruct = l2cap_sock_destruct;
 	sk->sndtimeo = L2CAP_CONN_TIMEOUT;
 
@@ -365,8 +361,6 @@
 	l2cap_sock_init_timer(sk);
 
 	bt_sock_link(&l2cap_sk_list, sk);
-
-	MOD_INC_USE_COUNT;
 	return sk;
 }
 
@@ -1319,15 +1313,18 @@
 {
 	struct l2cap_conf_rsp *rsp = data;
 	void *ptr = rsp->data;
+	u16 flags = 0;
 
 	BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
 
 	if (result)
 		*result = l2cap_conf_output(sk, &ptr);
+	else
+		flags = 0x0001;
 
 	rsp->scid   = __cpu_to_le16(l2cap_pi(sk)->dcid);
 	rsp->result = __cpu_to_le16(result ? *result : 0);
-	rsp->flags  = __cpu_to_le16(0);
+	rsp->flags  = __cpu_to_le16(flags);
 
 	return ptr - data;
 }
@@ -1440,7 +1437,7 @@
 	case L2CAP_CR_SUCCESS:
 		sk->state = BT_CONFIG;
 		l2cap_pi(sk)->dcid = dcid;
-		l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
+		l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
 
 		l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
 		break;
@@ -1475,7 +1472,7 @@
 
 	l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req));
 
-	if (flags & 0x01) {
+	if (flags & 0x0001) {
 		/* Incomplete config. Send empty response. */
 		l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
 		goto unlock;
@@ -1488,12 +1485,12 @@
 		goto unlock;
 
 	/* Output config done */
-	l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
+	l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
 
-	if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
+	if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
 		sk->state = BT_CONNECTED;
 		l2cap_chan_ready(sk);
-	} else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
+	} else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
 		u8 req[64];
 		l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
 	}
@@ -1538,9 +1535,9 @@
 		goto done;
 
 	/* Input config done */
-	l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
+	l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
 
-	if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
+	if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
 		sk->state = BT_CONNECTED;
 		l2cap_chan_ready(sk);
 	}
@@ -1943,21 +1940,27 @@
 		}
 
 		if (skb->len < 2) {
-			BT_ERR("Frame is too small (len %d)", skb->len);
+			BT_ERR("Frame is too short (len %d)", skb->len);
 			goto drop;
 		}
 
 		hdr = (struct l2cap_hdr *) skb->data;
 		len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
 
-		BT_DBG("Start: total len %d, frag len %d", len, skb->len);
-
 		if (len == skb->len) {
 			/* Complete frame received */
 			l2cap_recv_frame(conn, skb);
 			return 0;
 		}
 
+		BT_DBG("Start: total len %d, frag len %d", len, skb->len);
+
+		if (skb->len > len) {
+			BT_ERR("Frame is too long (len %d, expected len %d)",
+				skb->len, len);
+			goto drop;
+		}
+
 		/* Allocate skb for the complete frame (with header) */
 		if (!(conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC)))
 			goto drop;
@@ -1973,7 +1976,7 @@
 		}
 
 		if (skb->len > conn->rx_len) {
-			BT_ERR("Fragment is too large (len %d, expect %d)",
+			BT_ERR("Fragment is too long (len %d, expected %d)",
 					skb->len, conn->rx_len);
 			kfree_skb(conn->rx_skb);
 			conn->rx_skb = NULL;
@@ -2134,7 +2137,6 @@
 		return err;
 	}
 
-
 	l2cap_proc_init();
 	
 	BT_INFO("L2CAP ver %s", VERSION);
@@ -2155,6 +2157,15 @@
 		BT_ERR("L2CAP protocol unregistration failed");
 }
 
+void l2cap_load(void)
+{
+	/* Dummy function to trigger automatic L2CAP module loading by 
+	   other modules that use L2CAP sockets but don not use any other
+	   symbols from it. */
+	return;
+}
+EXPORT_SYMBOL(l2cap_load);
+
 module_init(l2cap_init);
 module_exit(l2cap_cleanup);
 
diff -urN linux-2.5.69-bk8/net/bluetooth/rfcomm/core.c linux-2.5.69-bk9/net/bluetooth/rfcomm/core.c
--- linux-2.5.69-bk8/net/bluetooth/rfcomm/core.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/bluetooth/rfcomm/core.c	2003-05-14 04:43:45.000000000 -0700
@@ -52,7 +52,7 @@
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/rfcomm.h>
 
-#define VERSION "0.3"
+#define VERSION "1.0"
 
 #ifndef CONFIG_BT_RFCOMM_DEBUG
 #undef  BT_DBG
@@ -203,6 +203,7 @@
 
 	d->state      = BT_OPEN;
 	d->flags      = 0;
+	d->mscex      = 0;
 	d->mtu        = RFCOMM_DEFAULT_MTU;
 	d->v24_sig    = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
 
@@ -304,10 +305,11 @@
 
 	rfcomm_dlc_clear_state(d);
 
-	d->dlci    = dlci;
-	d->addr    = __addr(s->initiator, dlci);
+	d->dlci     = dlci;
+	d->addr     = __addr(s->initiator, dlci);
+	d->priority = 7;
 
-	d->state   = BT_CONFIG;
+	d->state    = BT_CONFIG;
 	rfcomm_dlc_link(s, d);
 
 	d->mtu     = s->mtu;
@@ -481,9 +483,12 @@
 	list_add(&s->list, &session_list);
 
 	/* Do not increment module usage count for listeting sessions.
-	 * Otherwise we won't be able to unload the module. */
+	 * Otherwise we won't be able to unload the module.
+	 * Non listening session are added either by a socket or a TTYs
+	 * which means that we already hold refcount to this module.
+	 */
 	if (state != BT_LISTEN)
-		MOD_INC_USE_COUNT;
+		__module_get(THIS_MODULE);
 	return s;
 }
 
@@ -502,7 +507,7 @@
 	kfree(s);
 
 	if (state != BT_LISTEN)
-		MOD_DEC_USE_COUNT;
+		module_put(THIS_MODULE);
 }
 
 struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
@@ -741,7 +746,7 @@
 
 	pn = (void *) ptr; ptr += sizeof(*pn);
 	pn->dlci        = d->dlci;
-	pn->priority    = 0;
+	pn->priority    = d->priority;
 	pn->ack_timer   = 0;
 	pn->max_retrans = 0;
 
@@ -1099,8 +1104,6 @@
 			set_bit(RFCOMM_TX_THROTTLED, &d->flags);
 			d->credits = 0;
 		}
-
-		d->mtu = btohs(pn->mtu);
 	} else {
 		if (pn->flow_ctrl == 0xe0) {
 			d->tx_credits = pn->credits;
@@ -1108,10 +1111,12 @@
 			set_bit(RFCOMM_TX_THROTTLED, &d->flags);
 			d->credits = 0;
 		}
-
-		d->mtu = btohs(pn->mtu);
 	}
 
+	d->priority = pn->priority;
+
+	d->mtu = btohs(pn->mtu);
+
 	return 0;
 }
 
@@ -1137,7 +1142,7 @@
 			switch (d->state) {
 			case BT_CONFIG:
 				rfcomm_apply_pn(d, cr, pn);
-				
+
 				d->state = BT_CONNECT;
 				rfcomm_send_sabm(s, d->dlci);
 				break;
@@ -1148,7 +1153,7 @@
 
 		if (!cr)
 			return 0;
-		
+
 		/* PN request for non existing DLC.
 		 * Assume incoming connection. */
 		if (rfcomm_connect_ind(s, channel, &d)) {
@@ -1157,7 +1162,7 @@
 			rfcomm_dlc_link(s, d);
 
 			rfcomm_apply_pn(d, cr, pn);
-			
+
 			d->state = BT_OPEN;
 			rfcomm_send_pn(s, 0, d);
 		} else {
@@ -1229,21 +1234,21 @@
 	if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
 		if (rpn->flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
 			BT_DBG("RPN flow ctrl mismatch 0x%x", rpn->flow_ctrl);
-			rpn->flow_ctrl = RFCOMM_RPN_FLOW_NONE;
+			flow_ctrl = RFCOMM_RPN_FLOW_NONE;
 			rpn_mask ^= RFCOMM_RPN_PM_FLOW;
 		}
 	}
 	if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
 		if (rpn->xon_char != RFCOMM_RPN_XON_CHAR) {
 			BT_DBG("RPN XON char mismatch 0x%x", rpn->xon_char);
-			rpn->xon_char = RFCOMM_RPN_XON_CHAR;
+			xon_char = RFCOMM_RPN_XON_CHAR;
 			rpn_mask ^= RFCOMM_RPN_PM_XON;
 		}
 	}
 	if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
 		if (rpn->xoff_char != RFCOMM_RPN_XOFF_CHAR) {
 			BT_DBG("RPN XOFF char mismatch 0x%x", rpn->xoff_char);
-			rpn->xoff_char = RFCOMM_RPN_XOFF_CHAR;
+			xoff_char = RFCOMM_RPN_XOFF_CHAR;
 			rpn_mask ^= RFCOMM_RPN_PM_XOFF;
 		}
 	}
@@ -1284,11 +1289,11 @@
 
 	BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
 
-	if (!cr)
+	d = rfcomm_dlc_get(s, dlci);
+	if (!d) 
 		return 0;
 
-	d = rfcomm_dlc_get(s, dlci);
-	if (d) {
+	if (cr) {
 		if (msc->v24_sig & RFCOMM_V24_FC && !d->credits)
 			set_bit(RFCOMM_TX_THROTTLED, &d->flags);
 		else
@@ -1300,7 +1305,11 @@
 		rfcomm_dlc_unlock(d);
 		
 		rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
-	}
+
+		d->mscex |= RFCOMM_MSCEX_RX;
+	} else 
+		d->mscex |= RFCOMM_MSCEX_TX;
+
 	return 0;
 }
 
@@ -1524,7 +1533,8 @@
 			continue;
 		}
 
-		if (d->state == BT_CONNECTED || d->state == BT_DISCONN)
+		if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
+				d->mscex == RFCOMM_MSCEX_OK)
 			rfcomm_process_tx(d);
 	}
 }
@@ -1869,6 +1879,8 @@
 /* ---- Initialization ---- */
 int  __init rfcomm_init(void)
 {
+	l2cap_load();
+
 	kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 
 	BT_INFO("RFCOMM ver %s", VERSION);
diff -urN linux-2.5.69-bk8/net/bluetooth/rfcomm/sock.c linux-2.5.69-bk9/net/bluetooth/rfcomm/sock.c
--- linux-2.5.69-bk8/net/bluetooth/rfcomm/sock.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/bluetooth/rfcomm/sock.c	2003-05-14 04:43:45.000000000 -0700
@@ -182,8 +182,6 @@
 
 	if (sk->protinfo)
 		kfree(sk->protinfo);
-	
-	MOD_DEC_USE_COUNT;
 }
 
 static void rfcomm_sock_cleanup_listen(struct sock *parent)
@@ -265,6 +263,8 @@
 	if (!sk)
 		return NULL;
 
+	sk_set_owner(sk, THIS_MODULE);
+
 	d = rfcomm_dlc_alloc(prio);
 	if (!d) {
 		sk_free(sk);
@@ -288,8 +288,6 @@
 	bt_sock_link(&rfcomm_sk_list, sk);
 
 	BT_DBG("sk %p", sk);
-
-	MOD_INC_USE_COUNT;
 	return sk;
 }
 
diff -urN linux-2.5.69-bk8/net/bluetooth/rfcomm/tty.c linux-2.5.69-bk9/net/bluetooth/rfcomm/tty.c
--- linux-2.5.69-bk8/net/bluetooth/rfcomm/tty.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk9/net/bluetooth/rfcomm/tty.c	2003-05-14 04:43:45.000000000 -0700
@@ -99,7 +99,9 @@
 	rfcomm_dlc_put(dlc);
 	kfree(dev);
 
-	MOD_DEC_USE_COUNT;
+	/* It's safe to call module_put() here because socket still 
+	 holds refference to this module. */
+	module_put(THIS_MODULE);
 }
 
 static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
@@ -211,8 +213,9 @@
 	dev->dlc   = dlc;
 	rfcomm_dlc_unlock(dlc);
 
-	MOD_INC_USE_COUNT;
-	
+	/* It's safe to call __module_get() here because socket already 
+	 holds refference to this module. */
+	__module_get(THIS_MODULE);
 out:
 	write_unlock_bh(&rfcomm_dev_lock);
 
diff -urN linux-2.5.69-bk8/net/bluetooth/sco.c linux-2.5.69-bk9/net/bluetooth/sco.c
--- linux-2.5.69-bk8/net/bluetooth/sco.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/bluetooth/sco.c	2003-05-14 04:43:45.000000000 -0700
@@ -145,8 +145,6 @@
 		conn->mtu = 60;
 
 	BT_DBG("hcon %p conn %p", hcon, conn);
-
-	MOD_INC_USE_COUNT;
 	return conn;
 }
 
@@ -180,8 +178,6 @@
 
 	hcon->sco_data = NULL;
 	kfree(conn);
-
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -347,8 +343,6 @@
 
 	if (sk->protinfo)
 		kfree(sk->protinfo);
-	
-	MOD_DEC_USE_COUNT;
 }
 
 static void sco_sock_cleanup_listen(struct sock *parent)
@@ -434,6 +428,8 @@
 	if (!sk)
 		return NULL;
 
+	sk_set_owner(sk, THIS_MODULE);
+
 	sk->destruct = sco_sock_destruct;
 	sk->sndtimeo = SCO_CONN_TIMEOUT;
 	sk->state    = BT_OPEN;
@@ -441,8 +437,6 @@
 	sco_sock_init_timer(sk);
 
 	bt_sock_link(&sco_sk_list, sk);
-
-	MOD_INC_USE_COUNT;
 	return sk;
 }
 
diff -urN linux-2.5.69-bk8/net/core/dev.c linux-2.5.69-bk9/net/core/dev.c
--- linux-2.5.69-bk8/net/core/dev.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/core/dev.c	2003-05-14 04:43:45.000000000 -0700
@@ -1482,15 +1482,29 @@
 
 #endif
 
-#ifdef CONFIG_NET_DIVERT
-static inline int handle_diverter(struct sk_buff *skb)
+static inline void handle_diverter(struct sk_buff *skb)
 {
+#ifdef CONFIG_NET_DIVERT
 	/* if diversion is supported on device, then divert */
 	if (skb->dev->divert && skb->dev->divert->divert)
 		divert_frame(skb);
+#endif
+}
+
+static inline int __handle_bridge(struct sk_buff *skb,
+			struct packet_type **pt_prev, int *ret)
+{
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+	if (skb->dev->br_port) {
+		*ret = handle_bridge(skb, *pt_prev);
+		if (br_handle_frame_hook(skb) == 0)
+			return 1;
+
+		*pt_prev = NULL;
+	}
+#endif
 	return 0;
 }
-#endif   /* CONFIG_NET_DIVERT */
 
 int netif_receive_skb(struct sk_buff *skb)
 {
@@ -1532,20 +1546,10 @@
 		}
 	}
 
-#ifdef CONFIG_NET_DIVERT
-	if (skb->dev->divert && skb->dev->divert->divert)
-		ret = handle_diverter(skb);
-#endif /* CONFIG_NET_DIVERT */
-
-#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-	if (skb->dev->br_port) {
-		ret = handle_bridge(skb, pt_prev);
-		if (br_handle_frame_hook(skb) == 0) 
-			goto out;
+	handle_diverter(skb);
 
-		pt_prev = NULL;
-	}
-#endif
+	if (__handle_bridge(skb, &pt_prev, &ret))
+		goto out;
 
 	list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
 		if (ptype->type == type &&
@@ -1578,7 +1582,7 @@
 		ret = NET_RX_DROP;
 	}
 
- out:
+out:
 	rcu_read_unlock();
 	return ret;
 }
diff -urN linux-2.5.69-bk8/net/core/sock.c linux-2.5.69-bk9/net/core/sock.c
--- linux-2.5.69-bk8/net/core/sock.c	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk9/net/core/sock.c	2003-05-14 04:43:45.000000000 -0700
@@ -134,7 +134,7 @@
 /* Maximal space eaten by iovec or ancilliary data plus some space */
 int sysctl_optmem_max = sizeof(unsigned long)*(2*UIO_MAXIOV + 512);
 
-static int sock_set_timeout(long *timeo_p, char *optval, int optlen)
+static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
 {
 	struct timeval tv;
 
@@ -163,7 +163,7 @@
  */
 
 int sock_setsockopt(struct socket *sock, int level, int optname,
-		    char *optval, int optlen)
+		    char __user *optval, int optlen)
 {
 	struct sock *sk=sock->sk;
 	struct sk_filter *filter;
@@ -188,7 +188,7 @@
   	if(optlen<sizeof(int))
   		return(-EINVAL);
   	
-	if (get_user(val, (int *)optval))
+	if (get_user(val, (int __user *)optval))
 		return -EFAULT;
 	
   	valbool = val?1:0;
@@ -415,7 +415,7 @@
 
 
 int sock_getsockopt(struct socket *sock, int level, int optname,
-		    char *optval, int *optlen)
+		    char __user *optval, int __user *optlen)
 {
 	struct sock *sk = sock->sk;
 	
@@ -548,7 +548,7 @@
 				return -ENOTCONN;
 			if (lv < len)
 				return -EINVAL;
-			if(copy_to_user((void*)optval, address, len))
+			if (copy_to_user(optval, address, len))
 				return -EFAULT;
 			goto lenout;
 		}
@@ -996,7 +996,8 @@
 	msg.msg_controllen = 0;
 	msg.msg_flags = flags;
 
-	iov.iov_base = kaddr + offset;
+	/* This cast is ok because of the "set_fs(KERNEL_DS)" */
+	iov.iov_base = (void __user *) (kaddr + offset);
 	iov.iov_len = size;
 
 	old_fs = get_fs();
diff -urN linux-2.5.69-bk8/net/ipv4/arp.c linux-2.5.69-bk9/net/ipv4/arp.c
--- linux-2.5.69-bk8/net/ipv4/arp.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv4/arp.c	2003-05-14 04:43:45.000000000 -0700
@@ -108,8 +108,9 @@
 #include <net/netrom.h>
 #endif
 #endif
-#ifdef CONFIG_ATM_CLIP
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 #include <net/atmclip.h>
+struct neigh_table *clip_tbl_hook;
 #endif
 
 #include <asm/system.h>
@@ -443,8 +444,8 @@
 		if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT))
 			nexthop = 0;
 		n = __neigh_lookup_errno(
-#ifdef CONFIG_ATM_CLIP
-		    dev->type == ARPHRD_ATM ? &clip_tbl :
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+		    dev->type == ARPHRD_ATM ? clip_tbl_hook :
 #endif
 		    &arp_tbl, &nexthop, dev);
 		if (IS_ERR(n))
diff -urN linux-2.5.69-bk8/net/ipv4/netfilter/ip_fw_compat.c linux-2.5.69-bk9/net/ipv4/netfilter/ip_fw_compat.c
--- linux-2.5.69-bk8/net/ipv4/netfilter/ip_fw_compat.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv4/netfilter/ip_fw_compat.c	2003-05-14 04:43:45.000000000 -0700
@@ -51,31 +51,17 @@
 	int ret = FW_BLOCK;
 	u_int16_t redirpt;
 
-	/* FIXME: Push down to extensions --RR */
-	if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
-		return NF_DROP;
-
 	/* Assume worse case: any hook could change packet */
 	(*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
 	if ((*pskb)->ip_summed == CHECKSUM_HW)
 		(*pskb)->ip_summed = CHECKSUM_NONE;
 
-	/* Firewall rules can alter TOS: raw socket (tcpdump) may have
-           clone of incoming skb: don't disturb it --RR */
-	if (skb_cloned(*pskb) && !(*pskb)->sk) {
-		struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
-		if (!nskb)
-			return NF_DROP;
-		kfree_skb(*pskb);
-		*pskb = nskb;
-	}
-
 	switch (hooknum) {
 	case NF_IP_PRE_ROUTING:
 		if (fwops->fw_acct_in)
 			fwops->fw_acct_in(fwops, PF_INET,
 					  (struct net_device *)in,
-					  (*pskb)->nh.raw, &redirpt, pskb);
+					  &redirpt, pskb);
 
 		if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
 			*pskb = ip_ct_gather_frags(*pskb);
@@ -85,7 +71,7 @@
 		}
 
 		ret = fwops->fw_input(fwops, PF_INET, (struct net_device *)in,
-				      (*pskb)->nh.raw, &redirpt, pskb);
+				      &redirpt, pskb);
 		break;
 
 	case NF_IP_FORWARD:
@@ -95,18 +81,18 @@
 			ret = FW_ACCEPT;
 		else ret = fwops->fw_forward(fwops, PF_INET,
 					     (struct net_device *)out,
-					     (*pskb)->nh.raw, &redirpt, pskb);
+					     &redirpt, pskb);
 		break;
 
 	case NF_IP_POST_ROUTING:
 		ret = fwops->fw_output(fwops, PF_INET,
 				       (struct net_device *)out,
-				       (*pskb)->nh.raw, &redirpt, pskb);
+				       &redirpt, pskb);
 		if (ret == FW_ACCEPT || ret == FW_SKIP) {
 			if (fwops->fw_acct_out)
 				fwops->fw_acct_out(fwops, PF_INET,
 						   (struct net_device *)out,
-						   (*pskb)->nh.raw, &redirpt,
+						   &redirpt,
 						   pskb);
 
 			/* ip_conntrack_confirm return NF_DROP or NF_ACCEPT */
@@ -169,10 +155,6 @@
 			       const struct net_device *out,
 			       int (*okfn)(struct sk_buff *))
 {
-	/* FIXME: Push down to extensions --RR */
-	if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
-		return NF_DROP;
-
 	return ip_conntrack_confirm(*pskb);
 }
 
diff -urN linux-2.5.69-bk8/net/ipv4/netfilter/ipchains_core.c linux-2.5.69-bk9/net/ipv4/netfilter/ipchains_core.c
--- linux-2.5.69-bk8/net/ipv4/netfilter/ipchains_core.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv4/netfilter/ipchains_core.c	2003-05-14 04:43:45.000000000 -0700
@@ -94,6 +94,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4/compat_firewall.h>
 #include <linux/netfilter_ipv4/ipchains_core.h>
+#include <linux/netfilter_ipv4/ip_nat_core.h>
 
 #include <net/checksum.h>
 #include <linux/proc_fs.h>
@@ -280,11 +281,13 @@
 /* Returns whether matches rule or not. */
 static int ip_rule_match(struct ip_fwkernel *f,
 			 const char *ifname,
-			 struct iphdr *ip,
+			 struct sk_buff **pskb,
 			 char tcpsyn,
 			 __u16 src_port, __u16 dst_port,
 			 char isfrag)
 {
+	struct iphdr *ip = (*pskb)->nh.iph;
+
 #define FWINV(bool,invflg) ((bool) ^ !!(f->ipfw.fw_invflg & invflg))
 	/*
 	 *	This is a bit simpler as we don't have to walk
@@ -401,7 +404,7 @@
  * VERY ugly piece of code which actually
  * makes kernel printf for matching packets...
  */
-static void dump_packet(const struct iphdr *ip,
+static void dump_packet(struct sk_buff **pskb,
 			const char *ifname,
 			struct ip_fwkernel *f,
 			const ip_chainlabel chainlabel,
@@ -410,7 +413,7 @@
 			unsigned int count,
 			int syn)
 {
-	__u32 *opt = (__u32 *) (ip + 1);
+	__u32 *opt = (__u32 *) ((*pskb)->nh.iph + 1);
 	int opti;
 
 	if (f) {
@@ -422,13 +425,18 @@
 
 	printk("%s PROTO=%d %u.%u.%u.%u:%hu %u.%u.%u.%u:%hu"
 	       " L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
-	       ifname, ip->protocol, NIPQUAD(ip->saddr),
-	       src_port, NIPQUAD(ip->daddr),
+	       ifname, (*pskb)->nh.iph->protocol,
+	       NIPQUAD((*pskb)->nh.iph->saddr),
+	       src_port,
+	       NIPQUAD((*pskb)->nh.iph->daddr),
 	       dst_port,
-	       ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
-	       ntohs(ip->frag_off), ip->ttl);
+	       ntohs((*pskb)->nh.iph->tot_len),
+	       (*pskb)->nh.iph->tos,
+	       ntohs((*pskb)->nh.iph->id),
+	       ntohs((*pskb)->nh.iph->frag_off),
+	       (*pskb)->nh.iph->ttl);
 
-	for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
+	for (opti = 0; opti < ((*pskb)->nh.iph->ihl - sizeof(struct iphdr) / 4); opti++)
 		printk(" O=0x%8.8X", *opt++);
 	printk(" %s(#%d)\n", syn ? "SYN " : /* "PENANCE" */ "", count);
 }
@@ -509,34 +517,35 @@
 
 static inline int
 ip_fw_domatch(struct ip_fwkernel *f,
-	      struct iphdr *ip,
 	      const char *rif,
 	      const ip_chainlabel label,
-	      struct sk_buff *skb,
+	      struct sk_buff **pskb,
 	      unsigned int slot,
 	      __u16 src_port, __u16 dst_port,
 	      unsigned int count,
-	      int tcpsyn)
+	      int tcpsyn,
+	      unsigned char *tos)
 {
-	f->counters[slot].bcnt+=ntohs(ip->tot_len);
+	f->counters[slot].bcnt+=ntohs((*pskb)->nh.iph->tot_len);
 	f->counters[slot].pcnt++;
 	if (f->ipfw.fw_flg & IP_FW_F_PRN) {
-		dump_packet(ip,rif,f,label,src_port,dst_port,count,tcpsyn);
+		dump_packet(pskb,rif,f,label,src_port,dst_port,count,tcpsyn);
 	}
-	ip->tos = (ip->tos & f->ipfw.fw_tosand) ^ f->ipfw.fw_tosxor;
+
+	*tos = (*tos & f->ipfw.fw_tosand) ^ f->ipfw.fw_tosxor;
 
 /* This functionality is useless in stock 2.0.x series, but we don't
  * discard the mark thing altogether, to avoid breaking ipchains (and,
  * more importantly, the ipfwadm wrapper) --PR */
 	if (f->ipfw.fw_flg & IP_FW_F_MARKABS) {
-		skb->nfmark = f->ipfw.fw_mark;
+		(*pskb)->nfmark = f->ipfw.fw_mark;
 	} else {
-		skb->nfmark += f->ipfw.fw_mark;
+		(*pskb)->nfmark += f->ipfw.fw_mark;
 	}
 	if (f->ipfw.fw_flg & IP_FW_F_NETLINK) {
 #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-		size_t len = min_t(unsigned int, f->ipfw.fw_outputsize, ntohs(ip->tot_len))
-			+ sizeof(__u32) + sizeof(skb->nfmark) + IFNAMSIZ;
+		size_t len = min_t(unsigned int, f->ipfw.fw_outputsize, ntohs((*pskb)->nh.iph->tot_len))
+			+ sizeof(__u32) + sizeof((*pskb)->nfmark) + IFNAMSIZ;
 		struct sk_buff *outskb=alloc_skb(len, GFP_ATOMIC);
 
 		duprintf("Sending packet out NETLINK (length = %u).\n",
@@ -545,10 +554,13 @@
 			/* Prepend length, mark & interface */
 			skb_put(outskb, len);
 			*((__u32 *)outskb->data) = (__u32)len;
-			*((__u32 *)(outskb->data+sizeof(__u32))) = skb->nfmark;
+			*((__u32 *)(outskb->data+sizeof(__u32))) =
+				(*pskb)->nfmark;
 			strcpy(outskb->data+sizeof(__u32)*2, rif);
-			memcpy(outskb->data+sizeof(__u32)*2+IFNAMSIZ, ip,
-			       len-(sizeof(__u32)*2+IFNAMSIZ));
+			skb_copy_bits(*pskb,
+				((char *)(*pskb)->nh.iph - (char *)(*pskb)->data),
+				outskb->data+sizeof(__u32)*2+IFNAMSIZ,
+				len-(sizeof(__u32)*2+IFNAMSIZ));
 			netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
 		}
 		else {
@@ -571,22 +583,18 @@
  *	user checking mode (counters are not updated, TOS & mark not done).
  */
 static int
-ip_fw_check(struct iphdr *ip,
-	    const char *rif,
+ip_fw_check(const char *rif,
 	    __u16 *redirport,
 	    struct ip_chain *chain,
-	    struct sk_buff *skb,
+	    struct sk_buff **pskb,
 	    unsigned int slot,
 	    int testing)
 {
-	struct tcphdr		*tcp=(struct tcphdr *)((__u32 *)ip+ip->ihl);
-	struct udphdr		*udp=(struct udphdr *)((__u32 *)ip+ip->ihl);
-	struct icmphdr		*icmp=(struct icmphdr *)((__u32 *)ip+ip->ihl);
 	__u32			src, dst;
 	__u16			src_port = 0xFFFF, dst_port = 0xFFFF;
 	char			tcpsyn=0;
 	__u16			offset;
-	unsigned char		oldtos;
+	unsigned char		tos;
 	struct ip_fwkernel	*f;
 	int			ret = FW_SKIP+2;
 	unsigned int		count;
@@ -598,7 +606,7 @@
 	 * rule is also a fragment-specific rule, non-fragments won't
 	 * match it. */
 
-	offset = ntohs(ip->frag_off) & IP_OFFSET;
+	offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;
 
 	/*
 	 *	Don't allow a fragment of TCP 8 bytes in. Nobody
@@ -606,10 +614,10 @@
 	 *	in by doing a flag overwrite to pass the direction
 	 *	checks.
 	 */
-	if (offset == 1 && ip->protocol == IPPROTO_TCP)	{
+	if (offset == 1 && (*pskb)->nh.iph->protocol == IPPROTO_TCP) {
 		if (!testing && net_ratelimit()) {
 			printk("Suspect TCP fragment.\n");
-			dump_packet(ip,rif,NULL,NULL,0,0,0,0);
+			dump_packet(pskb,rif,NULL,NULL,0,0,0,0);
 		}
 		return FW_BLOCK;
 	}
@@ -621,7 +629,7 @@
 	 */
 	if (offset == 0) {
 		unsigned int size_req;
-		switch (ip->protocol) {
+		switch ((*pskb)->nh.iph->protocol) {
 		case IPPROTO_TCP:
 			/* Don't care about things past flags word */
 			size_req = 16;
@@ -640,18 +648,19 @@
 		 * used to rewrite port information, and thus should
 		 * be blocked.
 		 */
-		if (ntohs(ip->tot_len) < (ip->ihl<<2)+size_req) {
+		if (ntohs((*pskb)->nh.iph->tot_len) <
+		    ((*pskb)->nh.iph->ihl<<2)+size_req) {
 			if (!testing && net_ratelimit()) {
 				printk("Suspect short first fragment.\n");
-				dump_packet(ip,rif,NULL,NULL,0,0,0,0);
+				dump_packet(pskb,rif,NULL,NULL,0,0,0,0);
 			}
 			return FW_BLOCK;
 		}
 	}
 
-	src = ip->saddr;
-	dst = ip->daddr;
-	oldtos = ip->tos;
+	src = (*pskb)->nh.iph->saddr;
+	dst = (*pskb)->nh.iph->daddr;
+	tos = (*pskb)->nh.iph->tos;
 
 	/*
 	 *	If we got interface from which packet came
@@ -662,47 +671,68 @@
 	 */
 
 	dprintf("Packet ");
-	switch(ip->protocol)
-	{
+	switch ((*pskb)->nh.iph->protocol) {
 		case IPPROTO_TCP:
 			dprintf("TCP ");
 			if (!offset) {
-				src_port=ntohs(tcp->source);
-				dst_port=ntohs(tcp->dest);
+				struct tcphdr tcph;
+
+				if (skb_copy_bits(*pskb,
+						  (*pskb)->nh.iph->ihl * 4,
+						  &tcph, sizeof(tcph)))
+					return FW_BLOCK;
+
+				src_port = ntohs(tcph.source);
+				dst_port = ntohs(tcph.dest);
 
 				/* Connection initilisation can only
 				 * be made when the syn bit is set and
 				 * neither of the ack or reset is
 				 * set. */
-				if(tcp->syn && !(tcp->ack || tcp->rst))
-					tcpsyn=1;
+				if (tcph.syn && !(tcph.ack || tcph.rst))
+					tcpsyn = 1;
 			}
 			break;
 		case IPPROTO_UDP:
 			dprintf("UDP ");
 			if (!offset) {
-				src_port=ntohs(udp->source);
-				dst_port=ntohs(udp->dest);
+				struct udphdr udph;
+
+				if (skb_copy_bits(*pskb,
+						  (*pskb)->nh.iph->ihl * 4,
+						  &udph, sizeof(udph)))
+					return FW_BLOCK;
+
+				src_port = ntohs(udph.source);
+				dst_port = ntohs(udph.dest);
 			}
 			break;
 		case IPPROTO_ICMP:
 			if (!offset) {
-				src_port=(__u16)icmp->type;
-				dst_port=(__u16)icmp->code;
+				struct icmphdr icmph;
+
+				if (skb_copy_bits(*pskb,
+						  (*pskb)->nh.iph->ihl * 4,
+						  &icmph, sizeof(icmph)))
+					return FW_BLOCK;
+
+				src_port = (__u16) icmph.type;
+				dst_port = (__u16) icmph.code;
 			}
 			dprintf("ICMP ");
 			break;
 		default:
-			dprintf("p=%d ",ip->protocol);
+			dprintf("p=%d ", (*pskb)->nh.iph->protocol);
 			break;
 	}
 #ifdef DEBUG_IP_FIREWALL
-	print_ip(ip->saddr);
+	print_ip((*pskb)->nh.iph->saddr);
 
 	if (offset)
 		dprintf(":fragment (%i) ", ((int)offset)<<2);
-	else if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP
-		 || ip->protocol==IPPROTO_ICMP)
+	else if ((*pskb)->nh.iph->protocol == IPPROTO_TCP ||
+		 (*pskb)->nh.iph->protocol == IPPROTO_UDP ||
+		 (*pskb)->nh.iph->protocol == IPPROTO_ICMP)
 		dprintf(":%hu:%hu", src_port, dst_port);
 	dprintf("\n");
 #endif
@@ -715,13 +745,14 @@
 		count = 0;
 		for (; f; f = f->next) {
 			count++;
-			if (ip_rule_match(f,rif,ip,
-					  tcpsyn,src_port,dst_port,offset)) {
+			if (ip_rule_match(f, rif, pskb,
+					  tcpsyn, src_port, dst_port,
+					  offset)) {
 				if (!testing
-				    && !ip_fw_domatch(f, ip, rif, chain->label,
-						      skb, slot,
+				    && !ip_fw_domatch(f, rif, chain->label,
+						      pskb, slot,
 						      src_port, dst_port,
-						      count, tcpsyn)) {
+						      count, tcpsyn, &tos)) {
 					ret = FW_BLOCK;
 					cleanup(chain, 0, slot);
 					goto out;
@@ -780,7 +811,7 @@
 				if (!testing) {
 					chain->reent[slot].counters.pcnt++;
 					chain->reent[slot].counters.bcnt
-						+= ntohs(ip->tot_len);
+						+= ntohs((*pskb)->nh.iph->tot_len);
 				}
 			}
 		}
@@ -790,10 +821,16 @@
 	if (!testing) FWC_READ_UNLOCK(&ip_fw_lock);
 
 	/* Recalculate checksum if not going to reject, and TOS changed. */
-	if (ip->tos != oldtos
+	if ((*pskb)->nh.iph->tos != tos
 	    && ret != FW_REJECT && ret != FW_BLOCK
-	    && !testing)
-		ip_send_check(ip);
+	    && !testing) {
+		if (!skb_ip_make_writable(pskb, offsetof(struct iphdr, tos)+1))
+			ret = FW_BLOCK;
+		else {
+			(*pskb)->nh.iph->tos = tos;
+			ip_send_check((*pskb)->nh.iph);
+		}
+	}
 
 	if (ret == FW_REDIRECT && redirport) {
 		if ((*redirport = htons(f->ipfw.fw_redirpt)) == 0) {
@@ -1349,18 +1386,40 @@
 		if ((chain = find_label(new->fwt_label)) == NULL)
 			ret = ENOENT;
 		else {
+			struct sk_buff *tmp_skb;
+			int hdrlen;
+
+			hdrlen = sizeof(struct ip_fwpkt) -
+				sizeof(struct in_addr) -
+				IFNAMSIZ;
+
 			ip = &(new->fwt_packet.fwp_iph);
 
-			if (ip->ihl != sizeof(struct iphdr) / sizeof(int)) {
-			    duprintf("ip_fw_ctl: ip->ihl=%d, want %d\n",
-				     ip->ihl,
-				     sizeof(struct iphdr) / sizeof(int));
-			    ret = EINVAL;
-			}
-			else {
-				ret = ip_fw_check(ip, new->fwt_packet.fwp_vianame,
+			/* Fix this one up by hand, who knows how many
+			 * tools will break if we start to barf on this.
+			 */
+			if (ntohs(ip->tot_len) > hdrlen)
+				ip->tot_len = htons(hdrlen);
+
+			if (ip->ihl != sizeof(struct iphdr) / sizeof(u32)) {
+				duprintf("ip_fw_ctl: ip->ihl=%d, want %d\n",
+					 ip->ihl,
+					 sizeof(struct iphdr) / sizeof(u32));
+				ret = EINVAL;
+			} else if ((tmp_skb = alloc_skb(hdrlen,
+							GFP_ATOMIC)) == NULL) {
+				duprintf("ip_fw_ctl: tmp_skb alloc failure\n");
+				ret = EFAULT;
+			} else {
+				skb_reserve(tmp_skb, hdrlen);
+				skb_push(tmp_skb, hdrlen);
+				memcpy(tmp_skb->data, ip, hdrlen);
+				tmp_skb->nh.raw =
+					(unsigned char *) tmp_skb->data;
+				ret = ip_fw_check(new->fwt_packet.fwp_vianame,
 						  NULL, chain,
-						  NULL, SLOT_NUMBER(), 1);
+						  &tmp_skb, SLOT_NUMBER(), 1);
+				kfree_skb(tmp_skb);
 				switch (ret) {
 				case FW_ACCEPT:
 					ret = 0; break;
@@ -1690,41 +1749,37 @@
  *	Interface to the generic firewall chains.
  */
 int ipfw_input_check(struct firewall_ops *this, int pf,
-		     struct net_device *dev, void *phdr, void *arg,
+		     struct net_device *dev, void *arg,
 		     struct sk_buff **pskb)
 {
-	return ip_fw_check(phdr, dev->name,
-			   arg, IP_FW_INPUT_CHAIN, *pskb, SLOT_NUMBER(), 0);
+	return ip_fw_check(dev->name,
+			   arg, IP_FW_INPUT_CHAIN, pskb, SLOT_NUMBER(), 0);
 }
 
 int ipfw_output_check(struct firewall_ops *this, int pf,
-		      struct net_device *dev, void *phdr, void *arg,
+		      struct net_device *dev, void *arg,
 		      struct sk_buff **pskb)
 {
 	/* Locally generated bogus packets by root. <SIGH>. */
-	if (((struct iphdr *)phdr)->ihl * 4 < sizeof(struct iphdr)
-	    || (*pskb)->len < sizeof(struct iphdr))
+	if ((*pskb)->len < sizeof(struct iphdr) ||
+	    (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return FW_ACCEPT;
-	return ip_fw_check(phdr, dev->name,
-			   arg, IP_FW_OUTPUT_CHAIN, *pskb, SLOT_NUMBER(), 0);
+	return ip_fw_check(dev->name,
+			   arg, IP_FW_OUTPUT_CHAIN, pskb, SLOT_NUMBER(), 0);
 }
 
 int ipfw_forward_check(struct firewall_ops *this, int pf,
-		       struct net_device *dev, void *phdr, void *arg,
+		       struct net_device *dev, void *arg,
 		       struct sk_buff **pskb)
 {
-	return ip_fw_check(phdr, dev->name,
-			   arg, IP_FW_FORWARD_CHAIN, *pskb, SLOT_NUMBER(), 0);
+	return ip_fw_check(dev->name,
+			   arg, IP_FW_FORWARD_CHAIN, pskb, SLOT_NUMBER(), 0);
 }
 
-struct firewall_ops ipfw_ops=
-{
-	NULL,
-	ipfw_forward_check,
-	ipfw_input_check,
-	ipfw_output_check,
-	NULL,
-	NULL
+struct firewall_ops ipfw_ops = {
+	.fw_forward	=	ipfw_forward_check,
+	.fw_input	=	ipfw_input_check,
+	.fw_output	=	ipfw_output_check,
 };
 
 int ipfw_init_or_cleanup(int init)
diff -urN linux-2.5.69-bk8/net/ipv4/netfilter/ipfwadm_core.c linux-2.5.69-bk9/net/ipv4/netfilter/ipfwadm_core.c
--- linux-2.5.69-bk8/net/ipv4/netfilter/ipfwadm_core.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv4/netfilter/ipfwadm_core.c	2003-05-14 04:43:45.000000000 -0700
@@ -126,6 +126,7 @@
 #include <linux/netfilter_ipv4/ipfwadm_core.h>
 #include <linux/netfilter_ipv4/compat_firewall.h>
 #include <linux/netfilter_ipv4/lockhelp.h>
+#include <linux/netfilter_ipv4/ip_nat_core.h>
 
 #include <net/checksum.h>
 #include <linux/proc_fs.h>
@@ -259,18 +260,18 @@
 	}
 }
 
-static void print_packet(struct iphdr *ip,
+static void print_packet(struct sk_buff **pskb,
 			 u16 src_port, u16 dst_port, u16 icmp_type,
 			 char *chain, char *rule, char *devname)
 {
-	__u32 *opt = (__u32 *) (ip + 1);
+	__u32 *opt = (__u32 *) ((*pskb)->nh.iph + 1);
 	int opti;
-	__u16 foff = ntohs(ip->frag_off);
+	__u16 foff = ntohs((*pskb)->nh.iph->frag_off);
+	int protocol = (*pskb)->nh.iph->protocol;
 
 	printk(KERN_INFO "IP %s %s%s", chain, rule, devname);
 
-	switch(ip->protocol)
-	{
+	switch (protocol) {
 	case IPPROTO_TCP:
 		printk(" TCP ");
 		break;
@@ -281,22 +282,28 @@
 		printk(" ICMP/%d ", icmp_type);
 		break;
 	default:
-		printk(" PROTO=%d ", ip->protocol);
+		printk(" PROTO=%d ", protocol);
 		break;
-	}
-	print_ip(ip->saddr);
-	if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
+	};
+
+	print_ip((*pskb)->nh.iph->saddr);
+	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
 		printk(":%hu", src_port);
 	printk(" ");
-	print_ip(ip->daddr);
-	if(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP)
+	print_ip((*pskb)->nh.iph->daddr);
+	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
 		printk(":%hu", dst_port);
 	printk(" L=%hu S=0x%2.2hX I=%hu FO=0x%4.4hX T=%hu",
-	       ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
-	       foff & IP_OFFSET, ip->ttl);
-	if (foff & IP_DF) printk(" DF=1");
-	if (foff & IP_MF) printk(" MF=1");
-	for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
+	       ntohs((*pskb)->nh.iph->tot_len),
+	       (*pskb)->nh.iph->tos,
+	       ntohs((*pskb)->nh.iph->id),
+	       foff & IP_OFFSET,
+	       (*pskb)->nh.iph->ttl);
+	if (foff & IP_DF)
+		printk(" DF=1");
+	if (foff & IP_MF)
+		printk(" MF=1");
+	for (opti = 0; opti < ((*pskb)->nh.iph->ihl - sizeof(struct iphdr) / 4); opti++)
 		printk(" O=0x%8.8X", *opt++);
 	printk("\n");
 }
@@ -314,13 +321,11 @@
  */
 
 
-int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport,
+int ip_fw_chk(struct sk_buff **pskb,
+	      struct net_device *rif, __u16 *redirport,
 	      struct ip_fw *chain, int policy, int mode)
 {
 	struct ip_fw *f;
-	struct tcphdr		*tcp=(struct tcphdr *)((__u32 *)ip+ip->ihl);
-	struct udphdr		*udp=(struct udphdr *)((__u32 *)ip+ip->ihl);
-	struct icmphdr		*icmp=(struct icmphdr *)((__u32 *)ip+ip->ihl);
 	__u32			src, dst;
 	__u16			src_port=0xFFFF, dst_port=0xFFFF, icmp_type=0xFF;
 	unsigned short		f_prt=0, prt;
@@ -328,6 +333,7 @@
 	unsigned short		offset;
 	int			answer;
 	unsigned char		tosand, tosxor;
+	int			protocol;
 
 	/*
 	 *	If the chain is empty follow policy. The BSD one
@@ -335,9 +341,6 @@
 	 *	flushing and rebuilding the tables.
 	 */
 
-	src = ip->saddr;
-	dst = ip->daddr;
-
 	/*
 	 *	This way we handle fragmented packets.
 	 *	we ignore all fragments but the first one
@@ -352,7 +355,8 @@
 	 *	of system.
 	 */
 
-	offset = ntohs(ip->frag_off) & IP_OFFSET;
+	offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;
+	protocol = (*pskb)->nh.iph->protocol;
 
 	/*
 	 *	Don't allow a fragment of TCP 8 bytes in. Nobody
@@ -361,19 +365,21 @@
 	 *	checks.
 	 */
 
-	if (offset == 1 && ip->protocol == IPPROTO_TCP)
+	if (offset == 1 && protocol == IPPROTO_TCP)
 		return FW_BLOCK;
 
 	if (offset!=0 && !(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT)) &&
-		(ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP ||
-			ip->protocol == IPPROTO_ICMP))
+		(protocol == IPPROTO_TCP ||
+		 protocol == IPPROTO_UDP ||
+		 protocol == IPPROTO_ICMP))
 		return FW_ACCEPT;
 
 	/*
 	 *	 Header fragment for TCP is too small to check the bits.
 	 */
 
-	if(ip->protocol==IPPROTO_TCP && (ip->ihl<<2)+16 > ntohs(ip->tot_len))
+	if (protocol == IPPROTO_TCP &&
+	    ((*pskb)->nh.iph->ihl<<2)+16 > ntohs((*pskb)->nh.iph->tot_len))
 		return FW_BLOCK;
 
 	/*
@@ -382,11 +388,13 @@
 	 *	But only too short for a packet with ports...
 	 */
 
-	else if((ntohs(ip->tot_len)<8+(ip->ihl<<2))&&(ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP))
+	else if ((ntohs((*pskb)->nh.iph->tot_len) <
+		  8 + ((*pskb)->nh.iph->ihl << 2)) &&
+		 (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP))
 		return FW_BLOCK;
 
-	src = ip->saddr;
-	dst = ip->daddr;
+	src = (*pskb)->nh.iph->saddr;
+	dst = (*pskb)->nh.iph->daddr;
 
 	/*
 	 *	If we got interface from which packet came
@@ -397,54 +405,76 @@
 	 */
 
 	dprintf1("Packet ");
-	switch(ip->protocol)
-	{
+	switch (protocol) {
 		case IPPROTO_TCP:
 			dprintf1("TCP ");
 			/* ports stay 0xFFFF if it is not the first fragment */
 			if (!offset) {
-				src_port=ntohs(tcp->source);
-				dst_port=ntohs(tcp->dest);
-				if(!tcp->ack && !tcp->rst)
+				struct tcphdr tcph;
+
+				if (skb_copy_bits(*pskb,
+						  (*pskb)->nh.iph->ihl * 4,
+						  &tcph, sizeof(tcph)))
+					return FW_BLOCK;
+
+				src_port = ntohs(tcph.source);
+				dst_port = ntohs(tcph.dest);
+
+				if(!tcph.ack && !tcph.rst)
 					/* We do NOT have ACK, value TRUE */
-					notcpack=1;
-				if(!tcp->syn || !notcpack)
+					notcpack = 1;
+				if(!tcph.syn || !notcpack)
 					/* We do NOT have SYN, value TRUE */
-					notcpsyn=1;
+					notcpsyn = 1;
 			}
-			prt=IP_FW_F_TCP;
+			prt = IP_FW_F_TCP;
 			break;
 		case IPPROTO_UDP:
 			dprintf1("UDP ");
 			/* ports stay 0xFFFF if it is not the first fragment */
 			if (!offset) {
-				src_port=ntohs(udp->source);
-				dst_port=ntohs(udp->dest);
+				struct udphdr udph;
+
+				if (skb_copy_bits(*pskb,
+						  (*pskb)->nh.iph->ihl * 4,
+						  &udph, sizeof(udph)))
+					return FW_BLOCK;
+
+				src_port = ntohs(udph.source);
+				dst_port = ntohs(udph.dest);
 			}
-			prt=IP_FW_F_UDP;
+			prt = IP_FW_F_UDP;
 			break;
 		case IPPROTO_ICMP:
 			/* icmp_type stays 255 if it is not the first fragment */
-			if (!offset)
-				icmp_type=(__u16)(icmp->type);
-			dprintf2("ICMP:%d ",icmp_type);
-			prt=IP_FW_F_ICMP;
+			if (!offset) {
+				struct icmphdr icmph;
+
+				if (skb_copy_bits(*pskb,
+						  (*pskb)->nh.iph->ihl * 4,
+						  &icmph, sizeof(icmph)))
+					return FW_BLOCK;
+
+				icmp_type = (__u16) icmph.type;
+			}
+			dprintf2("ICMP:%d ", icmp_type);
+			prt = IP_FW_F_ICMP;
 			break;
 		default:
-			dprintf2("p=%d ",ip->protocol);
-			prt=IP_FW_F_ALL;
+			dprintf2("p=%d ", protocol);
+			prt = IP_FW_F_ALL;
 			break;
 	}
 #ifdef DEBUG_IP_FIREWALL
-	dprint_ip(ip->saddr);
+	dprint_ip(src);
 
-	if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
+	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
 		/* This will print 65535 when it is not the first fragment! */
 		dprintf2(":%d ", src_port);
-	dprint_ip(ip->daddr);
-	if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
+	dprint_ip(dst);
+	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
 		/* This will print 65535 when it is not the first fragment! */
-		dprintf2(":%d ",dst_port);
+		dprintf2(":%d ", dst_port);
 	dprintf1("\n");
 #endif
 
@@ -453,8 +483,7 @@
 	else
 		WRITE_LOCK(&ip_fw_lock);
 	
-	for (f=chain;f;f=f->fw_next)
-	{
+	for (f = chain; f; f = f->fw_next) {
 		/*
 		 *	This is a bit simpler as we don't have to walk
 		 *	an interface chain as you do in BSD - same logic
@@ -474,14 +503,14 @@
 		 */
 		match = 0x00;
 
-		if ((src&f->fw_smsk.s_addr)==f->fw_src.s_addr
-		&&  (dst&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
+		if ((src & f->fw_smsk.s_addr) == f->fw_src.s_addr &&
+		    (dst & f->fw_dmsk.s_addr) == f->fw_dst.s_addr)
 			/* normal direction */
 			match |= 0x01;
 
 		if ((f->fw_flg & IP_FW_F_BIDIR) &&
-		    (dst&f->fw_smsk.s_addr)==f->fw_src.s_addr
-		&&  (src&f->fw_dmsk.s_addr)==f->fw_dst.s_addr)
+		    (dst & f->fw_smsk.s_addr) == f->fw_src.s_addr &&
+		    (src & f->fw_dmsk.s_addr) == f->fw_dst.s_addr)
 			/* reverse direction */
 			match |= 0x02;
 
@@ -491,9 +520,8 @@
 		/*
 		 *	Look for a VIA device match
 		 */
-		if(f->fw_viadev)
-		{
-			if(rif!=f->fw_viadev)
+		if (f->fw_viadev) {
+			if (rif != f->fw_viadev)
 				continue;	/* Mismatch */
 		}
 
@@ -560,14 +588,13 @@
 		 	continue;
 
 		f_prt=f->fw_flg&IP_FW_F_KIND;
-		if (f_prt!=IP_FW_F_ALL)
-		{
+		if (f_prt != IP_FW_F_ALL) {
 			/*
 			 *	Specific firewall - packet's protocol
 			 *	must match firewall's.
 			 */
 
-			if(prt!=f_prt)
+			if (prt != f_prt)
 				continue;
 
 			if((prt==IP_FW_F_ICMP &&
@@ -592,14 +619,14 @@
 		{
 			char buf[16];
 
-			print_packet(ip, src_port, dst_port, icmp_type,
+			print_packet(pskb, src_port, dst_port, icmp_type,
 				     chain_name(chain, mode),
 				     rule_name(f, mode, buf),
 				     rif ? rif->name : "-");
 		}
 #endif
 		if (mode != IP_FW_MODE_CHK) {
-			f->fw_bcnt+=ntohs(ip->tot_len);
+			f->fw_bcnt += ntohs((*pskb)->nh.iph->tot_len);
 			f->fw_pcnt++;
 		}
 		if (!(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT)))
@@ -614,23 +641,30 @@
 		 * of firewall.
 		 */
 
-		if (f!=NULL) {
-			policy=f->fw_flg;
-			tosand=f->fw_tosand;
-			tosxor=f->fw_tosxor;
+		if (f != NULL) {
+			policy = f->fw_flg;
+			tosand = f->fw_tosand;
+			tosxor = f->fw_tosxor;
 		} else {
-			tosand=0xFF;
-			tosxor=0x00;
+			tosand = 0xFF;
+			tosxor = 0x00;
 		}
 
-		if (policy&IP_FW_F_ACCEPT) {
+		if (policy & IP_FW_F_ACCEPT) {
 			/* Adjust priority and recompute checksum */
-			__u8 old_tos = ip->tos;
-			ip->tos = (old_tos & tosand) ^ tosxor;
-			if (ip->tos != old_tos)
-		 		ip_send_check(ip);
+			__u8 tos = (*pskb)->nh.iph->tos;
+
+			if (((tos & tosand) ^ tosxor) != tos) {
+				if (!skb_ip_make_writable(pskb,
+					  offsetof(struct iphdr, tos)+1))
+					goto drop_it;
+
+				(*pskb)->nh.iph->tos = (tos & tosand) ^ tosxor;
+		 		ip_send_check((*pskb)->nh.iph);
+			}
+
 #ifdef CONFIG_IP_TRANSPARENT_PROXY
-			if (policy&IP_FW_F_REDIR) {
+			if (policy & IP_FW_F_REDIR) {
 				if (redirport)
 					if ((*redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp])) == 0) {
 						/* Wildcard redirection.
@@ -643,30 +677,36 @@
 			} else
 #endif
 #ifdef CONFIG_IP_MASQUERADE
-			if (policy&IP_FW_F_MASQ)
+			if (policy & IP_FW_F_MASQ)
 				answer = FW_MASQUERADE;
 			else
 #endif
 				answer = FW_ACCEPT;
 
-		} else if(policy&IP_FW_F_ICMPRPL)
+		} else if (policy & IP_FW_F_ICMPRPL)
 			answer = FW_REJECT;
-		else
+		else {
+		drop_it:
 			answer = FW_BLOCK;
+		}
 
 #ifdef CONFIG_IP_FIREWALL_NETLINK
-		if((policy&IP_FW_F_PRN) && (answer == FW_REJECT || answer == FW_BLOCK))
+		if ((policy & IP_FW_F_PRN) && (answer == FW_REJECT || answer == FW_BLOCK))
 		{
-			struct sk_buff *skb=alloc_skb(128, (mode == IP_FW_MODE_CHK) ?
-							GFP_KERNEL : GFP_ATOMIC);
-			if(skb)
-			{
+			struct sk_buff *skb = alloc_skb(128,
+					(mode == IP_FW_MODE_CHK) ?
+					GFP_KERNEL : GFP_ATOMIC);
+			if (skb) {
 				int len = min_t(unsigned int,
-					      128, ntohs(ip->tot_len));
+					128,
+					ntohs((*pskb)->nh.iph->tot_len));
 
-				skb_put(skb,len);
-				memcpy(skb->data,ip,len);
-				if(netlink_post(NETLINK_FIREWALL, skb))
+				skb_put(skb, len);
+				skb_copy_bits(*pskb,
+					((char *)(*pskb)->nh.iph -
+					 (char *)(*pskb)->data),
+					skb->data, len);
+				if (netlink_post(NETLINK_FIREWALL, skb))
 					kfree_skb(skb);
 			}
 		}
@@ -706,6 +746,9 @@
 		struct ip_fw *ftmp;
 		ftmp = *chainptr;
 		*chainptr = ftmp->fw_next;
+		if (ftmp->fw_viadev
+		    && ftmp->fw_viadev != (struct net_device *)-1)
+			dev_put(ftmp->fw_viadev);
 		kfree(ftmp);
 		/* We will block in cleanup's unregister sockopt if unloaded,
 		   so this is safe. */
@@ -856,6 +899,9 @@
 		if(matches)
 		{
 			was_found=1;
+			if (ftmp->fw_viadev
+			    && ftmp->fw_viadev != (struct net_device *)-1)
+				dev_put(ftmp->fw_viadev);
 			if (ltmp)
 			{
 				ltmp->fw_next=ftmp->fw_next;
@@ -1035,9 +1081,15 @@
 
 	if ( cmd == IP_FW_CHECK )
 	{
+		struct sk_buff *tmp_skb;
 		struct net_device *viadev;
 		struct ip_fwpkt *ipfwp;
 		struct iphdr *ip;
+		int hdrlen, ret;
+
+		hdrlen = sizeof(struct ip_fwpkt) -
+			sizeof(struct in_addr) -
+			IFNAMSIZ;
 
 		if ( len != sizeof(struct ip_fwpkt) )
 		{
@@ -1061,12 +1113,34 @@
 			printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
 					sizeof(struct iphdr)/sizeof(int));
 #endif
+			dev_put(viadev);
 			return(EINVAL);
 		}
 
-		switch (ip_fw_chk(ip, viadev, NULL, *chains[fwtype],
-				*policies[fwtype], IP_FW_MODE_CHK))
-		{
+		/* Fix this one up by hand, who knows how many
+		 * tools will break if we start to barf on this.
+		 */
+		if (ntohs(ip->tot_len) > hdrlen)
+			ip->tot_len = htons(hdrlen);
+
+		if ((tmp_skb = alloc_skb(hdrlen, GFP_ATOMIC)) == NULL) {
+#ifdef DEBUG_IP_FIREWALL
+			printk("ip_fw_ctl: tmp_skb alloc failure\n");
+#endif
+			dev_put(viadev);
+			return(EFAULT);
+		}
+		skb_reserve(tmp_skb, hdrlen);
+		skb_push(tmp_skb, hdrlen);
+		memcpy(tmp_skb->data, ip, hdrlen);
+
+		ret = ip_fw_chk(&tmp_skb, viadev, NULL, *chains[fwtype],
+				*policies[fwtype], IP_FW_MODE_CHK);
+
+		kfree_skb(tmp_skb);
+		dev_put(viadev);
+
+		switch (ret) {
 			case FW_ACCEPT:
 				return(0);
 	    		case FW_REDIRECT:
@@ -1242,55 +1316,50 @@
  */
 
 int ipfw_input_check(struct firewall_ops *this, int pf,
-		     struct net_device *dev, void *phdr, void *arg,
+		     struct net_device *dev, void *arg,
 		     struct sk_buff **pskb)
 {
-	return ip_fw_chk(phdr, dev, arg, ip_fw_in_chain, ip_fw_in_policy,
+	return ip_fw_chk(pskb, dev, arg, ip_fw_in_chain, ip_fw_in_policy,
 			 IP_FW_MODE_FW);
 }
 
 int ipfw_output_check(struct firewall_ops *this, int pf,
-		      struct net_device *dev, void *phdr, void *arg,
+		      struct net_device *dev, void *arg,
 		      struct sk_buff **pskb)
 {
-	return ip_fw_chk(phdr, dev, arg, ip_fw_out_chain, ip_fw_out_policy,
+	return ip_fw_chk(pskb, dev, arg, ip_fw_out_chain, ip_fw_out_policy,
 			 IP_FW_MODE_FW);
 }
 
 int ipfw_forward_check(struct firewall_ops *this, int pf,
-		       struct net_device *dev, void *phdr, void *arg,
+		       struct net_device *dev, void *arg,
 		       struct sk_buff **pskb)
 {
-	return ip_fw_chk(phdr, dev, arg, ip_fw_fwd_chain, ip_fw_fwd_policy,
+	return ip_fw_chk(pskb, dev, arg, ip_fw_fwd_chain, ip_fw_fwd_policy,
 			 IP_FW_MODE_FW);
 }
 
 #ifdef CONFIG_IP_ACCT
 int ipfw_acct_in(struct firewall_ops *this, int pf, struct net_device *dev,
-		 void *phdr, void *arg, struct sk_buff **pskb)
+		 void *arg, struct sk_buff **pskb)
 {
-	return ip_fw_chk(phdr,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_IN);
+	return ip_fw_chk(pskb,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_IN);
 }
 
 int ipfw_acct_out(struct firewall_ops *this, int pf, struct net_device *dev,
-		  void *phdr, void *arg, struct sk_buff **pskb)
+		  void *arg, struct sk_buff **pskb)
 {
-	return ip_fw_chk(phdr,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_OUT);
+	return ip_fw_chk(pskb,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_OUT);
 }
 #endif
 
-struct firewall_ops ipfw_ops=
-{
-	NULL,
-	ipfw_forward_check,
-	ipfw_input_check,
-	ipfw_output_check,
+struct firewall_ops ipfw_ops = {
+	.fw_forward	=	ipfw_forward_check,
+	.fw_input	=	ipfw_input_check,
+	.fw_output	=	ipfw_output_check,
 #ifdef CONFIG_IP_ACCT
-	ipfw_acct_in,
-	ipfw_acct_out
-#else
-	NULL,
-	NULL
+	.fw_acct_in	=	ipfw_acct_in,
+	.fw_acct_out	=	ipfw_acct_out,
 #endif
 };
 
@@ -1311,23 +1380,29 @@
 		for (chn = 0; chn < IP_FW_CHAINS; chn++)
 			for (fw = *chains[chn]; fw; fw = fw->fw_next)
 				if ((fw->fw_vianame)[0] && !strncmp(devname,
-						fw->fw_vianame, IFNAMSIZ))
+					    fw->fw_vianame, IFNAMSIZ)) {
+					dev_hold(dev);
 					fw->fw_viadev = dev;
+				}
 	} else if (event == NETDEV_DOWN) {
 		for (chn = 0; chn < IP_FW_CHAINS; chn++)
 			for (fw = *chains[chn]; fw; fw = fw->fw_next)
 				/* we could compare just the pointers ... */
 				if ((fw->fw_vianame)[0] && !strncmp(devname,
-						fw->fw_vianame, IFNAMSIZ))
+						    fw->fw_vianame, IFNAMSIZ)){
+					if (fw->fw_viadev
+					    && fw->fw_viadev != (struct net_device *)-1)
+						dev_put(fw->fw_viadev);
 					fw->fw_viadev = (struct net_device*)-1;
+				}
 	}
 
 	WRITE_UNLOCK(&ip_fw_lock);
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block ipfw_dev_notifier={
-	.notifier_call	= ipfw_device_event,
+static struct notifier_block ipfw_dev_notifier = {
+	.notifier_call	=	ipfw_device_event,
 };
 
 #endif
diff -urN linux-2.5.69-bk8/net/ipv4/tcp_diag.c linux-2.5.69-bk9/net/ipv4/tcp_diag.c
--- linux-2.5.69-bk8/net/ipv4/tcp_diag.c	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv4/tcp_diag.c	2003-05-14 04:43:45.000000000 -0700
@@ -88,8 +88,10 @@
 		r->tcpdiag_inode = 0;
 #ifdef CONFIG_IPV6
 		if (r->tcpdiag_family == AF_INET6) {
-			memcpy(r->id.tcpdiag_src, &tw->v6_rcv_saddr, 16);
-			memcpy(r->id.tcpdiag_dst, &tw->v6_daddr, 16);
+			ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src,
+				       &tw->v6_rcv_saddr);
+			ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_dst,
+				       &tw->v6_daddr);
 		}
 #endif
 		nlh->nlmsg_len = skb->tail - b;
@@ -105,8 +107,10 @@
 	if (r->tcpdiag_family == AF_INET6) {
 		struct ipv6_pinfo *np = inet6_sk(sk);
 
-		memcpy(r->id.tcpdiag_src, &np->rcv_saddr, 16);
-		memcpy(r->id.tcpdiag_dst, &np->daddr, 16);
+		ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src,
+			       &np->rcv_saddr);
+		ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_dst,
+			       &np->daddr);
 	}
 #endif
 
diff -urN linux-2.5.69-bk8/net/ipv4/tcp_minisocks.c linux-2.5.69-bk9/net/ipv4/tcp_minisocks.c
--- linux-2.5.69-bk8/net/ipv4/tcp_minisocks.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv4/tcp_minisocks.c	2003-05-14 04:43:45.000000000 -0700
@@ -381,10 +381,8 @@
 		if(tw->family == PF_INET6) {
 			struct ipv6_pinfo *np = inet6_sk(sk);
 
-			memcpy(&tw->v6_daddr, &np->daddr,
-			       sizeof(struct in6_addr));
-			memcpy(&tw->v6_rcv_saddr, &np->rcv_saddr,
-			       sizeof(struct in6_addr));
+			ipv6_addr_copy(&tw->v6_daddr, &np->daddr);
+			ipv6_addr_copy(&tw->v6_rcv_saddr, &np->rcv_saddr);
 		}
 #endif
 		/* Linkage updates. */
diff -urN linux-2.5.69-bk8/net/ipv6/addrconf.c linux-2.5.69-bk9/net/ipv6/addrconf.c
--- linux-2.5.69-bk8/net/ipv6/addrconf.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/addrconf.c	2003-05-14 04:43:45.000000000 -0700
@@ -1195,7 +1195,7 @@
 	struct in6_rtmsg rtmsg;
 
 	memset(&rtmsg, 0, sizeof(rtmsg));
-	memcpy(&rtmsg.rtmsg_dst, pfx, sizeof(struct in6_addr));
+	ipv6_addr_copy(&rtmsg.rtmsg_dst, pfx);
 	rtmsg.rtmsg_dst_len = plen;
 	rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
 	rtmsg.rtmsg_ifindex = dev->ifindex;
diff -urN linux-2.5.69-bk8/net/ipv6/af_inet6.c linux-2.5.69-bk9/net/ipv6/af_inet6.c
--- linux-2.5.69-bk8/net/ipv6/af_inet6.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/af_inet6.c	2003-05-14 04:43:45.000000000 -0700
@@ -437,16 +437,14 @@
 		if (((1<<sk->state)&(TCPF_CLOSE|TCPF_SYN_SENT)) && peer == 1)
 			return -ENOTCONN;
 		sin->sin6_port = inet->dport;
-		memcpy(&sin->sin6_addr, &np->daddr, sizeof(struct in6_addr));
+		ipv6_addr_copy(&sin->sin6_addr, &np->daddr);
 		if (np->sndflow)
 			sin->sin6_flowinfo = np->flow_label;
 	} else {
 		if (ipv6_addr_type(&np->rcv_saddr) == IPV6_ADDR_ANY)
-			memcpy(&sin->sin6_addr, &np->saddr,
-			       sizeof(struct in6_addr));
+			ipv6_addr_copy(&sin->sin6_addr, &np->saddr);
 		else
-			memcpy(&sin->sin6_addr, &np->rcv_saddr,
-			       sizeof(struct in6_addr));
+			ipv6_addr_copy(&sin->sin6_addr, &np->rcv_saddr);
 
 		sin->sin6_port = inet->sport;
 	}
@@ -873,6 +871,9 @@
 	ipv6_sysctl_unregister();	
 #endif
 	cleanup_ipv6_mibs();
+	kmem_cache_destroy(tcp6_sk_cachep);
+	kmem_cache_destroy(udp6_sk_cachep);
+	kmem_cache_destroy(raw6_sk_cachep);
 }
 module_exit(inet6_exit);
 #endif /* MODULE */
diff -urN linux-2.5.69-bk8/net/ipv6/ah6.c linux-2.5.69-bk9/net/ipv6/ah6.c
--- linux-2.5.69-bk8/net/ipv6/ah6.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/ah6.c	2003-05-14 04:43:45.000000000 -0700
@@ -75,8 +75,10 @@
 		skb->nh.ipv6h->version = 6;
 		skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 		skb->nh.ipv6h->nexthdr = IPPROTO_AH;
-		memcpy(&skb->nh.ipv6h->saddr, &x->props.saddr, sizeof(struct in6_addr));
-		memcpy(&skb->nh.ipv6h->daddr, &x->id.daddr, sizeof(struct in6_addr));
+		ipv6_addr_copy(&skb->nh.ipv6h->saddr,
+			       (struct in6_addr *) &x->props.saddr);
+		ipv6_addr_copy(&skb->nh.ipv6h->daddr,
+			       (struct in6_addr *) &x->id.daddr);
 		ah = (struct ip_auth_hdr*)(skb->nh.ipv6h+1);
 		ah->nexthdr = IPPROTO_IPV6;
 	} else {
diff -urN linux-2.5.69-bk8/net/ipv6/datagram.c linux-2.5.69-bk9/net/ipv6/datagram.c
--- linux-2.5.69-bk8/net/ipv6/datagram.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/datagram.c	2003-05-14 04:43:45.000000000 -0700
@@ -80,7 +80,7 @@
 
 	iph = (struct ipv6hdr*)skb_put(skb, sizeof(struct ipv6hdr));
 	skb->nh.ipv6h = iph;
-	memcpy(&iph->daddr, fl->fl6_dst, 16);
+	ipv6_addr_copy(&iph->daddr, fl->fl6_dst);
 
 	serr = SKB_EXT_ERR(skb);
 	serr->ee.ee_errno = err;
@@ -141,7 +141,8 @@
 		sin->sin6_port = serr->port; 
 		sin->sin6_scope_id = 0;
 		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
-			memcpy(&sin->sin6_addr, skb->nh.raw + serr->addr_offset, 16);
+			ipv6_addr_copy(&sin->sin6_addr,
+			  (struct in6_addr *)(skb->nh.raw + serr->addr_offset));
 			if (np->sndflow)
 				sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
 			if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
@@ -163,7 +164,7 @@
 		sin->sin6_flowinfo = 0;
 		sin->sin6_scope_id = 0;
 		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
-			memcpy(&sin->sin6_addr, &skb->nh.ipv6h->saddr, 16);
+			ipv6_addr_copy(&sin->sin6_addr, &skb->nh.ipv6h->saddr);
 			if (np->rxopt.all)
 				datagram_recv_ctl(sk, msg, skb);
 			if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
diff -urN linux-2.5.69-bk8/net/ipv6/esp6.c linux-2.5.69-bk9/net/ipv6/esp6.c
--- linux-2.5.69-bk8/net/ipv6/esp6.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/esp6.c	2003-05-14 04:43:45.000000000 -0700
@@ -184,8 +184,10 @@
 		top_iph->nexthdr = IPPROTO_ESP;
 		top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr));
 		top_iph->hop_limit = iph->hop_limit;
-		memcpy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr, sizeof(struct in6_addr));
-		memcpy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr, sizeof(struct in6_addr));
+		ipv6_addr_copy(&top_iph->saddr,
+			       (struct in6_addr *)&x->props.saddr);
+		ipv6_addr_copy(&top_iph->daddr,
+			       (struct in6_addr *)&x->id.daddr);
 	} else { 
 		/* XXX exthdr */
 		esph = (struct ipv6_esp_hdr*)skb_push(skb, x->props.header_len);
diff -urN linux-2.5.69-bk8/net/ipv6/ip6_fib.c linux-2.5.69-bk9/net/ipv6/ip6_fib.c
--- linux-2.5.69-bk8/net/ipv6/ip6_fib.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/ip6_fib.c	2003-05-14 04:43:45.000000000 -0700
@@ -1227,17 +1227,17 @@
 
 void __init fib6_init(void)
 {
-	if (!fib6_node_kmem)
-		fib6_node_kmem = kmem_cache_create("fib6_nodes",
-						   sizeof(struct fib6_node),
-						   0, SLAB_HWCACHE_ALIGN,
-						   NULL, NULL);
+	fib6_node_kmem = kmem_cache_create("fib6_nodes",
+					   sizeof(struct fib6_node),
+					   0, SLAB_HWCACHE_ALIGN,
+					   NULL, NULL);
 }
 
 #ifdef MODULE
 void fib6_gc_cleanup(void)
 {
 	del_timer(&ip6_fib_timer);
+	kmem_cache_destroy(fib6_node_kmem);
 }
 #endif
 
diff -urN linux-2.5.69-bk8/net/ipv6/ip6_output.c linux-2.5.69-bk9/net/ipv6/ip6_output.c
--- linux-2.5.69-bk8/net/ipv6/ip6_output.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/ip6_output.c	2003-05-14 04:43:45.000000000 -0700
@@ -141,7 +141,7 @@
 
 int ip6_output(struct sk_buff *skb)
 {
-	if ((skb->len > skb->dst->dev->mtu || skb_shinfo(skb)->frag_list))
+	if ((skb->len > dst_pmtu(skb->dst) || skb_shinfo(skb)->frag_list))
 		return ip6_fragment(skb, ip6_output2);
 	else
 		return ip6_output2(skb);
@@ -1463,8 +1463,8 @@
 		hdr->payload_len = 0;
 	hdr->hop_limit = np->hop_limit;
 	hdr->nexthdr = proto;
-	memcpy(&hdr->saddr, fl->fl6_src, sizeof(struct in6_addr));
-	memcpy(&hdr->daddr, final_dst, sizeof(struct in6_addr));
+	ipv6_addr_copy(&hdr->saddr, fl->fl6_src);
+	ipv6_addr_copy(&hdr->daddr, final_dst);
 
 	skb->dst = dst_clone(&rt->u.dst);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
diff -urN linux-2.5.69-bk8/net/ipv6/mcast.c linux-2.5.69-bk9/net/ipv6/mcast.c
--- linux-2.5.69-bk8/net/ipv6/mcast.c	2003-05-04 16:53:40.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/mcast.c	2003-05-14 04:43:45.000000000 -0700
@@ -179,7 +179,7 @@
 		return -ENOMEM;
 
 	mc_lst->next = NULL;
-	memcpy(&mc_lst->addr, addr, sizeof(struct in6_addr));
+	ipv6_addr_copy(&mc_lst->addr, addr);
 
 	if (ifindex == 0) {
 		struct rt6_info *rt;
@@ -825,7 +825,7 @@
 	mc->mca_timer.function = igmp6_timer_handler;
 	mc->mca_timer.data = (unsigned long) mc;
 
-	memcpy(&mc->mca_addr, addr, sizeof(struct in6_addr));
+	ipv6_addr_copy(&mc->mca_addr, addr);
 	mc->idev = idev;
 	mc->mca_users = 1;
 	atomic_set(&mc->mca_refcnt, 2);
diff -urN linux-2.5.69-bk8/net/ipv6/raw.c linux-2.5.69-bk9/net/ipv6/raw.c
--- linux-2.5.69-bk8/net/ipv6/raw.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/raw.c	2003-05-14 04:43:45.000000000 -0700
@@ -398,8 +398,7 @@
 	/* Copy the address. */
 	if (sin6) {
 		sin6->sin6_family = AF_INET6;
-		memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr, 
-		       sizeof(struct in6_addr));
+		ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
 		sin6->sin6_flowinfo = 0;
 		sin6->sin6_scope_id = 0;
 		if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
diff -urN linux-2.5.69-bk8/net/ipv6/route.c linux-2.5.69-bk9/net/ipv6/route.c
--- linux-2.5.69-bk8/net/ipv6/route.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/route.c	2003-05-14 04:43:45.000000000 -0700
@@ -1934,5 +1934,6 @@
 	xfrm6_fini();
 	rt6_ifdown(NULL);
 	fib6_gc_cleanup();
+	kmem_cache_destroy(ip6_dst_ops.kmem_cachep);
 }
 #endif	/* MODULE */
diff -urN linux-2.5.69-bk8/net/ipv6/udp.c linux-2.5.69-bk9/net/ipv6/udp.c
--- linux-2.5.69-bk8/net/ipv6/udp.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/udp.c	2003-05-14 04:43:45.000000000 -0700
@@ -467,8 +467,7 @@
 			if (inet->cmsg_flags)
 				ip_cmsg_recv(msg, skb);
 		} else {
-			memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
-			       sizeof(struct in6_addr));
+			ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
 
 			if (np->rxopt.all)
 				datagram_recv_ctl(sk, msg, skb);
diff -urN linux-2.5.69-bk8/net/ipv6/xfrm6_state.c linux-2.5.69-bk9/net/ipv6/xfrm6_state.c
--- linux-2.5.69-bk8/net/ipv6/xfrm6_state.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/ipv6/xfrm6_state.c	2003-05-14 04:43:45.000000000 -0700
@@ -25,8 +25,8 @@
 {
 	/* Initialize temporary selector matching only
 	 * to current session. */
-	memcpy(&x->sel.daddr, fl->fl6_dst, sizeof(struct in6_addr));
-	memcpy(&x->sel.saddr, fl->fl6_src, sizeof(struct in6_addr));
+	ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, fl->fl6_dst);
+	ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, fl->fl6_src);
 	x->sel.dport = fl->fl_ip_dport;
 	x->sel.dport_mask = ~0;
 	x->sel.sport = fl->fl_ip_sport;
@@ -93,13 +93,17 @@
 	if (x0) {
 		xfrm_state_hold(x0);
 	} else if (create && (x0 = xfrm_state_alloc()) != NULL) {
-		memcpy(x0->sel.daddr.a6, daddr, sizeof(struct in6_addr));
-		memcpy(x0->sel.saddr.a6, saddr, sizeof(struct in6_addr));
+		ipv6_addr_copy((struct in6_addr *)x0->sel.daddr.a6,
+			       (struct in6_addr *)daddr);
+		ipv6_addr_copy((struct in6_addr *)x0->sel.saddr.a6,
+			       (struct in6_addr *)saddr);
 		x0->sel.prefixlen_d = 128;
 		x0->sel.prefixlen_s = 128;
-		memcpy(x0->props.saddr.a6, saddr, sizeof(struct in6_addr));
+		ipv6_addr_copy((struct in6_addr *)x0->props.saddr.a6,
+			       (struct in6_addr *)saddr);
 		x0->km.state = XFRM_STATE_ACQ;
-		memcpy(x0->id.daddr.a6, daddr, sizeof(struct in6_addr));
+		ipv6_addr_copy((struct in6_addr *)x0->id.daddr.a6,
+			       (struct in6_addr *)daddr);
 		x0->id.proto = proto;
 		x0->props.family = AF_INET6;
 		x0->props.mode = mode;
diff -urN linux-2.5.69-bk8/net/netsyms.c linux-2.5.69-bk9/net/netsyms.c
--- linux-2.5.69-bk8/net/netsyms.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/netsyms.c	2003-05-14 04:43:46.000000000 -0700
@@ -45,6 +45,9 @@
 #include <linux/ip.h>
 #include <net/protocol.h>
 #include <net/arp.h>
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+#include <net/atmclip.h>
+#endif
 #include <net/ip.h>
 #include <net/udp.h>
 #include <net/tcp.h>
@@ -526,6 +529,9 @@
 EXPORT_SYMBOL(ip_rcv);
 EXPORT_SYMBOL(arp_rcv);
 EXPORT_SYMBOL(arp_tbl);
+#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
+EXPORT_SYMBOL(clip_tbl_hook);
+#endif
 EXPORT_SYMBOL(arp_find);
 
 #endif  /* CONFIG_INET */
diff -urN linux-2.5.69-bk8/net/sunrpc/rpc_pipe.c linux-2.5.69-bk9/net/sunrpc/rpc_pipe.c
--- linux-2.5.69-bk8/net/sunrpc/rpc_pipe.c	2003-05-14 04:43:39.000000000 -0700
+++ linux-2.5.69-bk9/net/sunrpc/rpc_pipe.c	2003-05-14 04:43:46.000000000 -0700
@@ -156,7 +156,7 @@
 }
 
 static ssize_t
-rpc_pipe_read(struct file *filp, char *buf, size_t len, loff_t *offset)
+rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct rpc_inode *rpci = RPC_I(inode);
@@ -193,7 +193,7 @@
 }
 
 static ssize_t
-rpc_pipe_write(struct file *filp, const char *buf, size_t len, loff_t *offset)
+rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct rpc_inode *rpci = RPC_I(inode);
diff -urN linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_device.h linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_device.h
--- linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_device.h	2003-05-04 16:53:29.000000000 -0700
+++ linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_device.h	2003-05-14 04:43:46.000000000 -0700
@@ -135,8 +135,8 @@
 int snd_seq_oss_open(struct file *file, int level);
 void snd_seq_oss_release(seq_oss_devinfo_t *dp);
 int snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long arg);
-int snd_seq_oss_read(seq_oss_devinfo_t *dev, char *buf, int count);
-int snd_seq_oss_write(seq_oss_devinfo_t *dp, const char *buf, int count, struct file *opt);
+int snd_seq_oss_read(seq_oss_devinfo_t *dev, char __user *buf, int count);
+int snd_seq_oss_write(seq_oss_devinfo_t *dp, const char __user *buf, int count, struct file *opt);
 unsigned int snd_seq_oss_poll(seq_oss_devinfo_t *dp, struct file *file, poll_table * wait);
 
 void snd_seq_oss_reset(seq_oss_devinfo_t *dp);
diff -urN linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_ioctl.c linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_ioctl.c
--- linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_ioctl.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_ioctl.c	2003-05-14 04:43:46.000000000 -0700
@@ -35,7 +35,7 @@
 	struct synth_info inf;
 	struct midi_info minf;
 	unsigned char ev[8];
-	void *arg = (void*)carg;
+	void __user *arg = (void __user *)carg;
 	snd_seq_event_t tmpev;
 
 	switch (cmd) {
diff -urN linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_rw.c linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_rw.c
--- linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_rw.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_rw.c	2003-05-14 04:43:46.000000000 -0700
@@ -41,7 +41,7 @@
  */
 
 int
-snd_seq_oss_read(seq_oss_devinfo_t *dp, char *buf, int count)
+snd_seq_oss_read(seq_oss_devinfo_t *dp, char __user *buf, int count)
 {
 	seq_oss_readq_t *readq = dp->readq;
 	int cnt, pos;
@@ -81,7 +81,7 @@
  */
 
 int
-snd_seq_oss_write(seq_oss_devinfo_t *dp, const char *buf, int count, struct file *opt)
+snd_seq_oss_write(seq_oss_devinfo_t *dp, const char __user *buf, int count, struct file *opt)
 {
 	int rc, c, p, ev_size;
 	evrec_t rec;
diff -urN linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_synth.c linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_synth.c
--- linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_synth.c	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_synth.c	2003-05-14 04:43:46.000000000 -0700
@@ -450,7 +450,7 @@
  */
 int
 snd_seq_oss_synth_load_patch(seq_oss_devinfo_t *dp, int dev, int fmt,
-			    const char *buf, int p, int c)
+			    const char __user *buf, int p, int c)
 {
 	seq_oss_synth_t *rec;
 	int rc;
diff -urN linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_timer.c linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_timer.c
--- linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_timer.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_timer.c	2003-05-14 04:43:46.000000000 -0700
@@ -227,19 +227,19 @@
  * ioctls
  */
 int
-snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, void *arg)
+snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, int __user *arg)
 {
 	int value;
 
 	if (cmd == SNDCTL_SEQ_CTRLRATE) {
 		debug_printk(("ctrl rate\n"));
 		/* if *arg == 0, just return the current rate */
-		if (get_user(value, (int *)arg))
+		if (get_user(value, arg))
 			return -EFAULT;
 		if (value)
 			return -EINVAL;
 		value = ((timer->oss_tempo * timer->oss_timebase) + 30) / 60;
-		return put_user(value, (int *)arg) ? -EFAULT : 0;
+		return put_user(value, arg) ? -EFAULT : 0;
 	}
 
 	if (timer->dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH)
@@ -257,12 +257,12 @@
 		return snd_seq_oss_timer_continue(timer);
 	case SNDCTL_TMR_TEMPO:
 		debug_printk(("timer tempo\n"));
-		if (get_user(value, (int *)arg))
+		if (get_user(value, arg))
 			return -EFAULT;
 		return snd_seq_oss_timer_tempo(timer, value);
 	case SNDCTL_TMR_TIMEBASE:
 		debug_printk(("timer timebase\n"));
-		if (get_user(value, (int *)arg))
+		if (get_user(value, arg))
 			return -EFAULT;
 		if (value < MIN_OSS_TIMEBASE)
 			value = MIN_OSS_TIMEBASE;
diff -urN linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_timer.h linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_timer.h
--- linux-2.5.69-bk8/sound/core/seq/oss/seq_oss_timer.h	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk9/sound/core/seq/oss/seq_oss_timer.h	2003-05-14 04:43:46.000000000 -0700
@@ -46,7 +46,7 @@
 int snd_seq_oss_timer_tempo(seq_oss_timer_t *timer, int value);
 #define snd_seq_oss_timer_reset  snd_seq_oss_timer_start
 
-int snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, void *arg);
+int snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, int __user *arg);
 
 /*
  * get current processed time
diff -urN linux-2.5.69-bk8/sound/core/seq/seq_clientmgr.c linux-2.5.69-bk9/sound/core/seq/seq_clientmgr.c
--- linux-2.5.69-bk8/sound/core/seq/seq_clientmgr.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk9/sound/core/seq/seq_clientmgr.c	2003-05-14 04:43:46.000000000 -0700
@@ -365,7 +365,7 @@
  *	-EINVAL	no enough user-space buffer to write the whole event
  *	-EFAULT	seg. fault during copy to user space
  */
-static ssize_t snd_seq_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
 	client_t *client = (client_t *) file->private_data;
 	fifo_t *fifo;
@@ -959,7 +959,7 @@
  *	-EMLINK	too many hops
  *	others	depends on return value from driver callback
  */
-static ssize_t snd_seq_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t snd_seq_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 {
 	client_t *client = (client_t *) file->private_data;
 	int written = 0, len;
@@ -1077,7 +1077,7 @@
 
 
 /* SYSTEM_INFO ioctl() */
-static int snd_seq_ioctl_system_info(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_system_info(client_t *client, void __user *arg)
 {
 	snd_seq_system_info_t info;
 
@@ -1090,20 +1090,20 @@
 	info.cur_clients = client_usage.cur;
 	info.cur_queues = snd_seq_queue_get_cur_queues();
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 	return 0;
 }
 
 
 /* RUNNING_MODE ioctl() */
-static int snd_seq_ioctl_running_mode(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_running_mode(client_t *client, void __user *arg)
 {
 	struct sndrv_seq_running_info info;
 	client_t *cptr;
 	int err = 0;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	/* requested client number */
@@ -1148,12 +1148,12 @@
 	memset(info->reserved, 0, sizeof(info->reserved));
 }
 
-static int snd_seq_ioctl_get_client_info(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_get_client_info(client_t * client, void __user *arg)
 {
 	client_t *cptr;
 	snd_seq_client_info_t client_info;
 
-	if (copy_from_user(&client_info, (void*)arg, sizeof(client_info)))
+	if (copy_from_user(&client_info, arg, sizeof(client_info)))
 		return -EFAULT;
 
 	/* requested client number */
@@ -1164,18 +1164,18 @@
 	get_client_info(cptr, &client_info);
 	snd_seq_client_unlock(cptr);
 
-	if (copy_to_user((void*)arg, &client_info, sizeof(client_info)))
+	if (copy_to_user(arg, &client_info, sizeof(client_info)))
 		return -EFAULT;
 	return 0;
 }
 
 
 /* CLIENT_INFO ioctl() */
-static int snd_seq_ioctl_set_client_info(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_set_client_info(client_t * client, void __user *arg)
 {
 	snd_seq_client_info_t client_info;
 
-	if (copy_from_user(&client_info, (void*)arg, sizeof(client_info)))
+	if (copy_from_user(&client_info, arg, sizeof(client_info)))
 		return -EFAULT;
 
 	/* it is not allowed to set the info fields for an another client */
@@ -1201,13 +1201,13 @@
 /* 
  * CREATE PORT ioctl() 
  */
-static int snd_seq_ioctl_create_port(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_create_port(client_t * client, void __user *arg)
 {
 	client_port_t *port;
 	snd_seq_port_info_t info;
 	snd_seq_port_callback_t *callback;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	/* it is not allowed to create the port for an another client */
@@ -1242,7 +1242,7 @@
 	snd_seq_set_port_info(port, &info);
 	snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port);
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 
 	return 0;
@@ -1251,13 +1251,13 @@
 /* 
  * DELETE PORT ioctl() 
  */
-static int snd_seq_ioctl_delete_port(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_delete_port(client_t * client, void __user *arg)
 {
 	snd_seq_port_info_t info;
 	int err;
 
 	/* set passed parameters */
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 	
 	/* it is not allowed to remove the port for an another client */
@@ -1274,13 +1274,13 @@
 /* 
  * GET_PORT_INFO ioctl() (on any client) 
  */
-static int snd_seq_ioctl_get_port_info(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_get_port_info(client_t *client, void __user *arg)
 {
 	client_t *cptr;
 	client_port_t *port;
 	snd_seq_port_info_t info;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 	cptr = snd_seq_client_use_ptr(info.addr.client);
 	if (cptr == NULL)
@@ -1297,7 +1297,7 @@
 	snd_seq_port_unlock(port);
 	snd_seq_client_unlock(cptr);
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 	return 0;
 }
@@ -1306,12 +1306,12 @@
 /* 
  * SET_PORT_INFO ioctl() (only ports on this/own client) 
  */
-static int snd_seq_ioctl_set_port_info(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_set_port_info(client_t * client, void __user *arg)
 {
 	client_port_t *port;
 	snd_seq_port_info_t info;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	if (info.addr.client != client->number) /* only set our own ports ! */
@@ -1381,14 +1381,14 @@
 /* 
  * add to port's subscription list IOCTL interface 
  */
-static int snd_seq_ioctl_subscribe_port(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_subscribe_port(client_t * client, void __user *arg)
 {
 	int result = -EINVAL;
 	client_t *receiver = NULL, *sender = NULL;
 	client_port_t *sport = NULL, *dport = NULL;
 	snd_seq_port_subscribe_t subs;
 
-	if (copy_from_user(&subs, (void*)arg, sizeof(subs)))
+	if (copy_from_user(&subs, arg, sizeof(subs)))
 		return -EFAULT;
 
 	if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL)
@@ -1425,14 +1425,14 @@
 /* 
  * remove from port's subscription list 
  */
-static int snd_seq_ioctl_unsubscribe_port(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_unsubscribe_port(client_t * client, void __user *arg)
 {
 	int result = -ENXIO;
 	client_t *receiver = NULL, *sender = NULL;
 	client_port_t *sport = NULL, *dport = NULL;
 	snd_seq_port_subscribe_t subs;
 
-	if (copy_from_user(&subs, (void*)arg, sizeof(subs)))
+	if (copy_from_user(&subs, arg, sizeof(subs)))
 		return -EFAULT;
 
 	if ((receiver = snd_seq_client_use_ptr(subs.dest.client)) == NULL)
@@ -1466,13 +1466,13 @@
 
 
 /* CREATE_QUEUE ioctl() */
-static int snd_seq_ioctl_create_queue(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_create_queue(client_t *client, void __user *arg)
 {
 	snd_seq_queue_info_t info;
 	int result;
 	queue_t *q;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	result = snd_seq_queue_alloc(client->number, info.locked, info.flags);
@@ -1494,30 +1494,30 @@
 	q->name[sizeof(q->name)-1] = 0;
 	queuefree(q);
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 
 	return 0;
 }
 
 /* DELETE_QUEUE ioctl() */
-static int snd_seq_ioctl_delete_queue(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_delete_queue(client_t *client, void __user *arg)
 {
 	snd_seq_queue_info_t info;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	return snd_seq_queue_delete(client->number, info.queue);
 }
 
 /* GET_QUEUE_INFO ioctl() */
-static int snd_seq_ioctl_get_queue_info(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_get_queue_info(client_t *client, void __user *arg)
 {
 	snd_seq_queue_info_t info;
 	queue_t *q;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	q = queueptr(info.queue);
@@ -1532,19 +1532,19 @@
 	info.name[sizeof(info.name)-1] = 0;
 	queuefree(q);
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 
 	return 0;
 }
 
 /* SET_QUEUE_INFO ioctl() */
-static int snd_seq_ioctl_set_queue_info(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_set_queue_info(client_t *client, void __user *arg)
 {
 	snd_seq_queue_info_t info;
 	queue_t *q;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	if (info.owner != client->number)
@@ -1575,12 +1575,12 @@
 }
 
 /* GET_NAMED_QUEUE ioctl() */
-static int snd_seq_ioctl_get_named_queue(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_get_named_queue(client_t *client, void __user *arg)
 {
 	snd_seq_queue_info_t info;
 	queue_t *q;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	q = snd_seq_queue_find_name(info.name);
@@ -1591,20 +1591,20 @@
 	info.locked = q->locked;
 	queuefree(q);
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 
 	return 0;
 }
 
 /* GET_QUEUE_STATUS ioctl() */
-static int snd_seq_ioctl_get_queue_status(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_get_queue_status(client_t * client, void __user *arg)
 {
 	snd_seq_queue_status_t status;
 	queue_t *queue;
 	seq_timer_t *tmr;
 
-	if (copy_from_user(&status, (void*)arg, sizeof(status)))
+	if (copy_from_user(&status, arg, sizeof(status)))
 		return -EFAULT;
 
 	queue = queueptr(status.queue);
@@ -1624,20 +1624,20 @@
 	status.flags = queue->flags;
 	queuefree(queue);
 
-	if (copy_to_user((void*)arg, &status, sizeof(status)))
+	if (copy_to_user(arg, &status, sizeof(status)))
 		return -EFAULT;
 	return 0;
 }
 
 
 /* GET_QUEUE_TEMPO ioctl() */
-static int snd_seq_ioctl_get_queue_tempo(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_get_queue_tempo(client_t * client, void __user *arg)
 {
 	snd_seq_queue_tempo_t tempo;
 	queue_t *queue;
 	seq_timer_t *tmr;
 
-	if (copy_from_user(&tempo, (void*)arg, sizeof(tempo)))
+	if (copy_from_user(&tempo, arg, sizeof(tempo)))
 		return -EFAULT;
 
 	queue = queueptr(tempo.queue);
@@ -1654,19 +1654,19 @@
 	tempo.skew_base = tmr->skew_base;
 	queuefree(queue);
 
-	if (copy_to_user((void*)arg, &tempo, sizeof(tempo)))
+	if (copy_to_user(arg, &tempo, sizeof(tempo)))
 		return -EFAULT;
 	return 0;
 }
 
 
 /* SET_QUEUE_TEMPO ioctl() */
-static int snd_seq_ioctl_set_queue_tempo(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_set_queue_tempo(client_t * client, void __user *arg)
 {
 	int result;
 	snd_seq_queue_tempo_t tempo;
 
-	if (copy_from_user(&tempo, (void*)arg, sizeof(tempo)))
+	if (copy_from_user(&tempo, arg, sizeof(tempo)))
 		return -EFAULT;
 
 	if (snd_seq_queue_check_access(tempo.queue, client->number)) {
@@ -1682,13 +1682,13 @@
 
 
 /* GET_QUEUE_TIMER ioctl() */
-static int snd_seq_ioctl_get_queue_timer(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_get_queue_timer(client_t * client, void __user *arg)
 {
 	snd_seq_queue_timer_t timer;
 	queue_t *queue;
 	seq_timer_t *tmr;
 
-	if (copy_from_user(&timer, (void*)arg, sizeof(timer)))
+	if (copy_from_user(&timer, arg, sizeof(timer)))
 		return -EFAULT;
 
 	queue = queueptr(timer.queue);
@@ -1711,19 +1711,19 @@
 	up(&queue->timer_mutex);
 	queuefree(queue);
 	
-	if (copy_to_user((void*)arg, &timer, sizeof(timer)))
+	if (copy_to_user(arg, &timer, sizeof(timer)))
 		return -EFAULT;
 	return 0;
 }
 
 
 /* SET_QUEUE_TIMER ioctl() */
-static int snd_seq_ioctl_set_queue_timer(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_set_queue_timer(client_t * client, void __user *arg)
 {
 	int result = 0;
 	snd_seq_queue_timer_t timer;
 
-	if (copy_from_user(&timer, (void*)arg, sizeof(timer)))
+	if (copy_from_user(&timer, arg, sizeof(timer)))
 		return -EFAULT;
 
 	if (timer.type != SNDRV_SEQ_TIMER_ALSA)
@@ -1759,12 +1759,12 @@
 
 
 /* GET_QUEUE_CLIENT ioctl() */
-static int snd_seq_ioctl_get_queue_client(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_get_queue_client(client_t * client, void __user *arg)
 {
 	snd_seq_queue_client_t info;
 	int used;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	used = snd_seq_queue_is_used(info.queue, client->number);
@@ -1773,19 +1773,19 @@
 	info.used = used;
 	info.client = client->number;
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 	return 0;
 }
 
 
 /* SET_QUEUE_CLIENT ioctl() */
-static int snd_seq_ioctl_set_queue_client(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_set_queue_client(client_t * client, void __user *arg)
 {
 	int err;
 	snd_seq_queue_client_t info;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	if (info.used >= 0) {
@@ -1799,12 +1799,12 @@
 
 
 /* GET_CLIENT_POOL ioctl() */
-static int snd_seq_ioctl_get_client_pool(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_get_client_pool(client_t * client, void __user *arg)
 {
 	snd_seq_client_pool_t info;
 	client_t *cptr;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	cptr = snd_seq_client_use_ptr(info.client);
@@ -1827,18 +1827,18 @@
 	}
 	snd_seq_client_unlock(cptr);
 	
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 	return 0;
 }
 
 /* SET_CLIENT_POOL ioctl() */
-static int snd_seq_ioctl_set_client_pool(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_set_client_pool(client_t * client, void __user *arg)
 {
 	snd_seq_client_pool_t info;
 	int rc;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	if (client->number != info.client)
@@ -1877,11 +1877,11 @@
 
 
 /* REMOVE_EVENTS ioctl() */
-static int snd_seq_ioctl_remove_events(client_t * client, unsigned long arg)
+static int snd_seq_ioctl_remove_events(client_t * client, void __user *arg)
 {
 	snd_seq_remove_events_t info;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	/*
@@ -1906,7 +1906,7 @@
 /*
  * get subscription info
  */
-static int snd_seq_ioctl_get_subscription(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_get_subscription(client_t *client, void __user *arg)
 {
 	int result;
 	client_t *sender = NULL;
@@ -1914,7 +1914,7 @@
 	snd_seq_port_subscribe_t subs;
 	subscribers_t *p;
 
-	if (copy_from_user(&subs, (void*)arg, sizeof(subs)))
+	if (copy_from_user(&subs, arg, sizeof(subs)))
 		return -EFAULT;
 
 	result = -EINVAL;
@@ -1935,7 +1935,7 @@
 	if (sender)
 		snd_seq_client_unlock(sender);
 	if (result >= 0) {
-		if (copy_to_user((void*)arg, &subs, sizeof(subs)))
+		if (copy_to_user(arg, &subs, sizeof(subs)))
 			return -EFAULT;
 	}
 	return result;
@@ -1945,7 +1945,7 @@
 /*
  * get subscription info - check only its presence
  */
-static int snd_seq_ioctl_query_subs(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_query_subs(client_t *client, void __user *arg)
 {
 	int result = -ENXIO;
 	client_t *cptr = NULL;
@@ -1955,7 +1955,7 @@
 	struct list_head *p;
 	int i;
 
-	if (copy_from_user(&subs, (void*)arg, sizeof(subs)))
+	if (copy_from_user(&subs, arg, sizeof(subs)))
 		return -EFAULT;
 
 	if ((cptr = snd_seq_client_use_ptr(subs.root.client)) == NULL)
@@ -2004,7 +2004,7 @@
 	if (cptr)
 		snd_seq_client_unlock(cptr);
 	if (result >= 0) {
-		if (copy_to_user((void*)arg, &subs, sizeof(subs)))
+		if (copy_to_user(arg, &subs, sizeof(subs)))
 			return -EFAULT;
 	}
 	return result;
@@ -2014,12 +2014,12 @@
 /*
  * query next client
  */
-static int snd_seq_ioctl_query_next_client(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_query_next_client(client_t *client, void __user *arg)
 {
 	client_t *cptr = NULL;
 	snd_seq_client_info_t info;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 
 	/* search for next client */
@@ -2037,7 +2037,7 @@
 	get_client_info(cptr, &info);
 	snd_seq_client_unlock(cptr);
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 	return 0;
 }
@@ -2045,13 +2045,13 @@
 /* 
  * query next port
  */
-static int snd_seq_ioctl_query_next_port(client_t *client, unsigned long arg)
+static int snd_seq_ioctl_query_next_port(client_t *client, void __user *arg)
 {
 	client_t *cptr;
 	client_port_t *port = NULL;
 	snd_seq_port_info_t info;
 
-	if (copy_from_user(&info, (void*)arg, sizeof(info)))
+	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
 	cptr = snd_seq_client_use_ptr(info.addr.client);
 	if (cptr == NULL)
@@ -2071,7 +2071,7 @@
 	snd_seq_port_unlock(port);
 	snd_seq_client_unlock(cptr);
 
-	if (copy_to_user((void*)arg, &info, sizeof(info)))
+	if (copy_to_user(arg, &info, sizeof(info)))
 		return -EFAULT;
 	return 0;
 }
@@ -2080,7 +2080,7 @@
 
 static struct seq_ioctl_table {
 	unsigned int cmd;
-	int (*func)(client_t *client, unsigned long arg);
+	int (*func)(client_t *client, void __user * arg);
 } ioctl_tables[] = {
 	{ SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info },
 	{ SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode },
@@ -2114,7 +2114,7 @@
 	{ 0, NULL },
 };
 
-static int snd_seq_do_ioctl(client_t *client, unsigned int cmd, unsigned long arg)
+static int snd_seq_do_ioctl(client_t *client, unsigned int cmd, void __user *arg)
 {
 	struct seq_ioctl_table *p;
 
@@ -2131,7 +2131,7 @@
 		return -EFAULT;
 	for (p = ioctl_tables; p->cmd; p++) {
 		if (p->cmd == cmd)
-			return p->func(client, arg);
+			return p->func(client, (void __user *) arg);
 	}
 	snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%2x)\n",
 		   cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
@@ -2146,7 +2146,7 @@
 
 	snd_assert(client != NULL, return -ENXIO);
 		
-	return snd_seq_do_ioctl(client, cmd, arg);
+	return snd_seq_do_ioctl(client, cmd, (void __user *) arg);
 }
 
 
@@ -2315,7 +2315,7 @@
  * exported, called by kernel clients to perform same functions as with
  * userland ioctl() 
  */
-int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
+int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void __user *arg)
 {
 	client_t *client;
 	mm_segment_t fs;
@@ -2325,7 +2325,7 @@
 	if (client == NULL)
 		return -ENXIO;
 	fs = snd_enter_user();
-	result = snd_seq_do_ioctl(client, cmd, (unsigned long)arg);
+	result = snd_seq_do_ioctl(client, cmd, arg);
 	snd_leave_user(fs);
 	return result;
 }
