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

diff -urN linux-2.5.69-bk16/Makefile linux-2.5.69-bk17/Makefile
--- linux-2.5.69-bk16/Makefile	2003-05-24 04:33:28.000000000 -0700
+++ linux-2.5.69-bk17/Makefile	2003-05-24 04:33:33.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 69
-EXTRAVERSION = -bk16
+EXTRAVERSION = -bk17
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.69-bk16/arch/i386/kernel/mpparse.c linux-2.5.69-bk17/arch/i386/kernel/mpparse.c
--- linux-2.5.69-bk16/arch/i386/kernel/mpparse.c	2003-05-24 04:33:28.000000000 -0700
+++ linux-2.5.69-bk17/arch/i386/kernel/mpparse.c	2003-05-24 04:33:33.000000000 -0700
@@ -1086,7 +1086,7 @@
 
 	/*
 	 * Parsing through the PCI Interrupt Routing Table (PRT) and program
-	 * routing for all static (IOAPIC-direct) entries.
+	 * routing for all entries.
 	 */
 	list_for_each(node, &acpi_prt.entries) {
 		entry = list_entry(node, struct acpi_prt_entry, node);
@@ -1100,6 +1100,10 @@
 		else
 			irq = entry->link.index;
 
+		/* Don't set up the ACPI SCI because it's already set up */
+		if (acpi_fadt.sci_int == irq)
+			continue;
+	
 		ioapic = mp_find_ioapic(irq);
 		if (ioapic < 0)
 			continue;
diff -urN linux-2.5.69-bk16/arch/x86_64/Kconfig linux-2.5.69-bk17/arch/x86_64/Kconfig
--- linux-2.5.69-bk16/arch/x86_64/Kconfig	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/Kconfig	2003-05-24 04:33:33.000000000 -0700
@@ -652,6 +652,7 @@
 config IOMMU_LEAK
        bool "IOMMU leak tracing"
        depends on DEBUG_KERNEL
+       depends on IOMMU_DEBUG
        help
          Add a simple leak tracer to the IOMMU code. This is useful when you
 	 are debugging a buggy device driver that leaks IOMMU mappings.
diff -urN linux-2.5.69-bk16/arch/x86_64/Makefile linux-2.5.69-bk17/arch/x86_64/Makefile
--- linux-2.5.69-bk16/arch/x86_64/Makefile	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/Makefile	2003-05-24 04:33:33.000000000 -0700
@@ -46,6 +46,7 @@
 CFLAGS += -fno-reorder-blocks	
 # should lower this a lot and see how much .text is saves	
 CFLAGS += -finline-limit=2000
+CFLAGS += -Wno-sign-compare
 #CFLAGS += -g
 # don't enable this when you use kgdb:
 ifneq ($(CONFIG_X86_REMOTE_DEBUG),y)
diff -urN linux-2.5.69-bk16/arch/x86_64/defconfig linux-2.5.69-bk17/arch/x86_64/defconfig
--- linux-2.5.69-bk16/arch/x86_64/defconfig	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/defconfig	2003-05-24 04:33:33.000000000 -0700
@@ -4,7 +4,6 @@
 CONFIG_X86_64=y
 CONFIG_X86=y
 CONFIG_MMU=y
-CONFIG_SWAP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_X86_CMPXCHG=y
 CONFIG_EARLY_PRINTK=y
@@ -18,6 +17,7 @@
 #
 # General setup
 #
+CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -47,8 +47,12 @@
 CONFIG_X86_IO_APIC=y
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_MTRR=y
-CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE is not set
 CONFIG_SMP=y
+# CONFIG_PREEMPT is not set
+CONFIG_K8_NUMA=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_NUMA=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_NR_CPUS=8
 CONFIG_GART_IOMMU=y
@@ -222,9 +226,8 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
-CONFIG_FILTER=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -239,8 +242,9 @@
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
-# CONFIG_XFRM_USER is not set
+# CONFIG_INET_IPCOMP is not set
 # CONFIG_IPV6 is not set
+# CONFIG_XFRM_USER is not set
 
 #
 #    SCTP Configuration (EXPERIMENTAL)
@@ -331,6 +335,11 @@
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
 CONFIG_TIGON3=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
@@ -405,15 +414,7 @@
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
-CONFIG_INPUT_JOYSTICK=y
-# CONFIG_JOYSTICK_IFORCE is not set
-# CONFIG_JOYSTICK_WARRIOR is not set
-# CONFIG_JOYSTICK_MAGELLAN is not set
-# CONFIG_JOYSTICK_SPACEORB is not set
-# CONFIG_JOYSTICK_SPACEBALL is not set
-# CONFIG_JOYSTICK_STINGER is not set
-# CONFIG_JOYSTICK_TWIDDLER is not set
-# CONFIG_INPUT_JOYDUMP is not set
+# CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -452,6 +453,7 @@
 #
 # I2C Hardware Sensors Chip support
 #
+# CONFIG_I2C_SENSOR is not set
 
 #
 # Mice
@@ -468,8 +470,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_AMD_RNG is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
 # CONFIG_DTLK is not set
@@ -481,8 +482,8 @@
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_AGP_GART is not set
+CONFIG_AGP=y
+CONFIG_AGP_AMD_8151=y
 # CONFIG_DRM is not set
 # CONFIG_MWAVE is not set
 CONFIG_RAW_DRIVER=y
@@ -498,57 +499,75 @@
 # CONFIG_VIDEO_DEV is not set
 
 #
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
 # File systems
 #
-# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_JFS_FS is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_FAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
 # CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
 # CONFIG_UFS_FS is not set
-CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
 
 #
 # Network File Systems
 #
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V4 is not set
@@ -556,14 +575,16 @@
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
-CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_GSS is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
-# CONFIG_CIFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_GSS is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -594,6 +615,7 @@
 # USB support
 #
 # CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
 
 #
 # Bluetooth support
@@ -615,6 +637,9 @@
 # CONFIG_INIT_DEBUG is not set
 CONFIG_KALLSYMS=y
 # CONFIG_FRAME_POINTER is not set
+CONFIG_IOMMU_DEBUG=y
+CONFIG_IOMMU_LEAK=y
+CONFIG_MCE_DEBUG=y
 
 #
 # Security options
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/Makefile linux-2.5.69-bk17/arch/x86_64/ia32/Makefile
--- linux-2.5.69-bk16/arch/x86_64/ia32/Makefile	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/ia32/Makefile	2003-05-24 04:33:33.000000000 -0700
@@ -5,3 +5,12 @@
 obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
 	ia32_signal.o tls32.o \
 	ia32_binfmt.o fpu32.o ptrace32.o ipc32.o syscall32.o
+
+$(obj)/syscall32.o: $(src)/syscall32.c $(obj)/vsyscall.so
+
+# The DSO images are built using a special linker script.
+$(obj)/vsyscall.so: $(src)/vsyscall.lds $(obj)/vsyscall.o
+	$(CC) -m32 -nostdlib -shared -s -Wl,-soname=linux-vsyscall.so.1 \
+		-o $@ -Wl,-T,$^
+
+AFLAGS_vsyscall.o = -m32
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/ia32_binfmt.c linux-2.5.69-bk17/arch/x86_64/ia32/ia32_binfmt.c
--- linux-2.5.69-bk16/arch/x86_64/ia32/ia32_binfmt.c	2003-05-24 04:33:28.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/ia32/ia32_binfmt.c	2003-05-24 04:33:33.000000000 -0700
@@ -6,11 +6,11 @@
  * of ugly preprocessor tricks. Talk about very very poor man's inheritance.
  */ 
 #include <linux/types.h>
-#include <linux/compat.h>
 #include <linux/config.h> 
 #include <linux/stddef.h>
 #include <linux/rwsem.h>
 #include <linux/sched.h>
+#include <linux/compat.h>
 #include <linux/string.h>
 #include <linux/binfmts.h>
 #include <linux/mm.h>
@@ -23,12 +23,17 @@
 #include <asm/i387.h>
 #include <asm/uaccess.h>
 #include <asm/ia32.h>
+#include <asm/vsyscall32.h>
 
 #define ELF_NAME "elf/i386"
 
 #define AT_SYSINFO 32
+#define AT_SYSINFO_EHDR		33
 
-#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO, 0xffffe000)
+#define ARCH_DLINFO do {  \
+	NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
+	NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE);    \
+} while(0)
 
 struct file;
 struct elf_phdr; 
@@ -54,6 +59,47 @@
 #define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
+/*
+ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
+ * extra segments containing the vsyscall DSO contents.  Dumping its
+ * contents makes post-mortem fully interpretable later without matching up
+ * the same kernel and hardware config to see what PC values meant.
+ * Dumping its extra ELF program headers includes all the other information
+ * a debugger needs to easily find how the vsyscall DSO was being used.
+ */
+#define ELF_CORE_EXTRA_PHDRS		(VSYSCALL32_EHDR->e_phnum)
+#define ELF_CORE_WRITE_EXTRA_PHDRS					      \
+do {									      \
+	const struct elf32_phdr *const vsyscall_phdrs =			      \
+		(const struct elf32_phdr *) (VSYSCALL32_BASE		      \
+					   + VSYSCALL32_EHDR->e_phoff);	      \
+	int i;								      \
+	Elf32_Off ofs = 0;						      \
+	for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) {		      \
+		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
+		if (phdr.p_type == PT_LOAD) {				      \
+			ofs = phdr.p_offset = offset;			      \
+			offset += phdr.p_filesz;			      \
+		}							      \
+		else							      \
+			phdr.p_offset += ofs;				      \
+		phdr.p_paddr = 0; /* match other core phdrs */		      \
+		DUMP_WRITE(&phdr, sizeof(phdr));			      \
+	}								      \
+} while (0)
+#define ELF_CORE_WRITE_EXTRA_DATA					      \
+do {									      \
+	const struct elf32_phdr *const vsyscall_phdrs =			      \
+		(const struct elf32_phdr *) (VSYSCALL32_BASE		      \
+					   + VSYSCALL32_EHDR->e_phoff);	      \
+	int i;								      \
+	for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) {		      \
+		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
+			DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,	      \
+				   vsyscall_phdrs[i].p_filesz);		      \
+	}								      \
+} while (0)
+
 struct elf_siginfo
 {
 	int	si_signo;			/* signal number */
@@ -157,7 +203,6 @@
 	struct _fpstate_ia32 *fpstate = (void*)fpu; 
 	struct pt_regs *regs = (struct pt_regs *)(tsk->thread.rsp0); 
 	mm_segment_t oldfs = get_fs();
-	int ret;
 
 	if (!tsk->used_math) 
 		return 0;
@@ -165,12 +210,12 @@
 	if (tsk == current)
 		unlazy_fpu(tsk);
 	set_fs(KERNEL_DS); 
-	ret = save_i387_ia32(tsk, fpstate, regs, 1);
+	save_i387_ia32(tsk, fpstate, regs, 1);
 	/* Correct for i386 bug. It puts the fop into the upper 16bits of 
 	   the tag word (like FXSAVE), not into the fcs*/ 
 	fpstate->cssel |= fpstate->tag & 0xffff0000; 
 	set_fs(oldfs); 
-	return ret; 
+	return 1; 
 }
 
 #define ELF_CORE_COPY_XFPREGS 1
@@ -302,8 +347,9 @@
 		mpnt->vm_mm = mm;
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
 		mpnt->vm_end = IA32_STACK_TOP;
-		mpnt->vm_page_prot = PAGE_COPY_EXEC;
-		mpnt->vm_flags = VM_STACK_FLAGS;
+		mpnt->vm_flags = vm_stack_flags32; 
+ 		mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? 
+ 			PAGE_COPY_EXEC : PAGE_COPY;
 		mpnt->vm_ops = NULL;
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
@@ -333,7 +379,7 @@
 	struct task_struct *me = current; 
 
 	if (prot & PROT_READ) 
-		prot |= PROT_EXEC; 
+		prot |= vm_force_exec32;
 
 	down_write(&me->mm->mmap_sem);
 	map_addr = do_mmap(filep, ELF_PAGESTART(addr),
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/ia32_ioctl.c linux-2.5.69-bk17/arch/x86_64/ia32/ia32_ioctl.c
--- linux-2.5.69-bk16/arch/x86_64/ia32/ia32_ioctl.c	2003-05-24 04:33:28.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/ia32/ia32_ioctl.c	2003-05-24 04:33:33.000000000 -0700
@@ -10,10 +10,10 @@
  */
 
 #include <linux/config.h>
+#include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/compat.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/ioctl.h>
@@ -108,10 +108,6 @@
 
 #include <asm/mtrr.h>
 
-
-#define A(__x) ((void *)(unsigned long)(__x))
-#define AA(__x)	A(__x)
-
 /* Aiee. Someone does not find a difference between int and long */
 #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
 #define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
@@ -163,10 +159,10 @@
 }
  
 struct video_tuner32 {
-	s32 tuner;
-	u8 name[32];
-	u32 rangelow, rangehigh;
-	u32 flags;
+	compat_int_t tuner;
+	char name[32];
+	compat_ulong_t rangelow, rangehigh;
+	u32 flags;	/* It is really u32 in videodev.h */
 	u16 mode, signal;
 };
 
@@ -203,8 +199,8 @@
 }
 
 struct video_buffer32 {
-	/* void * */ u32 base;
-	s32 height, width, depth, bytesperline;
+	compat_caddr_t base;
+	compat_int_t height, width, depth, bytesperline;
 };
 
 static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
@@ -235,14 +231,14 @@
 }
 
 struct video_clip32 {
-	s32 x, y, width, height;
-	/* struct video_clip32 * */ u32 next;
+	s32 x, y, width, height;	/* Its really s32 in videodev.h */
+	compat_caddr_t next;
 };
 
 struct video_window32 {
 	u32 x, y, width, height, chromakey, flags;
-	/* struct video_clip32 * */ u32 clips;
-	s32 clipcount;
+	compat_caddr_t clips;
+	compat_int_t clipcount;
 };
 
 static void free_kvideo_clips(struct video_window *kp)
@@ -270,7 +266,7 @@
 	__get_user(kp->flags, &up->flags);
 	__get_user(kp->clipcount, &up->clipcount);
 	__get_user(tmp, &up->clips);
-	ucp = (struct video_clip32 *)A(tmp);
+	ucp = compat_ptr(tmp);
 	kp->clips = NULL;
 
 	nclips = kp->clipcount;
@@ -421,8 +417,8 @@
 }
 
 struct ifmap32 {
-	u32 mem_start;
-	u32 mem_end;
+	compat_ulong_t mem_start;
+	compat_ulong_t mem_end;
 	unsigned short base_addr;
 	unsigned char irq;
 	unsigned char dma;
@@ -442,17 +438,18 @@
                 struct  sockaddr ifru_netmask;
                 struct  sockaddr ifru_hwaddr;
                 short   ifru_flags;
-                int     ifru_ivalue;
-                int     ifru_mtu;
+                compat_int_t     ifru_ivalue;
+                compat_int_t     ifru_mtu;
                 struct  ifmap32 ifru_map;
                 char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
 		char	ifru_newname[IFNAMSIZ];
                 compat_caddr_t ifru_data;
+	    /* XXXX? ifru_settings should be here */
         } ifr_ifru;
 };
 
 struct ifconf32 {
-        int     ifc_len;                        /* size of buffer       */
+        compat_int_t	ifc_len;                        /* size of buffer       */
         compat_caddr_t  ifcbuf;
 };
 
@@ -504,7 +501,7 @@
 			return -ENOMEM;
 	}
 	ifr = ifc.ifc_req;
-	ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
+	ifr32 = compat_ptr(ifc32.ifcbuf);
 	for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
 		if (copy_from_user(ifr, ifr32, sizeof (struct ifreq32))) {
 			kfree (ifc.ifc_buf);
@@ -518,7 +515,7 @@
 	set_fs (old_fs);
 	if (!err) {
 		ifr = ifc.ifc_req;
-		ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
+		ifr32 = compat_ptr(ifc32.ifcbuf);
 		for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
 		     i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
 			int k = copy_to_user(ifr32, ifr, sizeof (struct ifreq32));
@@ -568,7 +565,7 @@
 
 	__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
 
-	if (get_user(ethcmd, (u32 *)A(data))) {
+	if (get_user(ethcmd, (u32 *)compat_ptr(data))) {
 		err = -EFAULT;
 		goto out;
 	}
@@ -579,12 +576,16 @@
 	case ETHTOOL_GLINK:
 	case ETHTOOL_NWAY_RST:  len = sizeof(struct ethtool_value); break;
 	case ETHTOOL_GREGS: {
-		struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);
+		struct ethtool_regs *regaddr = compat_ptr(data);
 		/* darned variable size arguments */
 		if (get_user(len, (u32 *)&regaddr->len)) {
 			err = -EFAULT;
 			goto out;
 		}
+		if (len > PAGE_SIZE - sizeof(struct ethtool_regs)) { 
+			err = -EINVAL;
+			goto out;
+		}			
 		len += sizeof(struct ethtool_regs);
 		break;
 	}
@@ -595,7 +596,7 @@
                goto out;
 	}
 
-	if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
+	if (copy_from_user(ifr.ifr_data, compat_ptr(data), len)) {
 		err = -EFAULT;
 		goto out;
 	}
@@ -608,7 +609,7 @@
 		u32 data;
 
 		__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
-		len = copy_to_user((char *)A(data), ifr.ifr_data, len);
+		len = copy_to_user(compat_ptr(data), ifr.ifr_data, len);
 		if (len)
 			err = -EFAULT;
 	}
@@ -651,7 +652,7 @@
 	};
 
 	__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
-	if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
+	if (copy_from_user(ifr.ifr_data, compat_ptr(data), len)) {
 		err = -EFAULT;
 		goto out;
 	}
@@ -661,7 +662,7 @@
 	err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
 	set_fs (old_fs);
 	if (!err) {
-		len = copy_to_user((char *)A(data), ifr.ifr_data, len);
+		len = copy_to_user(compat_ptr(data), ifr.ifr_data, len);
 		if (len)
 			err = -EFAULT;
 	}
@@ -684,7 +685,7 @@
 		return -EFAULT;
 	if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
 		return -EFAULT;
-	data64 = (void *) A(data32);
+	data64 = compat_ptr(data32);
 
 	u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
 
@@ -821,7 +822,7 @@
 		ret |= __get_user (r4.rt_irtt, &(((struct rtentry32 *)arg)->rt_irtt));
 		ret |= __get_user (rtdev, &(((struct rtentry32 *)arg)->rt_dev));
 		if (rtdev) {
-			ret |= copy_from_user (devname, (char *)A(rtdev), 15);
+			ret |= copy_from_user (devname, compat_ptr(rtdev), 15);
 			r4.rt_dev = devname; devname[15] = 0;
 		} else
 			r4.rt_dev = 0;
@@ -868,23 +869,23 @@
 struct fb_fix_screeninfo32 {
 	char			id[16];
         compat_caddr_t	smem_start;
-	__u32			smem_len;
-	__u32			type;
-	__u32			type_aux;
-	__u32			visual;
-	__u16			xpanstep;
-	__u16			ypanstep;
-	__u16			ywrapstep;
-	__u32			line_length;
+	u32			smem_len;
+	u32			type;
+	u32			type_aux;
+	u32			visual;
+	u16			xpanstep;
+	u16			ypanstep;
+	u16			ywrapstep;
+	u32			line_length;
         compat_caddr_t	mmio_start;
-	__u32			mmio_len;
-	__u32			accel;
-	__u16			reserved[3];
+	u32			mmio_len;
+	u32			accel;
+	u16			reserved[3];
 };
 
 struct fb_cmap32 {
-	__u32			start;
-	__u32			len;
+	u32			start;
+	u32			len;
 	compat_caddr_t	red;
 	compat_caddr_t	green;
 	compat_caddr_t	blue;
@@ -918,6 +919,10 @@
 			err = -EFAULT;
 			goto out;
 		}
+		if (cmap.len > PAGE_SIZE/sizeof(u16)) { 
+			err = -EINVAL;
+			goto out;
+		}
 		err = -ENOMEM;
 		cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
 		if (!cmap.red)
@@ -937,10 +942,10 @@
 		if (cmd == FBIOGETCMAP)
 			break;
 
-		err = __copy_from_user(cmap.red, (char *)A(red), cmap.len * sizeof(__u16));
-		err |= __copy_from_user(cmap.green, (char *)A(green), cmap.len * sizeof(__u16));
-		err |= __copy_from_user(cmap.blue, (char *)A(blue), cmap.len * sizeof(__u16));
-		if (cmap.transp) err |= __copy_from_user(cmap.transp, (char *)A(transp), cmap.len * sizeof(__u16));
+		err = __copy_from_user(cmap.red, compat_ptr(red), cmap.len * sizeof(__u16));
+		err |= __copy_from_user(cmap.green, compat_ptr(green), cmap.len * sizeof(__u16));
+		err |= __copy_from_user(cmap.blue, compat_ptr(blue), cmap.len * sizeof(__u16));
+		if (cmap.transp) err |= __copy_from_user(cmap.transp, compat_ptr(transp), cmap.len * sizeof(__u16));
 		if (err) {
 			err = -EFAULT;
 			goto out;
@@ -979,11 +984,11 @@
 		err |= __copy_to_user((char *)((struct fb_fix_screeninfo32 *)arg)->reserved, (char *)fix.reserved, sizeof(fix.reserved));
 		break;
 	case FBIOGETCMAP:
-		err = __copy_to_user((char *)A(red), cmap.red, cmap.len * sizeof(__u16));
-		err |= __copy_to_user((char *)A(green), cmap.blue, cmap.len * sizeof(__u16));
-		err |= __copy_to_user((char *)A(blue), cmap.blue, cmap.len * sizeof(__u16));
+		err = __copy_to_user(compat_ptr(red), cmap.red, cmap.len * sizeof(__u16));
+		err |= __copy_to_user(compat_ptr(green), cmap.blue, cmap.len * sizeof(__u16));
+		err |= __copy_to_user(compat_ptr(blue), cmap.blue, cmap.len * sizeof(__u16));
 		if (cmap.transp)
-			err |= __copy_to_user((char *)A(transp), cmap.transp, cmap.len * sizeof(__u16));
+			err |= __copy_to_user(compat_ptr(transp), cmap.transp, cmap.len * sizeof(__u16));
 		break;
 	case FBIOPUTCMAP:
 		break;
@@ -1018,11 +1023,11 @@
 }
 
 struct floppy_struct32 {
-	unsigned int	size;
-	unsigned int	sect;
-	unsigned int	head;
-	unsigned int	track;
-	unsigned int	stretch;
+	compat_uint_t	size;
+	compat_uint_t	sect;
+	compat_uint_t	head;
+	compat_uint_t	track;
+	compat_uint_t	stretch;
 	unsigned char	gap;
 	unsigned char	rate;
 	unsigned char	spec1;
@@ -1032,51 +1037,51 @@
 
 struct floppy_drive_params32 {
 	char		cmos;
-	u32		max_dtr;
-	u32		hlt;
-	u32		hut;
-	u32		srt;
-	u32		spinup;
-	u32		spindown;
+	compat_ulong_t	max_dtr;
+	compat_ulong_t	hlt;
+	compat_ulong_t	hut;
+	compat_ulong_t	srt;
+	compat_ulong_t	spinup;
+	compat_ulong_t	spindown;
 	unsigned char	spindown_offset;
 	unsigned char	select_delay;
 	unsigned char	rps;
 	unsigned char	tracks;
-	u32		timeout;
+	compat_ulong_t	timeout;
 	unsigned char	interleave_sect;
 	struct floppy_max_errors max_errors;
 	char		flags;
 	char		read_track;
 	short		autodetect[8];
-	int		checkfreq;
-	int		native_format;
+	compat_int_t	checkfreq;
+	compat_int_t	native_format;
 };
 
 struct floppy_drive_struct32 {
 	signed char	flags;
-	u32		spinup_date;
-	u32		select_date;
-	u32		first_read_date;
+	compat_ulong_t	spinup_date;
+	compat_ulong_t	select_date;
+	compat_ulong_t	first_read_date;
 	short		probed_format;
 	short		track;
 	short		maxblock;
 	short		maxtrack;
-	int		generation;
-	int		keep_data;
-	int		fd_ref;
-	int		fd_device;
-	int		last_checked;
+	compat_int_t	generation;
+	compat_int_t	keep_data;
+	compat_int_t	fd_ref;
+	compat_int_t	fd_device;
+	compat_int_t	last_checked;
 	compat_caddr_t dmabuf;
-	int		bufblocks;
+	compat_int_t	bufblocks;
 };
 
 struct floppy_fdc_state32 {
-	int		spec1;
-	int		spec2;
-	int		dtr;
+	compat_int_t	spec1;
+	compat_int_t	spec2;
+	compat_int_t	dtr;
 	unsigned char	version;
 	unsigned char	dor;
-	u32		address;
+	compat_ulong_t	address;
 	unsigned int	rawcmd:2;
 	unsigned int	reset:1;
 	unsigned int	need_configure:1;
@@ -1088,11 +1093,11 @@
 
 struct floppy_write_errors32 {
 	unsigned int	write_errors;
-	u32		first_error_sector;
-	int		first_error_generation;
-	u32		last_error_sector;
-	int		last_error_generation;
-	unsigned int	badness;
+	compat_ulong_t	first_error_sector;
+	compat_int_t	first_error_generation;
+	compat_ulong_t	last_error_sector;
+	compat_int_t	last_error_generation;
+	compat_uint_t	badness;
 };
 
 #define FDSETPRM32 _IOW(2, 0x42, struct floppy_struct32)
@@ -1329,42 +1334,46 @@
 
 
 typedef struct sg_io_hdr32 {
-	s32 interface_id;	/* [i] 'S' for SCSI generic (required) */
-	s32 dxfer_direction;	/* [i] data transfer direction  */
-	u8  cmd_len;		/* [i] SCSI command length ( <= 16 bytes) */
-	u8  mx_sb_len;		/* [i] max length to write to sbp */
-	u16 iovec_count;	/* [i] 0 implies no scatter gather */
-	u32 dxfer_len;		/* [i] byte count of data transfer */
-	u32 dxferp;		/* [i], [*io] points to data transfer memory
+	compat_int_t interface_id;	/* [i] 'S' for SCSI generic (required) */
+	compat_int_t dxfer_direction;	/* [i] data transfer direction  */
+	unsigned char cmd_len;		/* [i] SCSI command length ( <= 16 bytes) */
+	unsigned char mx_sb_len;		/* [i] max length to write to sbp */
+	unsigned short iovec_count;	/* [i] 0 implies no scatter gather */
+	compat_uint_t dxfer_len;		/* [i] byte count of data transfer */
+	compat_uint_t dxferp;		/* [i], [*io] points to data transfer memory
 					      or scatter gather list */
-	u32 cmdp;		/* [i], [*i] points to command to perform */
-	u32 sbp;		/* [i], [*o] points to sense_buffer memory */
-	u32 timeout;		/* [i] MAX_UINT->no timeout (unit: millisec) */
-	u32 flags;		/* [i] 0 -> default, see SG_FLAG... */
-	s32 pack_id;		/* [i->o] unused internally (normally) */
-	u32 usr_ptr;		/* [i->o] unused internally */
-	u8  status;		/* [o] scsi status */
-	u8  masked_status;	/* [o] shifted, masked scsi status */
-	u8  msg_status;		/* [o] messaging level data (optional) */
-	u8  sb_len_wr;		/* [o] byte count actually written to sbp */
-	u16 host_status;	/* [o] errors from host adapter */
-	u16 driver_status;	/* [o] errors from software driver */
-	s32 resid;		/* [o] dxfer_len - actual_transferred */
-	u32 duration;		/* [o] time taken by cmd (unit: millisec) */
-	u32 info;		/* [o] auxiliary information */
+	compat_uptr_t cmdp;		/* [i], [*i] points to command to perform */
+	compat_uptr_t sbp;		/* [i], [*o] points to sense_buffer memory */
+	compat_uint_t timeout;		/* [i] MAX_UINT->no timeout (unit: millisec) */
+	compat_uint_t flags;		/* [i] 0 -> default, see SG_FLAG... */
+	compat_int_t pack_id;		/* [i->o] unused internally (normally) */
+	compat_uptr_t usr_ptr;		/* [i->o] unused internally */
+	unsigned char status;		/* [o] scsi status */
+	unsigned char masked_status;	/* [o] shifted, masked scsi status */
+	unsigned char msg_status;		/* [o] messaging level data (optional) */
+	unsigned char sb_len_wr;		/* [o] byte count actually written to sbp */
+	unsigned short host_status;	/* [o] errors from host adapter */
+	unsigned short driver_status;	/* [o] errors from software driver */
+	compat_int_t resid;		/* [o] dxfer_len - actual_transferred */
+	compat_uint_t duration;		/* [o] time taken by cmd (unit: millisec) */
+	compat_uint_t info;		/* [o] auxiliary information */
 } sg_io_hdr32_t;  /* 64 bytes long (on sparc32) */
 
 typedef struct sg_iovec32 {
-	u32 iov_base;
-	u32 iov_len;
+	compat_uint_t iov_base;
+	compat_uint_t iov_len;
 } sg_iovec32_t;
 
+#define EMU_SG_MAX 128
+
 static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
 {
-	sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
+	sg_iovec32_t *uiov = compat_ptr(uptr32);
 	sg_iovec_t *kiov;
 	int i;
 
+	if (sgp->iovec_count > EMU_SG_MAX)
+		return -EINVAL;
 	sgp->dxferp = kmalloc(sgp->iovec_count *
 			      sizeof(sg_iovec_t), GFP_KERNEL);
 	if (!sgp->dxferp)
@@ -1378,39 +1387,9 @@
 		if (__get_user(iov_base32, &uiov->iov_base) ||
 		    __get_user(kiov->iov_len, &uiov->iov_len))
 			return -EFAULT;
-
-		kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);
-		if (!kiov->iov_base)
-			return -ENOMEM;
-		if (copy_from_user(kiov->iov_base,
-				   (void *) A(iov_base32),
-				   kiov->iov_len))
+		if (verify_area(VERIFY_WRITE, compat_ptr(iov_base32), kiov->iov_len))
 			return -EFAULT;
-
-		uiov++;
-		kiov++;
-	}
-
-	return 0;
-}
-
-static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
-{
-	sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
-	sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
-	int i;
-
-	for (i = 0; i < sgp->iovec_count; i++) {
-		u32 iov_base32;
-
-		if (__get_user(iov_base32, &uiov->iov_base))
-			return -EFAULT;
-
-		if (copy_to_user((void *) A(iov_base32),
-				 kiov->iov_base,
-				 kiov->iov_len))
-			return -EFAULT;
-
+		kiov->iov_base = compat_ptr(iov_base32);
 		uiov++;
 		kiov++;
 	}
@@ -1420,16 +1399,6 @@
 
 static void free_sg_iovec(sg_io_hdr_t *sgp)
 {
-	sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
-	int i;
-
-	for (i = 0; i < sgp->iovec_count; i++) {
-		if (kiov->iov_base) {
-			kfree(kiov->iov_base);
-			kiov->iov_base = NULL;
-		}
-		kiov++;
-	}
 	kfree(sgp->dxferp);
 	sgp->dxferp = NULL;
 }
@@ -1459,12 +1428,8 @@
 
 	err |= __get_user(cmdp32, &sg_io32->cmdp);
 	sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
-	if (!sg_io64.cmdp) {
-		err = -ENOMEM;
-		goto out;
-	}
 	if (copy_from_user(sg_io64.cmdp,
-			   (void *) A(cmdp32),
+			   compat_ptr(cmdp32),
 			   sg_io64.cmd_len)) {
 		err = -EFAULT;
 		goto out;
@@ -1477,7 +1442,7 @@
 		goto out;
 	}
 	if (copy_from_user(sg_io64.sbp,
-			   (void *) A(sbp32),
+			   compat_ptr(sbp32),
 			   sg_io64.mx_sb_len)) {
 		err = -EFAULT;
 		goto out;
@@ -1492,17 +1457,11 @@
 			goto out;
 		}
 	} else {
-		sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
-		if (!sg_io64.dxferp) {
-			err = -ENOMEM;
+		err = verify_area(VERIFY_WRITE, compat_ptr(dxferp32), sg_io64.dxfer_len);
+		if (err) 
 			goto out;
-		}
-		if (copy_from_user(sg_io64.dxferp,
-				   (void *) A(dxferp32),
-				   sg_io64.dxfer_len)) {
-			err = -EFAULT;
-			goto out;
-		}
+
+		sg_io64.dxferp = compat_ptr(dxferp32); 
 	}
 
 	/* Unused internally, do not even bother to copy it over. */
@@ -1529,15 +1488,7 @@
 	err |= __put_user(sg_io64.resid, &sg_io32->resid);
 	err |= __put_user(sg_io64.duration, &sg_io32->duration);
 	err |= __put_user(sg_io64.info, &sg_io32->info);
-	err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
-	if (sg_io64.dxferp) {
-		if (sg_io64.iovec_count)
-			err |= copy_back_sg_iovec(&sg_io64, dxferp32);
-		else
-			err |= copy_to_user((void *)A(dxferp32),
-					    sg_io64.dxferp,
-					    sg_io64.dxfer_len);
-	}
+	err |= copy_to_user(compat_ptr(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
 	if (err)
 		err = -EFAULT;
 
@@ -1546,19 +1497,14 @@
 		kfree(sg_io64.cmdp);
 	if (sg_io64.sbp)
 		kfree(sg_io64.sbp);
-	if (sg_io64.dxferp) {
-		if (sg_io64.iovec_count) {
+	if (sg_io64.dxferp && sg_io64.iovec_count)
 			free_sg_iovec(&sg_io64);
-		} else {
-			kfree(sg_io64.dxferp);
-		}
-	}
 	return err;
 }
 
 struct sock_fprog32 {
-	__u16	len;
-	__u32	filter;
+	unsigned short	len;
+	compat_caddr_t	filter;
 };
 
 #define PPPIOCSPASS32	_IOW('t', 71, struct sock_fprog32)
@@ -1576,7 +1522,7 @@
 	    get_user(fptr32, &u_fprog32->filter))
 		return -EFAULT;
 
-	fptr64 = (void *) A(fptr32);
+	fptr64 = compat_ptr(fptr32);
 
 	if (put_user(flen, &u_fprog64->len) ||
 	    put_user(fptr64, &u_fprog64->filter))
@@ -1592,8 +1538,8 @@
 
 struct ppp_option_data32 {
 	compat_caddr_t	ptr;
-	__u32			length;
-	int			transmit;
+	u32			length;
+	compat_int_t		transmit;
 };
 #define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)
 
@@ -1622,10 +1568,12 @@
 	case PPPIOCSCOMPRESS32:
 		if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
 			return -EFAULT;
+		if (data32.length > PAGE_SIZE) 
+			return -EINVAL;
 		data.ptr = kmalloc (data32.length, GFP_KERNEL);
 		if (!data.ptr)
 			return -ENOMEM;
-		if (copy_from_user(data.ptr, (__u8 *)A(data32.ptr), data32.length)) {
+		if (copy_from_user(data.ptr, compat_ptr(data32.ptr), data32.length)) {
 			kfree(data.ptr);
 			return -EFAULT;
 		}
@@ -1667,40 +1615,40 @@
 
 
 struct mtget32 {
-	__u32	mt_type;
-	__u32	mt_resid;
-	__u32	mt_dsreg;
-	__u32	mt_gstat;
-	__u32	mt_erreg;
+	compat_long_t	mt_type;
+	compat_long_t	mt_resid;
+	compat_long_t	mt_dsreg;
+	compat_long_t	mt_gstat;
+	compat_long_t	mt_erreg;
 	compat_daddr_t	mt_fileno;
 	compat_daddr_t	mt_blkno;
 };
 #define MTIOCGET32	_IOR('m', 2, struct mtget32)
 
 struct mtpos32 {
-	__u32	mt_blkno;
+	compat_long_t	mt_blkno;
 };
 #define MTIOCPOS32	_IOR('m', 3, struct mtpos32)
 
 struct mtconfiginfo32 {
-	__u32	mt_type;
-	__u32	ifc_type;
-	__u16	irqnr;
-	__u16	dmanr;
-	__u16	port;
-	__u32	debug;
-	__u32	have_dens:1;
-	__u32	have_bsf:1;
-	__u32	have_fsr:1;
-	__u32	have_bsr:1;
-	__u32	have_eod:1;
-	__u32	have_seek:1;
-	__u32	have_tell:1;
-	__u32	have_ras1:1;
-	__u32	have_ras2:1;
-	__u32	have_ras3:1;
-	__u32	have_qfa:1;
-	__u32	pad1:5;
+	compat_long_t	mt_type;
+	compat_long_t	ifc_type;
+	unsigned short	irqnr;
+	unsigned short	dmanr;
+	unsigned short	port;
+	compat_ulong_t	debug;
+	compat_uint_t	have_dens:1;
+	compat_uint_t	have_bsf:1;
+	compat_uint_t	have_fsr:1;
+	compat_uint_t	have_bsr:1;
+	compat_uint_t	have_eod:1;
+	compat_uint_t	have_seek:1;
+	compat_uint_t	have_tell:1;
+	compat_uint_t	have_ras1:1;
+	compat_uint_t	have_ras2:1;
+	compat_uint_t	have_ras3:1;
+	compat_uint_t	have_qfa:1;
+	compat_uint_t	pad1:5;
 	char	reserved[10];
 };
 #define	MTIOCGETCONFIG32	_IOR('m', 4, struct mtconfiginfo32)
@@ -1790,25 +1738,25 @@
 }
 
 struct cdrom_read32 {
-	int			cdread_lba;
+	compat_int_t	cdread_lba;
 	compat_caddr_t	cdread_bufaddr;
-	int			cdread_buflen;
+	compat_int_t	cdread_buflen;
 };
 
 struct cdrom_read_audio32 {
 	union cdrom_addr	addr;
-	u_char			addr_format;
-	int			nframes;
+	u8			addr_format;
+	compat_int_t		nframes;
 	compat_caddr_t	buf;
 };
 
 struct cdrom_generic_command32 {
 	unsigned char		cmd[CDROM_PACKET_SIZE];
 	compat_caddr_t	buffer;
-	unsigned int		buflen;
-	int			stat;
+	compat_uint_t	buflen;
+	compat_int_t	stat;
 	compat_caddr_t	sense;
-	compat_caddr_t	reserved[3];
+	compat_caddr_t	reserved[3];	/* Oops? it has data_direction, quiet and timeout fields? */
 };
 
 static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -1833,10 +1781,9 @@
 		err |= __get_user(cdread.cdread_buflen, &((struct cdrom_read32 *)arg)->cdread_buflen);
 		if (err)
 			return -EFAULT;
-		data = kmalloc(cdread.cdread_buflen, GFP_KERNEL);
-		if (!data)
-			return -ENOMEM;
-		cdread.cdread_bufaddr = data;
+		if (verify_area(VERIFY_WRITE, compat_ptr(addr), cdread.cdread_buflen))
+			return -EFAULT;
+		cdread.cdread_bufaddr = compat_ptr(addr);
 		break;
 	case CDROMREADAUDIO:
 		karg = &cdreadaudio;
@@ -1846,10 +1793,11 @@
 		err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
 		if (err)
 			return -EFAULT;
-		data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);
-		if (!data)
-			return -ENOMEM;
-		cdreadaudio.buf = data;
+		
+
+		if (verify_area(VERIFY_WRITE, compat_ptr(addr), cdreadaudio.nframes*2352))
+			return -EFAULT;
+		cdreadaudio.buf = compat_ptr(addr);
 		break;
 	case CDROM_SEND_PACKET:
 		karg = &cgc;
@@ -1858,9 +1806,9 @@
 		err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
 		if (err)
 			return -EFAULT;
-		if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
-			return -ENOMEM;
-		cgc.buffer = data;
+		if (verify_area(VERIFY_WRITE, compat_ptr(addr), cgc.buflen))
+			return -EFAULT;
+		cgc.buffer = compat_ptr(addr);
 		break;
 	default:
 		do {
@@ -1875,41 +1823,23 @@
 	set_fs (KERNEL_DS);
 	err = sys_ioctl (fd, cmd, (unsigned long)karg);
 	set_fs (old_fs);
-	if (err)
-		goto out;
-	switch (cmd) {
-	case CDROMREADMODE2:
-	case CDROMREADMODE1:
-	case CDROMREADRAW:
-	case CDROMREADCOOKED:
-		err = copy_to_user((char *)A(addr), data, cdread.cdread_buflen);
-		break;
-	case CDROMREADAUDIO:
-		err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
-		break;
-	case CDROM_SEND_PACKET:
-		err = copy_to_user((char *)A(addr), data, cgc.buflen);
-		break;
-	default:
-		break;
-	}
-out:	if (data)
+	if (data)
 		kfree(data);
 	return err ? -EFAULT : 0;
 }
 
 struct loop_info32 {
-	int			lo_number;      /* ioctl r/o */
+	compat_int_t	lo_number;      /* ioctl r/o */
 	compat_dev_t	lo_device;      /* ioctl r/o */
-	unsigned int		lo_inode;       /* ioctl r/o */
+	compat_ulong_t	lo_inode;       /* ioctl r/o */
 	compat_dev_t	lo_rdevice;     /* ioctl r/o */
-	int			lo_offset;
-	int			lo_encrypt_type;
-	int			lo_encrypt_key_size;    /* ioctl w/o */
-	int			lo_flags;       /* ioctl r/o */
+	compat_int_t	lo_offset;
+	compat_int_t	lo_encrypt_type;
+	compat_int_t	lo_encrypt_key_size;    /* ioctl w/o */
+	compat_int_t	lo_flags;       /* ioctl r/o */
 	char			lo_name[LO_NAME_SIZE];
 	unsigned char		lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
-	unsigned int		lo_init[2];
+	compat_ulong_t	lo_init[2];
 	char			reserved[4];
 };
 
@@ -1925,6 +1855,7 @@
 		err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
 		err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
 		err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+		
 		err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
 					   8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
 		if (err) {
@@ -1990,7 +1921,7 @@
 struct consolefontdesc32 {
 	unsigned short charcount;       /* characters in font (256 or 512) */
 	unsigned short charheight;      /* scan lines per character (1-32) */
-	u32 chardata;			/* font data in expanded form */
+	compat_caddr_t chardata;	/* font data in expanded form */
 };
 
 static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file)
@@ -2005,7 +1936,7 @@
 	if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32)))
 		return -EFAULT;
 	
-	cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata);
+	cfdarg.chardata = compat_ptr(((struct consolefontdesc32 *)&cfdarg)->chardata);
  	
 	switch (cmd) {
 	case PIO_FONTX:
@@ -2041,11 +1972,11 @@
 }
 
 struct console_font_op32 {
-	unsigned int op;        /* operation code KD_FONT_OP_* */
-	unsigned int flags;     /* KD_FONT_FLAG_* */
-	unsigned int width, height;     /* font size */
-	unsigned int charcount;
-	u32 data;    /* font data with height fixed to 32 */
+	compat_uint_t op;        /* operation code KD_FONT_OP_* */
+	compat_uint_t flags;     /* KD_FONT_FLAG_* */
+	compat_uint_t width, height;     /* font size */
+	compat_uint_t charcount;
+	compat_caddr_t data;    /* font data with height fixed to 32 */
 };
                                         
 static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file)
@@ -2060,7 +1991,7 @@
 		return -EFAULT;
 	if (!perm && op.op != KD_FONT_OP_GET)
 		return -EPERM;
-	op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data);
+	op.data = compat_ptr(((struct console_font_op32 *)&op)->data);
 	op.flags |= KD_FONT_FLAG_OLD;
 	vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data;
 	i = con_font_op(vt->vc_num, &op);
@@ -2073,7 +2004,7 @@
 
 struct unimapdesc32 {
 	unsigned short entry_ct;
-	u32 entries;
+	compat_caddr_t entries;
 };
 
 static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file)
@@ -2087,9 +2018,9 @@
 	switch (cmd) {
 	case PIO_UNIMAP:
 		if (!perm) return -EPERM;
-		return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries));
+		return con_set_unimap(fg_console, tmp.entry_ct, compat_ptr(tmp.entries));
 	case GIO_UNIMAP:
-		return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries));
+		return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), compat_ptr(tmp.entries));
 	}
 	return 0;
 }
@@ -2113,13 +2044,13 @@
 }
 
 struct atmif_sioc32 {
-        int                number;
-        int                length;
+        compat_int_t	number;
+        compat_int_t	length;
         compat_caddr_t arg;
 };
 
 struct atm_iobuf32 {
-	int                length;
+	compat_int_t	length;
 	compat_caddr_t buffer;
 };
 
@@ -2184,38 +2115,17 @@
 	if (iobuf32.buffer == (compat_caddr_t) NULL || iobuf32.length == 0) {
 		iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
 	} else {
-		iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
-		if (iobuf.buffer == NULL) {
-			err = -ENOMEM;
-			goto out;
-		}
-
-		err = copy_from_user(iobuf.buffer, A(iobuf32.buffer), iobuf.length);
-		if (err) {
-			err = -EFAULT;
-			goto out;
-		}
+		iobuf.buffer = compat_ptr(iobuf32.buffer);
+		if (verify_area(VERIFY_WRITE, iobuf.buffer, iobuf.length))
+			return -EINVAL;
 	}
 
 	old_fs = get_fs(); set_fs (KERNEL_DS);
 	err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);      
 	set_fs (old_fs);
-        if(err)
-		goto out;
-
-        if(iobuf.buffer && iobuf.length > 0) {
-		err = copy_to_user(A(iobuf32.buffer), iobuf.buffer, iobuf.length);
-		if (err) {
-			err = -EFAULT;
-			goto out;
-		}
-	}
+        if(!err)
 	err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
 
- out:
-        if(iobuf32.buffer && iobuf32.length > 0)
-		kfree(iobuf.buffer);
-
 	return err;
 }
 
@@ -2238,39 +2148,16 @@
 	if (sioc32.arg == (compat_caddr_t) NULL || sioc32.length == 0) {
 		sioc.arg = (void*)(unsigned long)sioc32.arg;
         } else {
-                sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
-                if (sioc.arg == NULL) {
-                        err = -ENOMEM;
-			goto out;
-		}
-                
-                err = copy_from_user(sioc.arg, A(sioc32.arg), sioc32.length);
-                if (err) {
-                        err = -EFAULT;
-                        goto out;
-                }
+		sioc.arg = compat_ptr(sioc32.arg);
+		if (verify_area(VERIFY_WRITE, sioc.arg, sioc32.length))
+			return -EFAULT;
         }
         
         old_fs = get_fs(); set_fs (KERNEL_DS);
         err = sys_ioctl (fd, cmd, (unsigned long)&sioc);	
         set_fs (old_fs);
-        if(err) {
-                goto out;
-	}
-        
-        if(sioc.arg && sioc.length > 0) {
-                err = copy_to_user(A(sioc32.arg), sioc.arg, sioc.length);
-                if (err) {
-                        err = -EFAULT;
-                        goto out;
-                }
-        }
+	if (!err)
         err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
-        
- out:
-        if(sioc32.arg && sioc32.length > 0)
-		kfree(sioc.arg);
-        
 	return err;
 }
 
@@ -2340,10 +2227,10 @@
 }
 
 struct blkpg_ioctl_arg32 {
-	int op;
-	int flags;
-	int datalen;
-	u32 data;
+	compat_int_t op;
+	compat_int_t flags;
+	compat_int_t datalen;
+	compat_caddr_t data;
 };
                                 
 static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
@@ -2402,7 +2289,7 @@
 
 struct raw32_config_request 
 {
-	int	raw_minor;
+	compat_int_t	raw_minor;
 	__u64	block_major;
 	__u64	block_minor;
 } __attribute__((packed));
@@ -2434,24 +2321,24 @@
 } 
 
 struct serial_struct32 {
-	int	type;
-	int	line;
-	unsigned int	port;
-	int	irq;
-	int	flags;
-	int	xmit_fifo_size;
-	int	custom_divisor;
-	int	baud_base;
+	compat_int_t	type;
+	compat_int_t	line;
+	compat_uint_t	port;
+	compat_int_t	irq;
+	compat_int_t	flags;
+	compat_int_t	xmit_fifo_size;
+	compat_int_t	custom_divisor;
+	compat_int_t	baud_base;
 	unsigned short	close_delay;
 	char	io_type;
 	char	reserved_char[1];
-	int	hub6;
+	compat_int_t	hub6;
 	unsigned short	closing_wait; /* time to wait before closing */
 	unsigned short	closing_wait2; /* no longer used... */
-	__u32 iomem_base;
+	compat_uint_t	iomem_base;
 	unsigned short	iomem_reg_shift;
 	unsigned int	port_high;
-	int	reserved[1];
+	compat_int_t	reserved[1];
 };
 
 static int serial_struct_ioctl(unsigned fd, unsigned cmd,  void *ptr) 
@@ -2494,7 +2381,7 @@
 } 
 
 struct dirent32 {
-	unsigned int		d_ino;
+	compat_int_t	d_ino;
 	compat_off_t	d_off;
 	unsigned short	d_reclen;
 	char		d_name[256]; /* We must not include limits.h! */
@@ -2600,13 +2487,13 @@
 #define BNEPGETCONNINFO        _IOR('B', 211, int)
 
 struct usbdevfs_ctrltransfer32 {
-	__u8 bRequestType;
-	__u8 bRequest;
-	__u16 wValue;
-	__u16 wIndex;
-	__u16 wLength;
-	__u32 timeout;  /* in milliseconds */
-	__u32 data;
+	u8 bRequestType;
+	u8 bRequest;
+	u16 wValue;
+	u16 wIndex;
+	u16 wLength;
+	u32 timeout;  /* in milliseconds */
+	compat_caddr_t data;
 };
 
 #define USBDEVFS_CONTROL32           _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
@@ -2629,7 +2516,7 @@
 
 	if (get_user(udata, &uctrl->data))
 		return -EFAULT;
-	uptr = (void *) A(udata);
+	uptr = compat_ptr(udata);
 
 	/* In usbdevice_fs, it limits the control buffer to a page,
 	 * for simplicity so do we.
@@ -2664,10 +2551,10 @@
 }
 
 struct usbdevfs_bulktransfer32 {
-	unsigned int ep;
-	unsigned int len;
-	unsigned int timeout; /* in milliseconds */
-	__u32 data;
+	compat_uint_t ep;
+	compat_uint_t len;
+	compat_uint_t timeout; /* in milliseconds */
+	compat_caddr_t data;
 };
 
 #define USBDEVFS_BULK32              _IOWR('U', 2, struct usbdevfs_bulktransfer32)
@@ -2689,7 +2576,7 @@
 	    get_user(udata, &ubulk->data))
 		return -EFAULT;
 
-	uptr = (void *) A(udata);
+	uptr = compat_ptr(udata);
 
 	/* In usbdevice_fs, it limits the control buffer to a page,
 	 * for simplicity so do we.
@@ -2765,18 +2652,18 @@
  */
 #if 0
 struct usbdevfs_urb32 {
-	__u8 type;
-	__u8 endpoint;
-	__s32 status;
-	__u32 flags;
-	__u32 buffer;
-	__s32 buffer_length;
-	__s32 actual_length;
-	__s32 start_frame;
-	__s32 number_of_packets;
-	__s32 error_count;
-	__u32 signr;
-	__u32 usercontext; /* unused */
+	unsigned char type;
+	unsigned char endpoint;
+	compat_int_t status;
+	compat_uint_t flags;
+	compat_caddr_t buffer;
+	compat_int_t buffer_length;
+	compat_int_t actual_length;
+	compat_int_t start_frame;
+	compat_int_t number_of_packets;
+	compat_int_t error_count;
+	compat_uint_t signr;
+	compat_caddr_t usercontext; /* unused */
 	struct usbdevfs_iso_packet_desc iso_frame_desc[0];
 };
 
@@ -2896,19 +2783,13 @@
 	err = -EFAULT;
 	if (__get_user(udata, &uurb->buffer))
 		goto out;
-	uptr = (void *) A(udata);
+	uptr = compat_ptr(udata);
 
-	err = -ENOMEM;
 	buflen = kurb->buffer_length;
-	kptr = kmalloc(buflen, GFP_KERNEL);
-	if (!kptr)
+	err = verify_area(VERIFY_WRITE, uptr, buflen);
+	if (err) 
 		goto out;
 
-	kurb->buffer = kptr;
-
-	err = -EFAULT;
-	if (copy_from_user(kptr, uptr, buflen))
-		goto out_kptr;
 
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
@@ -2919,15 +2800,9 @@
 		/* RED-PEN Shit, this doesn't work for async URBs :-( XXX */
 		if (put_urb32(kurb, uurb)) {
 			err = -EFAULT;
-		} else if ((kurb->endpoint & USB_DIR_IN) != 0) {
-			if (copy_to_user(uptr, kptr, buflen))
-				err = -EFAULT;
 		}
 	}
 
-out_kptr:
-	kfree(kptr);
-
 out:
 	kfree(kurb);
 	return err;
@@ -2953,15 +2828,15 @@
 	set_fs(old_fs);
 
 	if (err >= 0 &&
-	    put_user(((u32)(long)kptr), (u32 *) A(arg)))
+	    put_user(((u32)(long)kptr), compat_ptr(arg)))
 		err = -EFAULT;
 
 	return err;
 }
 
 struct usbdevfs_disconnectsignal32 {
-	unsigned int signr;
-	u32 context;
+	compat_int_t signr;
+	compat_caddr_t context;
 };
 
 #define USBDEVFS_DISCSIGNAL32      _IOR('U', 14, struct usbdevfs_disconnectsignal32)
@@ -2991,9 +2866,9 @@
 }
 
 struct mtd_oob_buf32 {
-	u32 start;
-	u32 length;
-	u32 ptr;	/* unsigned char* */
+	u_int32_t start;
+	u_int32_t length;
+	compat_caddr_t ptr;	/* unsigned char* */
 };
 
 #define MEMWRITEOOB32 	_IOWR('M',3,struct mtd_oob_buf32)
@@ -3005,7 +2880,6 @@
 	struct mtd_oob_buf32	*uarg 	= (struct mtd_oob_buf32 *)arg;
 	struct mtd_oob_buf		karg;
 	u32 tmp;
-	char *ptr;
 	int ret;
 
 	if (get_user(karg.start, &uarg->start) 		||
@@ -3013,18 +2887,9 @@
 	    get_user(tmp, &uarg->ptr))
 		return -EFAULT;
 
-	ptr = (char *)A(tmp);
-	if (0 >= karg.length) 
-		return -EINVAL;
-
-	karg.ptr = kmalloc(karg.length, GFP_KERNEL);
-	if (NULL == karg.ptr)
-		return -ENOMEM;
-
-	if (copy_from_user(karg.ptr, ptr, karg.length)) {
-		kfree(karg.ptr);
+	karg.ptr = compat_ptr(tmp); 
+	if (verify_area(VERIFY_WRITE, karg.ptr, karg.length))
 		return -EFAULT;
-	}
 
 	set_fs(KERNEL_DS);
 	if (MEMREADOOB32 == cmd) 
@@ -3036,13 +2901,11 @@
 	set_fs(old_fs);
 
 	if (0 == ret && cmd == MEMREADOOB32) {
-		ret = copy_to_user(ptr, karg.ptr, karg.length);
-		ret |= put_user(karg.start, &uarg->start);
+		ret = put_user(karg.start, &uarg->start);
 		ret |= put_user(karg.length, &uarg->length);
 	}
 
-	kfree(karg.ptr);
-	return ((0 == ret) ? 0 : -EFAULT);
+	return ret;
 }	
 
 /* /proc/mtrr ioctls */
@@ -3050,17 +2913,17 @@
 
 struct mtrr_sentry32
 {
-    unsigned int base;    /*  Base address     */
-    unsigned int size;    /*  Size of region   */
-    unsigned int type;     /*  Type of region   */
+    compat_ulong_t base;    /*  Base address     */
+    compat_uint_t size;    /*  Size of region   */
+    compat_uint_t type;     /*  Type of region   */
 };
 
 struct mtrr_gentry32
 {
-    unsigned int regnum;   /*  Register number  */
-    unsigned int base;    /*  Base address     */
-    unsigned int size;    /*  Size of region   */
-    unsigned int type;     /*  Type of region   */
+    compat_ulong_t regnum;   /*  Register number  */
+    compat_uint_t base;    /*  Base address     */
+    compat_uint_t size;    /*  Size of region   */
+    compat_uint_t type;     /*  Type of region   */
 };
 
 #define	MTRR_IOCTL_BASE	'M'
@@ -3131,7 +2994,7 @@
 } 
 
 #define REF_SYMBOL(handler) if (0) (void)handler;
-#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler);  asm volatile(".quad %c0, " #handler ",0"::"i" (cmd)); 
+#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler);  asm volatile(".quad %P0, " #handler ",0"::"i" (cmd)); 
 #define HANDLE_IOCTL(cmd,handler) HANDLE_IOCTL2(cmd,handler)
 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
 #define IOCTL_TABLE_START void ioctl_dummy(void) { asm volatile("\n.global ioctl_start\nioctl_start:\n\t" );
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/ia32_signal.c linux-2.5.69-bk17/arch/x86_64/ia32/ia32_signal.c
--- linux-2.5.69-bk16/arch/x86_64/ia32/ia32_signal.c	2003-05-04 16:53:42.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/ia32/ia32_signal.c	2003-05-24 04:33:33.000000000 -0700
@@ -33,6 +33,7 @@
 #include <asm/sigcontext32.h>
 #include <asm/fpu32.h>
 #include <asm/proto.h>
+#include <asm/vsyscall32.h>
 
 #define ptr_to_u32(x) ((u32)(u64)(x))	/* avoid gcc warning */ 
 
@@ -428,7 +429,7 @@
 
 	/* Return stub is in 32bit vsyscall page */
 	{ 
-		void *restorer = syscall32_page + 32; 
+		void *restorer = VSYSCALL32_SIGRETURN; 
 		if (ka->sa.sa_flags & SA_RESTORER)
 			restorer = ka->sa.sa_restorer;       
 		err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
@@ -521,7 +522,7 @@
 
 	
 	{ 
-		void *restorer = syscall32_page + 32; 
+		void *restorer = VSYSCALL32_RTSIGRETURN; 
 		if (ka->sa.sa_flags & SA_RESTORER)
 			restorer = ka->sa.sa_restorer;       
 		err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/ia32entry.S linux-2.5.69-bk17/arch/x86_64/ia32/ia32entry.S
--- linux-2.5.69-bk16/arch/x86_64/ia32/ia32entry.S	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/ia32/ia32entry.S	2003-05-24 04:33:33.000000000 -0700
@@ -182,9 +182,9 @@
 	PTREGSCALL stub32_sigaltstack, sys32_sigaltstack
 	PTREGSCALL stub32_sigsuspend, sys32_sigsuspend
 	PTREGSCALL stub32_execve, sys32_execve
-	PTREGSCALL stub32_fork, sys32_fork
+	PTREGSCALL stub32_fork, sys_fork
 	PTREGSCALL stub32_clone, sys32_clone
-	PTREGSCALL stub32_vfork, sys32_vfork
+	PTREGSCALL stub32_vfork, sys_vfork
 	PTREGSCALL stub32_iopl, sys_iopl
 	PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend
 
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/ptrace32.c linux-2.5.69-bk17/arch/x86_64/ia32/ptrace32.c
--- linux-2.5.69-bk16/arch/x86_64/ia32/ptrace32.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/ia32/ptrace32.c	2003-05-24 04:33:33.000000000 -0700
@@ -78,12 +78,24 @@
 	case offsetof(struct user32, u_debugreg[5]):
 		return -EIO;
 
-	case offsetof(struct user32, u_debugreg[0]) ...
-	     offsetof(struct user32, u_debugreg[3]):
+	case offsetof(struct user32, u_debugreg[0]):
+		child->thread.debugreg0 = val;
+		break;
+
+	case offsetof(struct user32, u_debugreg[1]):
+		child->thread.debugreg1 = val;
+		break;
+
+	case offsetof(struct user32, u_debugreg[2]):
+		child->thread.debugreg2 = val;
+		break;
+
+	case offsetof(struct user32, u_debugreg[3]):
+		child->thread.debugreg3 = val;
+		break;
+
 	case offsetof(struct user32, u_debugreg[6]):
-		child->thread.debugreg
-			[(regno-offsetof(struct user32, u_debugreg[0]))/4] 
-			= val; 
+		child->thread.debugreg6 = val;
 		break; 
 
 	case offsetof(struct user32, u_debugreg[7]):
@@ -92,7 +104,7 @@
 		for(i=0; i<4; i++)
 			if ((0x5454 >> ((val >> (16 + 4*i)) & 0xf)) & 1)
 			       return -EIO;
-		child->thread.debugreg[7] = val; 
+		child->thread.debugreg7 = val; 
 		break; 
 		    
 	default:
@@ -142,8 +154,23 @@
 	R32(eflags, eflags);
 	R32(esp, rsp);
 
-	case offsetof(struct user32, u_debugreg[0]) ... offsetof(struct user32, u_debugreg[7]):
-		*val = child->thread.debugreg[(regno-offsetof(struct user32, u_debugreg[0]))/4]; 
+	case offsetof(struct user32, u_debugreg[0]): 
+		*val = child->thread.debugreg0; 
+		break; 
+	case offsetof(struct user32, u_debugreg[1]): 
+		*val = child->thread.debugreg1; 
+		break; 
+	case offsetof(struct user32, u_debugreg[2]): 
+		*val = child->thread.debugreg2; 
+		break; 
+	case offsetof(struct user32, u_debugreg[3]): 
+		*val = child->thread.debugreg3; 
+		break; 
+	case offsetof(struct user32, u_debugreg[6]): 
+		*val = child->thread.debugreg6; 
+		break; 
+	case offsetof(struct user32, u_debugreg[7]): 
+		*val = child->thread.debugreg7; 
 		break; 
 		    
 	default:
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/sys_ia32.c linux-2.5.69-bk17/arch/x86_64/ia32/sys_ia32.c
--- linux-2.5.69-bk16/arch/x86_64/ia32/sys_ia32.c	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/ia32/sys_ia32.c	2003-05-24 04:33:33.000000000 -0700
@@ -234,7 +234,7 @@
 	}
 	
 	if (a.prot & PROT_READ) 
-		a.prot |= PROT_EXEC; 
+		a.prot |= vm_force_exec32;
 
 	mm = current->mm; 
 	down_write(&mm->mmap_sem); 
@@ -253,7 +253,7 @@
 sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
 {
 	if (prot & PROT_READ) 
-		prot |= PROT_EXEC; 
+		prot |= vm_force_exec32;
 	return sys_mprotect(start,len,prot); 
 }
 
@@ -929,7 +929,11 @@
         u32 totalswap;
         u32 freeswap;
         unsigned short procs;
-        char _f[22];
+	unsigned short pad; 
+        u32 totalhigh;
+        u32 freehigh;
+        u32 mem_unit;
+        char _f[20-2*sizeof(u32)-sizeof(int)];
 };
 
 extern asmlinkage long sys_sysinfo(struct sysinfo *info);
@@ -955,7 +959,10 @@
 	    __put_user (s.bufferram, &info->bufferram) ||
 	    __put_user (s.totalswap, &info->totalswap) ||
 	    __put_user (s.freeswap, &info->freeswap) ||
-	    __put_user (s.procs, &info->procs))
+	    __put_user (s.procs, &info->procs) ||
+	    __put_user (s.totalhigh, &info->totalhigh) || 
+	    __put_user (s.freehigh, &info->freehigh) ||
+	    __put_user (s.mem_unit, &info->mem_unit))
 		return -EFAULT;
 	return 0;
 }
@@ -1419,7 +1426,7 @@
 	}
 
 	if (prot & PROT_READ)
-		prot |= PROT_EXEC;
+		prot |= vm_force_exec32;
 
 	down_write(&mm->mmap_sem);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
@@ -1587,40 +1594,14 @@
 	return ret; 
 } 
 
-asmlinkage long sys32_fork(struct pt_regs regs)
-{
-	struct task_struct *p;
-	p = do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
-	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
-}
-
 asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs)
 {
-	struct task_struct *p;
 	void *parent_tid = (void *)regs.rdx;
 	void *child_tid = (void *)regs.rdi; 
 	if (!newsp)
 		newsp = regs.rsp;
-	p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, 
+        return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, 
 		    parent_tid, child_tid);
-	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
-}
-
-/*
- * This is trivial, and on the face of it looks like it
- * could equally well be done in user mode.
- *
- * Not so, for quite unobvious reasons - register pressure.
- * In user mode vfork() cannot have a stack frame, and if
- * done by calling the "clone()" system call directly, you
- * do not have enough call-clobbered registers to hold all
- * the information you need.
- */
-asmlinkage long sys32_vfork(struct pt_regs regs)
-{
-	struct task_struct *p;
-	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
-	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
 /*
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/syscall32.c linux-2.5.69-bk17/arch/x86_64/ia32/syscall32.c
--- linux-2.5.69-bk16/arch/x86_64/ia32/syscall32.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/ia32/syscall32.c	2003-05-24 04:33:33.000000000 -0700
@@ -13,33 +13,14 @@
 #include <asm/tlbflush.h>
 #include <asm/ia32_unistd.h>
 
-/* 32bit SYSCALL stub mapped into user space. */ 
-asm("	.code32\n"
-    "\nsyscall32:\n"
-    "	pushl %ebp\n"
-    "	movl  %ecx,%ebp\n"
-    "	syscall\n"
-    "	popl  %ebp\n"
-    "	ret\n"
+/* 32bit VDSO mapped into user space. */ 
+asm(".section \".init.data\",\"aw\"\n"
+    "syscall32:\n"
+    ".incbin \"arch/x86_64/ia32/vsyscall.so\"\n"
     "syscall32_end:\n"
-
-    /* signal trampolines */
-
-    "sig32_rt_tramp:\n"
-    "	movl $"  __stringify(__NR_ia32_rt_sigreturn) ",%eax\n"
-    "   syscall\n"
-    "sig32_rt_tramp_end:\n"
-
-    "sig32_tramp:\n"
-    "	popl %eax\n"
-    "	movl $"  __stringify(__NR_ia32_sigreturn) ",%eax\n"
-    "	syscall\n"
-    "sig32_tramp_end:\n"
-    "	.code64\n"); 
+    ".previous");
 
 extern unsigned char syscall32[], syscall32_end[];
-extern unsigned char sig32_rt_tramp[], sig32_rt_tramp_end[];
-extern unsigned char sig32_tramp[], sig32_tramp_end[];
 
 char *syscall32_page; 
 
@@ -76,10 +57,6 @@
 		panic("Cannot allocate syscall32 page"); 
 	SetPageReserved(virt_to_page(syscall32_page));
 	memcpy(syscall32_page, syscall32, syscall32_end - syscall32);
-	memcpy(syscall32_page + 32, sig32_rt_tramp, 
-	       sig32_rt_tramp_end - sig32_rt_tramp);
-	memcpy(syscall32_page + 64, sig32_tramp, 
-	       sig32_tramp_end - sig32_tramp);	
 	return 0;
 } 
 	
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/vsyscall.S linux-2.5.69-bk17/arch/x86_64/ia32/vsyscall.S
--- linux-2.5.69-bk16/arch/x86_64/ia32/vsyscall.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk17/arch/x86_64/ia32/vsyscall.S	2003-05-24 04:33:33.000000000 -0700
@@ -0,0 +1,172 @@
+/*
+ * Code for the vsyscall page.  This version uses the syscall instruction.
+ */
+
+#include <asm/ia32_unistd.h>
+#include <asm/offset.h>
+
+	.text
+	.section .text.vsyscall,"ax"
+	.globl __kernel_vsyscall
+	.type __kernel_vsyscall,@function
+__kernel_vsyscall:
+.LSTART_vsyscall:
+	push	%ebp
+.Lpush_ebp:
+	movl	%ecx, %ebp
+	syscall
+	popl	%ebp
+.Lpop_ebp:
+	ret
+.LEND_vsyscall:
+	.size __kernel_vsyscall,.-.LSTART_vsyscall
+
+	.section .text.sigreturn,"ax"
+	.balign 32
+	.globl __kernel_sigreturn
+	.type __kernel_sigreturn,@function
+__kernel_sigreturn:
+.LSTART_sigreturn:
+	popl %eax
+	movl $__NR_ia32_sigreturn, %eax
+	syscall
+.LEND_sigreturn:
+	.size __kernel_sigreturn,.-.LSTART_sigreturn
+
+	.section .text.rtsigreturn,"ax"
+	.balign 32
+	.globl __kernel_rt_sigreturn,"ax"
+	.type __kernel_rt_sigreturn,@function
+__kernel_rt_sigreturn:
+.LSTART_rt_sigreturn:
+	movl $__NR_ia32_rt_sigreturn, %eax
+	syscall
+.LEND_rt_sigreturn:
+	.size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
+
+	.section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+	.long .LENDCIE-.LSTARTCIE
+.LSTARTCIE:
+	.long 0			/* CIE ID */
+	.byte 1			/* Version number */
+	.string "zR"		/* NUL-terminated augmentation string */
+	.uleb128 1		/* Code alignment factor */
+	.sleb128 -4		/* Data alignment factor */
+	.byte 8			/* Return address register column */
+	.uleb128 1		/* Augmentation value length */
+	.byte 0x1b		/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
+	.byte 0x0c		/* DW_CFA_def_cfa */
+	.uleb128 4
+	.uleb128 4
+	.byte 0x88		/* DW_CFA_offset, column 0x8 */
+	.uleb128 1
+	.align 4
+.LENDCIE:
+
+	.long .LENDFDE1-.LSTARTFDE1	/* Length FDE */
+.LSTARTFDE1:
+	.long .LSTARTFDE1-.LSTARTFRAME	/* CIE pointer */
+	.long .LSTART_vsyscall-.	/* PC-relative start address */
+	.long .LEND_vsyscall-.LSTART_vsyscall
+	.uleb128 0			/* Augmentation length */
+	/* What follows are the instructions for the table generation.
+	   We have to record all changes of the stack pointer.  */
+	.byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */
+	.byte 0x0e		/* DW_CFA_def_cfa_offset */
+	.uleb128 8
+	.byte 0x85, 0x02	/* DW_CFA_offset %ebp -8 */
+	.byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */
+	.byte 0xc5		/* DW_CFA_restore %ebp */
+	.byte 0x0e		/* DW_CFA_def_cfa_offset */
+	.uleb128 4
+	.align 4
+.LENDFDE1:
+
+	.long .LENDFDE2-.LSTARTFDE2	/* Length FDE */
+.LSTARTFDE2:
+	.long .LSTARTFDE2-.LSTARTFRAME	/* CIE pointer */
+	/* HACK: The dwarf2 unwind routines will subtract 1 from the
+	   return address to get an address in the middle of the
+	   presumed call instruction.  Since we didn't get here via
+	   a call, we need to include the nop before the real start
+	   to make up for it.  */
+	.long .LSTART_sigreturn-1-.	/* PC-relative start address */
+	.long .LEND_sigreturn-.LSTART_sigreturn+1
+	.uleb128 0			/* Augmentation length */
+	/* What follows are the instructions for the table generation.
+	   We record the locations of each register saved.  This is
+	   complicated by the fact that the "CFA" is always assumed to
+	   be the value of the stack pointer in the caller.  This means
+	   that we must define the CFA of this body of code to be the
+	   saved value of the stack pointer in the sigcontext.  Which
+	   also means that there is no fixed relation to the other 
+	   saved registers, which means that we must use DW_CFA_expression
+	   to compute their addresses.  It also means that when we 
+	   adjust the stack with the popl, we have to do it all over again.  */
+
+#define do_cfa_expr(offset)						\
+	.byte 0x0f;			/* DW_CFA_def_cfa_expression */	\
+	.uleb128 1f-0f;			/*   length */			\
+0:	.byte 0x74;			/*     DW_OP_breg4 */		\
+	.sleb128 offset;		/*      offset */		\
+	.byte 0x06;			/*     DW_OP_deref */		\
+1:
+
+#define do_expr(regno, offset)						\
+	.byte 0x10;			/* DW_CFA_expression */		\
+	.uleb128 regno;			/*   regno */			\
+	.uleb128 1f-0f;			/*   length */			\
+0:	.byte 0x74;			/*     DW_OP_breg4 */		\
+	.sleb128 offset;		/*       offset */		\
+1:
+
+	do_cfa_expr(IA32_SIGCONTEXT_esp+4)
+	do_expr(0, IA32_SIGCONTEXT_eax+4)
+	do_expr(1, IA32_SIGCONTEXT_ecx+4)
+	do_expr(2, IA32_SIGCONTEXT_edx+4)
+	do_expr(3, IA32_SIGCONTEXT_ebx+4)
+	do_expr(5, IA32_SIGCONTEXT_ebp+4)
+	do_expr(6, IA32_SIGCONTEXT_esi+4)
+	do_expr(7, IA32_SIGCONTEXT_edi+4)
+	do_expr(8, IA32_SIGCONTEXT_eip+4)
+
+	.byte 0x42	/* DW_CFA_advance_loc 2 -- nop; popl eax. */
+
+	do_cfa_expr(IA32_SIGCONTEXT_esp)
+	do_expr(0, IA32_SIGCONTEXT_eax)
+	do_expr(1, IA32_SIGCONTEXT_ecx)
+	do_expr(2, IA32_SIGCONTEXT_edx)
+	do_expr(3, IA32_SIGCONTEXT_ebx)
+	do_expr(5, IA32_SIGCONTEXT_ebp)
+	do_expr(6, IA32_SIGCONTEXT_esi)
+	do_expr(7, IA32_SIGCONTEXT_edi)
+	do_expr(8, IA32_SIGCONTEXT_eip)
+
+	.align 4
+.LENDFDE2:
+
+	.long .LENDFDE3-.LSTARTFDE3	/* Length FDE */
+.LSTARTFDE3:
+	.long .LSTARTFDE3-.LSTARTFRAME	/* CIE pointer */
+	/* HACK: See above wrt unwind library assumptions.  */
+	.long .LSTART_rt_sigreturn-1-.	/* PC-relative start address */
+	.long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
+	.uleb128 0			/* Augmentation */
+	/* What follows are the instructions for the table generation.
+	   We record the locations of each register saved.  This is
+	   slightly less complicated than the above, since we don't
+	   modify the stack pointer in the process.  */
+
+	do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp)
+	do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax)
+	do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx)
+	do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx)
+	do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx)
+	do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp)
+	do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi)
+	do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi)
+	do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip)
+
+	.align 4
+.LENDFDE3:
diff -urN linux-2.5.69-bk16/arch/x86_64/ia32/vsyscall.lds linux-2.5.69-bk17/arch/x86_64/ia32/vsyscall.lds
--- linux-2.5.69-bk16/arch/x86_64/ia32/vsyscall.lds	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk17/arch/x86_64/ia32/vsyscall.lds	2003-05-24 04:33:33.000000000 -0700
@@ -0,0 +1,77 @@
+/*
+ * Linker script for vsyscall DSO.  The vsyscall page is an ELF shared
+ * object prelinked to its virtual address. This script controls its layout.
+ */
+
+/* This must match <asm/fixmap.h>.  */
+VSYSCALL_BASE = 0xffffe000;
+
+SECTIONS
+{
+  . = VSYSCALL_BASE + SIZEOF_HEADERS;
+
+  .hash           : { *(.hash) }		:text
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+
+  /* This linker script is used both with -r and with -shared.
+     For the layouts to match, we need to skip more than enough
+     space for the dynamic symbol table et al.  If this amount
+     is insufficient, ld -shared will barf.  Just increase it here.  */
+  . = VSYSCALL_BASE + 0x400;
+  
+  .text.vsyscall   : { *(.text.vsyscall) } 	:text =0x90909090
+
+  /* This is an 32bit object and we cannot easily get the offsets
+     into the 64bit kernel. Just hardcode them here. This assumes
+     that all the stubs don't need more than 0x100 bytes. */
+  . = VSYSCALL_BASE + 0x500;
+
+  .text.sigreturn  : { *(.text.sigreturn) }	:text =0x90909090
+
+  . = VSYSCALL_BASE + 0x600;
+
+  .text.rtsigreturn : { *(.text.rtsigreturn) }   :text =0x90909090
+	
+  .eh_frame_hdr   : { *(.eh_frame_hdr) }	:text :eh_frame_hdr
+  .eh_frame       : { KEEP (*(.eh_frame)) }	:text
+  .dynamic        : { *(.dynamic) }		:text :dynamic
+  .useless        : {
+  	*(.got.plt) *(.got)
+	*(.data .data.* .gnu.linkonce.d.*)
+	*(.dynbss)
+	*(.bss .bss.* .gnu.linkonce.b.*)
+  }						:text
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+  text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+  dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+  eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
+}
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+  LINUX_2.5 {
+    global:
+    	__kernel_vsyscall;
+    	__kernel_sigreturn;
+    	__kernel_rt_sigreturn;
+
+    local: *;
+  };
+}
+
+/* The ELF entry point can be used to set the AT_SYSINFO value.  */
+ENTRY(__kernel_vsyscall);
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/Makefile linux-2.5.69-bk17/arch/x86_64/kernel/Makefile
--- linux-2.5.69-bk16/arch/x86_64/kernel/Makefile	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/Makefile	2003-05-24 04:33:33.000000000 -0700
@@ -7,7 +7,7 @@
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
 		pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
-		setup64.o bluesmoke.o bootflag.o e820.o reboot.o
+		setup64.o bluesmoke.o bootflag.o e820.o reboot.o warmreboot.o
 
 obj-$(CONFIG_MTRR)	+= mtrr/
 obj-$(CONFIG_ACPI)	+= acpi/
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/acpi/wakeup.S linux-2.5.69-bk17/arch/x86_64/kernel/acpi/wakeup.S
--- linux-2.5.69-bk16/arch/x86_64/kernel/acpi/wakeup.S	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/acpi/wakeup.S	2003-05-24 04:33:33.000000000 -0700
@@ -94,12 +94,6 @@
 	movw	%ax, %ss
 
 	mov	$(wakeup_stack - __START_KERNEL_map), %esp
-
-	call	1f
-1:	popl	%eax
-	movl	$0xb8040, %ebx
-	call	early_print
-	
 	movl	saved_magic - __START_KERNEL_map, %eax
 	cmpl	$0x9abcdef0, %eax
 	jne	bogus_32_magic
@@ -115,11 +109,7 @@
 	movl	%eax, %cr4
 
 	/* Setup early boot stage 4 level pagetables */
-#if 1
 	movl	$(wakeup_level4_pgt - __START_KERNEL_map), %eax
-#else
-	movl    saved_cr3 - __START_KERNEL_map, %eax
-#endif	
 	movl	%eax, %cr3
 
 	/* Setup EFER (Extended Feature Enable Register) */
@@ -223,19 +213,6 @@
 
 .code32
 
-early_print:
-	movl	$16, %edx
-1:	
-	movl	%eax, %ecx
-	andl	$0xf, %ecx
-	shrl	$4, %eax
-	addw	$0x0e00 + '0', %ecx
-	movw	%ecx, %ds:(%edx, %ebx)
-	decl	%edx
-	decl	%edx
-	jnz	1b
-	ret
-
 	.align	64	
 gdta:
 	.word	0, 0, 0, 0			# dummy
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/acpi.c linux-2.5.69-bk17/arch/x86_64/kernel/acpi.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/acpi.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/acpi.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,512 +0,0 @@
-/*
- *  acpi.c - Architecture-Specific Low-Level ACPI Support
- *
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
- *  Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
- *  Copyright (C) 2002 Andi Kleen, SuSE Labs (x86-64 port)
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/bootmem.h>
-#include <linux/irq.h>
-#include <linux/acpi.h>
-#include <asm/mpspec.h>
-#include <asm/io.h>
-#include <asm/apic.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-#include <asm/io_apic.h>
-#include <asm/proto.h>
-#include <asm/desc.h>
-#include <asm/system.h>
-#include <asm/segment.h>
-
-extern int acpi_disabled;
-
-#define PREFIX			"ACPI: "
-
-
-/* --------------------------------------------------------------------------
-                              Boot-time Configuration
-   -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI_BOOT
-
-enum acpi_irq_model_id		acpi_irq_model;
-
-/* rely on all ACPI tables being in the direct mapping */
-char *
-__acpi_map_table (
-	unsigned long	phys_addr,
-	unsigned long	size)
-{
-	if (!phys_addr || !size)
-		return NULL;
-
-	if (phys_addr < (end_pfn_map << PAGE_SHIFT)) 
-		return __va(phys_addr); 
-
-	return NULL; 
-} 	      
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-int acpi_lapic;
-
-static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
-
-
-static int __init
-acpi_parse_madt (
-	unsigned long		phys_addr,
-	unsigned long		size)
-{
-	struct acpi_table_madt	*madt = NULL;
-
-	if (!phys_addr || !size)
-		return -EINVAL;
-
-	madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size);
-	if (!madt) {
-		printk(KERN_WARNING PREFIX "Unable to map MADT\n");
-		return -ENODEV;
-	}
-
-	if (madt->lapic_address)
-		acpi_lapic_addr = (u64) madt->lapic_address;
-
-	printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n",
-		madt->lapic_address);
-
-	return 0;
-}
-
-
-static int __init
-acpi_parse_lapic (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_lapic	*processor = NULL;
-
-	processor = (struct acpi_table_lapic*) header;
-	if (!processor)
-		return -EINVAL;
-
-	acpi_table_print_madt_entry(header);
-
-	mp_register_lapic (
-		processor->id,					   /* APIC ID */
-		processor->flags.enabled);			  /* Enabled? */
-
-	return 0;
-}
-
-
-static int __init
-acpi_parse_lapic_addr_ovr (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
-
-	lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header;
-	if (!lapic_addr_ovr)
-		return -EINVAL;
-
-	acpi_lapic_addr = lapic_addr_ovr->address;
-
-	return 0;
-}
-
-
-static int __init
-acpi_parse_lapic_nmi (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_lapic_nmi *lapic_nmi = NULL;
-
-	lapic_nmi = (struct acpi_table_lapic_nmi*) header;
-	if (!lapic_nmi)
-		return -EINVAL;
-
-	acpi_table_print_madt_entry(header);
-
-	if (lapic_nmi->lint != 1)
-		printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
-
-	return 0;
-}
-
-#endif /*CONFIG_X86_LOCAL_APIC*/
-
-#ifdef CONFIG_X86_IO_APIC
-
-int acpi_ioapic;
-
-static int __init
-acpi_parse_ioapic (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_ioapic *ioapic = NULL;
-
-	ioapic = (struct acpi_table_ioapic*) header;
-	if (!ioapic)
-		return -EINVAL;
- 
-	acpi_table_print_madt_entry(header);
-
-	mp_register_ioapic (
-		ioapic->id,
-		ioapic->address,
-		ioapic->global_irq_base);
- 
-	return 0;
-}
-
-
-static int __init
-acpi_parse_int_src_ovr (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_int_src_ovr *intsrc = NULL;
-
-	intsrc = (struct acpi_table_int_src_ovr*) header;
-	if (!intsrc)
-		return -EINVAL;
-
-	acpi_table_print_madt_entry(header);
-
-	mp_override_legacy_irq (
-		intsrc->bus_irq,
-		intsrc->flags.polarity,
-		intsrc->flags.trigger,
-		intsrc->global_irq);
-
-	return 0;
-}
-
-
-static int __init
-acpi_parse_nmi_src (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_nmi_src *nmi_src = NULL;
-
-	nmi_src = (struct acpi_table_nmi_src*) header;
-	if (!nmi_src)
-		return -EINVAL;
-
-	acpi_table_print_madt_entry(header);
-
-	/* TBD: Support nimsrc entries? */
-
-	return 0;
-}
-
-#endif /*CONFIG_X86_IO_APIC*/
-
-#ifdef CONFIG_HPET_TIMER
-static int __init
-acpi_parse_hpet (
-	unsigned long		phys_addr,
-	unsigned long		size)
-{
-	struct acpi_table_hpet *hpet_tbl;
-
-	hpet_tbl = __va(phys_addr);
-
-	if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) {
-		printk(KERN_WARNING "acpi: HPET timers must be located in memory.\n");
-		return -1;
-	}
-
-	hpet.address = hpet_tbl->addr.addrl | ((long) hpet_tbl->addr.addrh << 32);
-
-	printk(KERN_INFO "acpi: HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet.address);
-
-	return 0;
-} 
-#endif
-
-static unsigned long __init
-acpi_scan_rsdp (
-	unsigned long		start,
-	unsigned long		length)
-{
-	unsigned long		offset = 0;
-	unsigned long		sig_len = sizeof("RSD PTR ") - 1;
-
-	/*
-	 * Scan all 16-byte boundaries of the physical memory region for the
-	 * RSDP signature.
-	 */
-	for (offset = 0; offset < length; offset += 16) {
-		if (strncmp((char *) (start + offset), "RSD PTR ", sig_len))
-			continue;
-		return (start + offset);
-	}
-
-	return 0;
-}
-
-
-unsigned long __init
-acpi_find_rsdp (void)
-{
-	unsigned long		rsdp_phys = 0;
-
-	/*
-	 * Scan memory looking for the RSDP signature. First search EBDA (low
-	 * memory) paragraphs and then search upper memory (E0000-FFFFF).
-	 */
-	rsdp_phys = acpi_scan_rsdp (0, 0x400);
-	if (!rsdp_phys)
-		rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF);
-
-	return rsdp_phys;
-}
-
-
-int __init
-acpi_boot_init (void)
-{
-	int			result = 0;
-
-	/*
-	 * The default interrupt routing model is PIC (8259).  This gets
-	 * overridden if IOAPICs are enumerated (below).
-	 */
-	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
-
-	/* 
-	 * Initialize the ACPI boot-time table parser.
-	 */
-	result = acpi_table_init();
-	if (result)
-		return result;
-
-	result = acpi_blacklisted();
-	if (result) {
-		acpi_disabled = 1;
-		return result;
-	} else
-               printk(KERN_NOTICE PREFIX "BIOS passes blacklist\n");
-
-	extern int disable_apic;
-	if (disable_apic)
-		return 0;
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-	/* 
-	 * MADT
-	 * ----
-	 * Parse the Multiple APIC Description Table (MADT), if exists.
-	 * Note that this table provides platform SMP configuration 
-	 * information -- the successor to MPS tables.
-	 */
-
-	result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
-	if (!result) {
-		printk(KERN_WARNING PREFIX "MADT not present\n");
-		return 0;
-	}
-	else if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing MADT\n");
-		return result;
-	}
-	else if (result > 1) 
-		printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n");
-
-	/* 
-	 * Local APIC
-	 * ----------
-	 * Note that the LAPIC address is obtained from the MADT (32-bit value)
-	 * and (optionally) overridden by a LAPIC_ADDR_OVR entry (64-bit value).
-	 */
-
-	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
-	if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
-		return result;
-	}
-
-	mp_register_lapic_address(acpi_lapic_addr);
-
-	result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
-	if (!result) { 
-		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return -ENODEV;
-	}
-	else if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return result;
-	}
-
-	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
-	if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return result;
-	}
-
-	acpi_lapic = 1;
-
-#endif /*CONFIG_X86_LOCAL_APIC*/
-
-#ifdef CONFIG_X86_IO_APIC
-
-	/* 
-	 * I/O APIC 
-	 * --------
-	 */
-
-	result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
-	if (!result) { 
-		printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
-		return -ENODEV;
-	}
-	else if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
-		return result;
-	}
-
-	/* Build a default routing table for legacy (ISA) interrupts. */
-	mp_config_acpi_legacy_irqs();
-
-	result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
-	if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return result;
-	}
-
-	result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
-	if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return result;
-	}
-
-	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
-
-	acpi_ioapic = 1;
-
-#endif /*CONFIG_X86_IO_APIC*/
-
-#ifdef CONFIG_X86_LOCAL_APIC
-	if (acpi_lapic && acpi_ioapic)
-		smp_found_config = 1;
-#endif
-
-#ifdef CONFIG_HPET_TIMER
-	result = acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
-	if (result < 0) 
-		printk("ACPI: no HPET table found (%d).\n", result); 
-#endif
-
-	return 0;
-}
-
-#endif /*CONFIG_ACPI_BOOT*/
-
-
-/* --------------------------------------------------------------------------
-                              Low-Level Sleep Support
-   -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI_SLEEP
-
-extern void acpi_prepare_wakeup(void);
-extern unsigned char acpi_wakeup[], acpi_wakeup_end[], s3_prot16[];
-
-/* address in low memory of the wakeup routine. */
-unsigned long acpi_wakeup_address;
-
-/**
- * acpi_save_state_mem - save kernel state
- */
-int acpi_save_state_mem (void)
-{
-	if (!acpi_wakeup_address)
-		return -1;
-
-	memcpy((void*)acpi_wakeup_address, acpi_wakeup, acpi_wakeup_end - acpi_wakeup); 
-	return 0;
-}
-
-/**
- * acpi_save_state_disk - save kernel state to disk
- *
- * Assume preemption/interrupts are already turned off and that we're running
- * on the BP (note this doesn't imply SMP is handled correctly)
- */
-int acpi_save_state_disk (void)
-{
-	unsigned long pbase = read_cr3() & PAGE_MASK; 
-	if (pbase >= 0xffffffffUL) {
-		printk(KERN_ERR "ACPI: High page table. Suspend disabled.\n");
-	return 1;
-	} 
-	set_seg_base(smp_processor_id(), GDT_ENTRY_KERNELCS16, s3_prot16); 
-	swap_low_mappings();
-	acpi_prepare_wakeup();
-	return 0;
-}
-
-/*
- * acpi_restore_state
- */
-void acpi_restore_state_mem (void)
-{
-	swap_low_mappings();
-}
-
-/**
- * acpi_reserve_bootmem - do _very_ early ACPI initialisation
- *
- * We allocate a page in 1MB low memory for the real-mode wakeup
- * routine for when we come back from a sleep state. The
- * runtime allocator allows specification of <16M pages, but not
- * <1M pages.
- */
-void __init acpi_reserve_bootmem(void)
-{
-	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
-	if (!acpi_wakeup_address) { 
-		printk(KERN_ERR "ACPI: Cannot allocate lowmem. S3 disabled.\n");
-		return;
-	} 
-}
-
-#endif /*CONFIG_ACPI_SLEEP*/
-
-void acpi_pci_link_exit(void) {}
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/apic.c linux-2.5.69-bk17/arch/x86_64/kernel/apic.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/apic.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/apic.c	2003-05-24 04:33:33.000000000 -0700
@@ -385,10 +385,10 @@
 	value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
 	if (!smp_processor_id() && (pic_mode || !value)) {
 		value = APIC_DM_EXTINT;
-		printk("enabled ExtINT on CPU#%d\n", smp_processor_id());
+		Dprintk(KERN_INFO "enabled ExtINT on CPU#%d\n", smp_processor_id());
 	} else {
 		value = APIC_DM_EXTINT | APIC_LVT_MASKED;
-		printk("masked ExtINT on CPU#%d\n", smp_processor_id());
+		Dprintk(KERN_INFO "masked ExtINT on CPU#%d\n", smp_processor_id());
 	}
 	apic_write_around(APIC_LVT0, value);
 
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/asm-offsets.c linux-2.5.69-bk17/arch/x86_64/kernel/asm-offsets.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/asm-offsets.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/asm-offsets.c	2003-05-24 04:33:33.000000000 -0700
@@ -12,6 +12,7 @@
 #include <asm/processor.h>
 #include <asm/segment.h>
 #include <asm/thread_info.h>
+#include <asm/ia32.h>
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -43,5 +44,21 @@
 	ENTRY(irqstackptr);
 	BLANK();
 #undef ENTRY
+#define ENTRY(entry) DEFINE(IA32_SIGCONTEXT_ ## entry, offsetof(struct sigcontext_ia32, entry))
+	ENTRY(eax);
+	ENTRY(ebx);
+	ENTRY(ecx);
+	ENTRY(edx);
+	ENTRY(esi);
+	ENTRY(edi);
+	ENTRY(ebp);
+	ENTRY(esp);
+	ENTRY(eip);
+	BLANK();
+#undef ENTRY
+	DEFINE(IA32_RT_SIGFRAME_sigcontext,
+	       offsetof (struct rt_sigframe32, uc.uc_mcontext));
+	BLANK();
+
 	return 0;
 }
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/bluesmoke.c linux-2.5.69-bk17/arch/x86_64/kernel/bluesmoke.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/bluesmoke.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/bluesmoke.c	2003-05-24 04:33:33.000000000 -0700
@@ -129,12 +129,75 @@
 	int cpu = smp_processor_id(); 
 	pci_for_each_dev(dev) {
 		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
-		    PCI_SLOT(dev->devfn) == (24+cpu))
+		    PCI_SLOT(dev->devfn) == (24U+cpu))
 			return dev;
 	}
 	return NULL;
 }
 
+/* When we have kallsyms we can afford kmcedecode too. */
+
+static char *transaction[] = { 
+	"instruction", "data", "generic", "reserved"
+}; 
+static char *cachelevel[] = { 
+	"level 0", "level 1", "level 2", "level generic"
+};
+static char *memtrans[] = { 
+	"generic error", "generic read", "generic write", "data read",
+	"data write", "instruction fetch", "prefetch", "snoop",
+	"?", "?", "?", "?", "?", "?", "?"
+};
+static char *partproc[] = { 
+	"local node origin", "local node response", 
+	"local node observed", "generic" 
+};
+static char *timeout[] = { 
+	"request didn't time out",
+	"request timed out"
+};
+static char *memoryio[] = { 
+	"memory access", "res.", "i/o access", "generic"
+}; 
+static char *extendederr[] = { 
+	"ecc error", 
+	"crc error",
+	"sync error",
+	"mst abort",
+	"tgt abort",
+	"gart error",
+	"rmw error",
+	"wdog error",
+	"chipkill ecc error", 
+	"<9>","<10>","<11>","<12>",
+	"<13>","<14>","<15>"
+}; 
+static char *highbits[32] = { 
+	[31] = "previous error lost", 
+	[30] = "error overflow",
+	[29] = "error uncorrected",
+	[28] = "error enable",
+	[27] = "misc error valid",
+	[26] = "error address valid", 
+	[25] = "processor context corrupt", 
+	[24] = "res24",
+	[23] = "res23",
+	/* 22-15 ecc syndrome bits */
+	[14] = "corrected ecc error",
+	[13] = "uncorrected ecc error",
+	[12] = "res12",
+	[11] = "res11",
+	[10] = "res10",
+	[9] = "res9",
+	[8] = "dram scrub error", 
+	[7] = "res7",
+	/* 6-4 ht link number of error */ 
+	[3] = "res3",
+	[2] = "res2",
+	[1] = "err cpu0",
+	[0] = "err cpu1",
+};
+
 static void check_k8_nb(void)
 {
 	struct pci_dev *nb;
@@ -149,20 +212,52 @@
 		return;
 	printk(KERN_ERR "Northbridge status %08x%08x\n",
 	       statushigh,statuslow); 
-	if (statuslow & 0x10) 
-		printk(KERN_ERR "GART error %d\n", statuslow & 0xf); 
-	if (statushigh & (1<<31))
-		printk(KERN_ERR "Lost an northbridge error\n"); 
-	if (statushigh & (1<<25))
-		printk(KERN_EMERG "NB status: unrecoverable\n"); 
+
+	unsigned short errcode = statuslow & 0xffff;	
+	switch (errcode >> 8) { 
+	case 0: 					
+		printk(KERN_ERR "    GART TLB error %s %s\n", 
+		       transaction[(errcode >> 2) & 3], 
+		       cachelevel[errcode & 3]);
+		break;
+	case 1: 
+		if (errcode & (1<<11)) { 
+			printk(KERN_ERR "    bus error %s %s %s %s %s\n",
+			       partproc[(errcode >> 10) & 0x3],
+			       timeout[(errcode >> 9) & 1],
+			       memtrans[(errcode >> 4) & 0xf],
+			       memoryio[(errcode >> 2) & 0x3], 
+			       cachelevel[(errcode & 0x3)]); 
+		} else if (errcode & (1<<8)) { 
+			printk(KERN_ERR "    memory error %s %s %s\n",
+			       memtrans[(errcode >> 4) & 0xf],
+			       transaction[(errcode >> 2) & 0x3],
+			       cachelevel[(errcode & 0x3)]);
+		} else {
+			printk(KERN_ERR "    unknown error code %x\n", errcode); 
+		}
+		break;
+	} 
+	if (statushigh & ((1<<14)|(1<<13)))
+		printk(KERN_ERR "    ECC syndrome bits %x\n", 
+		       (((statuslow >> 24) & 0xff)  << 8) | ((statushigh >> 15) & 0x7f));
+	errcode = (statuslow >> 16) & 0xf;
+	printk(KERN_ERR "    extended error %s\n", extendederr[(statuslow >> 16) & 0xf]); 
+	
+	/* should only print when it was a HyperTransport related error. */
+	printk(KERN_ERR "    link number %x\n", (statushigh >> 4) & 3);
+
+	int i;
+	for (i = 0; i < 32; i++) 
+		if (highbits[i] && (statushigh & (1<<i)))
+			printk(KERN_ERR "    %s\n", highbits[i]); 
+
 	if (statushigh & (1<<26)) { 
 		u32 addrhigh, addrlow; 
 		pci_read_config_dword(nb, 0x54, &addrhigh); 
 		pci_read_config_dword(nb, 0x50, &addrlow); 
-		printk(KERN_ERR "NB error address %08x%08x\n", addrhigh,addrlow); 
+		printk(KERN_ERR "    error address %08x%08x\n", addrhigh,addrlow); 
 	}
-	if (statushigh & (1<<29))
-		printk(KERN_EMERG "Error uncorrected\n"); 
 	statushigh &= ~(1<<31); 
 	pci_write_config_dword(nb, 0x4c, statushigh); 		
 }
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/e820.c linux-2.5.69-bk17/arch/x86_64/kernel/e820.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/e820.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/e820.c	2003-05-24 04:33:33.000000000 -0700
@@ -75,7 +75,7 @@
 	return 0;
 } 
 
-int __init e820_mapped(unsigned long start, unsigned long end, int type) 
+int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) 
 { 
 	int i;
 	for (i = 0; i < e820.nr_map; i++) { 
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/entry.S linux-2.5.69-bk17/arch/x86_64/kernel/entry.S
--- linux-2.5.69-bk16/arch/x86_64/kernel/entry.S	2003-05-04 16:53:12.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/entry.S	2003-05-24 04:33:33.000000000 -0700
@@ -97,8 +97,8 @@
 /*
  * A newly forked process directly context switches into this.
  */ 	
+/* rdi:	prev */	
 ENTRY(ret_from_fork)
-	movq %rax,%rdi		/* prev task, returned by __switch_to -> arg1 */
 	call schedule_tail
 	GET_THREAD_INFO(%rcx)
 	bt $TIF_SYSCALL_TRACE,threadinfo_flags(%rcx)
@@ -414,6 +414,7 @@
 	.previous
 	.section .fixup,"ax"
 	/* force a signal here? this matches i386 behaviour */
+	/* running with kernel gs */
 bad_iret:
 	movq $-9999,%rdi	/* better code? */
 	jmp do_exit			
@@ -519,21 +520,27 @@
  */ 		  				
 ENTRY(error_entry)
 	/* rdi slot contains rax, oldrax contains error code */
-	pushq %rsi
-	movq  8(%rsp),%rsi	/* load rax */
-	pushq %rdx
-	pushq %rcx
-	pushq %rsi	/* store rax */ 
-	pushq %r8
-	pushq %r9
-	pushq %r10
-	pushq %r11
 	cld	
-	SAVE_REST
+	subq  $14*8,%rsp
+	movq %rsi,13*8(%rsp)
+	movq 14*8(%rsp),%rsi	/* load rax from rdi slot */
+	movq %rdx,12*8(%rsp)
+	movq %rcx,11*8(%rsp)
+	movq %rsi,10*8(%rsp)	/* store rax */ 
+	movq %r8, 9*8(%rsp)
+	movq %r9, 8*8(%rsp)
+	movq %r10,7*8(%rsp)
+	movq %r11,6*8(%rsp)
+	movq %rbx,5*8(%rsp) 
+	movq %rbp,4*8(%rsp) 
+	movq %r12,3*8(%rsp) 
+	movq %r13,2*8(%rsp) 
+	movq %r14,1*8(%rsp) 
+	movq %r15,(%rsp) 
+	xorl %ebx,%ebx	
 	testl $3,CS(%rsp)
 	je  error_kernelspace
 error_swapgs:	
-	xorl %ebx,%ebx	
 	swapgs
 error_sti:	
 	movq %rdi,RDI(%rsp) 	
@@ -557,13 +564,14 @@
 	iretq
 
 error_kernelspace:
+	incl %ebx
        /* There are two places in the kernel that can potentially fault with
-          usergs. Handle them here. */    
+          usergs. Handle them here. The exception handlers after
+	  iret run with kernel gs again, so don't set the user space flag. */
 	cmpq $iret_label,RIP(%rsp) 
 	je   error_swapgs
 	cmpq $gs_change,RIP(%rsp)
         je   error_swapgs
-	movl $1,%ebx	
 	jmp  error_sti
 	
        /* Reload gs selector with exception handling */
@@ -584,7 +592,9 @@
         .quad gs_change,bad_gs
         .previous
         .section .fixup,"ax"
+	/* running with kernelgs */
 bad_gs: 
+	swapgs			/* switch back to user gs */
 	xorl %eax,%eax
         movl %eax,%gs
         jmp  2b
@@ -614,12 +624,8 @@
 	
 	# clone now
 	call do_fork
-
+	movq %rax,RAX(%rsp)
 	xorl %edi,%edi
-	cmpq $-1000,%rax
-	jnb  1f
-	movl tsk_pid(%rax),%eax	
-1:	movq %rax,RAX(%rsp)
 
 	/*
 	 * It isn't worth to check for reschedule here,
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/head.S linux-2.5.69-bk17/arch/x86_64/kernel/head.S
--- linux-2.5.69-bk16/arch/x86_64/kernel/head.S	2003-05-04 16:53:33.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/head.S	2003-05-24 04:33:33.000000000 -0700
@@ -351,7 +351,7 @@
 	
 ENTRY(cpu_gdt_table)
 	.quad	0x0000000000000000	/* NULL descriptor */
-	.quad	0x0000000000000000	/* unused */
+	.quad	0x00af9a000000ffff ^ (1<<21)	/* __KERNEL_COMPAT32_CS */	
 	.quad	0x00af9a000000ffff	/* __KERNEL_CS */
 	.quad	0x00cf92000000ffff	/* __KERNEL_DS */
 	.quad	0x00cffe000000ffff	/* __USER32_CS */
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/io_apic.c linux-2.5.69-bk17/arch/x86_64/kernel/io_apic.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/io_apic.c	2003-05-04 16:53:29.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/io_apic.c	2003-05-24 04:33:33.000000000 -0700
@@ -1060,7 +1060,8 @@
 			phys_id_present_map |= 1 << i;
 			mp_ioapics[apic].mpc_apicid = i;
 		} else {
-			printk("Setting %d in the phys_id_present_map\n", mp_ioapics[apic].mpc_apicid);
+			printk(KERN_INFO 
+			       "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid);
 			phys_id_present_map |= 1 << mp_ioapics[apic].mpc_apicid;
 		}
 
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/ioport.c linux-2.5.69-bk17/arch/x86_64/kernel/ioport.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/ioport.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/ioport.c	2003-05-24 04:33:33.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- *	linux/arch/i386/kernel/ioport.c
+ *	linux/arch/x86_64/kernel/ioport.c
  *
  * This contains the io-permission bitmap code - written by obz, with changes
  * by Linus.
@@ -15,34 +15,35 @@
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/slab.h>
+#include <asm/io.h>
 
 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
 static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
 {
-	int mask;
-	unsigned long *bitmap_base = bitmap + (base >> 6);
+	unsigned long mask;
+	unsigned long *bitmap_base = bitmap + (base / sizeof(unsigned long));
 	unsigned short low_index = base & 0x3f;
 	int length = low_index + extent;
 
 	if (low_index != 0) {
-		mask = (~0 << low_index);
+		mask = (~0UL << low_index);
 		if (length < 64)
-				mask &= ~(~0 << length);
+			mask &= ~(~0UL << length);
 		if (new_value)
 			*bitmap_base++ |= mask;
 		else
 			*bitmap_base++ &= ~mask;
-		length -= 32;
+		length -= 64;
 	}
 
-	mask = (new_value ? ~0 : 0);
+	mask = (new_value ? ~0UL : 0UL);
 	while (length >= 64) {
 		*bitmap_base++ = mask;
 		length -= 64;
 	}
 
 	if (length > 0) {
-		mask = ~(~0 << length);
+		mask = ~(~0UL << length);
 		if (new_value)
 			*bitmap_base++ |= mask;
 		else
@@ -113,3 +114,10 @@
 	regs.eflags = (regs.eflags & 0xffffffffffffcfff) | (level << 12);
 	return 0;
 }
+
+void eat_key(void)
+{
+	if (inb(0x60) & 1) 
+		inb(0x64);
+}
+
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/irq.c linux-2.5.69-bk17/arch/x86_64/kernel/irq.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/irq.c	2003-05-24 04:33:28.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/irq.c	2003-05-24 04:33:33.000000000 -0700
@@ -795,7 +795,7 @@
 {
 	unsigned char hexnum [HEX_DIGITS];
 	unsigned long value;
-	int i;
+	unsigned i;
 
 	if (!count)
 		return -EINVAL;
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/ldt.c linux-2.5.69-bk17/arch/x86_64/kernel/ldt.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/ldt.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/ldt.c	2003-05-24 04:33:33.000000000 -0700
@@ -32,13 +32,13 @@
 }
 #endif
 
-static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
+static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
 {
 	void *oldldt;
 	void *newldt;
-	int oldsize;
+	unsigned oldsize;
 
-	if (mincount <= pc->size)
+	if (mincount <= (unsigned)pc->size)
 		return 0;
 	oldsize = pc->size;
 	mincount = (mincount+511)&(~511);
@@ -63,7 +63,7 @@
 #ifdef CONFIG_SMP
 		preempt_disable();
 		load_LDT(pc);
-		if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
+		if (current->mm->cpu_vm_mask != (1UL<<smp_processor_id()))
 			smp_call_function(flush_ldt, 0, 1, 1);
 		preempt_enable();
 #else
@@ -116,7 +116,7 @@
 void destroy_context(struct mm_struct *mm)
 {
 	if (mm->context.size) {
-		if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
+		if ((unsigned)mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
 			vfree(mm->context.ldt);
 		else
 			kfree(mm->context.ldt);
@@ -190,7 +190,7 @@
 	}
 
 	down(&mm->context.sem);
-	if (ldt_info.entry_number >= mm->context.size) {
+	if (ldt_info.entry_number >= (unsigned)mm->context.size) {
 		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
 		if (error < 0)
 			goto out_unlock;
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/mpparse.c linux-2.5.69-bk17/arch/x86_64/kernel/mpparse.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/mpparse.c	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/mpparse.c	2003-05-24 04:33:33.000000000 -0700
@@ -892,11 +892,15 @@
 	list_for_each(node, &acpi_prt.entries) {
 		entry = list_entry(node, struct acpi_prt_entry, node);
 
-		/* We're only interested in static (non-link) entries. */
-		if (entry->link.handle)
+		/* Need to get irq for dynamic entry */
+		if (entry->link.handle) {
+			irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index);
+			if (!irq)
 			continue;
-
+		}
+		else
 		irq = entry->link.index;
+
 		ioapic = mp_find_ioapic(irq);
 		if (ioapic < 0)
 			continue;
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/pci-dma.c linux-2.5.69-bk17/arch/x86_64/kernel/pci-dma.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/pci-dma.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/pci-dma.c	2003-05-24 04:33:33.000000000 -0700
@@ -32,7 +32,6 @@
 	int i;
 
 	BUG_ON(direction == PCI_DMA_NONE);
- 
  	for (i = 0; i < nents; i++ ) {
 		struct scatterlist *s = &sg[i];
 
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/pci-gart.c linux-2.5.69-bk17/arch/x86_64/kernel/pci-gart.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/pci-gart.c	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/pci-gart.c	2003-05-24 04:33:33.000000000 -0700
@@ -14,15 +14,10 @@
 /* 
  * Notebook:
 
-agpgart_be
- check if the simple reservation scheme is enough.
-
 possible future tuning: 
- fast path for sg streaming mappings 
- more intelligent flush strategy - flush only a single NB? flush only when
- gart area fills up and alloc_iommu wraps. 
- don't flush on allocation - need to unmap the gart area first to avoid prefetches
- by the CPU
+ fast path for sg streaming mappings - only take the locks once.
+ more intelligent flush strategy - flush only the NB of the CPU directly
+ connected to the device?
  move boundary between IOMMU and AGP in GART dynamically
   
 */ 
@@ -67,7 +62,8 @@
 
 #define GPTE_VALID    1
 #define GPTE_COHERENT 2
-#define GPTE_ENCODE(x) (((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
+#define GPTE_ENCODE(x) \
+	(((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
 #define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))
 
 #define for_all_nb(dev) \
@@ -90,20 +86,23 @@
 
 static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
 
-static unsigned long alloc_iommu(int size) 
+static unsigned long alloc_iommu(int size, int *flush) 
 { 	
 	unsigned long offset, flags;
 
 	spin_lock_irqsave(&iommu_bitmap_lock, flags);	
-
 	offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size);
-	if (offset == -1) 
+	if (offset == -1) {
+		*flush = 1;
 	       	offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size);
+	}
 	if (offset != -1) { 
 		set_bit_string(iommu_gart_bitmap, offset, size); 
 		next_bit = offset+size; 
-		if (next_bit >= iommu_pages) 
+		if (next_bit >= iommu_pages) { 
 			next_bit = 0;
+			*flush = 1;
+		} 
 	} 
 	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);      
 	return offset;
@@ -114,7 +113,6 @@
 	unsigned long flags;
 	spin_lock_irqsave(&iommu_bitmap_lock, flags);
 	clear_bit_string(iommu_gart_bitmap, offset, size);
-	next_bit = offset;
 	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
 } 
 
@@ -137,6 +135,7 @@
 	int gfp = GFP_ATOMIC;
 	int i;
 	unsigned long iommu_page;
+	int flush = 0;
 
 	if (hwdev == NULL || hwdev->dma_mask < 0xffffffff || no_iommu)
 		gfp |= GFP_DMA;
@@ -150,9 +149,10 @@
 	if (memory == NULL) {
 		return NULL; 
 	} else {
-		int high = (unsigned long)virt_to_bus(memory) + size
-			>= 0xffffffff;
-		int mmu = high;
+		int high = 0, mmu;
+		if (((unsigned long)virt_to_bus(memory) + size) > 0xffffffffUL)
+			high = 1;
+		mmu = 1;
 		if (force_mmu && !(gfp & GFP_DMA)) 
 			mmu = 1;
 		if (no_iommu) { 
@@ -168,7 +168,7 @@
 
 	size >>= PAGE_SHIFT;
 
-	iommu_page = alloc_iommu(size);
+	iommu_page = alloc_iommu(size, &flush);
 	if (iommu_page == -1)
 		goto error; 
 
@@ -183,6 +183,7 @@
 		iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); 
 	} 
 
+	if (flush) 
 	flush_gart();
 	*dma_handle = iommu_bus_base + (iommu_page << PAGE_SHIFT);
 	return memory; 
@@ -199,25 +200,24 @@
 void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 			 void *vaddr, dma_addr_t bus)
 {
-	u64 pte;
 	unsigned long iommu_page;
-	int i;
 
 	size = round_up(size, PAGE_SIZE); 
-	if (bus < iommu_bus_base || bus > iommu_bus_base + iommu_size) { 
-		free_pages((unsigned long)vaddr, get_order(size)); 		
-		return;
-	} 
-	size >>= PAGE_SHIFT;
-	iommu_page = (bus - iommu_bus_base) / PAGE_SIZE;
-	for (i = 0; i < size; i++) {
-		pte = iommu_gatt_base[iommu_page + i];
+	if (bus >= iommu_bus_base && bus <= iommu_bus_base + iommu_size) { 
+		unsigned pages = size >> PAGE_SHIFT;
+		iommu_page = (bus - iommu_bus_base) >> PAGE_SHIFT;
+		vaddr = __va(GPTE_DECODE(iommu_gatt_base[iommu_page]));
+#ifdef CONFIG_IOMMU_DEBUG
+		int i;
+		for (i = 0; i < pages; i++) {
+			u64 pte = iommu_gatt_base[iommu_page + i];
 		BUG_ON((pte & GPTE_VALID) == 0); 
 		iommu_gatt_base[iommu_page + i] = 0; 		
-		free_page((unsigned long) __va(GPTE_DECODE(pte)));
 	} 
-	flush_gart(); 
-	free_iommu(iommu_page, size);
+#endif
+		free_iommu(iommu_page, pages);
+	}
+	free_pages((unsigned long)vaddr, get_order(size)); 		
 }
 
 #ifdef CONFIG_IOMMU_LEAK
@@ -257,7 +257,7 @@
 	 */ 
 	
 	printk(KERN_ERR 
-  "PCI-DMA: Error: ran out out IOMMU space for %p size %lu at device %s[%s]\n",
+  "PCI-DMA: Out of IOMMU space for %p size %lu at device %s[%s]\n",
 	       addr,size, dev ? dev->dev.name : "?", dev ? dev->slot_name : "?");
 
 	if (size > PAGE_SIZE*EMERGENCY_PAGES) {
@@ -287,12 +287,12 @@
 	return mmu; 
 }
 
-dma_addr_t __pci_map_single(struct pci_dev *dev, void *addr, size_t size,
-			    int dir, int flush)
+dma_addr_t pci_map_single(struct pci_dev *dev, void *addr, size_t size, int dir)
 { 
 	unsigned long iommu_page;
 	unsigned long phys_mem, bus;
 	int i, npages;
+	int flush = 0;
 
 	BUG_ON(dir == PCI_DMA_NONE);
 
@@ -302,7 +302,7 @@
 
 	npages = round_up(size + ((u64)addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
 
-	iommu_page = alloc_iommu(npages); 
+	iommu_page = alloc_iommu(npages, &flush); 
 	if (iommu_page == -1) {
 		iommu_full(dev, addr, size, dir); 
 		return iommu_bus_base; 
@@ -343,12 +343,14 @@
 		      size_t size, int direction)
 {
 	unsigned long iommu_page; 
-	int i, npages;
+	int npages;
 	if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || 
 	    dma_addr > iommu_bus_base + iommu_size)
 		return;
 	iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;	
 	npages = round_up(size + (dma_addr & ~PAGE_MASK), PAGE_SIZE) >> PAGE_SHIFT;
+#ifdef CONFIG_IOMMU_DEBUG
+	int i;
 	for (i = 0; i < npages; i++) { 
 		iommu_gatt_base[iommu_page + i] = 0; 
 #ifdef CONFIG_IOMMU_LEAK
@@ -356,11 +358,11 @@
 			iommu_leak_tab[iommu_page + i] = 0; 
 #endif
 	}
-	flush_gart(); 
+#endif
 	free_iommu(iommu_page, npages);
 }
 
-EXPORT_SYMBOL(__pci_map_single);
+EXPORT_SYMBOL(pci_map_single);
 EXPORT_SYMBOL(pci_unmap_single);
 
 static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
@@ -407,7 +409,7 @@
  * Private Northbridge GATT initialization in case we cannot use the
  * AGP driver for some reason.  
  */
-static __init int init_k8_gatt(agp_kern_info *info)
+static __init int init_k8_gatt(struct agp_kern_info *info)
 { 
 	struct pci_dev *dev;
 	void *gatt;
@@ -443,7 +445,7 @@
 		u32 ctl; 
 		u32 gatt_reg; 
 
-		gatt_reg = ((u64)gatt) >> 12; 
+		gatt_reg = __pa(gatt) >> 12; 
 		gatt_reg <<= 4; 
 		pci_write_config_dword(dev, 0x98, gatt_reg);
 		pci_read_config_dword(dev, 0x90, &ctl); 
@@ -465,9 +467,11 @@
 	return -1; 
 } 
 
+extern int agp_amdk8_init(void);
+
 void __init pci_iommu_init(void)
 { 
-	agp_kern_info info;
+	struct agp_kern_info info;
 	unsigned long aper_size;
 	unsigned long iommu_start;
 		
@@ -476,7 +480,6 @@
 #else
 	/* Add other K8 AGP bridge drivers here */
 	no_agp = no_agp || 
-		(agp_init() < 0) || 
 		(agp_amdk8_init() < 0) || 
 		(agp_copy_info(&info) < 0); 
 #endif	
@@ -536,8 +539,17 @@
 	iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
 	bad_dma_address = iommu_bus_base;
 
-	change_page_attr(virt_to_page(__va(iommu_start)), iommu_pages, PAGE_KERNEL); 
-	global_flush_tlb(); 
+	/* 
+         * Unmap the IOMMU part of the GART. The alias of the page is always mapped
+	 * with cache enabled and there is no full cache coherency across the GART
+	 * remapping. The unmapping avoids automatic prefetches from the CPU 
+	 * allocating cache lines in there. All CPU accesses are done via the 
+	 * direct mapping to the backing memory. The GART address is only used by PCI 
+	 * devices. 
+	 */
+	clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size);
+
+	flush_gart();
 } 
 
 /* iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/process.c linux-2.5.69-bk17/arch/x86_64/kernel/process.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/process.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/process.c	2003-05-24 04:33:33.000000000 -0700
@@ -216,7 +216,12 @@
 {
 	struct task_struct *tsk = current;
 
-	memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
+	tsk->thread.debugreg0 = 0;
+	tsk->thread.debugreg1 = 0;
+	tsk->thread.debugreg2 = 0;
+	tsk->thread.debugreg3 = 0;
+	tsk->thread.debugreg6 = 0;
+	tsk->thread.debugreg7 = 0;
 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));	
 	/*
 	 * Forget coprocessor state..
@@ -285,7 +290,7 @@
 
 	childregs->rax = 0;
 	childregs->rsp = rsp;
-	if (rsp == ~0) {
+	if (rsp == ~0UL) {
 		childregs->rsp = (unsigned long)childregs;
 	}
 	p->set_child_tid = p->clear_child_tid = NULL;
@@ -294,7 +299,7 @@
 	p->thread.rsp0 = (unsigned long) (childregs+1);
 	p->thread.userrsp = me->thread.userrsp; 
 
-	p->thread.rip = (unsigned long) ret_from_fork;
+	set_ti_thread_flag(p->thread_info, TIF_FORK);
 
 	p->thread.fs = me->thread.fs;
 	p->thread.gs = me->thread.gs;
@@ -335,8 +340,7 @@
 /*
  * This special macro can be used to load a debugging register
  */
-#define loaddebug(thread,register) \
-		set_debug(thread->debugreg[register], register)
+#define loaddebug(thread,r) set_debug(thread->debugreg ## r, r)
 
 /*
  *	switch_to(x,y) should switch tasks from x to y.
@@ -422,7 +426,7 @@
 	/*
 	 * Now maybe reload the debug registers
 	 */
-	if (unlikely(next->debugreg[7])) {
+	if (unlikely(next->debugreg7)) {
 		loaddebug(next, 0);
 		loaddebug(next, 1);
 		loaddebug(next, 2);
@@ -490,19 +494,15 @@
 
 asmlinkage long sys_fork(struct pt_regs regs)
 {
-	struct task_struct *p;
-	p = do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
-	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+	return do_fork(SIGCHLD, regs.rsp, &regs, 0, NULL, NULL);
 }
 
 asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void *parent_tid, void *child_tid, struct pt_regs regs)
 {
-	struct task_struct *p;
 	if (!newsp)
 		newsp = regs.rsp;
-	p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, 
+	return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, 
 		    parent_tid, child_tid);
-	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
 /*
@@ -517,10 +517,8 @@
  */
 asmlinkage long sys_vfork(struct pt_regs regs)
 {
-	struct task_struct *p;
-	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0, 
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0, 
 		    NULL, NULL);
-	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
 /*
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/ptrace.c linux-2.5.69-bk17/arch/x86_64/kernel/ptrace.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/ptrace.c	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/ptrace.c	2003-05-24 04:33:33.000000000 -0700
@@ -178,11 +178,11 @@
 
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data)
 {
 	struct task_struct *child;
-	struct user * dummy = NULL;
 	long i, ret;
+	unsigned ui;
 
 	/* This lock_kernel fixes a subtle race with suid exec */
 	lock_kernel();
@@ -240,18 +240,35 @@
 		unsigned long tmp;
 
 		ret = -EIO;
-		if ((addr & 7) || addr < 0 || 
+		if ((addr & 7) ||
 		    addr > sizeof(struct user) - 7)
 			break;
 
-		tmp = 0;  /* Default return condition */
-		if(addr < sizeof(struct user_regs_struct))
+		switch (addr) { 
+		case 0 ... sizeof(struct user_regs_struct):
 			tmp = getreg(child, addr);
-		if(addr >= (long) &dummy->u_debugreg[0] &&
-		   addr <= (long) &dummy->u_debugreg[7]){
-			addr -= (long) &dummy->u_debugreg[0];
-			addr = addr >> 3;
-			tmp = child->thread.debugreg[addr];
+			break;
+		case offsetof(struct user, u_debugreg[0]):
+			tmp = child->thread.debugreg0;
+			break;
+		case offsetof(struct user, u_debugreg[1]):
+			tmp = child->thread.debugreg1;
+			break;
+		case offsetof(struct user, u_debugreg[2]):
+			tmp = child->thread.debugreg2;
+			break;
+		case offsetof(struct user, u_debugreg[3]):
+			tmp = child->thread.debugreg3;
+			break;
+		case offsetof(struct user, u_debugreg[6]):
+			tmp = child->thread.debugreg6;
+			break;
+		case offsetof(struct user, u_debugreg[7]):
+			tmp = child->thread.debugreg7;
+			break;
+		default:
+			tmp = 0;
+			break;
 		}
 		ret = put_user(tmp,(unsigned long *) data);
 		break;
@@ -268,47 +285,53 @@
 
 	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
 		ret = -EIO;
-		if ((addr & 7) || addr < 0 || 
+		if ((addr & 7) ||
 		    addr > sizeof(struct user) - 7)
 			break;
 
-		if (addr < sizeof(struct user_regs_struct)) {
+		switch (addr) { 
+		case 0 ... sizeof(struct user_regs_struct): 
 			ret = putreg(child, addr, data);
 			break;
-		}
-		/* We need to be very careful here.  We implicitly
-		   want to modify a portion of the task_struct, and we
-		   have to be selective about what portions we allow someone
-		   to modify. */
-
-		  ret = -EIO;
-		  if(addr >= (long) &dummy->u_debugreg[0] &&
-		     addr <= (long) &dummy->u_debugreg[7]){
-
-			  if(addr == (long) &dummy->u_debugreg[4]) break;
-			  if(addr == (long) &dummy->u_debugreg[5]) break;
-			  if(addr < (long) &dummy->u_debugreg[4] &&
-			     ((unsigned long) data) >= TASK_SIZE-3) break;
-			  
-			  if (addr == (long) &dummy->u_debugreg[6]) {
+		/* Disallows to set a breakpoint into the vsyscall */
+		case offsetof(struct user, u_debugreg[0]):
+			if (data >= TASK_SIZE-7) break;
+			child->thread.debugreg0 = data;
+			ret = 0;
+			break;
+		case offsetof(struct user, u_debugreg[1]):
+			if (data >= TASK_SIZE-7) break;
+			child->thread.debugreg1 = data;
+			ret = 0;
+			break;
+		case offsetof(struct user, u_debugreg[2]):
+			if (data >= TASK_SIZE-7) break;
+			child->thread.debugreg2 = data;
+			ret = 0;
+			break;
+		case offsetof(struct user, u_debugreg[3]):
+			if (data >= TASK_SIZE-7) break;
+			child->thread.debugreg3 = data;
+			ret = 0;
+			break;
+		case offsetof(struct user, u_debugreg[6]):
 				  if (data >> 32)
-					  goto out_tsk;
-			  }
-
-			  if(addr == (long) &dummy->u_debugreg[7]) {
+				break; 
+			child->thread.debugreg6 = data;
+			ret = 0;
+			break;
+		case offsetof(struct user, u_debugreg[7]):
 				  data &= ~DR_CONTROL_RESERVED;
 				  for(i=0; i<4; i++)
 					  if ((0x5454 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
-						  goto out_tsk;
-			  }
-
-			  addr -= (long) &dummy->u_debugreg;
-			  addr = addr >> 3;
-			  child->thread.debugreg[addr] = data;
+					break;
+			if (i == 4) {
+				child->thread.debugreg7 = data;
 			  ret = 0;
 		  }
 		  break;
-
+		}
+		break;
 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
 	case PTRACE_CONT: { /* restart after signal. */
 		long tmp;
@@ -408,8 +431,8 @@
 			ret = -EIO;
 			break;
 		}
-		for ( i = 0; i < sizeof(struct user_regs_struct); i += sizeof(long) ) {
-			__put_user(getreg(child, i),(unsigned long *) data);
+		for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
+			__put_user(getreg(child, ui),(unsigned long *) data);
 			data += sizeof(long);
 		}
 		ret = 0;
@@ -422,9 +445,9 @@
 			ret = -EIO;
 			break;
 		}
-		for ( i = 0; i < sizeof(struct user_regs_struct); i += sizeof(long) ) {
+		for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
 			__get_user(tmp, (unsigned long *) data);
-			putreg(child, i, tmp);
+			putreg(child, ui, tmp);
 			data += sizeof(long);
 		}
 		ret = 0;
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/reboot.c linux-2.5.69-bk17/arch/x86_64/kernel/reboot.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/reboot.c	2003-05-24 04:33:28.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/reboot.c	2003-05-24 04:33:33.000000000 -0700
@@ -9,7 +9,9 @@
 #include <asm/kdebug.h>
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
-
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
 
 /*
  * Power off function, if any
@@ -17,35 +19,37 @@
 void (*pm_power_off)(void);
 
 static long no_idt[3];
-static int reboot_mode;
-
-#ifdef CONFIG_SMP
-int reboot_smp = 0;
-static int reboot_cpu = -1;
-#endif
-
+static enum { 
+	BOOT_BIOS = 'b',
+	BOOT_TRIPLE = 't',
+	BOOT_KBD = 'k'
+} reboot_type = BOOT_KBD;
+static int reboot_mode = 0;
+
+/* reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
+   bios	  Use the CPU reboto vector for warm reset
+   warm   Don't set the cold reboot flag
+   cold   Set the cold reboto flag
+   triple Force a triple fault (init)
+   kbd    Use the keyboard controller. cold reset (default)
+ */ 
 static int __init reboot_setup(char *str)
 {
-	while(1) {
+	for (;;) {
 		switch (*str) {
-		case 'w': /* "warm" reboot (no memory testing etc) */
+		case 'w': 
 			reboot_mode = 0x1234;
 			break;
-		case 'c': /* "cold" reboot (with memory testing etc) */
-			reboot_mode = 0x0;
+
+		case 'c':
+			reboot_mode = 0;
 			break;
-#ifdef CONFIG_SMP
-		case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
-			reboot_smp = 1;
-			if (isdigit(str[1]))
-				sscanf(str+1, "%d", &reboot_cpu);		
-			else if (!strncmp(str,"smp",3))
-				sscanf(str+3, "%d", &reboot_cpu); 
-				/* we will leave sorting out the final value 
-				when we are ready to reboot, since we might not
- 				have set up boot_cpu_id or smp_num_cpu */
+
+		case 't':
+		case 'b':
+		case 'k':
+			reboot_type = *str;
 			break;
-#endif
 		}
 		if((str = strchr(str,',')) != NULL)
 			str++;
@@ -57,6 +61,56 @@
 
 __setup("reboot=", reboot_setup);
 
+/* overwrites random kernel memory. Should not be kernel .text */
+#define WARMBOOT_TRAMP 0x1000UL
+
+static void reboot_warm(void)
+{
+	extern unsigned char warm_reboot[], warm_reboot_end[];
+	printk("warm reboot\n");
+
+	local_irq_disable(); 
+		
+	/* restore identity mapping */
+	init_level4_pgt[0] = __pml4(__pa(level3_ident_pgt) | 7); 
+	__flush_tlb_all(); 
+
+	/* Move the trampoline to low memory */
+	memcpy(__va(WARMBOOT_TRAMP), warm_reboot, warm_reboot_end - warm_reboot); 
+
+	/* Start it in compatibility mode. */
+	asm volatile( "   pushq $0\n" 		/* ss */
+		     "   pushq $0x2000\n" 	/* rsp */
+	             "   pushfq\n"		/* eflags */
+		     "   pushq %[cs]\n"
+		     "   pushq %[target]\n"
+		     "   iretq" :: 
+		      [cs] "i" (__KERNEL_COMPAT32_CS), 
+		      [target] "b" (WARMBOOT_TRAMP));
+}
+
+#ifdef CONFIG_SMP
+static void smp_halt(void)
+{
+	int cpuid = safe_smp_processor_id(); 
+
+	/* Only run this on the boot processor */
+	if (cpuid != boot_cpu_id) { 
+		static int first_entry = 1;
+		if (first_entry) { 
+			first_entry = 0;
+			smp_call_function((void *)machine_restart, NULL, 1, 0);
+		} else {
+			/* AP reentering. just halt */
+			for(;;) 
+				asm volatile("hlt");
+		} 
+			
+	}
+	smp_send_stop();
+}
+#endif
+
 static inline void kb_wait(void)
 {
 	int i;
@@ -68,48 +122,24 @@
 
 void machine_restart(char * __unused)
 {
-#ifdef CONFIG_SMP
-	int cpuid;
-	
-	cpuid = GET_APIC_ID(apic_read(APIC_ID));
-
-	if (reboot_smp) {
+	int i;
 
-		/* check to see if reboot_cpu is valid 
-		   if its not, default to the BSP */
-		if ((reboot_cpu == -1) ||  
-		      (reboot_cpu > (NR_CPUS -1))  || 
-		      !(phys_cpu_present_map & (1<<cpuid))) 
-			reboot_cpu = boot_cpu_id;
-
-		reboot_smp = 0;  /* use this as a flag to only go through this once*/
-		/* re-run this function on the other CPUs
-		   it will fall though this section since we have 
-		   cleared reboot_smp, and do the reboot if it is the
-		   correct CPU, otherwise it halts. */
-		if (reboot_cpu != cpuid)
-			smp_call_function((void *)machine_restart , NULL, 1, 0);
-	}
+#if CONFIG_SMP
+	smp_halt(); 
+#endif
 
-	/* if reboot_cpu is still -1, then we want a tradional reboot, 
-	   and if we are not running on the reboot_cpu,, halt */
-	if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
-		for (;;)
-		__asm__ __volatile__ ("hlt");
-	}
-	/*
-	 * Stop all CPUs and turn off local APICs and the IO-APIC, so
-	 * other OSs see a clean IRQ state.
-	 */
-	smp_send_stop();
 	disable_IO_APIC();
-#endif
 	
-	/* rebooting needs to touch the page at absolute addr 0 */
+	/* Tell the BIOS if we want cold or warm reboot */
 	*((unsigned short *)__va(0x472)) = reboot_mode;
+       
 	for (;;) {
-		int i;
-		/* First fondle with the keyboard controller. */ 
+		/* Could also try the reset bit in the Hammer NB */
+		switch (reboot_type) { 
+		case BOOT_BIOS:
+			reboot_warm();
+
+		case BOOT_KBD:
 		for (i=0; i<100; i++) {
 			kb_wait();
 			udelay(50);
@@ -117,11 +147,13 @@
 			udelay(50);
 		}
 
-		/* Could do reset through the northbridge of Hammer here. */
-
-		/* That didn't work - force a triple fault.. */
+		case BOOT_TRIPLE: 
 		__asm__ __volatile__("lidt %0": :"m" (no_idt));
 		__asm__ __volatile__("int3");
+
+			reboot_type = BOOT_KBD;
+			break;
+		}      
 	}      
 }
 
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/setup.c linux-2.5.69-bk17/arch/x86_64/kernel/setup.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/setup.c	2003-05-04 16:53:00.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/setup.c	2003-05-24 04:33:33.000000000 -0700
@@ -201,6 +201,11 @@
 		if (!memcmp(from, "mem=", 4))
 			parse_memopt(from+4, &from); 
 
+#ifdef CONFIG_DISCONTIGMEM
+		if (!memcmp(from, "numa=", 5))
+			numa_setup(from+5); 
+#endif
+
 #ifdef CONFIG_GART_IOMMU 
 		if (!memcmp(from,"iommu=",6)) { 
 			iommu_setup(from+6); 
@@ -236,8 +241,6 @@
 
 void __init setup_arch(char **cmdline_p)
 {
-	int i;
-
 	Dprintk("setup_arch\n");
 
  	ROOT_DEV = ORIG_ROOT_DEV;
@@ -367,9 +370,12 @@
 
 	request_resource(&iomem_resource, &vram_resource);
 
+	{
+	unsigned i;
 	/* request I/O space for devices used on all i[345]86 PCs */
 	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
 		request_resource(&ioport_resource, standard_io_resources+i);
+	}
 
 	pci_mem_start = IOMAP_START; 
 
@@ -694,7 +700,7 @@
 
 	seq_printf(m, "power management:");
 	{
-		int i;
+		unsigned i;
 		for (i = 0; i < 32; i++) 
 			if (c->x86_power & (1 << i)) {
 				if (i < ARRAY_SIZE(x86_power_flags))
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/setup64.c linux-2.5.69-bk17/arch/x86_64/kernel/setup64.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/setup64.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/setup64.c	2003-05-24 04:33:33.000000000 -0700
@@ -23,6 +23,7 @@
 #include <asm/percpu.h>
 #include <asm/mtrr.h>
 #include <asm/proto.h>
+#include <asm/mman.h>
 
 char x86_boot_params[2048] __initdata = {0,};
 
@@ -40,22 +41,79 @@
 char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned;
 
 unsigned long __supported_pte_mask = ~0UL;
-static int do_not_nx = 1;
+static int do_not_nx __initdata = 0;
+unsigned long vm_stack_flags = __VM_STACK_FLAGS; 
+unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; 
+unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; 
+unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; 
+unsigned long vm_force_exec32 = PROT_EXEC; 
+
+/* noexec=on|off
+Control non executable mappings for 64bit processes.
+
+on	Enable
+off	Disable
+noforce (default) Don't enable by default for heap/stack/data, 
+	but allow PROT_EXEC to be effective
 
+*/ 
 static int __init nonx_setup(char *str)
 {
-        if (!strncmp(str,"off",3)) { 
-                __supported_pte_mask &= ~_PAGE_NX; 
-                do_not_nx = 1; 
-        } else if (!strncmp(str, "on",3)) { 
-                do_not_nx = 0; 
+	if (!strncmp(str, "on",3)) { 
                 __supported_pte_mask |= _PAGE_NX; 
+ 		do_not_nx = 0; 
+ 		vm_data_default_flags &= ~VM_EXEC; 
+ 		vm_stack_flags &= ~VM_EXEC;  
+	} else if (!strncmp(str, "noforce",7) || !strncmp(str,"off",3)) { 
+		do_not_nx = (str[0] == 'o');
+		if (do_not_nx)
+			__supported_pte_mask &= ~_PAGE_NX; 
+		vm_data_default_flags |= VM_EXEC; 
+		vm_stack_flags |= VM_EXEC;
         } 
         return 1;
 } 
 
 __setup("noexec=", nonx_setup); 
 
+/* noexec32=opt{,opt} 
+
+Control the no exec default for 32bit processes. Can be also overwritten
+per executable using ELF header flags (e.g. needed for the X server)
+Requires noexec=on or noexec=noforce to be effective.
+
+Valid options: 
+   all,on    Heap,stack,data is non executable. 	
+   off       (default) Heap,stack,data is executable
+   stack     Stack is non executable, heap/data is.
+   force     Don't imply PROT_EXEC for PROT_READ 
+   compat    (default) Imply PROT_EXEC for PROT_READ
+
+*/
+ static int __init nonx32_setup(char *str)
+ {
+	char *s;
+	while ((s = strsep(&str, ",")) != NULL) { 
+		if (!strcmp(s, "all") || !strcmp(s,"on")) {
+			vm_data_default_flags32 &= ~VM_EXEC; 
+			vm_stack_flags32 &= ~VM_EXEC;  
+		} else if (!strcmp(s, "off")) { 
+			vm_data_default_flags32 |= VM_EXEC; 
+			vm_stack_flags32 |= VM_EXEC;  
+		} else if (!strcmp(s, "stack")) { 
+			vm_data_default_flags32 |= VM_EXEC; 
+			vm_stack_flags32 &= ~VM_EXEC;  		
+		} else if (!strcmp(s, "force")) { 
+			vm_force_exec32 = 0; 
+		} else if (!strcmp(s, "compat")) { 
+			vm_force_exec32 = PROT_EXEC;
+		} 
+	} 
+ 	return 1;
+} 
+
+__setup("noexec32=", nonx32_setup); 
+
 #ifndef  __GENERIC_PER_CPU
 
 unsigned long __per_cpu_offset[NR_CPUS];
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/signal.c linux-2.5.69-bk17/arch/x86_64/kernel/signal.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/signal.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/signal.c	2003-05-24 04:33:33.000000000 -0700
@@ -371,7 +371,7 @@
 				regs->rax = regs->orig_rax;
 				regs->rip -= 2;
 		}
-		if (regs->rax == -ERESTART_RESTARTBLOCK){
+		if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK){
 			regs->rax = __NR_restart_syscall;
  			regs->rip -= 2;
  		}		
@@ -434,8 +434,8 @@
 		 * have been cleared if the watchpoint triggered
 		 * inside the kernel.
 		 */
-		if (current->thread.debugreg[7])
-			asm volatile("movq %0,%%db7"	: : "r" (current->thread.debugreg[7]));
+		if (current->thread.debugreg7)
+			asm volatile("movq %0,%%db7"	: : "r" (current->thread.debugreg7));
 
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &info, oldset, regs);
@@ -446,9 +446,10 @@
 	/* Did we come from a system call? */
 	if (regs->orig_rax >= 0) {
 		/* Restart the system call - no handlers present */
-		if (regs->rax == -ERESTARTNOHAND ||
-		    regs->rax == -ERESTARTSYS ||
-		    regs->rax == -ERESTARTNOINTR) {
+		long res = regs->rax;
+		if (res == -ERESTARTNOHAND ||
+		    res == -ERESTARTSYS ||
+		    res == -ERESTARTNOINTR) {
 			regs->rax = regs->orig_rax;
 			regs->rip -= 2;
 		}
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/smpboot.c linux-2.5.69-bk17/arch/x86_64/kernel/smpboot.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/smpboot.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/smpboot.c	2003-05-24 04:33:33.000000000 -0700
@@ -42,6 +42,7 @@
 #include <linux/smp_lock.h>
 #include <linux/irq.h>
 #include <linux/bootmem.h>
+#include <linux/thread_info.h>
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
@@ -123,7 +124,7 @@
 	unsigned long long t0;
 	unsigned long long sum, avg;
 	long long delta;
-	unsigned long one_usec;
+	long one_usec;
 	int buggy = 0;
 	extern unsigned cpu_khz;
 
@@ -339,7 +340,7 @@
 /*
  * Activate a secondary processor.
  */
-int __init start_secondary(void *unused)
+void __init start_secondary(void)
 {
 	/*
 	 * Dont put anything before smp_callin(), SMP
@@ -380,29 +381,7 @@
 	set_bit(smp_processor_id(), &cpu_online_map);
 	wmb();
 	
-	return cpu_idle();
-}
-
-/*
- * Everything has been set up for the secondary
- * CPUs - they just need to reload everything
- * from the task structure
- * This function must not return.
- */
-void __init initialize_secondary(void)
-{
-	struct task_struct *me = stack_current();
-
-	/*
-	 * We don't actually need to load the full TSS,
-	 * basically just the stack pointer and the eip.
-	 */
-
-	asm volatile(
-		"movq %0,%%rsp\n\t"
-		"jmp *%1"
-		:
-		:"r" (me->thread.rsp),"r" (me->thread.rip));
+	cpu_idle();
 }
 
 extern volatile unsigned long init_rsp; 
@@ -412,16 +391,16 @@
 {
 	struct pt_regs regs;
 	/*
-	 * don't care about the rip and regs settings since
+	 * don't care about the eip and regs settings since
 	 * we'll never reschedule the forked task.
 	 */
-	return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
+	return copy_process(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 }
 
 #if APIC_DEBUG
 static inline void inquire_remote_apic(int apicid)
 {
-	int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
+	unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
 	char *names[] = { "ID", "VERSION", "SPIV" };
 	int timeout, status;
 
@@ -596,6 +575,7 @@
 	idle = fork_by_hand();
 	if (IS_ERR(idle))
 		panic("failed fork for CPU %d", cpu);
+	wake_up_forked_process(idle);	
 
 	/*
 	 * We remove it from the pidhash and the runqueue
@@ -603,22 +583,19 @@
 	 */
 	init_idle(idle,cpu);
 
-	idle->thread.rip = (unsigned long)start_secondary;
-//	idle->thread.rsp = (unsigned long)idle->thread_info + THREAD_SIZE - 512;
-
 	unhash_process(idle);
 
 	cpu_pda[cpu].pcurrent = idle;
 
-	/* start_eip had better be page-aligned! */
 	start_rip = setup_trampoline();
 
-	init_rsp = (unsigned long)idle->thread_info + PAGE_SIZE + 1024;
+	init_rsp = idle->thread.rsp; 
 	init_tss[cpu].rsp0 = init_rsp;
-	initial_code = initialize_secondary;
+	initial_code = start_secondary;
+	clear_ti_thread_flag(idle->thread_info, TIF_FORK);
 
-	printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx rsp2 %lx\n", cpu, apicid, 
-	       start_rip, idle->thread.rsp, init_rsp);
+	printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid, 
+	       start_rip, init_rsp);
 
 	/*
 	 * This grunge runs the startup process for
@@ -676,7 +653,7 @@
 		if (test_bit(cpu, &cpu_callin_map)) {
 			/* number CPUs logically, starting from 1 (BSP is 0) */
 			Dprintk("OK.\n");
-			printk("KERN_INFO CPU%d: ", cpu);
+			printk(KERN_INFO "CPU%d: ", cpu);
 			print_cpu_info(&cpu_data[cpu]);
 			Dprintk("CPU has booted.\n");
 		} else {
@@ -708,7 +685,7 @@
 
 static void smp_tune_scheduling (void)
 {
-	unsigned long cachesize;       /* kB   */
+	int cachesize;       /* kB   */
 	unsigned long bandwidth = 1000; /* MB/s */
 	/*
 	 * Rough estimation for SMP scheduling, this is the number of
@@ -753,7 +730,7 @@
 
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
-	int apicid, cpu;
+	unsigned apicid, cpu;
 
 	/*
 	 * Setup boot CPU information
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/sys_x86_64.c linux-2.5.69-bk17/arch/x86_64/kernel/sys_x86_64.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/sys_x86_64.c	2003-05-04 16:53:33.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/sys_x86_64.c	2003-05-24 04:33:33.000000000 -0700
@@ -117,5 +117,5 @@
 asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg)
 {
 	unsigned long raddr;
-	return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: raddr;
+	return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr;
 } 
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/traps.c linux-2.5.69-bk17/arch/x86_64/kernel/traps.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/traps.c	2003-05-24 04:33:28.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/traps.c	2003-05-24 04:33:33.000000000 -0700
@@ -584,12 +584,12 @@
 
 	/* Mask out spurious debug traps due to lazy DR7 setting */
 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
-		if (!tsk->thread.debugreg[7]) { 
+		if (!tsk->thread.debugreg7) { 
 			goto clear_dr7;
 		}
 	}
 
-	tsk->thread.debugreg[6] = condition;
+	tsk->thread.debugreg6 = condition;
 
 	/* Mask out spurious TF errors due to lazy TF clearing */
 	if (condition & DR_STEP) {
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/vsyscall.S linux-2.5.69-bk17/arch/x86_64/kernel/vsyscall.S
--- linux-2.5.69-bk16/arch/x86_64/kernel/vsyscall.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk17/arch/x86_64/kernel/vsyscall.S	2003-05-24 04:33:33.000000000 -0700
@@ -0,0 +1,169 @@
+/*
+ * Code for the vsyscall page.  This version uses the syscall instruction.
+ */
+
+#include <asm/ia32_unistd.h>
+#include <asm/offset.h>
+
+	.text
+	.globl __kernel_vsyscall
+	.type __kernel_vsyscall,@function
+__kernel_vsyscall:
+.LSTART_vsyscall:
+	push	%ebp
+.Lpush_ebp:
+	movl	%ecx, %ebp
+	syscall
+	popl	%ebp
+.Lpop_ebp:
+	ret
+.LEND_vsyscall:
+	.size __kernel_vsyscall,.-.LSTART_vsyscall
+
+	.balign 32
+	.globl __kernel_sigreturn
+	.type __kernel_sigreturn,@function
+__kernel_sigreturn:
+.LSTART_sigreturn:
+	popl %eax
+	movl $__NR_ia32_sigreturn, %eax
+	syscall
+.LEND_sigreturn:
+	.size __kernel_sigreturn,.-.LSTART_sigreturn
+
+	.balign 32
+	.globl __kernel_rt_sigreturn
+	.type __kernel_rt_sigreturn,@function
+__kernel_rt_sigreturn:
+.LSTART_rt_sigreturn:
+	movl $__NR_ia32_rt_sigreturn, %eax
+	syscall
+.LEND_rt_sigreturn:
+	.size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
+
+	.section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+	.long .LENDCIE-.LSTARTCIE
+.LSTARTCIE:
+	.long 0			/* CIE ID */
+	.byte 1			/* Version number */
+	.string "zR"		/* NUL-terminated augmentation string */
+	.uleb128 1		/* Code alignment factor */
+	.sleb128 -4		/* Data alignment factor */
+	.byte 8			/* Return address register column */
+	.uleb128 1		/* Augmentation value length */
+	.byte 0x1b		/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
+	.byte 0x0c		/* DW_CFA_def_cfa */
+	.uleb128 4
+	.uleb128 4
+	.byte 0x88		/* DW_CFA_offset, column 0x8 */
+	.uleb128 1
+	.align 4
+.LENDCIE:
+
+	.long .LENDFDE1-.LSTARTFDE1	/* Length FDE */
+.LSTARTFDE1:
+	.long .LSTARTFDE1-.LSTARTFRAME	/* CIE pointer */
+	.long .LSTART_vsyscall-.	/* PC-relative start address */
+	.long .LEND_vsyscall-.LSTART_vsyscall
+	.uleb128 0			/* Augmentation length */
+	/* What follows are the instructions for the table generation.
+	   We have to record all changes of the stack pointer.  */
+	.byte 0x40 + .Lpush_ebp-.LSTART_vsyscall /* DW_CFA_advance_loc */
+	.byte 0x0e		/* DW_CFA_def_cfa_offset */
+	.uleb128 8
+	.byte 0x85, 0x02	/* DW_CFA_offset %ebp -8 */
+	.byte 0x40 + .Lpop_ebp-.Lpush_ebp /* DW_CFA_advance_loc */
+	.byte 0xc5		/* DW_CFA_restore %ebp */
+	.byte 0x0e		/* DW_CFA_def_cfa_offset */
+	.uleb128 4
+	.align 4
+.LENDFDE1:
+
+	.long .LENDFDE2-.LSTARTFDE2	/* Length FDE */
+.LSTARTFDE2:
+	.long .LSTARTFDE2-.LSTARTFRAME	/* CIE pointer */
+	/* HACK: The dwarf2 unwind routines will subtract 1 from the
+	   return address to get an address in the middle of the
+	   presumed call instruction.  Since we didn't get here via
+	   a call, we need to include the nop before the real start
+	   to make up for it.  */
+	.long .LSTART_sigreturn-1-.	/* PC-relative start address */
+	.long .LEND_sigreturn-.LSTART_sigreturn+1
+	.uleb128 0			/* Augmentation length */
+	/* What follows are the instructions for the table generation.
+	   We record the locations of each register saved.  This is
+	   complicated by the fact that the "CFA" is always assumed to
+	   be the value of the stack pointer in the caller.  This means
+	   that we must define the CFA of this body of code to be the
+	   saved value of the stack pointer in the sigcontext.  Which
+	   also means that there is no fixed relation to the other 
+	   saved registers, which means that we must use DW_CFA_expression
+	   to compute their addresses.  It also means that when we 
+	   adjust the stack with the popl, we have to do it all over again.  */
+
+#define do_cfa_expr(offset)						\
+	.byte 0x0f;			/* DW_CFA_def_cfa_expression */	\
+	.uleb128 1f-0f;			/*   length */			\
+0:	.byte 0x74;			/*     DW_OP_breg4 */		\
+	.sleb128 offset;		/*      offset */		\
+	.byte 0x06;			/*     DW_OP_deref */		\
+1:
+
+#define do_expr(regno, offset)						\
+	.byte 0x10;			/* DW_CFA_expression */		\
+	.uleb128 regno;			/*   regno */			\
+	.uleb128 1f-0f;			/*   length */			\
+0:	.byte 0x74;			/*     DW_OP_breg4 */		\
+	.sleb128 offset;		/*       offset */		\
+1:
+
+	do_cfa_expr(IA32_SIGCONTEXT_esp+4)
+	do_expr(0, IA32_SIGCONTEXT_eax+4)
+	do_expr(1, IA32_SIGCONTEXT_ecx+4)
+	do_expr(2, IA32_SIGCONTEXT_edx+4)
+	do_expr(3, IA32_SIGCONTEXT_ebx+4)
+	do_expr(5, IA32_SIGCONTEXT_ebp+4)
+	do_expr(6, IA32_SIGCONTEXT_esi+4)
+	do_expr(7, IA32_SIGCONTEXT_edi+4)
+	do_expr(8, IA32_SIGCONTEXT_eip+4)
+
+	.byte 0x42	/* DW_CFA_advance_loc 2 -- nop; popl eax. */
+
+	do_cfa_expr(IA32_SIGCONTEXT_esp)
+	do_expr(0, IA32_SIGCONTEXT_eax)
+	do_expr(1, IA32_SIGCONTEXT_ecx)
+	do_expr(2, IA32_SIGCONTEXT_edx)
+	do_expr(3, IA32_SIGCONTEXT_ebx)
+	do_expr(5, IA32_SIGCONTEXT_ebp)
+	do_expr(6, IA32_SIGCONTEXT_esi)
+	do_expr(7, IA32_SIGCONTEXT_edi)
+	do_expr(8, IA32_SIGCONTEXT_eip)
+
+	.align 4
+.LENDFDE2:
+
+	.long .LENDFDE3-.LSTARTFDE3	/* Length FDE */
+.LSTARTFDE3:
+	.long .LSTARTFDE3-.LSTARTFRAME	/* CIE pointer */
+	/* HACK: See above wrt unwind library assumptions.  */
+	.long .LSTART_rt_sigreturn-1-.	/* PC-relative start address */
+	.long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
+	.uleb128 0			/* Augmentation */
+	/* What follows are the instructions for the table generation.
+	   We record the locations of each register saved.  This is
+	   slightly less complicated than the above, since we don't
+	   modify the stack pointer in the process.  */
+
+	do_cfa_expr(IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esp)
+	do_expr(0, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eax)
+	do_expr(1, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ecx)
+	do_expr(2, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edx)
+	do_expr(3, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebx)
+	do_expr(5, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_ebp)
+	do_expr(6, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_esi)
+	do_expr(7, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_edi)
+	do_expr(8, IA32_RT_SIGFRAME_sigcontext-4 + IA32_SIGCONTEXT_eip)
+
+	.align 4
+.LENDFDE3:
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/warmreboot.S linux-2.5.69-bk17/arch/x86_64/kernel/warmreboot.S
--- linux-2.5.69-bk16/arch/x86_64/kernel/warmreboot.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk17/arch/x86_64/kernel/warmreboot.S	2003-05-24 04:33:33.000000000 -0700
@@ -0,0 +1,83 @@
+/*
+ * Switch back to real mode and call the BIOS reboot vector.
+ * This is a trampoline copied around in process.c 
+ * Written 2003 by Andi Kleen, SuSE Labs.	 	
+ */			
+	
+#include <asm/msr.h>
+
+#define R(x) x-warm_reboot(%ebx)
+#define R64(x) x-warm_reboot(%rbx)
+		
+	/* running in identity mapping and in the first 64k of memory
+	   and in compatibility mode. This must be position independent */
+
+	/* Follows 14.7 "Leaving Long Mode" in the AMD x86-64 manual, volume 2
+	   and 8.9.2 "Switching Back to Real-Address Mode" in the Intel IA32
+	   manual, volume 2 */
+
+	/* ebx:	self pointer to warm_reboot */
+
+	.globl warm_reboot
+warm_reboot:
+	addl  %ebx,  R64(real_mode_desc)	/* relocate tables */
+	addl  %ebx,2+R64(warm_gdt_desc)		
+
+	movq  %cr0,%rax
+	btr  $31,%rax		
+	movq %rax,%cr0		/* disable paging */
+	jmp  1f			/* flush prefetch queue */
+	
+	.code32	
+1:	movl $MSR_EFER,%ecx
+	rdmsr
+	andl $~((1<<_EFER_LME)|(1<<_EFER_SCE)|(1<<_EFER_NX)),%eax
+	wrmsr			/* disable long mode in EFER */
+		
+	xorl %eax,%eax
+	movl %eax,%cr3		/* flush tlb */
+
+	/* Running protected mode without paging now */
+	
+	wbinvd			/* flush caches. Needed? */
+
+	lidt R(warm_idt_desc)
+	lgdt R(warm_gdt_desc)
+	
+	movl $0x10,%ecx		/* load segment registers with real mode settings */
+	movl %ecx,%ds
+	movl %ecx,%es
+	movl %ecx,%fs
+	movl %ecx,%gs
+	movl %ecx,%ss
+	
+	lea  R(real_mode_desc),%eax		
+	ljmp *(%eax)
+
+	.code16:
+real_mode:
+	xorl %eax,%eax
+	movl %eax,%cr0
+	
+	/* some people claim $0xf000,0xfff0 is better. Use what 32bit linux uses. */
+	/* code as bytes because gas has problems with it */
+	.byte 	0xea,0xf0,0xff,0x00,0xf0	/* ljmp  0xf000:0xfff0 */
+
+real_mode_desc:
+	.long  real_mode - warm_reboot
+	.short 8	
+warm_gdt_desc:
+	.short 8*3
+	.long warm_gdt - warm_reboot
+warm_gdt:	
+	.quad   0
+	.quad 	0x00009a000000ffff	/* 16-bit real-mode 64k code at 0x00000000 */
+	.quad   0x000092000100ffff	/* 16-bit real-mode 64k data at 0x00000100 */
+	
+warm_idt_desc:
+	.short 0x3ff
+	.long  0
+				
+	.globl warm_reboot_end
+warm_reboot_end:
+
diff -urN linux-2.5.69-bk16/arch/x86_64/kernel/x8664_ksyms.c linux-2.5.69-bk17/arch/x86_64/kernel/x8664_ksyms.c
--- linux-2.5.69-bk16/arch/x86_64/kernel/x8664_ksyms.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/kernel/x8664_ksyms.c	2003-05-24 04:33:33.000000000 -0700
@@ -207,3 +207,12 @@
 
 extern unsigned long __supported_pte_mask;
 EXPORT_SYMBOL(__supported_pte_mask);
+
+#ifdef CONFIG_DISCONTIGMEM
+EXPORT_SYMBOL(memnode_shift);
+EXPORT_SYMBOL(memnodemap);
+EXPORT_SYMBOL(node_data);
+EXPORT_SYMBOL(fake_node);
+#endif
+
+EXPORT_SYMBOL(clear_page);
diff -urN linux-2.5.69-bk16/arch/x86_64/lib/copy_user.S linux-2.5.69-bk17/arch/x86_64/lib/copy_user.S
--- linux-2.5.69-bk16/arch/x86_64/lib/copy_user.S	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/lib/copy_user.S	2003-05-24 04:33:33.000000000 -0700
@@ -6,16 +6,13 @@
 
 #define FIX_ALIGNMENT 1
 		
-#define movnti movq  /* write to cache for now */
-#define prefetch prefetcht2
-		
 	#include <asm/current.h>
 	#include <asm/offset.h>
 	#include <asm/thread_info.h>
 
 /* Standard copy_to_user with segment limit checking */		
 	.globl copy_to_user
-	.p2align 	
+	.p2align 4	
 copy_to_user:
 	GET_THREAD_INFO(%rax)
 	movq %rdi,%rcx
@@ -27,7 +24,7 @@
 
 /* Standard copy_from_user with segment limit checking */	
 	.globl copy_from_user
-	.p2align 	
+	.p2align 4	
 copy_from_user:
 	GET_THREAD_INFO(%rax)
 	movq %rsi,%rcx
@@ -58,23 +55,23 @@
  * rdx count
  *
  * Output:		
- * eax uncopied bytes or 0 if successful. 
+ * eax uncopied bytes or 0 if successfull. 
  */
 	.globl copy_user_generic	
+	.p2align 4
 copy_user_generic:	
 	/* Put the first cacheline into cache. This should handle
 	   the small movements in ioctls etc., but not penalize the bigger
 	   filesystem data copies too much. */
 	pushq %rbx
-	prefetch (%rsi)
 	xorl %eax,%eax		/*zero for the exception handler */
 
 #ifdef FIX_ALIGNMENT
 	/* check for bad alignment of destination */
 	movl %edi,%ecx
 	andl $7,%ecx
-	jnz  bad_alignment
-after_bad_alignment:
+	jnz  .Lbad_alignment
+.Lafter_bad_alignment:
 #endif
 
 	movq %rdx,%rcx
@@ -82,133 +79,133 @@
 	movl $64,%ebx	
 	shrq $6,%rdx
 	decq %rdx
-	js   handle_tail
-	jz   loop_no_prefetch
-	
-loop:
-	prefetch 64(%rsi)
+	js   .Lhandle_tail
 	
-loop_no_prefetch:	
-s1:	movq (%rsi),%r11
-s2:	movq 1*8(%rsi),%r8
-s3:	movq 2*8(%rsi),%r9
-s4:	movq 3*8(%rsi),%r10
-d1:	movnti %r11,(%rdi)
-d2:	movnti %r8,1*8(%rdi)
-d3:	movnti %r9,2*8(%rdi)
-d4:	movnti %r10,3*8(%rdi)
+	.p2align 4
+.Lloop:
+.Ls1:	movq (%rsi),%r11
+.Ls2:	movq 1*8(%rsi),%r8
+.Ls3:	movq 2*8(%rsi),%r9
+.Ls4:	movq 3*8(%rsi),%r10
+.Ld1:	movq %r11,(%rdi)
+.Ld2:	movq %r8,1*8(%rdi)
+.Ld3:	movq %r9,2*8(%rdi)
+.Ld4:	movq %r10,3*8(%rdi)
 		
-s5:	movq 4*8(%rsi),%r11
-s6:	movq 5*8(%rsi),%r8
-s7:	movq 6*8(%rsi),%r9
-s8:	movq 7*8(%rsi),%r10
-d5:	movnti %r11,4*8(%rdi)
-d6:	movnti %r8,5*8(%rdi)
-d7:	movnti %r9,6*8(%rdi)
-d8:	movnti %r10,7*8(%rdi)
-
-	addq %rbx,%rsi	
-	addq %rbx,%rdi
+.Ls5:	movq 4*8(%rsi),%r11
+.Ls6:	movq 5*8(%rsi),%r8
+.Ls7:	movq 6*8(%rsi),%r9
+.Ls8:	movq 7*8(%rsi),%r10
+.Ld5:	movq %r11,4*8(%rdi)
+.Ld6:	movq %r8,5*8(%rdi)
+.Ld7:	movq %r9,6*8(%rdi)
+.Ld8:	movq %r10,7*8(%rdi)
 	
 	decq %rdx
-	jz   loop_no_prefetch
-	jns  loop
 
-handle_tail:
+	leaq 64(%rsi),%rsi
+	leaq 64(%rdi),%rdi
+	
+	jns  .Lloop
+
+	.p2align 4
+.Lhandle_tail:
 	movl %ecx,%edx
 	andl $63,%ecx
 	shrl $3,%ecx
-	jz   handle_7
+	jz   .Lhandle_7
 	movl $8,%ebx
-loop_8:
-s9:	movq (%rsi),%r8
-d9:	movq %r8,(%rdi)
-	addq %rbx,%rdi
-	addq %rbx,%rsi
+	.p2align 4
+.Lloop_8:
+.Ls9:	movq (%rsi),%r8
+.Ld9:	movq %r8,(%rdi)
 	decl %ecx
-	jnz loop_8
+	leaq 8(%rdi),%rdi
+	leaq 8(%rsi),%rsi
+	jnz .Lloop_8
 	
-handle_7:		
+.Lhandle_7:		
 	movl %edx,%ecx	
 	andl $7,%ecx
-	jz   ende
-loop_1:
-s10:	movb (%rsi),%bl
-d10:	movb %bl,(%rdi)
+	jz   .Lende
+	.p2align 4
+.Lloop_1:
+.Ls10:	movb (%rsi),%bl
+.Ld10:	movb %bl,(%rdi)
 	incq %rdi
 	incq %rsi
 	decl %ecx
-	jnz loop_1
+	jnz .Lloop_1
 			
-ende:
-	sfence
+.Lende:
 	popq %rbx
 	ret	
 
 #ifdef FIX_ALIGNMENT		  		
 	/* align destination */
-bad_alignment:
+	.p2align 4
+.Lbad_alignment:
 	movl $8,%r9d
 	subl %ecx,%r9d
 	movl %r9d,%ecx
 	subq %r9,%rdx
-	jz   small_align
-	js   small_align
-align_1:		
-s11:	movb (%rsi),%bl
-d11:	movb %bl,(%rdi)
+	jz   .Lsmall_align
+	js   .Lsmall_align
+.Lalign_1:		
+.Ls11:	movb (%rsi),%bl
+.Ld11:	movb %bl,(%rdi)
 	incq %rsi
 	incq %rdi
 	decl %ecx
-	jnz align_1
-	jmp after_bad_alignment
-small_align:
+	jnz .Lalign_1
+	jmp .Lafter_bad_alignment
+.Lsmall_align:
 	addq %r9,%rdx
-	jmp handle_7
+	jmp .Lhandle_7
 #endif
 	
 	/* table sorted by exception address */	
 	.section __ex_table,"a"
 	.align 8
-	.quad s1,s1e
-	.quad s2,s2e
-	.quad s3,s3e
-	.quad s4,s4e	
-	.quad d1,s1e
-	.quad d2,s2e
-	.quad d3,s3e
-	.quad d4,s4e
-	.quad s5,s5e
-	.quad s6,s6e
-	.quad s7,s7e
-	.quad s8,s8e	
-	.quad d5,s5e
-	.quad d6,s6e
-	.quad d7,s7e
-	.quad d8,s8e
-	.quad s9,e_quad
-	.quad d9,e_quad
-	.quad s10,e_byte
-	.quad d10,e_byte
+	.quad .Ls1,.Ls1e
+	.quad .Ls2,.Ls2e
+	.quad .Ls3,.Ls3e
+	.quad .Ls4,.Ls4e	
+	.quad .Ld1,.Ls1e
+	.quad .Ld2,.Ls2e
+	.quad .Ld3,.Ls3e
+	.quad .Ld4,.Ls4e
+	.quad .Ls5,.Ls5e
+	.quad .Ls6,.Ls6e
+	.quad .Ls7,.Ls7e
+	.quad .Ls8,.Ls8e	
+	.quad .Ld5,.Ls5e
+	.quad .Ld6,.Ls6e
+	.quad .Ld7,.Ls7e
+	.quad .Ld8,.Ls8e
+	.quad .Ls9,.Le_quad
+	.quad .Ld9,.Le_quad
+	.quad .Ls10,.Le_byte
+	.quad .Ld10,.Le_byte
 #ifdef FIX_ALIGNMENT	
-	.quad s11,e_byte
-	.quad d11,e_byte
+	.quad .Ls11,.Le_byte
+	.quad .Ld11,.Le_byte
 #endif
-	.quad e5,e_zero
+	.quad .Le5,.Le_zero
 	.previous
 
 	/* compute 64-offset for main loop. 8 bytes accuracy with error on the 
 	   pessimistic side. this is gross. it would be better to fix the 
 	   interface. */	
 	/* eax: zero, ebx: 64 */
-s1e: 	addl $8,%eax
-s2e: 	addl $8,%eax
-s3e: 	addl $8,%eax
-s4e: 	addl $8,%eax
-s5e: 	addl $8,%eax
-s6e: 	addl $8,%eax
-s7e: 	addl $8,%eax
-s8e: 	addl $8,%eax
+.Ls1e: 	addl $8,%eax
+.Ls2e: 	addl $8,%eax
+.Ls3e: 	addl $8,%eax
+.Ls4e: 	addl $8,%eax
+.Ls5e: 	addl $8,%eax
+.Ls6e: 	addl $8,%eax
+.Ls7e: 	addl $8,%eax
+.Ls8e: 	addl $8,%eax
 	addq %rbx,%rdi	/* +64 */
 	subq %rax,%rdi  /* correct destination with computed offset */
 
@@ -216,22 +213,22 @@
 	addq %rax,%rdx	/* add offset to loopcnt */
 	andl $63,%ecx	/* remaining bytes */
 	addq %rcx,%rdx	/* add them */
-	jmp zero_rest
+	jmp .Lzero_rest
 
 	/* exception on quad word loop in tail handling */
 	/* ecx:	loopcnt/8, %edx: length, rdi: correct */
-e_quad:
+.Le_quad:
 	shll $3,%ecx
 	andl $7,%edx
 	addl %ecx,%edx
 	/* edx: bytes to zero, rdi: dest, eax:zero */
-zero_rest:
+.Lzero_rest:
 	movq %rdx,%rcx
-e_byte:
+.Le_byte:
 	xorl %eax,%eax
-e5:	rep 
+.Le5:	rep 
 	stosb
 	/* when there is another exception while zeroing the rest just return */
-e_zero:		
+.Le_zero:		
 	movq %rdx,%rax
-	jmp ende
+	jmp .Lende
diff -urN linux-2.5.69-bk16/arch/x86_64/mm/fault.c linux-2.5.69-bk17/arch/x86_64/mm/fault.c
--- linux-2.5.69-bk16/arch/x86_64/mm/fault.c	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/mm/fault.c	2003-05-24 04:33:33.000000000 -0700
@@ -226,17 +226,18 @@
 
 bad_area_nosemaphore:
 
-	/* User mode accesses just cause a SIGSEGV */
-	if (error_code & 4) {
 #ifdef CONFIG_IA32_EMULATION
 		/* 32bit vsyscall. map on demand. */
 		if (test_thread_flag(TIF_IA32) && 
-		    address >= 0xffffe000 && address < 0xffffefff-7) { 
+	    address >= 0xffffe000 && address < 0xffffe000 + PAGE_SIZE) { 
 			if (map_syscall32(mm, address) < 0) 
 				goto out_of_memory2;
 			return;
 		} 			
 #endif
+
+	/* User mode accesses just cause a SIGSEGV */
+	if (error_code & 4) {
 		printk(KERN_INFO 
 		       "%s[%d] segfault at rip:%lx rsp:%lx adr:%lx err:%lx\n",
 		       tsk->comm, tsk->pid, regs->rip, regs->rsp, address, 
diff -urN linux-2.5.69-bk16/arch/x86_64/mm/init.c linux-2.5.69-bk17/arch/x86_64/mm/init.c
--- linux-2.5.69-bk16/arch/x86_64/mm/init.c	2003-05-04 16:53:07.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/mm/init.c	2003-05-24 04:33:33.000000000 -0700
@@ -39,7 +39,7 @@
 #include <asm/proto.h>
 #include <asm/smp.h>
 
-#define Dprintk(x...) printk(x)
+#define Dprintk(x...)
 
 struct mmu_gather mmu_gathers[NR_CPUS];
 
@@ -105,7 +105,7 @@
 	pml4_t *level4;
 	pgd_t *pgd;
 	pmd_t *pmd;
-	pte_t *pte;
+	pte_t *pte, new_pte;
 
 	Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
 
@@ -132,11 +132,13 @@
 			return;
 		}
 	}
+	new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
+
 	pte = pte_offset_kernel(pmd, vaddr);
-	/* CHECKME: */
-	if (pte_val(*pte))
+	if (!pte_none(*pte) &&
+	    pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
 		pte_ERROR(*pte);
-	set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
+	set_pte(pte, new_pte);
 
 	/*
 	 * It's enough to flush this one mapping.
@@ -340,6 +342,35 @@
 }
 #endif
 
+/* Unmap a kernel mapping if it exists. This is useful to avoid prefetches
+   from the CPU leading to inconsistent cache lines. address and size
+   must be aligned to 2MB boundaries. 
+   Does nothing when the mapping doesn't exist. */
+void __init clear_kernel_mapping(unsigned long address, unsigned long size) 
+{
+	unsigned long end = address + size;
+
+	BUG_ON(address & ~LARGE_PAGE_MASK);
+	BUG_ON(size & ~LARGE_PAGE_MASK); 
+	
+	for (; address < end; address += LARGE_PAGE_SIZE) { 
+		pgd_t *pgd = pgd_offset_k(address);
+		if (!pgd || pgd_none(*pgd))
+			continue; 
+		pmd_t *pmd = pmd_offset(pgd, address);
+		if (!pmd || pmd_none(*pmd))
+			continue; 
+		if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { 
+			/* Could handle this, but it should not happen currently. */
+			printk(KERN_ERR 
+	       "clear_kernel_mapping: mapping has been split. will leak memory\n"); 
+			pmd_ERROR(*pmd); 
+		}
+		set_pmd(pmd, __pmd(0)); 		
+	}
+	__flush_tlb_all();
+} 
+
 static inline int page_is_ram (unsigned long pagenr)
 {
 	int i;
diff -urN linux-2.5.69-bk16/arch/x86_64/mm/k8topology.c linux-2.5.69-bk17/arch/x86_64/mm/k8topology.c
--- linux-2.5.69-bk16/arch/x86_64/mm/k8topology.c	2003-05-04 16:53:55.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/mm/k8topology.c	2003-05-24 04:33:33.000000000 -0700
@@ -87,10 +87,8 @@
 
 		if (limit > end_pfn_map << PAGE_SHIFT) 
 			limit = end_pfn_map << PAGE_SHIFT; 
-		if (limit <= base) { 
-			printk(KERN_INFO "Node %d beyond memory map\n", nodeid);
+		if (limit <= base)
 			continue; 
-		} 
 			
 		base >>= 16;
 		base <<= 24; 
diff -urN linux-2.5.69-bk16/arch/x86_64/mm/numa.c linux-2.5.69-bk17/arch/x86_64/mm/numa.c
--- linux-2.5.69-bk16/arch/x86_64/mm/numa.c	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/mm/numa.c	2003-05-24 04:33:33.000000000 -0700
@@ -15,7 +15,7 @@
 #include <asm/dma.h>
 #include <asm/numa.h>
 
-#define Dprintk(x...) printk(x)
+#define Dprintk(x...)
 
 struct pglist_data *node_data[MAXNODE];
 bootmem_data_t plat_node_bdata[MAX_NUMNODES];
@@ -104,8 +104,11 @@
 
 	reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 
 	reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT);
-	if (nodeid + 1 > numnodes) 
+	if (nodeid + 1 > numnodes) { 
 		numnodes = nodeid + 1;
+		printk(KERN_INFO 
+		       "setup_node_bootmem: enlarging numnodes to %d\n", numnodes);
+	}
 	nodes_present |= (1UL << nodeid); 
 } 
 
@@ -121,7 +124,7 @@
 	start_pfn = node_start_pfn(nodeid);
 	end_pfn = node_end_pfn(nodeid);
 
-	printk("setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn); 
+	printk(KERN_INFO "setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn); 
 	
 	/* All nodes > 0 have a zero length zone DMA */ 
 	dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; 
diff -urN linux-2.5.69-bk16/arch/x86_64/mm/pageattr.c linux-2.5.69-bk17/arch/x86_64/mm/pageattr.c
--- linux-2.5.69-bk16/arch/x86_64/mm/pageattr.c	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/mm/pageattr.c	2003-05-24 04:33:33.000000000 -0700
@@ -63,29 +63,53 @@
 	__flush_tlb_one(address);
 }
 
+
+static inline void flush_map(unsigned long address)
+{	
+	on_each_cpu(flush_kernel_map, (void *)address, 1, 1);
+}
+
+struct deferred_page { 
+	struct deferred_page *next; 
+	struct page *fpage;
+	unsigned long address;
+}; 
+static struct deferred_page *df_list; /* protected by init_mm.mmap_sem */
+
+static inline void save_page(unsigned long address, struct page *fpage)
+{
+	struct deferred_page *df;
+	df = kmalloc(sizeof(struct deferred_page), GFP_KERNEL); 
+	if (!df) {
+		flush_map(address);
+		__free_page(fpage);
+	} else { 
+		df->next = df_list;
+		df->fpage = fpage;
+		df->address = address;
+		df_list = df;
+	} 			
+}
+
 /* 
  * No more special protections in this 2/4MB area - revert to a
  * large page again. 
  */
-static inline void revert_page(struct page *kpte_page, unsigned long address)
+static void revert_page(struct page *kpte_page, unsigned long address)
 {
        pgd_t *pgd;
        pmd_t *pmd; 
        pte_t large_pte; 
        
        pgd = pgd_offset_k(address); 
-       if (!pgd) BUG(); 
        pmd = pmd_offset(pgd, address);
-       if (!pmd) BUG(); 
-       if ((pmd_val(*pmd) & _PAGE_GLOBAL) == 0) BUG(); 
-       
+       BUG_ON(pmd_val(*pmd) & _PAGE_PSE); 
        large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, PAGE_KERNEL_LARGE);
        set_pte((pte_t *)pmd, large_pte);
 }      
 
 static int
-__change_page_attr(unsigned long address, struct page *page, pgprot_t prot, 
-		   struct page **oldpage) 
+__change_page_attr(unsigned long address, struct page *page, pgprot_t prot)
 { 
 	pte_t *kpte; 
 	struct page *kpte_page;
@@ -107,6 +131,7 @@
 			struct page *split = split_large_page(address, prot); 
 			if (!split)
 				return -ENOMEM;
+			atomic_inc(&kpte_page->count);
 			set_pte(kpte,mk_pte(split, PAGE_KERNEL));
 		}	
 	} else if ((kpte_flags & _PAGE_PSE) == 0) { 
@@ -115,39 +140,12 @@
 	}
 
 	if (atomic_read(&kpte_page->count) == 1) { 
-		*oldpage = kpte_page;
+		save_page(address, kpte_page); 		     
 		revert_page(kpte_page, address);
 	} 
 	return 0;
 } 
 
-static inline void flush_map(unsigned long address)
-{	
-	on_each_cpu(flush_kernel_map, (void *)address, 1, 1);
-}
-
-struct deferred_page { 
-	struct deferred_page *next; 
-	struct page *fpage;
-	unsigned long address;
-}; 
-static struct deferred_page *df_list; /* protected by init_mm.mmap_sem */
-
-static inline void save_page(unsigned long address, struct page *fpage)
-{
-	struct deferred_page *df;
-	df = kmalloc(sizeof(struct deferred_page), GFP_KERNEL); 
-	if (!df) {
-		flush_map(address);
-		__free_page(fpage);
-	} else { 
-		df->next = df_list;
-		df->fpage = fpage;
-		df->address = address;
-		df_list = df;
-	} 			
-}
-
 /*
  * Change the page attributes of an page in the linear mapping.
  *
@@ -164,24 +162,19 @@
 int change_page_attr(struct page *page, int numpages, pgprot_t prot)
 {
 	int err = 0; 
-	struct page *fpage, *fpage2; 
 	int i; 
 
 	down_write(&init_mm.mmap_sem);
-	for (i = 0; i < numpages; i++, page++) { 
+	for (i = 0; i < numpages; !err && i++, page++) { 
 		unsigned long address = (unsigned long)page_address(page); 
-		fpage = NULL;
-		err = __change_page_attr(address, page, prot, &fpage); 
+		err = __change_page_attr(address, page, prot); 
+		if (err) 
+			break; 
 		/* Handle kernel mapping too which aliases part of the lowmem */
-		if (!err && page_to_phys(page) < KERNEL_TEXT_SIZE) {		
+		if (page_to_phys(page) < KERNEL_TEXT_SIZE) {		
 			unsigned long addr2 = __START_KERNEL_map + page_to_phys(page);
-			fpage2 = NULL;
-			err = __change_page_attr(addr2, page, prot, &fpage2); 
-			if (fpage2) 
-				save_page(addr2, fpage2); 		     
+			err = __change_page_attr(addr2, page, prot);
 		} 
-		if (fpage)
-			save_page(address, fpage);
 	} 	
 	up_write(&init_mm.mmap_sem); 
 	return err;
diff -urN linux-2.5.69-bk16/arch/x86_64/pci/irq.c linux-2.5.69-bk17/arch/x86_64/pci/irq.c
--- linux-2.5.69-bk16/arch/x86_64/pci/irq.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/pci/irq.c	2003-05-24 04:33:33.000000000 -0700
@@ -378,8 +378,9 @@
 	return NULL;
 }
 
-static void pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
+	return IRQ_NONE; 
 }
 
 static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
diff -urN linux-2.5.69-bk16/arch/x86_64/vmlinux.lds.S linux-2.5.69-bk17/arch/x86_64/vmlinux.lds.S
--- linux-2.5.69-bk16/arch/x86_64/vmlinux.lds.S	2003-05-04 16:53:00.000000000 -0700
+++ linux-2.5.69-bk17/arch/x86_64/vmlinux.lds.S	2003-05-24 04:33:33.000000000 -0700
@@ -127,7 +127,7 @@
   /* Sections to be discarded */
   /DISCARD/ : {
 	*(.exit.data)
-	*(.exit.text)
+	/* *(.exit.text) */
 	*(.exitcall.exit)
 	*(.eh_frame)
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/dispatcher/dsinit.c linux-2.5.69-bk17/drivers/acpi/dispatcher/dsinit.c
--- linux-2.5.69-bk16/drivers/acpi/dispatcher/dsinit.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/dispatcher/dsinit.c	2003-05-24 04:33:33.000000000 -0700
@@ -222,8 +222,8 @@
 	}
 
 	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
-		"\nTable [%4.4s] - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
-		table_desc->pointer->signature, info.object_count,
+		"\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
+		table_desc->pointer->signature, table_desc->table_id, info.object_count,
 		info.device_count, info.method_count, info.op_region_count));
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
diff -urN linux-2.5.69-bk16/drivers/acpi/dispatcher/dsmethod.c linux-2.5.69-bk17/drivers/acpi/dispatcher/dsmethod.c
--- linux-2.5.69-bk16/drivers/acpi/dispatcher/dsmethod.c	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/dispatcher/dsmethod.c	2003-05-24 04:33:33.000000000 -0700
@@ -290,6 +290,8 @@
 		return_ACPI_STATUS (AE_NULL_OBJECT);
 	}
 
+	obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
+
 	/* Init for new method, wait on concurrency semaphore */
 
 	status = acpi_ds_begin_method_execution (method_node, obj_desc,
diff -urN linux-2.5.69-bk16/drivers/acpi/dispatcher/dsobject.c linux-2.5.69-bk17/drivers/acpi/dispatcher/dsobject.c
--- linux-2.5.69-bk16/drivers/acpi/dispatcher/dsobject.c	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/dispatcher/dsobject.c	2003-05-24 04:33:33.000000000 -0700
@@ -204,7 +204,8 @@
 
 	if (obj_desc->buffer.length == 0) {
 		obj_desc->buffer.pointer = NULL;
-		ACPI_REPORT_WARNING (("Buffer created with zero length in AML\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"Buffer defined with zero length in AML, creating\n"));
 	}
 	else {
 		obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE (
diff -urN linux-2.5.69-bk16/drivers/acpi/dispatcher/dsopcode.c linux-2.5.69-bk17/drivers/acpi/dispatcher/dsopcode.c
--- linux-2.5.69-bk16/drivers/acpi/dispatcher/dsopcode.c	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/dispatcher/dsopcode.c	2003-05-24 04:33:33.000000000 -0700
@@ -82,7 +82,7 @@
 	union acpi_parse_object         *arg;
 
 
-	ACPI_FUNCTION_TRACE ("acpi_ds_execute_arguments");
+	ACPI_FUNCTION_TRACE ("ds_execute_arguments");
 
 
 	/*
@@ -99,7 +99,7 @@
 
 	/* Create and initialize a new parser state */
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
 	if (!walk_state) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
@@ -139,7 +139,7 @@
 
 	/* Create and initialize a new parser state */
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
 	if (!walk_state) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/dispatcher/dswexec.c linux-2.5.69-bk17/drivers/acpi/dispatcher/dswexec.c
--- linux-2.5.69-bk16/drivers/acpi/dispatcher/dswexec.c	2003-05-04 16:53:55.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/dispatcher/dswexec.c	2003-05-24 04:33:33.000000000 -0700
@@ -50,6 +50,7 @@
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acdebug.h>
+#include <acpi/acdisasm.h>
 
 
 #define _COMPONENT          ACPI_DISPATCHER
@@ -657,6 +658,16 @@
 	/* Always clear the object stack */
 
 	walk_state->num_operands = 0;
+
+#ifdef ACPI_DISASSEMBLER
+
+	/* On error, display method locals/args */
+
+	if (ACPI_FAILURE (status)) {
+		acpi_dm_dump_method_info (status, walk_state, op);
+	}
+#endif
+
 	return_ACPI_STATUS (status);
 }
 
diff -urN linux-2.5.69-bk16/drivers/acpi/ec.c linux-2.5.69-bk17/drivers/acpi/ec.c
--- linux-2.5.69-bk16/drivers/acpi/ec.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/ec.c	2003-05-24 04:33:33.000000000 -0700
@@ -113,7 +113,7 @@
 	switch (event) {
 	case ACPI_EC_EVENT_OBF:
 		do {
-			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr, 0);
+			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
 			if (acpi_ec_status & ACPI_EC_FLAG_OBF)
 				return 0;
 			udelay(ACPI_EC_UDELAY);
@@ -121,7 +121,7 @@
 		break;
 	case ACPI_EC_EVENT_IBE:
 		do {
-			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr, 0);
+			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
 			if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
 				return 0;
 			udelay(ACPI_EC_UDELAY);
@@ -161,18 +161,18 @@
 	
 	spin_lock_irqsave(&ec->lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr, 0);
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, address, &ec->data_addr, 0);
+	acpi_hw_low_level_write(8, address, &ec->data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (result)
 		goto end;
 
 
-	acpi_hw_low_level_read(8, data, &ec->data_addr, 0);
+	acpi_hw_low_level_read(8, data, &ec->data_addr);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
 		*data, address));
@@ -211,17 +211,17 @@
 
 	spin_lock_irqsave(&ec->lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr, 0);
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, address, &ec->data_addr, 0);
+	acpi_hw_low_level_write(8, address, &ec->data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, data, &ec->data_addr, 0);
+	acpi_hw_low_level_write(8, data, &ec->data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
@@ -310,12 +310,12 @@
 	 */
 	spin_lock_irqsave(&ec->lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr, 0);
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (result)
 		goto end;
 	
-	acpi_hw_low_level_read(8, data, &ec->data_addr, 0);
+	acpi_hw_low_level_read(8, data, &ec->data_addr);
 	if (!*data)
 		result = -ENODATA;
 
@@ -355,7 +355,7 @@
 		goto end;	
 
 	spin_lock_irqsave(&ec->lock, flags);
-	acpi_hw_low_level_read(8, &value, &ec->command_addr, 0);
+	acpi_hw_low_level_read(8, &value, &ec->command_addr);
 	spin_unlock_irqrestore(&ec->lock, flags);
 
 	/* TBD: Implement asynch events!
diff -urN linux-2.5.69-bk16/drivers/acpi/events/evgpe.c linux-2.5.69-bk17/drivers/acpi/events/evgpe.c
--- linux-2.5.69-bk16/drivers/acpi/events/evgpe.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/events/evgpe.c	2003-05-24 04:33:33.000000000 -0700
@@ -170,7 +170,7 @@
 			/* Read the Status Register */
 
 			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
-					 &gpe_register_info->status_address, 0);
+					 &gpe_register_info->status_address);
 			gpe_register_info->status = (u8) in_value;
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
@@ -179,7 +179,7 @@
 			/* Read the Enable Register */
 
 			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
-					 &gpe_register_info->enable_address, 0);
+					 &gpe_register_info->enable_address);
 			gpe_register_info->enable = (u8) in_value;
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
diff -urN linux-2.5.69-bk16/drivers/acpi/events/evgpeblk.c linux-2.5.69-bk17/drivers/acpi/events/evgpeblk.c
--- linux-2.5.69-bk16/drivers/acpi/events/evgpeblk.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/events/evgpeblk.c	2003-05-24 04:33:33.000000000 -0700
@@ -634,13 +634,13 @@
 		 * by writing a '0'.
 		 */
 		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00,
-				 &this_register->enable_address, 0);
+				 &this_register->enable_address);
 		if (ACPI_FAILURE (status)) {
 			goto error_exit;
 		}
 
 		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF,
-				 &this_register->status_address, 0);
+				 &this_register->status_address);
 		if (ACPI_FAILURE (status)) {
 			goto error_exit;
 		}
@@ -732,18 +732,16 @@
 
 	/* Dump info about this GPE block */
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block: [%4.4s] %X registers at %8.8X%8.8X on interrupt %d\n",
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
+		gpe_block->block_base_number,
+		(u32) (gpe_block->block_base_number +
+				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
 		gpe_device->name.ascii,
 		gpe_block->register_count,
 		ACPI_HIDWORD (gpe_block->block_address.address),
 		ACPI_LODWORD (gpe_block->block_address.address),
 		interrupt_level));
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block defined as GPE 0x%.2X to GPE 0x%.2X\n",
-		gpe_block->block_base_number,
-		(u32) (gpe_block->block_base_number +
-				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1))));
-
 	/* Find all GPE methods (_Lxx, _Exx) for this block */
 
 	status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,
diff -urN linux-2.5.69-bk16/drivers/acpi/events/evmisc.c linux-2.5.69-bk17/drivers/acpi/events/evmisc.c
--- linux-2.5.69-bk16/drivers/acpi/events/evmisc.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/events/evmisc.c	2003-05-24 04:33:33.000000000 -0700
@@ -156,10 +156,10 @@
 		case ACPI_TYPE_POWER:
 
 			if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
-				handler_obj = obj_desc->common_notify.sys_handler;
+				handler_obj = obj_desc->common_notify.system_notify;
 			}
 			else {
-				handler_obj = obj_desc->common_notify.drv_handler;
+				handler_obj = obj_desc->common_notify.device_notify;
 			}
 			break;
 
@@ -171,8 +171,8 @@
 
 	/* If there is any handler to run, schedule the dispatcher */
 
-	if ((acpi_gbl_sys_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
-		(acpi_gbl_drv_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) ||
+	if ((acpi_gbl_system_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+		(acpi_gbl_device_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) ||
 		handler_obj) {
 		notify_info = acpi_ut_create_generic_state ();
 		if (!notify_info) {
@@ -235,17 +235,17 @@
 	if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
 		/* Global system notification handler */
 
-		if (acpi_gbl_sys_notify.handler) {
-			global_handler = acpi_gbl_sys_notify.handler;
-			global_context = acpi_gbl_sys_notify.context;
+		if (acpi_gbl_system_notify.handler) {
+			global_handler = acpi_gbl_system_notify.handler;
+			global_context = acpi_gbl_system_notify.context;
 		}
 	}
 	else {
 		/* Global driver notification handler */
 
-		if (acpi_gbl_drv_notify.handler) {
-			global_handler = acpi_gbl_drv_notify.handler;
-			global_context = acpi_gbl_drv_notify.context;
+		if (acpi_gbl_device_notify.handler) {
+			global_handler = acpi_gbl_device_notify.handler;
+			global_context = acpi_gbl_device_notify.context;
 		}
 	}
 
@@ -259,8 +259,8 @@
 
 	handler_obj = notify_info->notify.handler_obj;
 	if (handler_obj) {
-		handler_obj->notify_handler.handler (notify_info->notify.node, notify_info->notify.value,
-				  handler_obj->notify_handler.context);
+		handler_obj->notify.handler (notify_info->notify.node, notify_info->notify.value,
+				  handler_obj->notify.context);
 	}
 
 	/* All done with the info object */
diff -urN linux-2.5.69-bk16/drivers/acpi/events/evregion.c linux-2.5.69-bk17/drivers/acpi/events/evregion.c
--- linux-2.5.69-bk16/drivers/acpi/events/evregion.c	2003-05-04 16:53:34.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/events/evregion.c	2003-05-24 04:33:33.000000000 -0700
@@ -50,24 +50,32 @@
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evregion")
 
+#define ACPI_NUM_DEFAULT_SPACES     4
+
+u8                              acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
+			 ACPI_ADR_SPACE_SYSTEM_MEMORY,
+			 ACPI_ADR_SPACE_SYSTEM_IO,
+			 ACPI_ADR_SPACE_PCI_CONFIG,
+			 ACPI_ADR_SPACE_DATA_TABLE};
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_init_address_spaces
  *
- * PARAMETERS:
+ * PARAMETERS:  None
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Installs the core subsystem address space handlers.
+ * DESCRIPTION: Installs the core subsystem default address space handlers.
  *
  ******************************************************************************/
 
 acpi_status
 acpi_ev_init_address_spaces (
-	void)
-{
+	void) {
 	acpi_status                     status;
+	acpi_native_uint                i;
 
 
 	ACPI_FUNCTION_TRACE ("ev_init_address_spaces");
@@ -75,9 +83,11 @@
 
 	/*
 	 * All address spaces (PCI Config, EC, SMBus) are scope dependent
-	 * and registration must occur for a specific device.  In the case
-	 * system memory and IO address spaces there is currently no device
-	 * associated with the address space.  For these we use the root.
+	 * and registration must occur for a specific device.
+	 *
+	 * In the case of the system memory and IO address spaces there is currently
+	 * no device associated with the address space.  For these we use the root.
+	 *
 	 * We install the default PCI config space handler at the root so
 	 * that this space is immediately available even though the we have
 	 * not enumerated all the PCI Root Buses yet.  This is to conform
@@ -86,39 +96,27 @@
 	 * near ready to find the PCI root buses at this point.
 	 *
 	 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
-	 * has already been installed (via acpi_install_address_space_handler)
+	 * has already been installed (via acpi_install_address_space_handler).
+	 * Similar for AE_SAME_HANDLER.
 	 */
 
-	status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
-			   ACPI_ADR_SPACE_SYSTEM_MEMORY,
-			   ACPI_DEFAULT_HANDLER, NULL, NULL);
-	if ((ACPI_FAILURE (status)) &&
-		(status != AE_ALREADY_EXISTS)) {
-		return_ACPI_STATUS (status);
-	}
-
-	status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
-			   ACPI_ADR_SPACE_SYSTEM_IO,
-			   ACPI_DEFAULT_HANDLER, NULL, NULL);
-	if ((ACPI_FAILURE (status)) &&
-		(status != AE_ALREADY_EXISTS)) {
-		return_ACPI_STATUS (status);
-	}
-
-	status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
-			   ACPI_ADR_SPACE_PCI_CONFIG,
-			   ACPI_DEFAULT_HANDLER, NULL, NULL);
-	if ((ACPI_FAILURE (status)) &&
-		(status != AE_ALREADY_EXISTS)) {
-		return_ACPI_STATUS (status);
-	}
-
-	status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
-			   ACPI_ADR_SPACE_DATA_TABLE,
-			   ACPI_DEFAULT_HANDLER, NULL, NULL);
-	if ((ACPI_FAILURE (status)) &&
-		(status != AE_ALREADY_EXISTS)) {
-		return_ACPI_STATUS (status);
+	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
+		status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
+				  acpi_gbl_default_address_spaces[i],
+				  ACPI_DEFAULT_HANDLER, NULL, NULL);
+		switch (status) {
+		case AE_OK:
+		case AE_SAME_HANDLER:
+		case AE_ALREADY_EXISTS:
+
+			/* These exceptions are all OK */
+
+			break;
+
+		default:
+
+			return_ACPI_STATUS (status);
+		}
 	}
 
 	return_ACPI_STATUS (AE_OK);
@@ -161,10 +159,10 @@
 	}
 
 	/*
-	 *  _REG method has two arguments
-	 *  Arg0:   Integer: Operation region space ID
+	 * _REG method has two arguments
+	 * Arg0:   Integer: Operation region space ID
 	 *          Same value as region_obj->Region.space_id
-	 *  Arg1:   Integer: connection status
+	 * Arg1:   Integer: connection status
 	 *          1 for connecting the handler,
 	 *          0 for disconnecting the handler
 	 *          Passed as a parameter
@@ -180,16 +178,14 @@
 		goto cleanup;
 	}
 
-	/*
-	 *  Set up the parameter objects
-	 */
+	/* Set up the parameter objects */
+
 	params[0]->integer.value = region_obj->region.space_id;
 	params[1]->integer.value = function;
 	params[2] = NULL;
 
-	/*
-	 *  Execute the method, no return value
-	 */
+	/* Execute the method, no return value */
+
 	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL));
 	status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL);
 
@@ -245,10 +241,9 @@
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
 
-	/*
-	 * Ensure that there is a handler associated with this region
-	 */
-	handler_desc = region_obj->region.addr_handler;
+	/* Ensure that there is a handler associated with this region */
+
+	handler_desc = region_obj->region.address_space;
 	if (!handler_desc) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n",
 			region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
@@ -264,24 +259,23 @@
 		/*
 		 * This region has not been initialized yet, do it
 		 */
-		region_setup = handler_desc->addr_handler.setup;
+		region_setup = handler_desc->address_space.setup;
 		if (!region_setup) {
-			/*
-			 *  Bad news, no init routine and not init'd
-			 */
+			/* No initialization routine, exit with error */
+
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n",
 				region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
-			return_ACPI_STATUS (AE_UNKNOWN_STATUS);
+			return_ACPI_STATUS (AE_NOT_EXIST);
 		}
 
 		/*
 		 * We must exit the interpreter because the region setup will potentially
-		 * execute control methods
+		 * execute control methods (e.g., _REG method for this region)
 		 */
 		acpi_ex_exit_interpreter ();
 
 		status = region_setup (region_obj, ACPI_REGION_ACTIVATE,
-				  handler_desc->addr_handler.context, &region_context);
+				  handler_desc->address_space.context, &region_context);
 
 		/* Re-enter the interpreter */
 
@@ -290,9 +284,8 @@
 			return_ACPI_STATUS (status2);
 		}
 
-		/*
-		 *  Init routine may fail
-		 */
+		/* Check for failure of the Region Setup */
+
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n",
 				acpi_format_exception (status),
@@ -300,40 +293,50 @@
 			return_ACPI_STATUS (status);
 		}
 
-		region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
-
 		/*
-		 *  Save the returned context for use in all accesses to
-		 *  this particular region.
+		 * Region initialization may have been completed by region_setup
 		 */
-		region_obj2->extra.region_context = region_context;
+		if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
+			region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
+
+			if (region_obj2->extra.region_context) {
+				/* The handler for this region was already installed */
+
+				ACPI_MEM_FREE (region_context);
+			}
+			else {
+				/*
+				 * Save the returned context for use in all accesses to
+				 * this particular region
+				 */
+				region_obj2->extra.region_context = region_context;
+			}
+		}
 	}
 
-	/*
-	 *  We have everything we need, begin the process
-	 */
-	handler = handler_desc->addr_handler.handler;
+	/* We have everything we need, we can invoke the address space handler */
+
+	handler = handler_desc->address_space.handler;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
-		&region_obj->region.addr_handler->addr_handler, handler,
+		&region_obj->region.address_space->address_space, handler,
 		ACPI_HIDWORD (address), ACPI_LODWORD (address),
 		acpi_ut_get_region_name (region_obj->region.space_id)));
 
-	if (!(handler_desc->addr_handler.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 		/*
-		 *  For handlers other than the default (supplied) handlers, we must
-		 *  exit the interpreter because the handler *might* block -- we don't
-		 *  know what it will do, so we can't hold the lock on the intepreter.
+		 * For handlers other than the default (supplied) handlers, we must
+		 * exit the interpreter because the handler *might* block -- we don't
+		 * know what it will do, so we can't hold the lock on the intepreter.
 		 */
 		acpi_ex_exit_interpreter();
 	}
 
-	/*
-	 *  Invoke the handler.
-	 */
+	/* Call the handler */
+
 	status = handler (function, address, bit_width, value,
-			 handler_desc->addr_handler.context,
+			 handler_desc->address_space.context,
 			 region_obj2->extra.region_context);
 
 	if (ACPI_FAILURE (status)) {
@@ -342,7 +345,7 @@
 			acpi_format_exception (status)));
 	}
 
-	if (!(handler_desc->addr_handler.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 		/*
 		 * We just returned from a non-default handler, we must re-enter the
 		 * interpreter
@@ -393,35 +396,30 @@
 	}
 	region_context = region_obj2->extra.region_context;
 
-	/*
-	 *  Get the address handler from the region object
-	 */
-	handler_obj = region_obj->region.addr_handler;
+	/* Get the address handler from the region object */
+
+	handler_obj = region_obj->region.address_space;
 	if (!handler_obj) {
-		/*
-		 *  This region has no handler, all done
-		 */
+		/* This region has no handler, all done */
+
 		return_VOID;
 	}
 
+	/* Find this region in the handler's list */
 
-	/*
-	 *  Find this region in the handler's list
-	 */
-	obj_desc = handler_obj->addr_handler.region_list;
-	last_obj_ptr = &handler_obj->addr_handler.region_list;
+	obj_desc = handler_obj->address_space.region_list;
+	last_obj_ptr = &handler_obj->address_space.region_list;
 
 	while (obj_desc) {
-		/*
-		 *  See if this is the one
-		 */
+		/* Is this the correct Region? */
+
 		if (obj_desc == region_obj) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 				"Removing Region %p from address handler %p\n",
 				region_obj, handler_obj));
-			/*
-			 *  This is it, remove it from the handler's list
-			 */
+
+			/* This is it, remove it from the handler's list */
+
 			*last_obj_ptr = obj_desc->region.next;
 			obj_desc->region.next = NULL;           /* Must clear field */
 
@@ -432,9 +430,8 @@
 				}
 			}
 
-			/*
-			 *  Now stop region accesses by executing the _REG method
-			 */
+			/* Now stop region accesses by executing the _REG method */
+
 			status = acpi_ev_execute_reg_method (region_obj, 0);
 			if (ACPI_FAILURE (status)) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n",
@@ -449,16 +446,14 @@
 				}
 			}
 
-			/*
-			 *  Call the setup handler with the deactivate notification
-			 */
-			region_setup = handler_obj->addr_handler.setup;
+			/* Call the setup handler with the deactivate notification */
+
+			region_setup = handler_obj->address_space.setup;
 			status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
-					  handler_obj->addr_handler.context, &region_context);
+					  handler_obj->address_space.context, &region_context);
+
+			/* Init routine may fail, Just ignore errors */
 
-			/*
-			 *  Init routine may fail, Just ignore errors
-			 */
 			if (ACPI_FAILURE (status)) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n",
 					acpi_format_exception (status),
@@ -468,31 +463,29 @@
 			region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
 
 			/*
-			 *  Remove handler reference in the region
+			 * Remove handler reference in the region
 			 *
-			 *  NOTE: this doesn't mean that the region goes away
-			 *  The region is just inaccessible as indicated to
-			 *  the _REG method
+			 * NOTE: this doesn't mean that the region goes away
+			 * The region is just inaccessible as indicated to
+			 * the _REG method
 			 *
-			 *  If the region is on the handler's list
-			 *  this better be the region's handler
+			 * If the region is on the handler's list
+			 * this better be the region's handler
 			 */
-			region_obj->region.addr_handler = NULL;
+			region_obj->region.address_space = NULL;
+			acpi_ut_remove_reference (handler_obj);
 
 			return_VOID;
+		}
 
-		} /* found the right handler */
+		/* Walk the linked list of handlers */
 
-		/*
-		 *  Move through the linked list of handlers
-		 */
 		last_obj_ptr = &obj_desc->region.next;
 		obj_desc = obj_desc->region.next;
 	}
 
-	/*
-	 *  If we get here, the region was not in the handler's region list
-	 */
+	/* If we get here, the region was not in the handler's region list */
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"Cannot remove region %p from address handler %p\n",
 		region_obj, handler_obj));
@@ -534,16 +527,19 @@
 		region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
 
 
-	/*
-	 * Link this region to the front of the handler's list
-	 */
-	region_obj->region.next = handler_obj->addr_handler.region_list;
-	handler_obj->addr_handler.region_list = region_obj;
+	/* Link this region to the front of the handler's list */
 
-	/*
-	 * Set the region's handler
-	 */
-	region_obj->region.addr_handler = handler_obj;
+	region_obj->region.next = handler_obj->address_space.region_list;
+	handler_obj->address_space.region_list = region_obj;
+
+	/* Install the region's handler */
+
+	if (region_obj->region.address_space) {
+		return_ACPI_STATUS (AE_ALREADY_EXISTS);
+	}
+
+	region_obj->region.address_space = handler_obj;
+	acpi_ut_add_reference (handler_obj);
 
 	/*
 	 * Tell all users that this region is usable by running the _REG
@@ -571,14 +567,14 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_addr_handler_helper
+ * FUNCTION:    acpi_ev_install_handler
  *
  * PARAMETERS:  Handle              - Node to be dumped
  *              Level               - Nesting level of the handle
  *              Context             - Passed into acpi_ns_walk_namespace
  *
  * DESCRIPTION: This routine installs an address handler into objects that are
- *              of type Region.
+ *              of type Region or Device.
  *
  *              If the Object is a Device, and the device has a handler of
  *              the same type then the search is terminated in that branch.
@@ -589,20 +585,20 @@
  ******************************************************************************/
 
 acpi_status
-acpi_ev_addr_handler_helper (
+acpi_ev_install_handler (
 	acpi_handle                     obj_handle,
 	u32                             level,
 	void                            *context,
 	void                            **return_value)
 {
 	union acpi_operand_object       *handler_obj;
-	union acpi_operand_object       *tmp_obj;
+	union acpi_operand_object       *next_handler_obj;
 	union acpi_operand_object       *obj_desc;
 	struct acpi_namespace_node      *node;
 	acpi_status                     status;
 
 
-	ACPI_FUNCTION_NAME ("ev_addr_handler_helper");
+	ACPI_FUNCTION_NAME ("ev_install_handler");
 
 
 	handler_obj = (union acpi_operand_object   *) context;
@@ -621,8 +617,8 @@
 	}
 
 	/*
-	 *  We only care about regions.and objects
-	 *  that can have address handlers
+	 * We only care about regions.and objects
+	 * that are allowed to have address space handlers
 	 */
 	if ((node->type != ACPI_TYPE_DEVICE) &&
 		(node->type != ACPI_TYPE_REGION) &&
@@ -634,81 +630,70 @@
 
 	obj_desc = acpi_ns_get_attached_object (node);
 	if (!obj_desc) {
-		/*
-		 *  The object DNE, we don't care about it
-		 */
+		/* No object, just exit */
+
 		return (AE_OK);
 	}
 
-	/*
-	 *  Devices are handled different than regions
-	 */
+	/* Devices are handled different than regions */
+
 	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {
-		/*
-		 *  See if this guy has any handlers
-		 */
-		tmp_obj = obj_desc->device.addr_handler;
-		while (tmp_obj) {
-			/*
-			 *  Now let's see if it's for the same address space.
-			 */
-			if (tmp_obj->addr_handler.space_id == handler_obj->addr_handler.space_id) {
-				/*
-				 *  It's for the same address space
-				 */
+		/* Check if this Device already has a handler for this address space */
+
+		next_handler_obj = obj_desc->device.address_space;
+		while (next_handler_obj) {
+			/* Found a handler, is it for the same address space? */
+
+			if (next_handler_obj->address_space.space_id == handler_obj->address_space.space_id) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 					"Found handler for region [%s] in device %p(%p) handler %p\n",
-					acpi_ut_get_region_name (handler_obj->addr_handler.space_id),
-					obj_desc, tmp_obj, handler_obj));
+					acpi_ut_get_region_name (handler_obj->address_space.space_id),
+					obj_desc, next_handler_obj, handler_obj));
 
 				/*
-				 *  Since the object we found it on was a device, then it
-				 *  means that someone has already installed a handler for
-				 *  the branch of the namespace from this device on.  Just
-				 *  bail out telling the walk routine to not traverse this
-				 *  branch.  This preserves the scoping rule for handlers.
+				 * Since the object we found it on was a device, then it
+				 * means that someone has already installed a handler for
+				 * the branch of the namespace from this device on.  Just
+				 * bail out telling the walk routine to not traverse this
+				 * branch.  This preserves the scoping rule for handlers.
 				 */
 				return (AE_CTRL_DEPTH);
 			}
 
-			/*
-			 *  Move through the linked list of handlers
-			 */
-			tmp_obj = tmp_obj->addr_handler.next;
+			/* Walk the linked list of handlers attached to this device */
+
+			next_handler_obj = next_handler_obj->address_space.next;
 		}
 
 		/*
-		 *  As long as the device didn't have a handler for this
-		 *  space we don't care about it.  We just ignore it and
-		 *  proceed.
+		 * As long as the device didn't have a handler for this
+		 * space we don't care about it.  We just ignore it and
+		 * proceed.
 		 */
 		return (AE_OK);
 	}
 
-	/*
-	 *  Only here if it was a region
-	 */
-	if (obj_desc->region.space_id != handler_obj->addr_handler.space_id) {
+	/* Object is a Region */
+
+	if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
 		/*
-		 *  This region is for a different address space
-		 *  ignore it
+		 * This region is for a different address space
+		 * -- just ignore it
 		 */
 		return (AE_OK);
 	}
 
 	/*
-	 *  Now we have a region and it is for the handler's address
-	 *  space type.
+	 * Now we have a region and it is for the handler's address
+	 * space type.
 	 *
-	 *  First disconnect region for any previous handler (if any)
+	 * First disconnect region for any previous handler (if any)
 	 */
 	acpi_ev_detach_region (obj_desc, FALSE);
 
-	/*
-	 *  Then connect the region to the new handler
-	 */
-	status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);
+	/* Connect the region to the new handler */
 
+	status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);
 	return (status);
 }
 
diff -urN linux-2.5.69-bk16/drivers/acpi/events/evrgnini.c linux-2.5.69-bk17/drivers/acpi/events/evrgnini.c
--- linux-2.5.69-bk16/drivers/acpi/events/evrgnini.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/events/evrgnini.c	2003-05-24 04:33:33.000000000 -0700
@@ -165,10 +165,11 @@
 	void                            **region_context)
 {
 	acpi_status                     status = AE_OK;
-	acpi_integer                    temp;
+	acpi_integer                    pci_value;
 	struct acpi_pci_id              *pci_id = *region_context;
 	union acpi_operand_object       *handler_obj;
-	struct acpi_namespace_node      *node;
+	struct acpi_namespace_node      *parent_node;
+	struct acpi_namespace_node      *pci_root_node;
 	union acpi_operand_object       *region_obj = (union acpi_operand_object   *) handle;
 	struct acpi_device_id           object_hID;
 
@@ -176,7 +177,7 @@
 	ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup");
 
 
-	handler_obj = region_obj->region.addr_handler;
+	handler_obj = region_obj->region.address_space;
 	if (!handler_obj) {
 		/*
 		 * No installed handler. This shouldn't happen because the dispatch
@@ -187,45 +188,15 @@
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
 
+	*region_context = NULL;
 	if (function == ACPI_REGION_DEACTIVATE) {
 		if (pci_id) {
 			ACPI_MEM_FREE (pci_id);
-			*region_context = NULL;
 		}
-
 		return_ACPI_STATUS (status);
 	}
 
-	/* Create a new context */
-
-	pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
-	if (!pci_id) {
-		return_ACPI_STATUS (AE_NO_MEMORY);
-	}
-
-	/*
-	 * For PCI Config space access, we have to pass the segment, bus,
-	 * device and function numbers.  This routine must acquire those.
-	 */
-
-	/*
-	 * First get device and function numbers from the _ADR object
-	 * in the parent's scope.
-	 */
-	node = acpi_ns_get_parent_node (region_obj->region.node);
-
-	/* Evaluate the _ADR object */
-
-	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp);
-
-	/*
-	 * The default is zero, and since the allocation above zeroed
-	 * the data, just do nothing on failure.
-	 */
-	if (ACPI_SUCCESS (status)) {
-		pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (temp));
-		pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp));
-	}
+	parent_node = acpi_ns_get_parent_node (region_obj->region.node);
 
 	/*
 	 * Get the _SEG and _BBN values from the device upon which the handler
@@ -236,61 +207,106 @@
 	 */
 
 	/*
-	 * If the addr_handler.Node is still pointing to the root, we need
+	 * If the address_space.Node is still pointing to the root, we need
 	 * to scan upward for a PCI Root bridge and re-associate the op_region
 	 * handlers with that device.
 	 */
-	if (handler_obj->addr_handler.node == acpi_gbl_root_node) {
-		/*
-		 * Node is currently the parent object
-		 */
-		while (node != acpi_gbl_root_node) {
-			status = acpi_ut_execute_HID (node, &object_hID);
+	if (handler_obj->address_space.node == acpi_gbl_root_node) {
+		/* Start search from the parent object */
+
+		pci_root_node = parent_node;
+		while (pci_root_node != acpi_gbl_root_node) {
+			status = acpi_ut_execute_HID (pci_root_node, &object_hID);
 			if (ACPI_SUCCESS (status)) {
 				/* Got a valid _HID, check if this is a PCI root */
 
-				if (!(ACPI_STRNCMP (object_hID.buffer, PCI_ROOT_HID_STRING,
+				if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING,
 						   sizeof (PCI_ROOT_HID_STRING)))) {
 					/* Install a handler for this PCI root bridge */
 
-					status = acpi_install_address_space_handler ((acpi_handle) node,
+					status = acpi_install_address_space_handler ((acpi_handle) pci_root_node,
 							   ACPI_ADR_SPACE_PCI_CONFIG,
 							   ACPI_DEFAULT_HANDLER, NULL, NULL);
 					if (ACPI_FAILURE (status)) {
-						ACPI_REPORT_ERROR (("Could not install pci_config handler for %4.4s, %s\n",
-							node->name.ascii, acpi_format_exception (status)));
+						if (status == AE_SAME_HANDLER) {
+							/*
+							 * It is OK if the handler is already installed on the root
+							 * bridge.  Still need to return a context object for the
+							 * new PCI_Config operation region, however.
+							 */
+							status = AE_OK;
+						}
+						else {
+							ACPI_REPORT_ERROR ((
+								"Could not install pci_config handler for Root Bridge %4.4s, %s\n",
+								pci_root_node->name.ascii, acpi_format_exception (status)));
+						}
 					}
 					break;
 				}
 			}
 
-			node = acpi_ns_get_parent_node (node);
+			pci_root_node = acpi_ns_get_parent_node (pci_root_node);
 		}
+
+		/* PCI root bridge not found, use namespace root node */
 	}
 	else {
-		node = handler_obj->addr_handler.node;
+		pci_root_node = handler_obj->address_space.node;
 	}
 
 	/*
-	 * The PCI segment number comes from the _SEG method
+	 * If this region is now initialized, we are done.
+	 * (install_address_space_handler could have initialized it)
 	 */
-	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp);
-	if (ACPI_SUCCESS (status)) {
-		pci_id->segment = ACPI_LOWORD (temp);
+	if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Region is still not initialized. Create a new context */
+
+	pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
+	if (!pci_id) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
 	/*
-	 * The PCI bus number comes from the _BBN method
+	 * For PCI_Config space access, we need the segment, bus,
+	 * device and function numbers.  Acquire them here.
 	 */
-	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp);
-	if (ACPI_SUCCESS (status)) {
-		pci_id->bus = ACPI_LOWORD (temp);
-	}
 
 	/*
-	 * Complete this device's pci_id
+	 * Get the PCI device and function numbers from the _ADR object
+	 * contained in the parent's scope.
+	 */
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, parent_node, &pci_value);
+
+	/*
+	 * The default is zero, and since the allocation above zeroed
+	 * the data, just do nothing on failure.
 	 */
-	acpi_os_derive_pci_id (node, region_obj->region.node, &pci_id);
+	if (ACPI_SUCCESS (status)) {
+		pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (pci_value));
+		pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value));
+	}
+
+	/* The PCI segment number comes from the _SEG method */
+
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value);
+	if (ACPI_SUCCESS (status)) {
+		pci_id->segment = ACPI_LOWORD (pci_value);
+	}
+
+	/* The PCI bus number comes from the _BBN method */
+
+	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value);
+	if (ACPI_SUCCESS (status)) {
+		pci_id->bus = ACPI_LOWORD (pci_value);
+	}
+
+	/* Complete this device's pci_id */
+
+	acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id);
 
 	*region_context = pci_id;
 	return_ACPI_STATUS (AE_OK);
@@ -451,14 +467,15 @@
 	node = acpi_ns_get_parent_node (region_obj->region.node);
 	space_id = region_obj->region.space_id;
 
-	region_obj->region.addr_handler = NULL;
+	/* Setup defaults */
+
+	region_obj->region.address_space = NULL;
 	region_obj2->extra.method_REG = NULL;
 	region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
 	region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
 
-	/*
-	 * Find any "_REG" method associated with this region definition
-	 */
+	/* Find any "_REG" method associated with this region definition */
+
 	status = acpi_ns_search_node (*reg_name_ptr, node,
 			  ACPI_TYPE_METHOD, &method_node);
 	if (ACPI_SUCCESS (status)) {
@@ -475,29 +492,27 @@
 	 * ie: acpi_gbl_root_node->parent_entry being set to NULL
 	 */
 	while (node) {
-		/*
-		 * Check to see if a handler exists
-		 */
+		/* Check to see if a handler exists */
+
 		handler_obj = NULL;
 		obj_desc = acpi_ns_get_attached_object (node);
 		if (obj_desc) {
-			/*
-			 * Can only be a handler if the object exists
-			 */
+			/* Can only be a handler if the object exists */
+
 			switch (node->type) {
 			case ACPI_TYPE_DEVICE:
 
-				handler_obj = obj_desc->device.addr_handler;
+				handler_obj = obj_desc->device.address_space;
 				break;
 
 			case ACPI_TYPE_PROCESSOR:
 
-				handler_obj = obj_desc->processor.addr_handler;
+				handler_obj = obj_desc->processor.address_space;
 				break;
 
 			case ACPI_TYPE_THERMAL:
 
-				handler_obj = obj_desc->thermal_zone.addr_handler;
+				handler_obj = obj_desc->thermal_zone.address_space;
 				break;
 
 			default:
@@ -508,7 +523,7 @@
 			while (handler_obj) {
 				/* Is this handler of the correct type? */
 
-				if (handler_obj->addr_handler.space_id == space_id) {
+				if (handler_obj->address_space.space_id == space_id) {
 					/* Found correct handler */
 
 					ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
@@ -523,7 +538,7 @@
 
 				/* Try next handler in the list */
 
-				handler_obj = handler_obj->addr_handler.next;
+				handler_obj = handler_obj->address_space.next;
 			}
 		}
 
@@ -534,9 +549,8 @@
 		node = acpi_ns_get_parent_node (node);
 	}
 
-	/*
-	 * If we get here, there is no handler for this region
-	 */
+	/* If we get here, there is no handler for this region */
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"No handler for region_type %s(%X) (region_obj %p)\n",
 		acpi_ut_get_region_name (space_id), space_id, region_obj));
diff -urN linux-2.5.69-bk16/drivers/acpi/events/evxface.c linux-2.5.69-bk17/drivers/acpi/events/evxface.c
--- linux-2.5.69-bk16/drivers/acpi/events/evxface.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/events/evxface.c	2003-05-24 04:33:33.000000000 -0700
@@ -244,22 +244,22 @@
 		/* Make sure the handler is not already installed */
 
 		if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
-			  acpi_gbl_sys_notify.handler) ||
+				acpi_gbl_system_notify.handler)        ||
 			((handler_type == ACPI_DEVICE_NOTIFY) &&
-			  acpi_gbl_drv_notify.handler)) {
+				acpi_gbl_device_notify.handler)) {
 			status = AE_ALREADY_EXISTS;
 			goto unlock_and_exit;
 		}
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			acpi_gbl_sys_notify.node = node;
-			acpi_gbl_sys_notify.handler = handler;
-			acpi_gbl_sys_notify.context = context;
+			acpi_gbl_system_notify.node  = node;
+			acpi_gbl_system_notify.handler = handler;
+			acpi_gbl_system_notify.context = context;
 		}
 		else /* ACPI_DEVICE_NOTIFY */ {
-			acpi_gbl_drv_notify.node = node;
-			acpi_gbl_drv_notify.handler = handler;
-			acpi_gbl_drv_notify.context = context;
+			acpi_gbl_device_notify.node  = node;
+			acpi_gbl_device_notify.handler = handler;
+			acpi_gbl_device_notify.context = context;
 		}
 
 		/* Global notify handler installed */
@@ -282,13 +282,12 @@
 
 		obj_desc = acpi_ns_get_attached_object (node);
 		if (obj_desc) {
-
 			/* Object exists - make sure there's no handler */
 
 			if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
-				  obj_desc->common_notify.sys_handler) ||
+					obj_desc->common_notify.system_notify) ||
 				((handler_type == ACPI_DEVICE_NOTIFY) &&
-				  obj_desc->common_notify.drv_handler)) {
+					obj_desc->common_notify.device_notify)) {
 				status = AE_ALREADY_EXISTS;
 				goto unlock_and_exit;
 			}
@@ -305,6 +304,11 @@
 			/* Attach new object to the Node */
 
 			status = acpi_ns_attach_object (device, obj_desc, node->type);
+
+			/* Remove local reference to the object */
+
+			acpi_ut_remove_reference (obj_desc);
+
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
 			}
@@ -318,15 +322,15 @@
 			goto unlock_and_exit;
 		}
 
-		notify_obj->notify_handler.node = node;
-		notify_obj->notify_handler.handler = handler;
-		notify_obj->notify_handler.context = context;
+		notify_obj->notify.node   = node;
+		notify_obj->notify.handler = handler;
+		notify_obj->notify.context = context;
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			obj_desc->common_notify.sys_handler = notify_obj;
+			obj_desc->common_notify.system_notify = notify_obj;
 		}
 		else /* ACPI_DEVICE_NOTIFY */ {
-			obj_desc->common_notify.drv_handler = notify_obj;
+			obj_desc->common_notify.device_notify = notify_obj;
 		}
 	}
 
@@ -395,22 +399,22 @@
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
 
 		if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
-			  !acpi_gbl_sys_notify.handler) ||
+			  !acpi_gbl_system_notify.handler) ||
 			((handler_type == ACPI_DEVICE_NOTIFY) &&
-			  !acpi_gbl_drv_notify.handler)) {
+			  !acpi_gbl_device_notify.handler)) {
 			status = AE_NOT_EXIST;
 			goto unlock_and_exit;
 		}
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			acpi_gbl_sys_notify.node  = NULL;
-			acpi_gbl_sys_notify.handler = NULL;
-			acpi_gbl_sys_notify.context = NULL;
+			acpi_gbl_system_notify.node  = NULL;
+			acpi_gbl_system_notify.handler = NULL;
+			acpi_gbl_system_notify.context = NULL;
 		}
 		else {
-			acpi_gbl_drv_notify.node  = NULL;
-			acpi_gbl_drv_notify.handler = NULL;
-			acpi_gbl_drv_notify.context = NULL;
+			acpi_gbl_device_notify.node  = NULL;
+			acpi_gbl_device_notify.handler = NULL;
+			acpi_gbl_device_notify.context = NULL;
 		}
 	}
 
@@ -436,14 +440,14 @@
 		/* Object exists - make sure there's an existing handler */
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			notify_obj = obj_desc->common_notify.sys_handler;
+			notify_obj = obj_desc->common_notify.system_notify;
 		}
 		else {
-			notify_obj = obj_desc->common_notify.drv_handler;
+			notify_obj = obj_desc->common_notify.device_notify;
 		}
 
 		if ((!notify_obj) ||
-			(notify_obj->notify_handler.handler != handler)) {
+			(notify_obj->notify.handler != handler)) {
 			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
 		}
@@ -451,10 +455,10 @@
 		/* Remove the handler */
 
 		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			obj_desc->common_notify.sys_handler = NULL;
+			obj_desc->common_notify.system_notify = NULL;
 		}
 		else {
-			obj_desc->common_notify.drv_handler = NULL;
+			obj_desc->common_notify.device_notify = NULL;
 		}
 
 		acpi_ut_remove_reference (notify_obj);
diff -urN linux-2.5.69-bk16/drivers/acpi/events/evxfevnt.c linux-2.5.69-bk17/drivers/acpi/events/evxfevnt.c
--- linux-2.5.69-bk16/drivers/acpi/events/evxfevnt.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/events/evxfevnt.c	2003-05-24 04:33:33.000000000 -0700
@@ -654,7 +654,11 @@
 		}
 
 		status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE);
+
+		/* Remove local reference to the object */
+
 		acpi_ut_remove_reference (obj_desc);
+
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
diff -urN linux-2.5.69-bk16/drivers/acpi/events/evxfregn.c linux-2.5.69-bk17/drivers/acpi/events/evxfregn.c
--- linux-2.5.69-bk16/drivers/acpi/events/evxfregn.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/events/evxfregn.c	2003-05-24 04:33:33.000000000 -0700
@@ -154,7 +154,7 @@
 			break;
 
 		default:
-			status = AE_NOT_EXIST;
+			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
 		}
 	}
@@ -170,26 +170,36 @@
 	obj_desc = acpi_ns_get_attached_object (node);
 	if (obj_desc) {
 		/*
-		 * The object exists.
+		 * The attached device object already exists.
 		 * Make sure the handler is not already installed.
 		 */
+		handler_obj = obj_desc->device.address_space;
 
-		/* check the address handler the user requested */
+		/* Walk the handler list for this device */
 
-		handler_obj = obj_desc->device.addr_handler;
 		while (handler_obj) {
-			/*
-			 * Found an Address handler, see if user requested this
-			 * address space.
-			 */
-			if(handler_obj->addr_handler.space_id == space_id) {
-				status = AE_ALREADY_EXISTS;
+			/* Same space_id indicates a handler already installed */
+
+			if(handler_obj->address_space.space_id == space_id) {
+				if (handler_obj->address_space.handler == handler) {
+					/*
+					 * It is (relatively) OK to attempt to install the SAME
+					 * handler twice. This can easily happen with PCI_Config space.
+					 */
+					status = AE_SAME_HANDLER;
+					goto unlock_and_exit;
+				}
+				else {
+					/* A handler is already installed */
+
+					status = AE_ALREADY_EXISTS;
+				}
 				goto unlock_and_exit;
 			}
 
 			/* Walk the linked list of handlers */
 
-			handler_obj = handler_obj->addr_handler.next;
+			handler_obj = handler_obj->address_space.next;
 		}
 	}
 	else {
@@ -218,8 +228,12 @@
 		/* Attach the new object to the Node */
 
 		status = acpi_ns_attach_object (node, obj_desc, type);
+
+		/* Remove local reference to the object */
+
+		acpi_ut_remove_reference (obj_desc);
+
 		if (ACPI_FAILURE (status)) {
-			acpi_ut_remove_reference (obj_desc);
 			goto unlock_and_exit;
 		}
 	}
@@ -241,14 +255,25 @@
 		goto unlock_and_exit;
 	}
 
-	handler_obj->addr_handler.space_id  = (u8) space_id;
-	handler_obj->addr_handler.hflags    = flags;
-	handler_obj->addr_handler.next      = obj_desc->device.addr_handler;
-	handler_obj->addr_handler.region_list = NULL;
-	handler_obj->addr_handler.node      = node;
-	handler_obj->addr_handler.handler   = handler;
-	handler_obj->addr_handler.context   = context;
-	handler_obj->addr_handler.setup     = setup;
+	/* Init handler obj */
+
+	handler_obj->address_space.space_id  = (u8) space_id;
+	handler_obj->address_space.hflags    = flags;
+	handler_obj->address_space.region_list = NULL;
+	handler_obj->address_space.node      = node;
+	handler_obj->address_space.handler   = handler;
+	handler_obj->address_space.context   = context;
+	handler_obj->address_space.setup     = setup;
+
+	/* Install at head of Device.address_space list */
+
+	handler_obj->address_space.next      = obj_desc->device.address_space;
+
+	/*
+	 * The Device object is the first reference on the handler_obj.
+	 * Each region that uses the handler adds a reference.
+	 */
+	obj_desc->device.address_space = handler_obj;
 
 	/*
 	 * Walk the namespace finding all of the regions this
@@ -262,18 +287,9 @@
 	 * In either case, back up and search down the remainder
 	 * of the branch
 	 */
-	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device,
-			 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
-			 acpi_ev_addr_handler_helper,
-			 handler_obj, NULL);
-
-	/* Place this handler 1st on the list */
-
-	handler_obj->common.reference_count =
-			 (u16) (handler_obj->common.reference_count +
-			 obj_desc->common.reference_count - 1);
-	obj_desc->device.addr_handler = handler_obj;
-
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
+			  ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
+			  handler_obj, NULL);
 
 unlock_and_exit:
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
@@ -341,12 +357,12 @@
 
 	/* Find the address handler the user requested */
 
-	handler_obj = obj_desc->device.addr_handler;
-	last_obj_ptr = &obj_desc->device.addr_handler;
+	handler_obj = obj_desc->device.address_space;
+	last_obj_ptr = &obj_desc->device.address_space;
 	while (handler_obj) {
 		/* We have a handler, see if user requested this one */
 
-		if (handler_obj->addr_handler.space_id == space_id) {
+		if (handler_obj->address_space.space_id == space_id) {
 			/* Matched space_id, first dereference this in the Regions */
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
@@ -354,7 +370,7 @@
 				handler_obj, handler, acpi_ut_get_region_name (space_id),
 				node, obj_desc));
 
-			region_obj = handler_obj->addr_handler.region_list;
+			region_obj = handler_obj->address_space.region_list;
 
 			/* Walk the handler's region list */
 
@@ -372,13 +388,13 @@
 				 * Walk the list: Just grab the head because the
 				 * detach_region removed the previous head.
 				 */
-				region_obj = handler_obj->addr_handler.region_list;
+				region_obj = handler_obj->address_space.region_list;
 
 			}
 
 			/* Remove this Handler object from the list */
 
-			*last_obj_ptr = handler_obj->addr_handler.next;
+			*last_obj_ptr = handler_obj->address_space.next;
 
 			/* Now we can delete the handler object */
 
@@ -388,8 +404,8 @@
 
 		/* Walk the linked list of handlers */
 
-		last_obj_ptr = &handler_obj->addr_handler.next;
-		handler_obj = handler_obj->addr_handler.next;
+		last_obj_ptr = &handler_obj->address_space.next;
+		handler_obj = handler_obj->address_space.next;
 	}
 
 	/* The handler does not exist */
diff -urN linux-2.5.69-bk16/drivers/acpi/executer/exconfig.c linux-2.5.69-bk17/drivers/acpi/executer/exconfig.c
--- linux-2.5.69-bk16/drivers/acpi/executer/exconfig.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/executer/exconfig.c	2003-05-24 04:33:33.000000000 -0700
@@ -360,11 +360,11 @@
 	/* The table must be either an SSDT or a PSDT */
 
 	if ((!ACPI_STRNCMP (table_ptr->signature,
-			  acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].signature,
-			  acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].sig_length)) &&
+			  acpi_gbl_table_data[ACPI_TABLE_PSDT].signature,
+			  acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) &&
 		(!ACPI_STRNCMP (table_ptr->signature,
-				 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].signature,
-				 acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length))) {
+				 acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
+				 acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Table has invalid signature [%4.4s], must be SSDT or PSDT\n",
 			table_ptr->signature));
diff -urN linux-2.5.69-bk16/drivers/acpi/executer/exdump.c linux-2.5.69-bk17/drivers/acpi/executer/exdump.c
--- linux-2.5.69-bk16/drivers/acpi/executer/exdump.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/executer/exdump.c	2003-05-24 04:33:33.000000000 -0700
@@ -635,9 +635,9 @@
 
 	case ACPI_TYPE_DEVICE:
 
-		acpi_ex_out_pointer ("addr_handler", obj_desc->device.addr_handler);
-		acpi_ex_out_pointer ("sys_handler",  obj_desc->device.sys_handler);
-		acpi_ex_out_pointer ("drv_handler",  obj_desc->device.drv_handler);
+		acpi_ex_out_pointer ("address_space", obj_desc->device.address_space);
+		acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
 		break;
 
 
@@ -673,7 +673,7 @@
 		acpi_ex_out_integer ("Flags",        obj_desc->region.flags);
 		acpi_ex_out_address ("Address",      obj_desc->region.address);
 		acpi_ex_out_integer ("Length",       obj_desc->region.length);
-		acpi_ex_out_pointer ("addr_handler", obj_desc->region.addr_handler);
+		acpi_ex_out_pointer ("address_space", obj_desc->region.address_space);
 		acpi_ex_out_pointer ("Next",         obj_desc->region.next);
 		break;
 
@@ -682,8 +682,8 @@
 
 		acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level);
 		acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order);
-		acpi_ex_out_pointer ("sys_handler",  obj_desc->power_resource.sys_handler);
-		acpi_ex_out_pointer ("drv_handler",  obj_desc->power_resource.drv_handler);
+		acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify);
 		break;
 
 
@@ -692,17 +692,17 @@
 		acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id);
 		acpi_ex_out_integer ("Length",       obj_desc->processor.length);
 		acpi_ex_out_address ("Address",      (acpi_physical_address) obj_desc->processor.address);
-		acpi_ex_out_pointer ("sys_handler",  obj_desc->processor.sys_handler);
-		acpi_ex_out_pointer ("drv_handler",  obj_desc->processor.drv_handler);
-		acpi_ex_out_pointer ("addr_handler", obj_desc->processor.addr_handler);
+		acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify);
+		acpi_ex_out_pointer ("address_space", obj_desc->processor.address_space);
 		break;
 
 
 	case ACPI_TYPE_THERMAL:
 
-		acpi_ex_out_pointer ("sys_handler",  obj_desc->thermal_zone.sys_handler);
-		acpi_ex_out_pointer ("drv_handler",  obj_desc->thermal_zone.drv_handler);
-		acpi_ex_out_pointer ("addr_handler", obj_desc->thermal_zone.addr_handler);
+		acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify);
+		acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify);
+		acpi_ex_out_pointer ("address_space", obj_desc->thermal_zone.address_space);
 		break;
 
 
@@ -762,18 +762,18 @@
 
 	case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
 
-		acpi_ex_out_integer ("space_id",     obj_desc->addr_handler.space_id);
-		acpi_ex_out_pointer ("Next",         obj_desc->addr_handler.next);
-		acpi_ex_out_pointer ("region_list",  obj_desc->addr_handler.region_list);
-		acpi_ex_out_pointer ("Node",         obj_desc->addr_handler.node);
-		acpi_ex_out_pointer ("Context",      obj_desc->addr_handler.context);
+		acpi_ex_out_integer ("space_id",     obj_desc->address_space.space_id);
+		acpi_ex_out_pointer ("Next",         obj_desc->address_space.next);
+		acpi_ex_out_pointer ("region_list",  obj_desc->address_space.region_list);
+		acpi_ex_out_pointer ("Node",         obj_desc->address_space.node);
+		acpi_ex_out_pointer ("Context",      obj_desc->address_space.context);
 		break;
 
 
 	case ACPI_TYPE_LOCAL_NOTIFY:
 
-		acpi_ex_out_pointer ("Node",         obj_desc->notify_handler.node);
-		acpi_ex_out_pointer ("Context",      obj_desc->notify_handler.context);
+		acpi_ex_out_pointer ("Node",         obj_desc->notify.node);
+		acpi_ex_out_pointer ("Context",      obj_desc->notify.context);
 		break;
 
 
diff -urN linux-2.5.69-bk16/drivers/acpi/hardware/hwgpe.c linux-2.5.69-bk17/drivers/acpi/hardware/hwgpe.c
--- linux-2.5.69-bk16/drivers/acpi/hardware/hwgpe.c	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/hardware/hwgpe.c	2003-05-24 04:33:33.000000000 -0700
@@ -77,7 +77,7 @@
 	 * to enable the GPE, and write out the new register.
 	 */
 	status = acpi_hw_low_level_read (8, &in_byte,
-			  &gpe_event_info->register_info->enable_address, 0);
+			  &gpe_event_info->register_info->enable_address);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -85,7 +85,7 @@
 	/* Write with the new GPE bit enabled */
 
 	status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask),
-			  &gpe_event_info->register_info->enable_address, 0);
+			  &gpe_event_info->register_info->enable_address);
 
 	return (status);
 }
@@ -164,7 +164,7 @@
 	 * and write out the new register value to disable the GPE.
 	 */
 	status = acpi_hw_low_level_read (8, &in_byte,
-			  &gpe_register_info->enable_address, 0);
+			  &gpe_register_info->enable_address);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -172,7 +172,7 @@
 	/* Write the byte with this GPE bit cleared */
 
 	status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)),
-			  &gpe_register_info->enable_address, 0);
+			  &gpe_register_info->enable_address);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
@@ -246,7 +246,7 @@
 	 * clear this GPE.
 	 */
 	status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask,
-			  &gpe_event_info->register_info->status_address, 0);
+			  &gpe_event_info->register_info->status_address);
 
 	return (status);
 }
@@ -293,7 +293,7 @@
 
 	/* GPE Enabled? */
 
-	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address, 0);
+	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
@@ -310,7 +310,7 @@
 
 	/* GPE active (set)? */
 
-	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address, 0);
+	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
@@ -360,7 +360,7 @@
 
 	for (i = 0; i < gpe_block->register_count; i++) {
 		status = acpi_hw_low_level_write (8, 0x00,
-				 &gpe_block->register_info[i].enable_address, (u32) i);
+				 &gpe_block->register_info[i].enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -401,7 +401,7 @@
 
 	for (i = 0; i < gpe_block->register_count; i++) {
 		status = acpi_hw_low_level_write (8, 0xFF,
-				 &gpe_block->register_info[i].status_address, (u32) i);
+				 &gpe_block->register_info[i].status_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -447,7 +447,7 @@
 		 * will be using it to restore all the GPEs later.
 		 */
 		status = acpi_hw_low_level_read (8, &in_value,
-				 &gpe_register_info->enable_address, 0);
+				 &gpe_register_info->enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -458,7 +458,7 @@
 		 * Disable all GPEs except wakeup GPEs.
 		 */
 		status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
-				&gpe_register_info->enable_address, 0);
+				&gpe_register_info->enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -539,7 +539,7 @@
 		 * Blast them back in.
 		 */
 		status = acpi_hw_low_level_write (8, gpe_register_info->enable,
-				 &gpe_register_info->enable_address, 0);
+				 &gpe_register_info->enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
diff -urN linux-2.5.69-bk16/drivers/acpi/hardware/hwregs.c linux-2.5.69-bk17/drivers/acpi/hardware/hwregs.c
--- linux-2.5.69-bk16/drivers/acpi/hardware/hwregs.c	2003-05-04 16:53:40.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/hardware/hwregs.c	2003-05-24 04:33:33.000000000 -0700
@@ -93,7 +93,7 @@
 
 	if (acpi_gbl_FADT->xpm1b_evt_blk.address) {
 		status = acpi_hw_low_level_write (16, ACPI_BITMASK_ALL_FIXED_STATUS,
-				 &acpi_gbl_FADT->xpm1b_evt_blk, 0);
+				 &acpi_gbl_FADT->xpm1b_evt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
@@ -470,7 +470,6 @@
 {
 	u32                             value1 = 0;
 	u32                             value2 = 0;
-	u32                             bank_offset;
 	acpi_status                     status;
 
 
@@ -487,50 +486,53 @@
 	switch (register_id) {
 	case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
 
-		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk, 0);
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk, 0);
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk);
 		value1 |= value2;
 		break;
 
 
-	case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access*/
+	case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access */
 
-		bank_offset = ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len);
-		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk, bank_offset);
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_xpm1a_enable);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk, bank_offset);
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_xpm1b_enable);
 		value1 |= value2;
 		break;
 
 
 	case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
 
-		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk, 0);
+		status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk, 0);
+		status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk);
 		value1 |= value2;
 		break;
 
 
 	case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
 
-		status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk, 0);
+		status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
 
-		status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk, 0);
+		status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk);
 		break;
 
 	case ACPI_REGISTER_SMI_COMMAND_BLOCK:    /* 8-bit access */
@@ -577,7 +579,6 @@
 	u32                             register_id,
 	u32                             value)
 {
-	u32                             bank_offset;
 	acpi_status                     status;
 
 
@@ -594,59 +595,62 @@
 	switch (register_id) {
 	case ACPI_REGISTER_PM1_STATUS:           /* 16-bit access */
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk, 0);
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM1_ENABLE:           /* 16-bit access*/
 
-		bank_offset = ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len);
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk, bank_offset);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1a_enable);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk, bank_offset);
+		/* PM1B is optional */
+
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1b_enable);
 		break;
 
 
 	case ACPI_REGISTER_PM1_CONTROL:          /* 16-bit access */
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk);
 		if (ACPI_FAILURE (status)) {
 			goto unlock_and_exit;
 		}
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM1A_CONTROL:         /* 16-bit access */
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM1B_CONTROL:         /* 16-bit access */
 
-		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk, 0);
+		status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM2_CONTROL:          /* 8-bit access */
 
-		status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk, 0);
+		status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk);
 		break;
 
 
 	case ACPI_REGISTER_PM_TIMER:             /* 32-bit access */
 
-		status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk, 0);
+		status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk);
 		break;
 
 
@@ -676,11 +680,11 @@
  *
  * FUNCTION:    acpi_hw_low_level_read
  *
- * PARAMETERS:  Register            - GAS register structure
- *              Offset              - Offset from the base address in the GAS
- *              Width               - 8, 16, or 32
+ * PARAMETERS:  Width               - 8, 16, or 32
+ *              Value               - Where the value is returned
+ *              Register            - GAS register structure
  *
- * RETURN:      Value read
+ * RETURN:      Status
  *
  * DESCRIPTION: Read from either memory, IO, or PCI config space.
  *
@@ -690,11 +694,8 @@
 acpi_hw_low_level_read (
 	u32                             width,
 	u32                             *value,
-	struct acpi_generic_address     *reg,
-	u32                             offset)
+	struct acpi_generic_address     *reg)
 {
-	acpi_physical_address           mem_address;
-	acpi_io_address                 io_address;
 	struct acpi_pci_id              pci_id;
 	u16                             pci_register;
 	acpi_status                     status;
@@ -721,19 +722,16 @@
 	switch (reg->address_space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
-		mem_address = (reg->address
-				  + (acpi_physical_address) offset);
-
-		status = acpi_os_read_memory (mem_address, value, width);
+		status = acpi_os_read_memory (
+				 (acpi_physical_address) reg->address,
+				 value, width);
 		break;
 
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		io_address = (acpi_io_address) (reg->address
-				   + (acpi_physical_address) offset);
-
-		status = acpi_os_read_port (io_address, value, width);
+		status = acpi_os_read_port ((acpi_io_address) reg->address,
+				 value, width);
 		break;
 
 
@@ -743,15 +741,16 @@
 		pci_id.bus     = 0;
 		pci_id.device  = ACPI_PCI_DEVICE (reg->address);
 		pci_id.function = ACPI_PCI_FUNCTION (reg->address);
-		pci_register   = (u16) (ACPI_PCI_REGISTER (reg->address)
-				  + offset);
+		pci_register   = (u16) ACPI_PCI_REGISTER (reg->address);
 
-		status = acpi_os_read_pci_configuration (&pci_id, pci_register, value, width);
+		status = acpi_os_read_pci_configuration (&pci_id, pci_register,
+				 value, width);
 		break;
 
 
 	default:
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", reg->address_space_id));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unsupported address space: %X\n", reg->address_space_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -767,12 +766,10 @@
  * PARAMETERS:  Width               - 8, 16, or 32
  *              Value               - To be written
  *              Register            - GAS register structure
- *              Offset              - Offset from the base address in the GAS
- *
  *
- * RETURN:      Value read
+ * RETURN:      Status
  *
- * DESCRIPTION: Read from either memory, IO, or PCI config space.
+ * DESCRIPTION: Write to either memory, IO, or PCI config space.
  *
  ******************************************************************************/
 
@@ -780,11 +777,8 @@
 acpi_hw_low_level_write (
 	u32                             width,
 	u32                             value,
-	struct acpi_generic_address     *reg,
-	u32                             offset)
+	struct acpi_generic_address     *reg)
 {
-	acpi_physical_address           mem_address;
-	acpi_io_address                 io_address;
 	struct acpi_pci_id              pci_id;
 	u16                             pci_register;
 	acpi_status                     status;
@@ -809,19 +803,16 @@
 	switch (reg->address_space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 
-		mem_address = (reg->address
-				  + (acpi_physical_address) offset);
-
-		status = acpi_os_write_memory (mem_address, value, width);
+		status = acpi_os_write_memory (
+				 (acpi_physical_address) reg->address,
+				 value, width);
 		break;
 
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		io_address = (acpi_io_address) (reg->address
-				   + (acpi_physical_address) offset);
-
-		status = acpi_os_write_port (io_address, value, width);
+		status = acpi_os_write_port ((acpi_io_address) reg->address,
+				 value, width);
 		break;
 
 
@@ -831,15 +822,16 @@
 		pci_id.bus     = 0;
 		pci_id.device  = ACPI_PCI_DEVICE (reg->address);
 		pci_id.function = ACPI_PCI_FUNCTION (reg->address);
-		pci_register   = (u16) (ACPI_PCI_REGISTER (reg->address)
-				  + offset);
+		pci_register   = (u16) ACPI_PCI_REGISTER (reg->address);
 
-		status = acpi_os_write_pci_configuration (&pci_id, pci_register, (acpi_integer) value, width);
+		status = acpi_os_write_pci_configuration (&pci_id, pci_register,
+				 (acpi_integer) value, width);
 		break;
 
 
 	default:
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", reg->address_space_id));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unsupported address space: %X\n", reg->address_space_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/hardware/hwtimer.c linux-2.5.69-bk17/drivers/acpi/hardware/hwtimer.c
--- linux-2.5.69-bk16/drivers/acpi/hardware/hwtimer.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/hardware/hwtimer.c	2003-05-24 04:33:33.000000000 -0700
@@ -108,7 +108,7 @@
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk, 0);
+	status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk);
 
 	return_ACPI_STATUS (status);
 }
diff -urN linux-2.5.69-bk16/drivers/acpi/namespace/nsalloc.c linux-2.5.69-bk17/drivers/acpi/namespace/nsalloc.c
--- linux-2.5.69-bk16/drivers/acpi/namespace/nsalloc.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/namespace/nsalloc.c	2003-05-24 04:33:33.000000000 -0700
@@ -116,19 +116,33 @@
 	prev_node = NULL;
 	next_node = parent_node->child;
 
+	/* Find the node that is the previous peer in the parent's child list */
+
 	while (next_node != node) {
 		prev_node = next_node;
 		next_node = prev_node->peer;
 	}
 
 	if (prev_node) {
+		/* Node is not first child, unlink it */
+
 		prev_node->peer = next_node->peer;
 		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
 			prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
 		}
 	}
 	else {
-		parent_node->child = next_node->peer;
+		/* Node is first child (has no previous peer) */
+
+		if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
+			/* No peers at all */
+
+			parent_node->child = NULL;
+		}
+		else {   /* Link peer list to parent */
+
+			parent_node->child = next_node->peer;
+		}
 	}
 
 
@@ -222,7 +236,7 @@
 	struct acpi_namespace_node      *node,          /* New Child*/
 	acpi_object_type                type)
 {
-	u16                             owner_id = TABLE_ID_DSDT;
+	u16                             owner_id = 0;
 	struct acpi_namespace_node      *child_node;
 #ifdef ACPI_ALPHABETIC_NAMESPACE
 
@@ -355,6 +369,7 @@
 {
 	struct acpi_namespace_node      *child_node;
 	struct acpi_namespace_node      *next_node;
+	struct acpi_namespace_node      *node;
 	u8                              flags;
 
 
@@ -399,6 +414,25 @@
 		 * Detach an object if there is one, then free the child node
 		 */
 		acpi_ns_detach_object (child_node);
+
+		/*
+		 * Decrement the reference count(s) of all parents up to
+		 * the root! (counts were incremented when the node was created)
+		 */
+		node = child_node;
+		while ((node = acpi_ns_get_parent_node (node)) != NULL) {
+			node->reference_count--;
+		}
+
+		/* There should be only one reference remaining on this node */
+
+		if (child_node->reference_count != 1) {
+			ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n",
+				child_node->reference_count, child_node));
+		}
+
+		/* Now we can delete the node */
+
 		ACPI_MEM_FREE (child_node);
 
 		/* And move on to the next child in the list */
@@ -512,7 +546,7 @@
  *
  ******************************************************************************/
 
-static void
+void
 acpi_ns_remove_reference (
 	struct acpi_namespace_node      *node)
 {
diff -urN linux-2.5.69-bk16/drivers/acpi/namespace/nsdumpdv.c linux-2.5.69-bk17/drivers/acpi/namespace/nsdumpdv.c
--- linux-2.5.69-bk16/drivers/acpi/namespace/nsdumpdv.c	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/namespace/nsdumpdv.c	2003-05-24 04:33:33.000000000 -0700
@@ -72,7 +72,8 @@
 	void                            *context,
 	void                            **return_value)
 {
-	struct acpi_device_info         info;
+	struct acpi_buffer              buffer;
+	struct acpi_device_info         *info;
 	acpi_status                     status;
 	u32                             i;
 
@@ -82,16 +83,19 @@
 
 	status = acpi_ns_dump_one_object (obj_handle, level, context, return_value);
 
-	status = acpi_get_object_info (obj_handle, &info);
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_get_object_info (obj_handle, &buffer);
 	if (ACPI_SUCCESS (status)) {
+		info = buffer.pointer;
 		for (i = 0; i < level; i++) {
 			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " "));
 		}
 
 		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "    HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
-				  info.hardware_id,
-				  ACPI_HIDWORD (info.address), ACPI_LODWORD (info.address),
-				  info.current_status));
+				  info->hardware_id.value,
+				  ACPI_HIDWORD (info->address), ACPI_LODWORD (info->address),
+				  info->current_status));
+		ACPI_MEM_FREE (info);
 	}
 
 	return (status);
diff -urN linux-2.5.69-bk16/drivers/acpi/namespace/nsload.c linux-2.5.69-bk17/drivers/acpi/namespace/nsload.c
--- linux-2.5.69-bk16/drivers/acpi/namespace/nsload.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/namespace/nsload.c	2003-05-24 04:33:33.000000000 -0700
@@ -79,7 +79,7 @@
 
 	/* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
 
-	if (!(acpi_gbl_acpi_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
+	if (!(acpi_gbl_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
 		/* Just ignore this table */
 
 		return_ACPI_STATUS (AE_OK);
@@ -182,7 +182,7 @@
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n"));
 
-		table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_DSDT];
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next;
 
 		/* If table already loaded into namespace, just return */
 
@@ -190,8 +190,6 @@
 			goto unlock_and_exit;
 		}
 
-		table_desc->table_id = TABLE_ID_DSDT;
-
 		/* Now load the single DSDT */
 
 		status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
@@ -205,13 +203,13 @@
 	case ACPI_TABLE_SSDT:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n",
-			acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count));
+			acpi_gbl_table_lists[ACPI_TABLE_SSDT].count));
 
 		/*
 		 * Traverse list of SSDT tables
 		 */
-		table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT];
-		for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) {
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_SSDT].next;
+		for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_SSDT].count; i++) {
 			/*
 			 * Only attempt to load table if it is not
 			 * already loaded!
@@ -233,14 +231,14 @@
 	case ACPI_TABLE_PSDT:
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n",
-			acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count));
+			acpi_gbl_table_lists[ACPI_TABLE_PSDT].count));
 
 		/*
 		 * Traverse list of PSDT tables
 		 */
-		table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT];
+		table_desc = acpi_gbl_table_lists[ACPI_TABLE_PSDT].next;
 
-		for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) {
+		for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_PSDT].count; i++) {
 			/* Only attempt to load table if it is not already loaded! */
 
 			if (!table_desc->loaded_into_namespace) {
diff -urN linux-2.5.69-bk16/drivers/acpi/namespace/nsparse.c linux-2.5.69-bk17/drivers/acpi/namespace/nsparse.c
--- linux-2.5.69-bk16/drivers/acpi/namespace/nsparse.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/namespace/nsparse.c	2003-05-24 04:33:33.000000000 -0700
@@ -85,10 +85,9 @@
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-
 	/* Create and initialize a new walk state */
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT,
+	walk_state = acpi_ds_create_walk_state (table_desc->table_id,
 			   NULL, NULL, NULL);
 	if (!walk_state) {
 		acpi_ps_free_op (parse_root);
diff -urN linux-2.5.69-bk16/drivers/acpi/namespace/nssearch.c linux-2.5.69-bk17/drivers/acpi/namespace/nssearch.c
--- linux-2.5.69-bk16/drivers/acpi/namespace/nssearch.c	2003-05-04 16:53:42.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/namespace/nssearch.c	2003-05-24 04:33:33.000000000 -0700
@@ -117,8 +117,9 @@
 			 * Found matching entry.
 			 */
 			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
-				"Name %4.4s Type [%s] found at %p\n",
-				(char *) &target_name, acpi_ut_get_type_name (next_node->type), next_node));
+				"Name %4.4s Type [%s] found in scope [%4.4s] %p\n",
+				(char *) &target_name, acpi_ut_get_type_name (next_node->type),
+				next_node->name.ascii, next_node));
 
 			*return_node = next_node;
 			return_ACPI_STATUS (AE_OK);
@@ -141,8 +142,10 @@
 
 	/* Searched entire namespace level, not found */
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Name %4.4s Type [%s] not found at %p\n",
-		(char *) &target_name, acpi_ut_get_type_name (type), next_node));
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+		"Name %4.4s Type [%s] not found in search in scope [%4.4s] %p first child %p\n",
+		(char *) &target_name, acpi_ut_get_type_name (type),
+		node->name.ascii, node, node->child));
 
 	return_ACPI_STATUS (AE_NOT_FOUND);
 }
diff -urN linux-2.5.69-bk16/drivers/acpi/namespace/nsutils.c linux-2.5.69-bk17/drivers/acpi/namespace/nsutils.c
--- linux-2.5.69-bk16/drivers/acpi/namespace/nsutils.c	2003-05-04 16:53:28.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/namespace/nsutils.c	2003-05-24 04:33:33.000000000 -0700
@@ -181,7 +181,11 @@
 
 	status = acpi_ns_handle_to_pathname (node, &buffer);
 	if (ACPI_SUCCESS (status)) {
-		acpi_os_printf ("%s [%s] (Node %p)", msg, (char *) buffer.pointer, node);
+		if (msg) {
+			acpi_os_printf ("%s ", msg);
+		}
+
+		acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node);
 		ACPI_MEM_FREE (buffer.pointer);
 	}
 }
@@ -799,38 +803,31 @@
 acpi_ns_terminate (void)
 {
 	union acpi_operand_object       *obj_desc;
-	struct acpi_namespace_node      *this_node;
 
 
 	ACPI_FUNCTION_TRACE ("ns_terminate");
 
 
-	this_node = acpi_gbl_root_node;
-
 	/*
-	 * 1) Free the entire namespace -- all objects, tables, and stacks
+	 * 1) Free the entire namespace -- all nodes and objects
 	 *
-	 * Delete all objects linked to the root
-	 * (additional table descriptors)
+	 * Delete all object descriptors attached to namepsace nodes
 	 */
-	acpi_ns_delete_namespace_subtree (this_node);
+	acpi_ns_delete_namespace_subtree (acpi_gbl_root_node);
 
-	/* Detach any object(s) attached to the root */
+	/* Detach any objects attached to the root */
 
-	obj_desc = acpi_ns_get_attached_object (this_node);
+	obj_desc = acpi_ns_get_attached_object (acpi_gbl_root_node);
 	if (obj_desc) {
-		acpi_ns_detach_object (this_node);
-		acpi_ut_remove_reference (obj_desc);
+		acpi_ns_detach_object (acpi_gbl_root_node);
 	}
 
-	acpi_ns_delete_children (this_node);
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
 
-
 	/*
 	 * 2) Now we can delete the ACPI tables
 	 */
-	acpi_tb_delete_acpi_tables ();
+	acpi_tb_delete_all_tables ();
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
 
 	return_VOID;
diff -urN linux-2.5.69-bk16/drivers/acpi/namespace/nsxfeval.c linux-2.5.69-bk17/drivers/acpi/namespace/nsxfeval.c
--- linux-2.5.69-bk16/drivers/acpi/namespace/nsxfeval.c	2003-05-04 16:53:56.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/namespace/nsxfeval.c	2003-05-24 04:33:33.000000000 -0700
@@ -437,16 +437,15 @@
 	void                            *context,
 	void                            **return_value)
 {
+	struct acpi_get_devices_info    *info = context;
 	acpi_status                     status;
 	struct acpi_namespace_node      *node;
 	u32                             flags;
 	struct acpi_device_id           hid;
-	struct acpi_device_id           cid;
-	struct acpi_get_devices_info    *info;
+	struct acpi_compatible_id_list *cid;
+	acpi_native_uint                i;
 
 
-	info = context;
-
 	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE (status)) {
 		return (status);
@@ -462,9 +461,8 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Run _STA to determine if device is present
-	 */
+	/* Run _STA to determine if device is present */
+
 	status = acpi_ut_execute_STA (node, &flags);
 	if (ACPI_FAILURE (status)) {
 		return (AE_CTRL_DEPTH);
@@ -472,12 +470,12 @@
 
 	if (!(flags & 0x01)) {
 		/* Don't return at the device or children of the device if not there */
+
 		return (AE_CTRL_DEPTH);
 	}
 
-	/*
-	 * Filter based on device HID & CID
-	 */
+	/* Filter based on device HID & CID */
+
 	if (info->hid != NULL) {
 		status = acpi_ut_execute_HID (node, &hid);
 		if (status == AE_NOT_FOUND) {
@@ -487,7 +485,9 @@
 			return (AE_CTRL_DEPTH);
 		}
 
-		if (ACPI_STRNCMP (hid.buffer, info->hid, sizeof (hid.buffer)) != 0) {
+		if (ACPI_STRNCMP (hid.value, info->hid, sizeof (hid.value)) != 0) {
+			/* Get the list of Compatible IDs */
+
 			status = acpi_ut_execute_CID (node, &cid);
 			if (status == AE_NOT_FOUND) {
 				return (AE_OK);
@@ -496,11 +496,16 @@
 				return (AE_CTRL_DEPTH);
 			}
 
-			/* TBD: Handle CID packages */
+			/* Walk the CID list */
 
-			if (ACPI_STRNCMP (cid.buffer, info->hid, sizeof (cid.buffer)) != 0) {
-				return (AE_OK);
+			for (i = 0; i < cid->count; i++) {
+				if (ACPI_STRNCMP (cid->id[i].value, info->hid,
+						 sizeof (struct acpi_compatible_id)) != 0) {
+					ACPI_MEM_FREE (cid);
+					return (AE_OK);
+				}
 			}
+			ACPI_MEM_FREE (cid);
 		}
 	}
 
diff -urN linux-2.5.69-bk16/drivers/acpi/namespace/nsxfname.c linux-2.5.69-bk17/drivers/acpi/namespace/nsxfname.c
--- linux-2.5.69-bk16/drivers/acpi/namespace/nsxfname.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/namespace/nsxfname.c	2003-05-24 04:33:33.000000000 -0700
@@ -51,7 +51,7 @@
 	 ACPI_MODULE_NAME    ("nsxfname")
 
 
-/****************************************************************************
+/******************************************************************************
  *
  * FUNCTION:    acpi_get_handle
  *
@@ -119,7 +119,8 @@
 	/*
 	 *  Find the Node and convert to a handle
 	 */
-	status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH, &node);
+	status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH,
+			  &node);
 
 	*ret_handle = NULL;
 	if (ACPI_SUCCESS (status)) {
@@ -130,7 +131,7 @@
 }
 
 
-/****************************************************************************
+/******************************************************************************
  *
  * FUNCTION:    acpi_get_name
  *
@@ -211,7 +212,7 @@
 }
 
 
-/****************************************************************************
+/******************************************************************************
  *
  * FUNCTION:    acpi_get_object_info
  *
@@ -229,22 +230,27 @@
 acpi_status
 acpi_get_object_info (
 	acpi_handle                     handle,
-	struct acpi_device_info         *info)
+	struct acpi_buffer              *buffer)
 {
-	struct acpi_device_id           hid;
-	struct acpi_device_id           uid;
 	acpi_status                     status;
-	u32                             device_status = 0;
-	acpi_integer                    address = 0;
 	struct acpi_namespace_node      *node;
+	struct acpi_device_info         info;
+	struct acpi_device_info         *return_info;
+	struct acpi_compatible_id_list *cid_list = NULL;
+	acpi_size                       size;
 
 
 	/* Parameter validation */
 
-	if (!handle || !info) {
+	if (!handle || !buffer) {
 		return (AE_BAD_PARAMETER);
 	}
 
+	status = acpi_ut_validate_buffer (buffer);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
 	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE (status)) {
 		return (status);
@@ -256,69 +262,94 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	info->type = node->type;
-	info->name = node->name.integer;
+	/* Init return structure */
+
+	size = sizeof (struct acpi_device_info);
+	ACPI_MEMSET (&info, 0, size);
+
+	info.type  = node->type;
+	info.name  = node->name.integer;
+	info.valid = 0;
 
 	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
 
-	/*
-	 * If not a device, we are all done.
-	 */
-	if (info->type != ACPI_TYPE_DEVICE) {
-		return (AE_OK);
-	}
+	/* If not a device, we are all done */
 
+	if (info.type == ACPI_TYPE_DEVICE) {
+		/*
+		 * Get extra info for ACPI Devices objects only:
+		 * Run the Device _HID, _UID, _CID, _STA, and _ADR methods.
+		 *
+		 * Note: none of these methods are required, so they may or may
+		 * not be present for this device.  The Info.Valid bitfield is used
+		 * to indicate which methods were found and ran successfully.
+		 */
+
+		/* Execute the Device._HID method */
+
+		status = acpi_ut_execute_HID (node, &info.hardware_id);
+		if (ACPI_SUCCESS (status)) {
+			info.valid |= ACPI_VALID_HID;
+		}
 
-	/*
-	 * Get extra info for ACPI devices only.  Run the
-	 * _HID, _UID, _STA, and _ADR methods.  Note: none
-	 * of these methods are required, so they may or may
-	 * not be present.  The Info->Valid bits are used
-	 * to indicate which methods ran successfully.
-	 */
-	info->valid = 0;
+		/* Execute the Device._UID method */
 
-	/* Execute the _HID method and save the result */
+		status = acpi_ut_execute_UID (node, &info.unique_id);
+		if (ACPI_SUCCESS (status)) {
+			info.valid |= ACPI_VALID_UID;
+		}
 
-	status = acpi_ut_execute_HID (node, &hid);
-	if (ACPI_SUCCESS (status)) {
-		ACPI_STRNCPY (info->hardware_id, hid.buffer, sizeof(info->hardware_id));
-		info->valid |= ACPI_VALID_HID;
-	}
+		/* Execute the Device._CID method */
 
-	/* Execute the _UID method and save the result */
+		status = acpi_ut_execute_CID (node, &cid_list);
+		if (ACPI_SUCCESS (status)) {
+			size += ((acpi_size) cid_list->count - 1) *
+					 sizeof (struct acpi_compatible_id);
+			info.valid |= ACPI_VALID_CID;
+		}
 
-	status = acpi_ut_execute_UID (node, &uid);
-	if (ACPI_SUCCESS (status)) {
-		ACPI_STRCPY (info->unique_id, uid.buffer);
-		info->valid |= ACPI_VALID_UID;
+		/* Execute the Device._STA method */
+
+		status = acpi_ut_execute_STA (node, &info.current_status);
+		if (ACPI_SUCCESS (status)) {
+			info.valid |= ACPI_VALID_STA;
+		}
+
+		/* Execute the Device._ADR method */
+
+		status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
+				  &info.address);
+		if (ACPI_SUCCESS (status)) {
+			info.valid |= ACPI_VALID_ADR;
+		}
+
+		status = AE_OK;
 	}
 
-	/*
-	 * Execute the _STA method and save the result
-	 * _STA is not always present
-	 */
-	status = acpi_ut_execute_STA (node, &device_status);
-	if (ACPI_SUCCESS (status)) {
-		info->current_status = device_status;
-		info->valid |= ACPI_VALID_STA;
+	/* Validate/Allocate/Clear caller buffer */
+
+	status = acpi_ut_initialize_buffer (buffer, size);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
 	}
 
-	/*
-	 * Execute the _ADR method and save result if successful
-	 * _ADR is not always present
-	 */
-	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR,
-			  node, &address);
+	/* Populate the return buffer */
 
-	if (ACPI_SUCCESS (status)) {
-		info->address = address;
-		info->valid |= ACPI_VALID_ADR;
+	return_info = buffer->pointer;
+	ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info));
+
+	if (cid_list) {
+		ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
 	}
 
-	return (AE_OK);
+
+cleanup:
+	if (cid_list) {
+		ACPI_MEM_FREE (cid_list);
+	}
+	return (status);
 }
 
diff -urN linux-2.5.69-bk16/drivers/acpi/osl.c linux-2.5.69-bk17/drivers/acpi/osl.c
--- linux-2.5.69-bk16/drivers/acpi/osl.c	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/osl.c	2003-05-24 04:33:33.000000000 -0700
@@ -237,7 +237,7 @@
 static irqreturn_t
 acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
-	return (*acpi_irq_handler)(acpi_irq_context);
+	return (*acpi_irq_handler)(acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
 }
 
 acpi_status
@@ -1006,7 +1006,7 @@
 		return 0;
 
 	for (; count-- && str && *str; str++) {
-		if (isalnum(*str) || *str == ' ')
+		if (isalnum(*str) || *str == ' ' || *str == ':')
 			*p++ = *str;
 		else if (*str == '\'' || *str == '"')
 			continue;
diff -urN linux-2.5.69-bk16/drivers/acpi/parser/psargs.c linux-2.5.69-bk17/drivers/acpi/parser/psargs.c
--- linux-2.5.69-bk16/drivers/acpi/parser/psargs.c	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/parser/psargs.c	2003-05-24 04:33:33.000000000 -0700
@@ -350,6 +350,11 @@
 
 				(status != AE_NOT_FOUND)) {
 				ACPI_REPORT_NSERROR (path, status);
+
+				acpi_os_printf ("search_node %p start_node %p return_node %p\n",
+					scope_info.scope.node, parser_state->start_node, node);
+
+
 			}
 			else {
 				/*
diff -urN linux-2.5.69-bk16/drivers/acpi/parser/pswalk.c linux-2.5.69-bk17/drivers/acpi/parser/pswalk.c
--- linux-2.5.69-bk16/drivers/acpi/parser/pswalk.c	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/parser/pswalk.c	2003-05-24 04:33:33.000000000 -0700
@@ -270,7 +270,7 @@
 		return_VOID;
 	}
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, thread);
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, thread);
 	if (!walk_state) {
 		return_VOID;
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/parser/psxface.c linux-2.5.69-bk17/drivers/acpi/parser/psxface.c
--- linux-2.5.69-bk16/drivers/acpi/parser/psxface.c	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/parser/psxface.c	2003-05-24 04:33:33.000000000 -0700
@@ -178,7 +178,7 @@
 
 	/* Create and initialize a new walk state */
 
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
+	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
 	if (!walk_state) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/resources/rsxface.c linux-2.5.69-bk17/drivers/acpi/resources/rsxface.c
--- linux-2.5.69-bk16/drivers/acpi/resources/rsxface.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/resources/rsxface.c	2003-05-24 04:33:33.000000000 -0700
@@ -379,25 +379,31 @@
 {
 	struct acpi_resource_address16      *address16;
 	struct acpi_resource_address32      *address32;
-	struct acpi_resource_address64      *address64;
 
 
 	switch (resource->id) {
 	case ACPI_RSTYPE_ADDRESS16:
+
 		address16 = (struct acpi_resource_address16 *) &resource->data;
 		ACPI_COPY_ADDRESS(out, address16);
 		break;
 
+
 	case ACPI_RSTYPE_ADDRESS32:
+
 		address32 = (struct acpi_resource_address32 *) &resource->data;
 		ACPI_COPY_ADDRESS(out, address32);
 		break;
 
+
 	case ACPI_RSTYPE_ADDRESS64:
-		address64 = (struct acpi_resource_address64 *) &resource->data;
-		ACPI_COPY_ADDRESS(out, address64);
+
+		/* Simple copy for 64 bit source */
+
+		ACPI_MEMCPY (out, &resource->data, sizeof (struct acpi_resource_address64));
 		break;
 
+
 	default:
 		return (AE_BAD_PARAMETER);
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/scan.c linux-2.5.69-bk17/drivers/acpi/scan.c
--- linux-2.5.69-bk16/drivers/acpi/scan.c	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/scan.c	2003-05-24 04:33:33.000000000 -0700
@@ -28,6 +28,8 @@
 static void acpi_device_release(struct kobject * kobj)
 {
 	struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj);
+	if (dev->pnp.cid_list)
+		kfree(dev->pnp.cid_list);
 	kfree(dev);
 }
 
@@ -69,7 +71,7 @@
 		device->kobj.parent = &parent->kobj;
 	device->kobj.ktype = &ktype_acpi_ns;
 	device->kobj.kset = &acpi_namespace_kset;
-	kobject_register(&device->kobj);
+	kobject_add(&device->kobj);
 }
 
 static int
@@ -201,32 +203,15 @@
 			goto Done;
 
 	if (device->flags.compatible_ids) {
-		acpi_status		status = AE_OK;
-		union acpi_object	*object = NULL;
-		char			cid[256] = {};
-
-		status = acpi_evaluate_object(device->handle, "_CID", NULL, 
-			&buffer);
-		if (ACPI_FAILURE(status) || !buffer.pointer)
-			return -ENOENT;
-
-		object = (union acpi_object *) buffer.pointer;
-
-		switch (object->type) {
-		case ACPI_TYPE_INTEGER:
-			acpi_ex_eisa_id_to_string((u32) object->integer.value, 
-				cid);
-			break;
-		case ACPI_TYPE_STRING:
-			strncpy(cid, object->string.pointer, sizeof(cid) - 1);
-			break;
-		case ACPI_TYPE_PACKAGE:
-			/* TBD: Support CID packages */
-			break;
-		}
+		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
+		int i;
 
-		if (strlen(cid) && strstr(driver->ids,cid))
-			goto Done;
+		/* compare multiple _CID entries against driver ids */
+		for (i = 0; i < cid_list->count; i++)
+		{
+			if (strstr(driver->ids, cid_list->id[i].value))
+				goto Done;
+		}
 	}
 	error = -ENOENT;
 
@@ -523,27 +508,30 @@
 static void acpi_device_set_id(struct acpi_device * device, struct acpi_device * parent,
 			       acpi_handle handle, int type)
 {
-	struct acpi_device_info	info;
+	struct acpi_device_info	*info;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 	char			*hid = NULL;
 	char			*uid = NULL;
+	struct acpi_compatible_id_list *cid_list = NULL;
 	acpi_status		status;
 
 	switch (type) {
 	case ACPI_BUS_TYPE_DEVICE:
-		status = acpi_get_object_info(handle, &info);
+		status = acpi_get_object_info(handle, &buffer);
 		if (ACPI_FAILURE(status)) {
 			printk("%s: Error reading device info\n",__FUNCTION__);
 			return;
 		}
-		/* Clean up info strings (not NULL terminated) */
-		info.hardware_id[sizeof(info.hardware_id)-1] = '\0';
-		info.unique_id[sizeof(info.unique_id)-1] = '\0';
-		if (info.valid & ACPI_VALID_HID)
-			hid = info.hardware_id;
-		if (info.valid & ACPI_VALID_UID)
-			uid = info.unique_id;
-		if (info.valid & ACPI_VALID_ADR) {
-			device->pnp.bus_address = info.address;
+
+		info = buffer.pointer;
+		if (info->valid & ACPI_VALID_HID)
+			hid = info->hardware_id.value;
+		if (info->valid & ACPI_VALID_UID)
+			uid = info->unique_id.value;
+		if (info->valid & ACPI_VALID_CID)
+			cid_list = &info->compatibility_id;
+		if (info->valid & ACPI_VALID_ADR) {
+			device->pnp.bus_address = info->address;
 			device->flags.bus_address = 1;
 		}
 		break;
@@ -586,6 +574,15 @@
 		sprintf(device->pnp.unique_id, "%s", uid);
 		device->flags.unique_id = 1;
 	}
+	if (cid_list) {
+		device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL);
+		if (device->pnp.cid_list)
+			memcpy(device->pnp.cid_list, cid_list, cid_list->size);
+		else
+			printk(KERN_ERR "Memory allocation error\n");
+	}
+
+	acpi_os_free(buffer.pointer);
 }
 
 int acpi_device_set_context(struct acpi_device * device, int type)
@@ -781,8 +778,12 @@
 end:
 	if (!result)
 		*child = device;
-	else
+	else {
+		if (device->pnp.cid_list)
+			kfree(device->pnp.cid_list);
 		kfree(device);
+	}
+
 	return_VALUE(result);
 }
 
diff -urN linux-2.5.69-bk16/drivers/acpi/tables/tbconvrt.c linux-2.5.69-bk17/drivers/acpi/tables/tbconvrt.c
--- linux-2.5.69-bk16/drivers/acpi/tables/tbconvrt.c	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/tables/tbconvrt.c	2003-05-24 04:33:33.000000000 -0700
@@ -164,6 +164,36 @@
 }
 
 
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_init_generic_address
+ *
+ * PARAMETERS:  new_gas_struct      - GAS struct to be initialized
+ *              register_bit_width  - Width of this register
+ *              Address             - Address of the register
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize a GAS structure.
+ *
+ ******************************************************************************/
+
+static void
+acpi_tb_init_generic_address (
+	struct acpi_generic_address     *new_gas_struct,
+	u8                              register_bit_width,
+	acpi_physical_address           address)
+{
+
+	ACPI_STORE_ADDRESS (new_gas_struct->address, address);
+
+	new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
+	new_gas_struct->register_bit_width = register_bit_width;
+	new_gas_struct->register_bit_offset = 0;
+	new_gas_struct->reserved        = 0;
+}
+
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_convert_fadt1
@@ -233,14 +263,34 @@
 	/*
 	 * Convert the V1.0 block addresses to V2.0 GAS structures
 	 */
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len, local_fadt->V1_pm1a_evt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len, local_fadt->V1_pm1b_evt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1a_cnt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk,  0,                     local_fadt->V1_gpe0_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk,  0,                     local_fadt->V1_gpe1_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1a_evt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1b_evt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1a_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm1b_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len,
+			  (acpi_physical_address)   local_fadt->V1_pm2_cnt_blk);
+	acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len,
+			  (acpi_physical_address)   local_fadt->V1_pm_tmr_blk);
+	acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0,
+			  (acpi_physical_address)   local_fadt->V1_gpe0_blk);
+	acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0,
+			  (acpi_physical_address)   local_fadt->V1_gpe1_blk);
+
+	/* Create separate GAS structs for the PM1 Enable registers */
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
+		 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		 (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
+		 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		 (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
 }
 
 
@@ -282,44 +332,58 @@
 	}
 
 	if (!(local_fadt->xpm1a_evt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_evt_blk,
-			local_fadt->pm1_evt_len, local_fadt->V1_pm1a_evt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk,
+			local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
 	}
 
 	if (!(local_fadt->xpm1b_evt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_evt_blk,
-			local_fadt->pm1_evt_len, local_fadt->V1_pm1b_evt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk,
+			local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
 	}
 
 	if (!(local_fadt->xpm1a_cnt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_cnt_blk,
-			local_fadt->pm1_cnt_len, local_fadt->V1_pm1a_cnt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk,
+			local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm1b_cnt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk,
-			local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk,
+			local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm2_cnt_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk,
-			local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk,
+			local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm_tmr_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk,
-			local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk);
+		acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk,
+			local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
 	}
 
 	if (!(local_fadt->xgpe0_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk,
-			0, local_fadt->V1_gpe0_blk);
+		acpi_tb_init_generic_address (&local_fadt->xgpe0_blk,
+			0, (acpi_physical_address) local_fadt->V1_gpe0_blk);
 	}
 
 	if (!(local_fadt->xgpe1_blk.address)) {
-		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk,
-			0, local_fadt->V1_gpe1_blk);
+		acpi_tb_init_generic_address (&local_fadt->xgpe1_blk,
+			0, (acpi_physical_address) local_fadt->V1_gpe1_blk);
 	}
+
+	/* Create separate GAS structs for the PM1 Enable registers */
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
+		(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		(acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+	acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id;
+
+	acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
+		(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
+		(acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
+	acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id;
 }
 
 
@@ -396,7 +460,7 @@
 
 	/* Free the original table */
 
-	table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT];
+	table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next;
 	acpi_tb_delete_single_table (table_desc);
 
 	/* Install the new table */
diff -urN linux-2.5.69-bk16/drivers/acpi/tables/tbget.c linux-2.5.69-bk17/drivers/acpi/tables/tbget.c
--- linux-2.5.69-bk16/drivers/acpi/tables/tbget.c	2003-05-04 16:53:33.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/tables/tbget.c	2003-05-24 04:33:33.000000000 -0700
@@ -456,18 +456,18 @@
 	 * instance is always in the list head.
 	 */
 	if (instance == 1) {
-		/*
-		 * Just pluck the pointer out of the global table!
-		 * Will be null if no table is present
-		 */
-		*table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
+		/* Get the first */
+
+		if (acpi_gbl_table_lists[table_type].next) {
+			*table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
+		}
 		return_ACPI_STATUS (AE_OK);
 	}
 
 	/*
 	 * Check for instance out of range
 	 */
-	if (instance > acpi_gbl_acpi_tables[table_type].count) {
+	if (instance > acpi_gbl_table_lists[table_type].count) {
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
 
@@ -478,7 +478,7 @@
 	 * need to walk from the 2nd table until we reach the Instance
 	 * that the user is looking for and return its table pointer.
 	 */
-	table_desc = acpi_gbl_acpi_tables[table_type].next;
+	table_desc = acpi_gbl_table_lists[table_type].next;
 	for (i = 2; i < instance; i++) {
 		table_desc = table_desc->next;
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/tables/tbgetall.c linux-2.5.69-bk17/drivers/acpi/tables/tbgetall.c
--- linux-2.5.69-bk16/drivers/acpi/tables/tbgetall.c	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/tables/tbgetall.c	2003-05-24 04:33:33.000000000 -0700
@@ -307,7 +307,7 @@
 
 	/* Always delete the RSDP mapping, we are done with it */
 
-	acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
+	acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP);
 	return_ACPI_STATUS (status);
 }
 
diff -urN linux-2.5.69-bk16/drivers/acpi/tables/tbinstal.c linux-2.5.69-bk17/drivers/acpi/tables/tbinstal.c
--- linux-2.5.69-bk16/drivers/acpi/tables/tbinstal.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/tables/tbinstal.c	2003-05-24 04:33:33.000000000 -0700
@@ -79,13 +79,13 @@
 	/*
 	 * Search for a signature match among the known table types
 	 */
-	for (i = 0; i < NUM_ACPI_TABLES; i++) {
-		if (!(acpi_gbl_acpi_table_data[i].flags & search_type)) {
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
+		if (!(acpi_gbl_table_data[i].flags & search_type)) {
 			continue;
 		}
 
-		if (!ACPI_STRNCMP (signature, acpi_gbl_acpi_table_data[i].signature,
-				   acpi_gbl_acpi_table_data[i].sig_length)) {
+		if (!ACPI_STRNCMP (signature, acpi_gbl_table_data[i].signature,
+				   acpi_gbl_table_data[i].sig_length)) {
 			/* Found a signature match, return index if requested */
 
 			if (table_info) {
@@ -94,7 +94,7 @@
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 				"Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
-				(char *) acpi_gbl_acpi_table_data[i].signature));
+				(char *) acpi_gbl_table_data[i].signature));
 
 			return_ACPI_STATUS (AE_OK);
 		}
@@ -149,7 +149,7 @@
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
-		acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer));
+		acpi_gbl_table_data[table_info->type].name, table_info->pointer));
 
 	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
 	return_ACPI_STATUS (status);
@@ -239,70 +239,58 @@
 	acpi_table_type                 table_type,
 	struct acpi_table_desc          *table_info)
 {
-	struct acpi_table_desc          *list_head;
+	struct acpi_table_list          *list_head;
 	struct acpi_table_desc          *table_desc;
 
 
 	ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type);
 
+
+	/* Allocate a descriptor for this table */
+
+	table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
+	if (!table_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
 	/*
 	 * Install the table into the global data structure
 	 */
-	list_head   = &acpi_gbl_acpi_tables[table_type];
-	table_desc  = list_head;
+	list_head = &acpi_gbl_table_lists[table_type];
 
 	/*
 	 * Two major types of tables:  1) Only one instance is allowed.  This
 	 * includes most ACPI tables such as the DSDT.  2) Multiple instances of
 	 * the table are allowed.  This includes SSDT and PSDTs.
 	 */
-	if (ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) {
+	if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) {
 		/*
 		 * Only one table allowed, and a table has alread been installed
 		 *  at this location, so return an error.
 		 */
-		if (list_head->pointer) {
+		if (list_head->next) {
 			return_ACPI_STATUS (AE_ALREADY_EXISTS);
 		}
-
-		table_desc->count = 1;
-		table_desc->prev = NULL;
-		table_desc->next = NULL;
 	}
-	else {
-		/*
-		 * Multiple tables allowed for this table type, we must link
-		 * the new table in to the list of tables of this type.
-		 */
-		if (list_head->pointer) {
-			table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
-			if (!table_desc) {
-				return_ACPI_STATUS (AE_NO_MEMORY);
-			}
-
-			list_head->count++;
-
-			/* Update the original previous */
-
-			list_head->prev->next = table_desc;
-
-			/* Update new entry */
 
-			table_desc->prev = list_head->prev;
-			table_desc->next = list_head;
-
-			/* Update list head */
+	/*
+	 * Link the new table in to the list of tables of this type.
+	 * Just insert at the start of the list, order unimportant.
+	 *
+	 * table_desc->Prev is already NULL from calloc()
+	 */
+	table_desc->next = list_head->next;
+	list_head->next = table_desc;
 
-			list_head->prev = table_desc;
-		}
-		else {
-			table_desc->count = 1;
-		}
+	if (table_desc->next) {
+		table_desc->next->prev = table_desc;
 	}
 
-	/* Common initialization of the table descriptor */
+	list_head->count++;
 
-	table_desc->type                = table_info->type;
+	/* Finish initialization of the table descriptor */
+
+	table_desc->type                = (u8) table_type;
 	table_desc->pointer             = table_info->pointer;
 	table_desc->length              = table_info->length;
 	table_desc->allocation          = table_info->allocation;
@@ -316,8 +304,8 @@
 	 * Set the appropriate global pointer (if there is one) to point to the
 	 * newly installed table
 	 */
-	if (acpi_gbl_acpi_table_data[table_type].global_ptr) {
-		*(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer;
+	if (acpi_gbl_table_data[table_type].global_ptr) {
+		*(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer;
 	}
 
 	/* Return Data */
@@ -331,7 +319,7 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_delete_acpi_tables
+ * FUNCTION:    acpi_tb_delete_all_tables
  *
  * PARAMETERS:  None.
  *
@@ -342,7 +330,7 @@
  ******************************************************************************/
 
 void
-acpi_tb_delete_acpi_tables (void)
+acpi_tb_delete_all_tables (void)
 {
 	acpi_table_type                     type;
 
@@ -351,15 +339,15 @@
 	 * Free memory allocated for ACPI tables
 	 * Memory can either be mapped or allocated
 	 */
-	for (type = 0; type < NUM_ACPI_TABLES; type++) {
-		acpi_tb_delete_acpi_table (type);
+	for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) {
+		acpi_tb_delete_tables_by_type (type);
 	}
 }
 
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_delete_acpi_table
+ * FUNCTION:    acpi_tb_delete_tables_by_type
  *
  * PARAMETERS:  Type                - The table type to be deleted
  *
@@ -371,11 +359,15 @@
  ******************************************************************************/
 
 void
-acpi_tb_delete_acpi_table (
+acpi_tb_delete_tables_by_type (
 	acpi_table_type                     type)
 {
+	struct acpi_table_desc          *table_desc;
+	u32                             count;
+	u32                             i;
 
-	ACPI_FUNCTION_TRACE_U32 ("tb_delete_acpi_table", type);
+
+	ACPI_FUNCTION_TRACE_U32 ("tb_delete_tables_by_type", type);
 
 
 	if (type > ACPI_TABLE_MAX) {
@@ -416,43 +408,10 @@
 	}
 
 	/* Free the table */
-
-	acpi_tb_free_acpi_tables_of_type (&acpi_gbl_acpi_tables[type]);
-
-	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
-	return_VOID;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_free_acpi_tables_of_type
- *
- * PARAMETERS:  table_info          - A table info struct
- *
- * RETURN:      None.
- *
- * DESCRIPTION: Free the memory associated with an internal ACPI table
- *              Table mutex should be locked.
- *
- ******************************************************************************/
-
-void
-acpi_tb_free_acpi_tables_of_type (
-	struct acpi_table_desc          *list_head)
-{
-	struct acpi_table_desc          *table_desc;
-	u32                             count;
-	u32                             i;
-
-
-	ACPI_FUNCTION_TRACE_PTR ("tb_free_acpi_tables_of_type", list_head);
-
-
 	/* Get the head of the list */
 
-	table_desc  = list_head;
-	count       = list_head->count;
+	table_desc = acpi_gbl_table_lists[type].next;
+	count     = acpi_gbl_table_lists[type].count;
 
 	/*
 	 * Walk the entire list, deleting both the allocated tables
@@ -462,6 +421,7 @@
 		table_desc = acpi_tb_uninstall_table (table_desc);
 	}
 
+	(void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
 	return_VOID;
 }
 
@@ -484,30 +444,31 @@
 	struct acpi_table_desc          *table_desc)
 {
 
-	if (!table_desc) {
+	/* Must have a valid table descriptor and pointer */
+
+	if ((!table_desc) ||
+		 (!table_desc->pointer)) {
 		return;
 	}
 
-	if (table_desc->pointer) {
-		/* Valid table, determine type of memory allocation */
+	/* Valid table, determine type of memory allocation */
 
-		switch (table_desc->allocation) {
-		case ACPI_MEM_NOT_ALLOCATED:
-			break;
+	switch (table_desc->allocation) {
+	case ACPI_MEM_NOT_ALLOCATED:
+		break;
 
-		case ACPI_MEM_ALLOCATED:
+	case ACPI_MEM_ALLOCATED:
 
-			ACPI_MEM_FREE (table_desc->pointer);
-			break;
+		ACPI_MEM_FREE (table_desc->pointer);
+		break;
 
-		case ACPI_MEM_MAPPED:
+	case ACPI_MEM_MAPPED:
 
-			acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
-			break;
+		acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
+		break;
 
-		default:
-			break;
-		}
+	default:
+		break;
 	}
 }
 
@@ -533,18 +494,23 @@
 	struct acpi_table_desc          *next_desc;
 
 
-	ACPI_FUNCTION_TRACE_PTR ("acpi_tb_uninstall_table", table_desc);
+	ACPI_FUNCTION_TRACE_PTR ("tb_uninstall_table", table_desc);
 
 
 	if (!table_desc) {
 		return_PTR (NULL);
 	}
 
-	/* Unlink the descriptor */
+	/* Unlink the descriptor from the doubly linked list */
 
 	if (table_desc->prev) {
 		table_desc->prev->next = table_desc->next;
 	}
+	else {
+		/* Is first on list, update list head */
+
+		acpi_gbl_table_lists[table_desc->type].next = table_desc->next;
+	}
 
 	if (table_desc->next) {
 		table_desc->next->prev = table_desc->prev;
@@ -554,23 +520,12 @@
 
 	acpi_tb_delete_single_table (table_desc);
 
-	/* Free the table descriptor (Don't delete the list head, tho) */
-
-	if ((table_desc->prev) == (table_desc->next)) {
-		next_desc = NULL;
+	/* Free the table descriptor */
 
-		/* Clear the list head */
+	next_desc = table_desc->next;
+	ACPI_MEM_FREE (table_desc);
 
-		table_desc->pointer  = NULL;
-		table_desc->length   = 0;
-		table_desc->count    = 0;
-	}
-	else {
-		/* Free the table descriptor */
-
-		next_desc = table_desc->next;
-		ACPI_MEM_FREE (table_desc);
-	}
+	/* Return pointer to the next descriptor */
 
 	return_PTR (next_desc);
 }
diff -urN linux-2.5.69-bk16/drivers/acpi/tables/tbutils.c linux-2.5.69-bk17/drivers/acpi/tables/tbutils.c
--- linux-2.5.69-bk16/drivers/acpi/tables/tbutils.c	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/tables/tbutils.c	2003-05-24 04:33:33.000000000 -0700
@@ -66,26 +66,25 @@
 acpi_status
 acpi_tb_handle_to_object (
 	u16                             table_id,
-	struct acpi_table_desc          **table_desc)
+	struct acpi_table_desc          **return_table_desc)
 {
 	u32                             i;
-	struct acpi_table_desc          *list_head;
+	struct acpi_table_desc          *table_desc;
 
 
 	ACPI_FUNCTION_NAME ("tb_handle_to_object");
 
 
 	for (i = 0; i < ACPI_TABLE_MAX; i++) {
-		list_head = &acpi_gbl_acpi_tables[i];
-		do {
-			if (list_head->table_id == table_id) {
-				*table_desc = list_head;
+		table_desc = acpi_gbl_table_lists[i].next;
+		while (table_desc) {
+			if (table_desc->table_id == table_id) {
+				*return_table_desc = table_desc;
 				return (AE_OK);
 			}
 
-			list_head = list_head->next;
-
-		} while (list_head != &acpi_gbl_acpi_tables[i]);
+			table_desc = table_desc->next;
+		}
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
diff -urN linux-2.5.69-bk16/drivers/acpi/tables/tbxface.c linux-2.5.69-bk17/drivers/acpi/tables/tbxface.c
--- linux-2.5.69-bk16/drivers/acpi/tables/tbxface.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/tables/tbxface.c	2003-05-24 04:33:33.000000000 -0700
@@ -235,7 +235,7 @@
 acpi_unload_table (
 	acpi_table_type                 table_type)
 {
-	struct acpi_table_desc          *list_head;
+	struct acpi_table_desc          *table_desc;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_unload_table");
@@ -250,22 +250,22 @@
 
 	/* Find all tables of the requested type */
 
-	list_head = &acpi_gbl_acpi_tables[table_type];
-	do {
+	table_desc = acpi_gbl_table_lists[table_type].next;
+	while (table_desc); {
 		/*
 		 * Delete all namespace entries owned by this table.  Note that these
 		 * entries can appear anywhere in the namespace by virtue of the AML
 		 * "Scope" operator.  Thus, we need to track ownership by an ID, not
 		 * simply a position within the hierarchy
 		 */
-		acpi_ns_delete_namespace_by_owner (list_head->table_id);
+		acpi_ns_delete_namespace_by_owner (table_desc->table_id);
 
-		/* Delete (or unmap) the actual table */
-
-		acpi_tb_delete_acpi_table (table_type);
+		table_desc = table_desc->next;
+	}
 
-	} while (list_head != &acpi_gbl_acpi_tables[table_type]);
+	/* Delete (or unmap) all tables of this type */
 
+	acpi_tb_delete_tables_by_type (table_type);
 	return_ACPI_STATUS (AE_OK);
 }
 
@@ -313,7 +313,7 @@
 	/* Check the table type and instance */
 
 	if ((table_type > ACPI_TABLE_MAX)   ||
-		(ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
+		(ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
 		 instance > 1)) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
@@ -394,7 +394,7 @@
 	/* Check the table type and instance */
 
 	if ((table_type > ACPI_TABLE_MAX)   ||
-		(ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
+		(ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
 		 instance > 1)) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/toshiba_acpi.c linux-2.5.69-bk17/drivers/acpi/toshiba_acpi.c
--- linux-2.5.69-bk16/drivers/acpi/toshiba_acpi.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/toshiba_acpi.c	2003-05-24 04:33:33.000000000 -0700
@@ -33,7 +33,7 @@
  *
  */
 
-#define TOSHIBA_ACPI_VERSION	"0.14"
+#define TOSHIBA_ACPI_VERSION	"0.15"
 #define PROC_INTERFACE_VERSION	1
 
 #include <linux/kernel.h>
@@ -172,9 +172,7 @@
 	for (i = 0; i < HCI_WORDS; ++i) {
 		in_objs[i].type = ACPI_TYPE_INTEGER;
 		in_objs[i].integer.value = in[i];
-		/*printk("%04x ", in[i]);*/
 	}
-	/*printk("\n");*/
 
 	results.length = sizeof(out_objs);
 	results.pointer = out_objs;
@@ -184,9 +182,7 @@
 	if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) {
 		for (i = 0; i < out_objs->package.count; ++i) {
 			out[i] = out_objs->package.elements[i].integer.value;
-			/*printk("%04x ", out[i]);*/
 		}
-		/*printk("\n");*/
 	}
 
 	return status;
@@ -226,7 +222,7 @@
 
 typedef struct _ProcItem
 {
-	char* name;
+	const char* name;
 	char* (*read_func)(char*);
 	unsigned long (*write_func)(const char*, unsigned long);
 } ProcItem;
@@ -284,10 +280,8 @@
 write_lcd(const char* buffer, unsigned long count)
 {
 	int value;
-	/*int byte_count;*/
 	u32 hci_result;
 
-	/* ISSUE: %i doesn't work with hex values as advertised */
 	if (snscanf(buffer, count, " brightness : %i", &value) == 1 &&
 			value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
 		value = value << HCI_LCD_BRIGHTNESS_SHIFT;
@@ -414,6 +408,11 @@
 			last_key_event = value;
 		} else if (hci_result == HCI_EMPTY) {
 			/* better luck next time */
+		} else if (hci_result == HCI_NOT_SUPPORTED) {
+			/* This is a workaround for an unresolved issue on
+			 * some machines where system events sporadically
+			 * become disabled. */
+			hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
 		} else {
 			p += sprintf(p, "ERROR\n");
 			goto end;
diff -urN linux-2.5.69-bk16/drivers/acpi/utilities/utcopy.c linux-2.5.69-bk17/drivers/acpi/utilities/utcopy.c
--- linux-2.5.69-bk16/drivers/acpi/utilities/utcopy.c	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/utilities/utcopy.c	2003-05-24 04:33:33.000000000 -0700
@@ -651,13 +651,21 @@
 		 */
 		if ((source_desc->buffer.pointer) &&
 			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
-			dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
-			if (!dest_desc->buffer.pointer) {
-				return (AE_NO_MEMORY);
-			}
+			dest_desc->buffer.pointer = NULL;
+
+			/* Create an actual buffer only if length > 0 */
 
-			ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer,
-					  source_desc->buffer.length);
+			if (source_desc->buffer.length) {
+				dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
+				if (!dest_desc->buffer.pointer) {
+					return (AE_NO_MEMORY);
+				}
+
+				/* Copy the actual buffer data */
+
+				ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer,
+						  source_desc->buffer.length);
+			}
 		}
 		break;
 
diff -urN linux-2.5.69-bk16/drivers/acpi/utilities/utdelete.c linux-2.5.69-bk17/drivers/acpi/utilities/utdelete.c
--- linux-2.5.69-bk16/drivers/acpi/utilities/utdelete.c	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/utilities/utdelete.c	2003-05-24 04:33:33.000000000 -0700
@@ -71,6 +71,7 @@
 	void                            *obj_pointer = NULL;
 	union acpi_operand_object       *handler_desc;
 	union acpi_operand_object       *second_desc;
+	union acpi_operand_object       *next_desc;
 
 
 	ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object);
@@ -136,6 +137,15 @@
 		if (object->device.gpe_block) {
 			(void) acpi_ev_delete_gpe_block (object->device.gpe_block);
 		}
+
+		/* Walk the handler list for this device */
+
+		handler_desc = object->device.address_space;
+		while (handler_desc) {
+			next_desc = handler_desc->address_space.next;
+			acpi_ut_remove_reference (handler_desc);
+			handler_desc = next_desc;
+		}
 		break;
 
 
@@ -183,10 +193,13 @@
 			 * default handlers -- and therefore, we created the context object
 			 * locally, it was not created by an external caller.
 			 */
-			handler_desc = object->region.addr_handler;
-			if ((handler_desc) &&
-				(handler_desc->addr_handler.hflags == ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
-				obj_pointer = second_desc->extra.region_context;
+			handler_desc = object->region.address_space;
+			if (handler_desc) {
+				if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+					obj_pointer = second_desc->extra.region_context;
+				}
+
+				acpi_ut_remove_reference (handler_desc);
 			}
 
 			/* Now we can free the Extra object */
@@ -211,7 +224,6 @@
 		break;
 	}
 
-
 	/* Free any allocated memory (pointer within the object) found above */
 
 	if (obj_pointer) {
@@ -299,7 +311,7 @@
 	new_count = count;
 
 	/*
-	 * Reference count action (increment, decrement, or force delete)
+	 * Perform the reference count action (increment, decrement, or force delete)
 	 */
 	switch (action) {
 
@@ -402,8 +414,6 @@
 {
 	acpi_status                     status;
 	u32                             i;
-	union acpi_operand_object       *next;
-	union acpi_operand_object       *new;
 	union acpi_generic_state         *state_list = NULL;
 	union acpi_generic_state         *state;
 
@@ -417,9 +427,8 @@
 		return_ACPI_STATUS (AE_OK);
 	}
 
-	/*
-	 * Make sure that this isn't a namespace handle
-	 */
+	/* Make sure that this isn't a namespace handle */
+
 	if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object));
 		return_ACPI_STATUS (AE_OK);
@@ -439,28 +448,8 @@
 		switch (ACPI_GET_OBJECT_TYPE (object)) {
 		case ACPI_TYPE_DEVICE:
 
-			status = acpi_ut_create_update_state_and_push (object->device.addr_handler,
-					   action, &state_list);
-			if (ACPI_FAILURE (status)) {
-				goto error_exit;
-			}
-
-			acpi_ut_update_ref_count (object->device.sys_handler, action);
-			acpi_ut_update_ref_count (object->device.drv_handler, action);
-			break;
-
-
-		case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
-
-			/* Must walk list of address handlers */
-
-			next = object->addr_handler.next;
-			while (next) {
-				new = next->addr_handler.next;
-				acpi_ut_update_ref_count (next, action);
-
-				next = new;
-			}
+			acpi_ut_update_ref_count (object->device.system_notify, action);
+			acpi_ut_update_ref_count (object->device.device_notify, action);
 			break;
 
 
@@ -590,16 +579,14 @@
 	ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object);
 
 
-	/*
-	 * Ensure that we have a valid object
-	 */
+	/* Ensure that we have a valid object */
+
 	if (!acpi_ut_valid_internal_object (object)) {
 		return_VOID;
 	}
 
-	/*
-	 * We have a valid ACPI internal object, now increment the reference count
-	 */
+	/* Increment the reference count */
+
 	(void) acpi_ut_update_object_reference (object, REF_INCREMENT);
 	return_VOID;
 }
@@ -624,6 +611,7 @@
 
 	ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object);
 
+
 	/*
 	 * Allow a NULL pointer to be passed in, just ignore it.  This saves
 	 * each caller from having to check.  Also, ignore NS nodes.
@@ -634,9 +622,8 @@
 		return_VOID;
 	}
 
-	/*
-	 * Ensure that we have a valid object
-	 */
+	/* Ensure that we have a valid object */
+
 	if (!acpi_ut_valid_internal_object (object)) {
 		return_VOID;
 	}
diff -urN linux-2.5.69-bk16/drivers/acpi/utilities/uteval.c linux-2.5.69-bk17/drivers/acpi/utilities/uteval.c
--- linux-2.5.69-bk16/drivers/acpi/utilities/uteval.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/utilities/uteval.c	2003-05-24 04:33:33.000000000 -0700
@@ -210,6 +210,46 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ut_copy_id_string
+ *
+ * PARAMETERS:  Destination         - Where to copy the string
+ *              Source              - Source string
+ *              max_length          - Length of the destination buffer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
+ *              Performs removal of a leading asterisk if present -- workaround
+ *              for a known issue on a bunch of machines.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ut_copy_id_string (
+	char                            *destination,
+	char                            *source,
+	acpi_size                       max_length)
+{
+
+
+	/*
+	 * Workaround for ID strings that have a leading asterisk. This construct
+	 * is not allowed by the ACPI specification  (ID strings must be
+	 * alphanumeric), but enough existing machines have this embedded in their
+	 * ID strings that the following code is useful.
+	 */
+	if (*source == '*') {
+		source++;
+	}
+
+	/* Do the actual copy */
+
+	ACPI_STRNCPY (destination, source, max_length);
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ut_execute_HID
  *
  * PARAMETERS:  device_node         - Node for the device
@@ -245,12 +285,13 @@
 	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 		/* Convert the Numeric HID to string */
 
-		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer);
+		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value);
 	}
 	else {
 		/* Copy the String HID from the returned object */
 
-		ACPI_STRNCPY (hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer));
+		acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer,
+				sizeof (hid->value));
 	}
 
 	/* On exit, we must delete the return object */
@@ -262,6 +303,57 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ut_translate_one_cid
+ *
+ * PARAMETERS:  obj_desc            - _CID object, must be integer or string
+ *              one_cid             - Where the CID string is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Return a numeric or string _CID value as a string.
+ *              (Compatible ID)
+ *
+ *              NOTE:  Assumes a maximum _CID string length of
+ *                     ACPI_MAX_CID_LENGTH.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_translate_one_cid (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_compatible_id       *one_cid)
+{
+
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_INTEGER:
+
+		/* Convert the Numeric CID to string */
+
+		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value);
+		return (AE_OK);
+
+	case ACPI_TYPE_STRING:
+
+		if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
+			return (AE_AML_STRING_LIMIT);
+		}
+
+		/* Copy the String CID from the returned object */
+
+		acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer,
+				ACPI_MAX_CID_LENGTH);
+		return (AE_OK);
+
+	default:
+
+		return (AE_TYPE);
+	}
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ut_execute_CID
  *
  * PARAMETERS:  device_node         - Node for the device
@@ -279,55 +371,86 @@
 acpi_status
 acpi_ut_execute_CID (
 	struct acpi_namespace_node      *device_node,
-	struct acpi_device_id           *cid)
+	struct acpi_compatible_id_list **return_cid_list)
 {
 	union acpi_operand_object       *obj_desc;
 	acpi_status                     status;
+	u32                             count;
+	u32                             size;
+	struct acpi_compatible_id_list *cid_list;
+	acpi_native_uint                i;
 
 
 	ACPI_FUNCTION_TRACE ("ut_execute_CID");
 
 
+	/* Evaluate the _CID method for this device */
+
 	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
-			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, &obj_desc);
+			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
+			 &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	/*
-	 *  A _CID can return either a single compatible ID or a package of compatible
-	 *  IDs.  Each compatible ID can be a Number (32 bit compressed EISA ID) or
-	 *  string (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
-	 */
-	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
-	case ACPI_TYPE_INTEGER:
+	/* Get the number of _CIDs returned */
 
-		/* Convert the Numeric CID to string */
+	count = 1;
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+		count = obj_desc->package.count;
+	}
 
-		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, cid->buffer);
-		break;
+	/* Allocate a worst-case buffer for the _CIDs */
 
-	case ACPI_TYPE_STRING:
+	size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
+			   sizeof (struct acpi_compatible_id_list));
 
-		/* Copy the String CID from the returned object */
+	cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
+	if (!cid_list) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
 
-		ACPI_STRNCPY (cid->buffer, obj_desc->string.pointer, sizeof (cid->buffer));
-		break;
+	/* Init CID list */
 
-	case ACPI_TYPE_PACKAGE:
+	cid_list->count = count;
+	cid_list->size = size;
 
-		/* TBD: Parse package elements; need different return struct, etc. */
+	/*
+	 *  A _CID can return either a single compatible ID or a package of compatible
+	 *  IDs.  Each compatible ID can be one of the following:
+	 *  -- Number (32 bit compressed EISA ID) or
+	 *  -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
+	 */
 
-		status = AE_SUPPORT;
-		break;
+	/* The _CID object can be either a single CID or a package (list) of CIDs */
 
-	default:
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
+		/* Translate each package element */
 
-		status = AE_TYPE;
-		break;
+		for (i = 0; i < count; i++) {
+			status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
+					  &cid_list->id[i]);
+			if (ACPI_FAILURE (status)) {
+				break;
+			}
+		}
 	}
+	else {
+		/* Only one CID, translate to a string */
 
-	/* On exit, we must delete the return object */
+		status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
+	}
+
+	/* Cleanup on error */
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_MEM_FREE (cid_list);
+	}
+	else {
+		*return_cid_list = cid_list;
+	}
+
+	/* On exit, we must delete the _CID return object */
 
 	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
@@ -371,12 +494,13 @@
 	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 		/* Convert the Numeric UID to string */
 
-		acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer);
+		acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
 	}
 	else {
 		/* Copy the String UID from the returned object */
 
-		ACPI_STRNCPY (uid->buffer, obj_desc->string.pointer, sizeof (uid->buffer));
+		acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
+				sizeof (uid->value));
 	}
 
 	/* On exit, we must delete the return object */
diff -urN linux-2.5.69-bk16/drivers/acpi/utilities/utglobal.c linux-2.5.69-bk17/drivers/acpi/utilities/utglobal.c
--- linux-2.5.69-bk16/drivers/acpi/utilities/utglobal.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/utilities/utglobal.c	2003-05-24 04:33:33.000000000 -0700
@@ -299,10 +299,10 @@
  ******************************************************************************/
 
 
-struct acpi_table_desc              acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
+struct acpi_table_list              acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
 
 
-struct acpi_table_support           acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] =
+struct acpi_table_support           acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
 {
 	/***********    Name,   Signature, Global typed pointer     Signature size,      Type                  How many allowed?,    Contains valid AML? */
 
@@ -535,12 +535,10 @@
 
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-
 /*
  * Strings and procedures used for debug only
  */
 
-
 /*****************************************************************************
  *
  * FUNCTION:    acpi_ut_get_mutex_name
@@ -558,7 +556,7 @@
 	u32                             mutex_id)
 {
 
-	if (mutex_id > MAX_MTX)
+	if (mutex_id > MAX_MUTEX)
 	{
 		return ("Invalid Mutex ID");
 	}
@@ -566,7 +564,6 @@
 	return (acpi_gbl_mutex_names[mutex_id]);
 }
 
-
 #endif
 
 
@@ -630,9 +627,12 @@
 		owner_id = acpi_gbl_next_table_owner_id;
 		acpi_gbl_next_table_owner_id++;
 
+		/* Check for wraparound */
+
 		if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID)
 		{
 			acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
+			ACPI_REPORT_WARNING (("Table owner ID wraparound\n"));
 		}
 		break;
 
@@ -644,6 +644,8 @@
 
 		if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID)
 		{
+			/* Check for wraparound */
+
 			acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
 		}
 		break;
@@ -710,23 +712,19 @@
 
 	/* ACPI table structure */
 
-	for (i = 0; i < NUM_ACPI_TABLES; i++)
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
 	{
-		acpi_gbl_acpi_tables[i].prev        = &acpi_gbl_acpi_tables[i];
-		acpi_gbl_acpi_tables[i].next        = &acpi_gbl_acpi_tables[i];
-		acpi_gbl_acpi_tables[i].pointer     = NULL;
-		acpi_gbl_acpi_tables[i].length      = 0;
-		acpi_gbl_acpi_tables[i].allocation  = ACPI_MEM_NOT_ALLOCATED;
-		acpi_gbl_acpi_tables[i].count       = 0;
+		acpi_gbl_table_lists[i].next        = NULL;
+		acpi_gbl_table_lists[i].count       = 0;
 	}
 
 	/* Mutex locked flags */
 
-	for (i = 0; i < NUM_MTX; i++)
+	for (i = 0; i < NUM_MUTEX; i++)
 	{
-		acpi_gbl_acpi_mutex_info[i].mutex   = NULL;
-		acpi_gbl_acpi_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
-		acpi_gbl_acpi_mutex_info[i].use_count = 0;
+		acpi_gbl_mutex_info[i].mutex        = NULL;
+		acpi_gbl_mutex_info[i].owner_id     = ACPI_MUTEX_NOT_ACQUIRED;
+		acpi_gbl_mutex_info[i].use_count    = 0;
 	}
 
 	/* GPE support */
@@ -737,8 +735,8 @@
 
 	/* Global notify handlers */
 
-	acpi_gbl_sys_notify.handler         = NULL;
-	acpi_gbl_drv_notify.handler         = NULL;
+	acpi_gbl_system_notify.handler      = NULL;
+	acpi_gbl_device_notify.handler      = NULL;
 	acpi_gbl_init_handler               = NULL;
 
 	/* Global "typed" ACPI table pointers */
diff -urN linux-2.5.69-bk16/drivers/acpi/utilities/utmisc.c linux-2.5.69-bk17/drivers/acpi/utilities/utmisc.c
--- linux-2.5.69-bk16/drivers/acpi/utilities/utmisc.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/utilities/utmisc.c	2003-05-24 04:33:33.000000000 -0700
@@ -549,7 +549,7 @@
 	/*
 	 * Create each of the predefined mutex objects
 	 */
-	for (i = 0; i < NUM_MTX; i++) {
+	for (i = 0; i < NUM_MUTEX; i++) {
 		status = acpi_ut_create_mutex (i);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
@@ -588,7 +588,7 @@
 	/*
 	 * Delete each predefined mutex object
 	 */
-	for (i = 0; i < NUM_MTX; i++) {
+	for (i = 0; i < NUM_MUTEX; i++) {
 		(void) acpi_ut_delete_mutex (i);
 	}
 
@@ -619,15 +619,15 @@
 	ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id);
 
 
-	if (mutex_id > MAX_MTX) {
+	if (mutex_id > MAX_MUTEX) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	if (!acpi_gbl_acpi_mutex_info[mutex_id].mutex) {
+	if (!acpi_gbl_mutex_info[mutex_id].mutex) {
 		status = acpi_os_create_semaphore (1, 1,
-				  &acpi_gbl_acpi_mutex_info[mutex_id].mutex);
-		acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
-		acpi_gbl_acpi_mutex_info[mutex_id].use_count = 0;
+				  &acpi_gbl_mutex_info[mutex_id].mutex);
+		acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+		acpi_gbl_mutex_info[mutex_id].use_count = 0;
 	}
 
 	return_ACPI_STATUS (status);
@@ -656,14 +656,14 @@
 	ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id);
 
 
-	if (mutex_id > MAX_MTX) {
+	if (mutex_id > MAX_MUTEX) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	status = acpi_os_delete_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex);
+	status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex);
 
-	acpi_gbl_acpi_mutex_info[mutex_id].mutex = NULL;
-	acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+	acpi_gbl_mutex_info[mutex_id].mutex = NULL;
+	acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
 
 	return_ACPI_STATUS (status);
 }
@@ -693,7 +693,7 @@
 	ACPI_FUNCTION_NAME ("ut_acquire_mutex");
 
 
-	if (mutex_id > MAX_MTX) {
+	if (mutex_id > MAX_MUTEX) {
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -705,8 +705,8 @@
 	 * the mutex ordering rule.  This indicates a coding error somewhere in
 	 * the ACPI subsystem code.
 	 */
-	for (i = mutex_id; i < MAX_MTX; i++) {
-		if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) {
+	for (i = mutex_id; i < MAX_MUTEX; i++) {
+		if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
 			if (i == mutex_id) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 						"Mutex [%s] already acquired by this thread [%X]\n",
@@ -728,14 +728,14 @@
 			 "Thread %X attempting to acquire Mutex [%s]\n",
 			 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
 
-	status = acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex,
+	status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
 			   1, ACPI_WAIT_FOREVER);
 	if (ACPI_SUCCESS (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
 				 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
 
-		acpi_gbl_acpi_mutex_info[mutex_id].use_count++;
-		acpi_gbl_acpi_mutex_info[mutex_id].owner_id = this_thread_id;
+		acpi_gbl_mutex_info[mutex_id].use_count++;
+		acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
 	}
 	else {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
@@ -776,14 +776,14 @@
 		"Thread %X releasing Mutex [%s]\n", this_thread_id,
 		acpi_ut_get_mutex_name (mutex_id)));
 
-	if (mutex_id > MAX_MTX) {
+	if (mutex_id > MAX_MUTEX) {
 		return (AE_BAD_PARAMETER);
 	}
 
 	/*
 	 * Mutex must be acquired in order to release it!
 	 */
-	if (acpi_gbl_acpi_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
+	if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Mutex [%s] is not acquired, cannot release\n",
 				acpi_ut_get_mutex_name (mutex_id)));
@@ -797,8 +797,8 @@
 	 * ordering rule.  This indicates a coding error somewhere in
 	 * the ACPI subsystem code.
 	 */
-	for (i = mutex_id; i < MAX_MTX; i++) {
-		if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) {
+	for (i = mutex_id; i < MAX_MUTEX; i++) {
+		if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
 			if (i == mutex_id) {
 				continue;
 			}
@@ -813,9 +813,9 @@
 
 	/* Mark unlocked FIRST */
 
-	acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+	acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
 
-	status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1);
+	status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
 
 	if (ACPI_FAILURE (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
diff -urN linux-2.5.69-bk16/drivers/acpi/utilities/utobject.c linux-2.5.69-bk17/drivers/acpi/utilities/utobject.c
--- linux-2.5.69-bk16/drivers/acpi/utilities/utobject.c	2003-05-04 16:53:33.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/utilities/utobject.c	2003-05-24 04:33:33.000000000 -0700
@@ -149,7 +149,7 @@
 	acpi_size                       buffer_size)
 {
 	union acpi_operand_object       *buffer_desc;
-	u8                              *buffer;
+	u8                              *buffer = NULL;
 
 
 	ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);
@@ -163,14 +163,18 @@
 		return_PTR (NULL);
 	}
 
-	/* Allocate the actual buffer */
+	/* Create an actual buffer only if size > 0 */
 
-	buffer = ACPI_MEM_CALLOCATE (buffer_size);
-	if (!buffer) {
-		ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
-			(u32) buffer_size));
-		acpi_ut_remove_reference (buffer_desc);
-		return_PTR (NULL);
+	if (buffer_size > 0) {
+		/* Allocate the actual buffer */
+
+		buffer = ACPI_MEM_CALLOCATE (buffer_size);
+		if (!buffer) {
+			ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
+				(u32) buffer_size));
+			acpi_ut_remove_reference (buffer_desc);
+			return_PTR (NULL);
+		}
 	}
 
 	/* Complete buffer object initialization */
diff -urN linux-2.5.69-bk16/drivers/acpi/utilities/utxface.c linux-2.5.69-bk17/drivers/acpi/utilities/utxface.c
--- linux-2.5.69-bk16/drivers/acpi/utilities/utxface.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/drivers/acpi/utilities/utxface.c	2003-05-24 04:33:33.000000000 -0700
@@ -145,22 +145,8 @@
 
 
 	/*
-	 * Install the default op_region handlers. These are installed unless
-	 * other handlers have already been installed via the
-	 * install_address_space_handler interface
-	 */
-	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
-
-		status = acpi_ev_init_address_spaces ();
-		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
-		}
-	}
-
-	/*
 	 * We must initialize the hardware before we can enable ACPI.
-	 * FADT values are validated here.
+	 * The values from the FADT are validated here.
 	 */
 	if (!(flags & ACPI_NO_HARDWARE_INIT)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n"));
@@ -172,7 +158,7 @@
 	}
 
 	/*
-	 * Enable ACPI on this platform
+	 * Enable ACPI mode
 	 */
 	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
@@ -187,8 +173,9 @@
 	}
 
 	/*
-	 * Note:
-	 * We must have the hardware AND events initialized before we can execute
+	 * Initialize ACPI Event handling
+	 *
+	 * NOTE: We must have the hardware AND events initialized before we can execute
 	 * ANY control methods SAFELY.  Any control method can require ACPI hardware
 	 * support, so the hardware MUST be initialized before execution!
 	 */
@@ -201,7 +188,7 @@
 		}
 	}
 
-	/* Install SCI handler, Global Lock handler, GPE handlers */
+	/* Install the SCI handler, Global Lock handler, and GPE handlers */
 
 	if (!(flags & ACPI_NO_HANDLER_INIT)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL/GPE handlers\n"));
@@ -237,14 +224,20 @@
 
 	ACPI_FUNCTION_TRACE ("acpi_initialize_objects");
 
+
 	/*
-	 * Initialize all device objects in the namespace
-	 * This runs the _STA and _INI methods.
+	 * Install the default op_region handlers. These are installed unless
+	 * other handlers have already been installed via the
+	 * install_address_space_handler interface.
+	 *
+	 * NOTE: This will cause _REG methods to be run.  Any objects accessed
+	 * by the _REG methods will be automatically initialized, even if they
+	 * contain executable AML (see call to acpi_ns_initialize_objects below).
 	 */
-	if (!(flags & ACPI_NO_DEVICE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
 
-		status = acpi_ns_initialize_devices ();
+		status = acpi_ev_init_address_spaces ();
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -252,8 +245,8 @@
 
 	/*
 	 * Initialize the objects that remain uninitialized.  This
-	 * runs the executable AML that is part of the declaration of op_regions
-	 * and Fields.
+	 * runs the executable AML that may be part of the declaration of these
+	 * objects: operation_regions, buffer_fields, Buffers, and Packages.
 	 */
 	if (!(flags & ACPI_NO_OBJECT_INIT)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n"));
@@ -265,6 +258,19 @@
 	}
 
 	/*
+	 * Initialize all device objects in the namespace
+	 * This runs the _STA and _INI methods.
+	 */
+	if (!(flags & ACPI_NO_DEVICE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
+
+		status = acpi_ns_initialize_devices ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
 	 * Empty the caches (delete the cached objects) on the assumption that
 	 * the table load filled them up more than they will be at runtime --
 	 * thus wasting non-paged memory.
@@ -431,9 +437,9 @@
 
 	/* Current status of the ACPI tables, per table type */
 
-	info_ptr->num_table_types = NUM_ACPI_TABLES;
-	for (i = 0; i < NUM_ACPI_TABLES; i++) {
-		info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count;
+	info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES;
+	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
+		info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
 	}
 
 	return_ACPI_STATUS (AE_OK);
diff -urN linux-2.5.69-bk16/drivers/ide/ide-disk.c linux-2.5.69-bk17/drivers/ide/ide-disk.c
--- linux-2.5.69-bk16/drivers/ide/ide-disk.c	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/ide-disk.c	2003-05-24 04:33:33.000000000 -0700
@@ -247,7 +247,7 @@
  *
  * Returns 0 on success.
  *
- * Note that we may be called from two contexts - the do_rw_disk context
+ * Note that we may be called from two contexts - __ide_do_rw_disk() context
  * and IRQ context. The IRQ can happen any time after we've output the
  * full "mcount" number of sectors, so we must make sure we update the
  * state _before_ we output the final part of the data!
@@ -351,11 +351,11 @@
 }
 
 /*
- * do_rw_disk() issues READ and WRITE commands to a disk,
+ * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
  * using LBA if supported, or CHS otherwise, to address sectors.
  * It also takes care of issuing special DRIVE_CMDs.
  */
-static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 lba48		= (drive->addressing == 1) ? 1 : 0;
@@ -367,11 +367,6 @@
 	if (driver_blocked)
 		panic("Request while ide driver is blocked?");
 
-#if defined(CONFIG_BLK_DEV_PDC4030) || defined(CONFIG_BLK_DEV_PDC4030_MODULE)
-	if (IS_PDC4030_DRIVE)
-		return promise_rw_disk(drive, rq, block);
-#endif /* CONFIG_BLK_DEV_PDC4030 */
-
 	if (drive->using_tcq && idedisk_start_tag(drive, rq)) {
 		if (!ata_pending_commands(drive))
 			BUG();
@@ -550,10 +545,11 @@
 		}
 		return ide_started;
 	}
-	blk_dump_rq_flags(rq, "do_rw_disk - bad command");
+	blk_dump_rq_flags(rq, "__ide_do_rw_disk - bad command");
 	ide_end_request(drive, 0, 0);
 	return ide_stopped;
 }
+EXPORT_SYMBOL_GPL(__ide_do_rw_disk);
 
 #else /* CONFIG_IDE_TASKFILE_IO */
 
@@ -562,15 +558,15 @@
 static ide_startstop_t lba_48_rw_disk(ide_drive_t *, struct request *, unsigned long long);
 
 /*
- * do_rw_disk() issues READ and WRITE commands to a disk,
+ * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
  * using LBA if supported, or CHS otherwise, to address sectors.
  * It also takes care of issuing special DRIVE_CMDs.
  */
-static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	BUG_ON(drive->blocked);
 	if (!blk_fs_request(rq)) {
-		blk_dump_rq_flags(rq, "do_rw_disk - bad command");
+		blk_dump_rq_flags(rq, "__ide_do_rw_disk - bad command");
 		ide_end_request(drive, 0, 0);
 		return ide_stopped;
 	}
@@ -581,11 +577,6 @@
 	 * need to add split taskfile operations based on 28bit threshold.
 	 */
 
-#if defined(CONFIG_BLK_DEV_PDC4030) || defined(CONFIG_BLK_DEV_PDC4030_MODULE)
-        if (IS_PDC4030_DRIVE)
-                return promise_rw_disk(drive, rq, block);
-#endif /* CONFIG_BLK_DEV_PDC4030 */
-
 	if (drive->using_tcq && idedisk_start_tag(drive, rq)) {
 		if (!ata_pending_commands(drive))
 			BUG();
@@ -601,6 +592,7 @@
 	/* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */
 	return chs_rw_disk(drive, rq, (unsigned long) block);
 }
+EXPORT_SYMBOL_GPL(__ide_do_rw_disk);
 
 static task_ioreg_t get_command (ide_drive_t *drive, int cmd)
 {
@@ -760,6 +752,16 @@
 
 #endif /* CONFIG_IDE_TASKFILE_IO */
 
+static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+
+	if (hwif->rw_disk)
+		return hwif->rw_disk(drive, rq, block);
+	else
+		return __ide_do_rw_disk(drive, rq, block);
+}
+
 static int do_idedisk_flushcache(ide_drive_t *drive);
 
 static u8 idedisk_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
@@ -1541,11 +1543,6 @@
 	struct hd_driveid *id = drive->id;
 	unsigned long capacity;
 
-#if 0
-	if (IS_PDC4030_DRIVE)
-		DRIVER(drive)->do_request = promise_rw_disk;
-#endif
-	
 	idedisk_add_settings(drive);
 
 	if (drive->id_read == 0)
@@ -1674,7 +1671,7 @@
 	.supports_dsc_overlap	= 0,
 	.cleanup		= idedisk_cleanup,
 	.flushcache		= do_idedisk_flushcache,
-	.do_request		= do_rw_disk,
+	.do_request		= ide_do_rw_disk,
 	.sense			= idedisk_dump_status,
 	.error			= idedisk_error,
 	.abort			= idedisk_abort,
diff -urN linux-2.5.69-bk16/drivers/ide/ide.c linux-2.5.69-bk17/drivers/ide/ide.c
--- linux-2.5.69-bk16/drivers/ide/ide.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/ide.c	2003-05-24 04:33:33.000000000 -0700
@@ -913,6 +913,8 @@
 		}
 		for (index = 0; index < MAX_HWIFS; ++index) {
 			hwif = &ide_hwifs[index];
+			if (hwif->hold)
+				continue;
 			if ((!hwif->present && !hwif->mate && !initializing) ||
 			    (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing))
 				goto found;
@@ -924,6 +926,8 @@
 found:
 	if (hwif->present)
 		ide_unregister(index);
+	else if (!hwif->hold)
+		init_hwif_data(index);
 	if (hwif->present)
 		return -1;
 	memcpy(&hwif->hw, hw, sizeof(*hw));
diff -urN linux-2.5.69-bk16/drivers/ide/legacy/ali14xx.c linux-2.5.69-bk17/drivers/ide/legacy/ali14xx.c
--- linux-2.5.69-bk16/drivers/ide/legacy/ali14xx.c	2003-05-04 16:53:06.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/legacy/ali14xx.c	2003-05-24 04:33:33.000000000 -0700
@@ -54,13 +54,7 @@
 
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_ALI14XX_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_ALI14XX_MODULE */
+#include "ide_modes.h"
 
 /* port addresses for auto-detection */
 #define ALI_NUM_PORTS 4
diff -urN linux-2.5.69-bk16/drivers/ide/legacy/dtc2278.c linux-2.5.69-bk17/drivers/ide/legacy/dtc2278.c
--- linux-2.5.69-bk16/drivers/ide/legacy/dtc2278.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/legacy/dtc2278.c	2003-05-24 04:33:33.000000000 -0700
@@ -21,13 +21,7 @@
 
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_DTC2278_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_DTC2278_MODULE */
+#include "ide_modes.h"
 
 /*
  * Changing this #undef to #define may solve start up problems in some systems.
diff -urN linux-2.5.69-bk16/drivers/ide/legacy/ht6560b.c linux-2.5.69-bk17/drivers/ide/legacy/ht6560b.c
--- linux-2.5.69-bk16/drivers/ide/legacy/ht6560b.c	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/legacy/ht6560b.c	2003-05-24 04:33:33.000000000 -0700
@@ -53,13 +53,7 @@
 
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_HT6560B_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_HT6560B_MODULE */
+#include "ide_modes.h"
 
 /* #define DEBUG */  /* remove comments for DEBUG messages */
 
diff -urN linux-2.5.69-bk16/drivers/ide/legacy/pdc4030.c linux-2.5.69-bk17/drivers/ide/legacy/pdc4030.c
--- linux-2.5.69-bk16/drivers/ide/legacy/pdc4030.c	2003-05-04 16:53:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/legacy/pdc4030.c	2003-05-24 04:33:33.000000000 -0700
@@ -94,6 +94,8 @@
 
 #include "pdc4030.h"
 
+static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block);
+
 /*
  * promise_selectproc() is invoked by ide.c
  * in preparation for access to the specified drive.
@@ -231,6 +233,10 @@
 	/* DC4030 hosted drives need their own identify... */
 	hwif->identify = hwif2->identify = &pdc4030_identify;
 
+	/* Override the normal ide disk read/write. */
+	hwif->rw_disk = promise_rw_disk;
+	hwif2->rw_disk = promise_rw_disk;
+
 	/* Shift the remaining interfaces up by one */
 	for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) {
 		ide_hwif_t *h = &ide_hwifs[i];
@@ -803,7 +809,7 @@
 	}
 }
 
-ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
 {
 	/* The four drives on the two logical (one physical) interfaces
 	   are distinguished by writing the drive number (0-3) to the
diff -urN linux-2.5.69-bk16/drivers/ide/legacy/qd65xx.c linux-2.5.69-bk17/drivers/ide/legacy/qd65xx.c
--- linux-2.5.69-bk16/drivers/ide/legacy/qd65xx.c	2003-05-04 16:53:03.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/legacy/qd65xx.c	2003-05-24 04:33:33.000000000 -0700
@@ -42,14 +42,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_QD65XX_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_QD65XX_MODULE */
-
+#include "ide_modes.h"
 #include "qd65xx.h"
 
 /*
diff -urN linux-2.5.69-bk16/drivers/ide/legacy/umc8672.c linux-2.5.69-bk17/drivers/ide/legacy/umc8672.c
--- linux-2.5.69-bk16/drivers/ide/legacy/umc8672.c	2003-05-04 16:53:03.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/legacy/umc8672.c	2003-05-24 04:33:33.000000000 -0700
@@ -54,13 +54,7 @@
 
 #include <asm/io.h>
 
-#ifdef CONFIG_BLK_DEV_UMC8672_MODULE
-# define _IDE_C
-# include "ide_modes.h"
-# undef _IDE_C
-#else
-# include "ide_modes.h"
-#endif /* CONFIG_BLK_DEV_UMC8672_MODULE */
+#include "ide_modes.h"
 
 /*
  * Default speeds.  These can be changed with "auto-tune" and/or hdparm.
diff -urN linux-2.5.69-bk16/drivers/ide/pci/amd74xx.c linux-2.5.69-bk17/drivers/ide/pci/amd74xx.c
--- linux-2.5.69-bk16/drivers/ide/pci/amd74xx.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/pci/amd74xx.c	2003-05-24 04:33:33.000000000 -0700
@@ -313,7 +313,8 @@
 
 		case AMD_UDMA_100:
 			pci_read_config_byte(dev, AMD_CABLE_DETECT, &t);
-			amd_80w = ((u & 0x3) ? 1 : 0) | ((u & 0xc) ? 2 : 0);
+			pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
+			amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0);
 			for (i = 24; i >= 0; i -= 8)
 				if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) {
 					printk(KERN_WARNING "AMD_IDE: Bios didn't set cable bits correctly. Enabling workaround.\n");
@@ -383,11 +384,6 @@
 	return 0;
 }
 
-static unsigned int __init ata66_amd74xx(ide_hwif_t *hwif)
-{
-	return ((amd_enabled & amd_80w) >> hwif->channel) & 1;
-}
-
 static void __init init_hwif_amd74xx(ide_hwif_t *hwif)
 {
 	int i;
diff -urN linux-2.5.69-bk16/drivers/ide/pci/amd74xx.h linux-2.5.69-bk17/drivers/ide/pci/amd74xx.h
--- linux-2.5.69-bk16/drivers/ide/pci/amd74xx.h	2003-05-04 16:53:00.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/pci/amd74xx.h	2003-05-24 04:33:33.000000000 -0700
@@ -40,7 +40,7 @@
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},{	/* 1 */
@@ -53,7 +53,7 @@
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},{	/* 2 */
@@ -66,7 +66,7 @@
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},{	/* 3 */
@@ -79,7 +79,7 @@
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},{	/* 4 */
@@ -92,7 +92,7 @@
 		.init_dma	= init_dma_amd74xx,
 		.autodma	= AUTODMA,
 		.channels	= 2,
-		.enablebits	= {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
+		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0
 	},
@@ -106,7 +106,7 @@
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x50,0x01,0x01}, {0x50,0x02,0x02}},
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
 	},
@@ -120,7 +120,7 @@
 		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
-		.enablebits	= {{0x50,0x01,0x01}, {0x50,0x02,0x02}},
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
 	},
diff -urN linux-2.5.69-bk16/drivers/ide/pci/piix.c linux-2.5.69-bk17/drivers/ide/pci/piix.c
--- linux-2.5.69-bk16/drivers/ide/pci/piix.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/pci/piix.c	2003-05-24 04:33:33.000000000 -0700
@@ -142,6 +142,9 @@
 		p += sprintf(p, "\nController: %d\n", i);
 		p += sprintf(p, "\n                                Intel ");
 		switch(dev->device) {
+			case PCI_DEVICE_ID_INTEL_82801EB_1:
+				p += sprintf(p, "PIIX4 SATA 150 ");
+				break;
 			case PCI_DEVICE_ID_INTEL_82801BA_8:
 			case PCI_DEVICE_ID_INTEL_82801BA_9:
 			case PCI_DEVICE_ID_INTEL_82801CA_10:
@@ -275,6 +278,9 @@
 	u8 mode;
 
 	switch(dev->device) {
+		case PCI_DEVICE_ID_INTEL_82801EB_1:
+			mode = 3;
+			break;
 		/* UDMA 100 capable */
 		case PCI_DEVICE_ID_INTEL_82801BA_8:
 		case PCI_DEVICE_ID_INTEL_82801BA_9:
@@ -325,6 +331,7 @@
  
 static u8 piix_dma_2_pio (u8 xfer_rate) {
 	switch(xfer_rate) {
+		case XFER_UDMA_6:
 		case XFER_UDMA_5:
 		case XFER_UDMA_4:
 		case XFER_UDMA_3:
@@ -603,6 +610,7 @@
 static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
 {
         switch(dev->device) {
+		case PCI_DEVICE_ID_INTEL_82801EB_1:
 		case PCI_DEVICE_ID_INTEL_82801AA_1:
 		case PCI_DEVICE_ID_INTEL_82801AB_1:
 		case PCI_DEVICE_ID_INTEL_82801BA_8:
@@ -803,6 +811,7 @@
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17},
+ 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18},
 	{ 0, },
 };
 
diff -urN linux-2.5.69-bk16/drivers/ide/pci/piix.h linux-2.5.69-bk17/drivers/ide/pci/piix.h
--- linux-2.5.69-bk16/drivers/ide/pci/piix.h	2003-05-04 16:53:07.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/pci/piix.h	2003-05-24 04:33:33.000000000 -0700
@@ -291,10 +291,10 @@
 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
-	},{	/* 17 */
+	},{	/* 18 */
 		.vendor		= PCI_VENDOR_ID_INTEL,
-		.device		= PCI_DEVICE_ID_INTEL_82801DB_10,
-		.name		= "ICH4",
+		.device		= PCI_DEVICE_ID_INTEL_82801EB_1,
+		.name		= "ICH5-SATA",
 		.init_setup	= init_setup_piix,
 		.init_chipset	= init_chipset_piix,
 		.init_iops	= NULL,
diff -urN linux-2.5.69-bk16/drivers/ide/pci/serverworks.c linux-2.5.69-bk17/drivers/ide/pci/serverworks.c
--- linux-2.5.69-bk16/drivers/ide/pci/serverworks.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/pci/serverworks.c	2003-05-24 04:33:33.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/serverworks.c		Version 0.7	10 Sept 2002
+ * linux/drivers/ide/pci/serverworks.c		Version 0.8	 25 Ebr 2003
  *
  * Copyright (C) 1998-2000 Michel Aubry
  * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -203,11 +203,22 @@
 }
 #endif  /* defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) */
 
+static int check_in_drive_lists (ide_drive_t *drive, const char **list)
+{
+	while (*list)
+		if (!strcmp(*list++, drive->id->model))
+			return 1;
+	return 0;
+}
+
 static u8 svwks_ratemask (ide_drive_t *drive)
 {
 	struct pci_dev *dev     = HWIF(drive)->pci_dev;
 	u8 mode;
 
+	if (!svwks_revision)
+		pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
+
 	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
 		u32 reg = 0;
 		if (isa_dev)
@@ -225,9 +236,13 @@
 	} else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) {
 		u8 btr = 0;
 		pci_read_config_byte(dev, 0x5A, &btr);
-		mode = btr;
+		mode = btr & 0x3;
 		if (!eighty_ninty_three(drive))
 			mode = min(mode, (u8)1);
+		/* If someone decides to do UDMA133 on CSB5 the same
+		   issue will bite so be inclusive */
+		if (mode > 2 && check_in_drive_lists(drive, svwks_bad_ata100))
+			mode = 2;
 	}
 	if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
 	     (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
@@ -419,13 +434,10 @@
 
 static void svwks_tune_drive (ide_drive_t *drive, u8 pio)
 {
-	/* Tune to desired value or to "best". We must not adjust
-	   "best" when we adjust from pio numbers to rate values! */
-	   
-	if(pio != 255)
-		(void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio));
-	else
+	if(pio == 255)
 		(void) svwks_tune_chipset(drive, 255);
+	else
+		(void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio));
 }
 
 static int config_chipset_for_dma (ide_drive_t *drive)
@@ -446,7 +458,7 @@
 
 	drive->init_speed = 0;
 
-	if (id && (id->capability & 1) && drive->autodma) {
+	if ((id->capability & 1) && drive->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (hwif->ide_dma_bad_drive(drive))
 			goto fast_ata_pio;
@@ -483,28 +495,10 @@
 	return hwif->ide_dma_on(drive);
 }
 
+/* This can go soon */
+
 static int svwks_ide_dma_end (ide_drive_t *drive)
 {
-	/*
-	 *	We never place the OSB4 into a UDMA mode with a disk
-	 *	medium, that means the UDMA "all my data is 4 byte shifted"
-	 *	problem cannot occur.
-	 */
-#if 0
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 dma_stat		= hwif->INB(hwif->dma_status);
-
-	if ((dma_stat & 1) && drive->media == ide_disk)
-	{
-		printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
-		printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
-		printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
-		/* Panic might sys_sync -> death by corrupt disk */
-		printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
-		while(1)
-			cpu_relax();
-	}
-#endif	
 	return __ide_dma_end(drive);
 }
 
@@ -630,8 +624,6 @@
 
 static unsigned int __init ata66_svwks_svwks (ide_hwif_t *hwif)
 {
-//	struct pci_dev *dev = hwif->pci_dev;
-//	return 0;
 	return 1;
 }
 
diff -urN linux-2.5.69-bk16/drivers/ide/pci/serverworks.h linux-2.5.69-bk17/drivers/ide/pci/serverworks.h
--- linux-2.5.69-bk16/drivers/ide/pci/serverworks.h	2003-05-04 16:53:12.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/pci/serverworks.h	2003-05-24 04:33:33.000000000 -0700
@@ -11,6 +11,16 @@
 #define SVWKS_CSB5_REVISION_NEW	0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
 #define SVWKS_CSB6_REVISION	0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
 
+/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
+ * can overrun their FIFOs when used with the CSB5 */
+const char *svwks_bad_ata100[] = {
+	"ST320011A",
+	"ST340016A",
+	"ST360021A",
+	"ST380021A",
+	NULL
+};
+
 #define DISPLAY_SVWKS_TIMINGS	1
 
 #if defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS)
diff -urN linux-2.5.69-bk16/drivers/ide/pci/sis5513.c linux-2.5.69-bk17/drivers/ide/pci/sis5513.c
--- linux-2.5.69-bk16/drivers/ide/pci/sis5513.c	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/pci/sis5513.c	2003-05-24 04:33:33.000000000 -0700
@@ -161,9 +161,10 @@
 	{ "SiS748",	PCI_DEVICE_ID_SI_748,	ATA_133,	0 },
 	{ "SiS746",	PCI_DEVICE_ID_SI_746,	ATA_133,	0 },
 	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_133,	0 },
-	{ "SiS740",	PCI_DEVICE_ID_SI_740,	ATA_100,	0 },
+	{ "SiS740",	PCI_DEVICE_ID_SI_740,	ATA_133,	0 },
 	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS730",	PCI_DEVICE_ID_SI_730,	ATA_100a,	SIS5513_LATENCY },
+	{ "SiS655",	PCI_DEVICE_ID_SI_655,	ATA_133,	0 },
 	{ "SiS652",	PCI_DEVICE_ID_SI_652,	ATA_133,	0 },
 	{ "SiS651",	PCI_DEVICE_ID_SI_651,	ATA_133,	0 },
 	{ "SiS650",	PCI_DEVICE_ID_SI_650,	ATA_133,	0 },
@@ -257,8 +258,8 @@
 static char* chipset_capability[] = {
 	"ATA", "ATA 16",
 	"ATA 33", "ATA 66",
-	"ATA 100", "ATA 100",
-	"ATA 133", "ATA 133"
+	"ATA 100 (1st gen)", "ATA 100 (2nd gen)",
+	"ATA 133 (1st gen)", "ATA 133 (2nd gen)"
 };
 
 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
@@ -331,8 +332,8 @@
 			// Configuration space remapped to 0x70
 			drive_pci = 0x70;
 		}
-		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos, &regdw0);
-		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos+4, &regdw1);
+		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, &regdw0);
+		pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, &regdw1);
 		p += sprintf(p, "Drive %d:\n", pos);
 	}
 
@@ -357,8 +358,7 @@
 			case ATA_100a:	p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break;
 			case ATA_100:
 			case ATA_133a:	p += sprintf(p, cycle_time[reg01 & 0x0F]); break;
-			case ATA_133:
-			default:	p += sprintf(p, "133+ ?"); break;
+			default:	p += sprintf(p, "?"); break;
 		}
 		p += sprintf(p, " \t UDMA Cycle Time    ");
 		switch(chipset_family) {
@@ -367,42 +367,39 @@
 			case ATA_100a:	p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break;
 			case ATA_100:
 			case ATA_133a:  p += sprintf(p, cycle_time[reg11 & 0x0F]); break;
-			case ATA_133:
-			default:	p += sprintf(p, "133+ ?"); break;
+			default:	p += sprintf(p, "?"); break;
 		}
 		p += sprintf(p, "\n");
 	}
 
+	if (chipset_family < ATA_133) { /* else case TODO */
 /* Data Active */
-	p += sprintf(p, "                Data Active Time   ");
-	switch(chipset_family) {
-		case ATA_00:
-		case ATA_16: /* confirmed */
-		case ATA_33:
-		case ATA_66:
-		case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
-		case ATA_100:
-		case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
-		case ATA_133:
-		default: p += sprintf(p, "133+ ?"); break;
-	}
-	p += sprintf(p, " \t Data Active Time   ");
-	switch(chipset_family) {
-		case ATA_00:
-		case ATA_16:
-		case ATA_33:
-		case ATA_66:
-		case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
-		case ATA_100:
-		case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
-		case ATA_133:
-		default: p += sprintf(p, "133+ ?"); break;
-	}
-	p += sprintf(p, "\n");
+		p += sprintf(p, "                Data Active Time   ");
+		switch(chipset_family) {
+			case ATA_00:
+			case ATA_16: /* confirmed */
+			case ATA_33:
+			case ATA_66:
+			case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
+			case ATA_100:
+			case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
+			default: p += sprintf(p, "?"); break;
+		}
+		p += sprintf(p, " \t Data Active Time   ");
+		switch(chipset_family) {
+			case ATA_00:
+			case ATA_16:
+			case ATA_33:
+			case ATA_66:
+			case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
+			case ATA_100:
+			case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
+			default: p += sprintf(p, "?"); break;
+		}
+		p += sprintf(p, "\n");
 
 /* Data Recovery */
 	/* warning: may need (reg&0x07) for pre ATA66 chips */
-	if (chipset_family < ATA_133) {
 		p += sprintf(p, "                Data Recovery Time %s \t Data Recovery Time %s\n",
 			     recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]);
 	}
@@ -430,7 +427,6 @@
 
 	p += sprintf(p, "\nSiS 5513 ");
 	switch(chipset_family) {
-		case ATA_00: p += sprintf(p, "Unknown???"); break;
 		case ATA_16: p += sprintf(p, "DMA 16"); break;
 		case ATA_33: p += sprintf(p, "Ultra 33"); break;
 		case ATA_66: p += sprintf(p, "Ultra 66"); break;
@@ -867,6 +863,19 @@
 	return sis5513_config_drive_xfer_rate(drive);
 }
 
+/* Helper function used at init time
+ * returns a PCI device revision ID
+ * (used to detect different IDE controller versions)
+ */
+static u8 __init devfn_rev(int device, int function)
+{
+	u8 revision;
+	/* Find device */
+	struct pci_dev* dev = pci_find_slot(0,PCI_DEVFN(device,function));
+	pci_read_config_byte(dev, PCI_REVISION_ID, &revision);
+	return revision;
+}
+
 /* Chip detection and general config */
 static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name)
 {
@@ -887,26 +896,24 @@
 		/* check 100/133 chipset family */
 		if (chipset_family == ATA_133) {
 			u32 reg54h;
-			u16 reg02h;
+			u16 devid;
 			pci_read_config_dword(dev, 0x54, &reg54h);
+			/* SiS962 and above report 0x5518 dev id if high bit is cleared */
 			pci_write_config_dword(dev, 0x54, (reg54h & 0x7fffffff));
-			pci_read_config_word(dev, 0x02, &reg02h);
+			pci_read_config_word(dev, 0x02, &devid);
+			/* restore register 0x54 */
 			pci_write_config_dword(dev, 0x54, reg54h);
+
 			/* devid 5518 here means SiS962 or later
-			   which supports ATA133 */
-			if (reg02h != 0x5518) {
+			   which supports ATA133.
+			   These are refered by chipset_family = ATA133
+			*/
+			if (devid != 0x5518) {
 				u8 reg49h;
-				unsigned long sbrev;
 				/* SiS961 family */
-
-		/*
-		 * FIXME !!! GAK!!!!!!!!!! PCI DIRECT POKING 
-		 */
-				outl(0x80001008, 0x0cf8);
-				sbrev = inl(0x0cfc);
-
 				pci_read_config_byte(dev, 0x49, &reg49h);
-				if (((sbrev & 0xff) == 0x10) && (reg49h & 0x80))
+				/* check isa bridge device rev id */
+				if (((devfn_rev(2,0) & 0xff) == 0x10) && (reg49h & 0x80))
 					chipset_family = ATA_133a;
 				else
 					chipset_family = ATA_100;
@@ -924,6 +931,14 @@
 			u8 latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */
 			pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
 		}
+
+		/* Special case for SiS630 : 630S/ET is ATA_100a */
+		if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) {
+			/* check host device rev id */
+			if (devfn_rev(0,0) >= 0x30) {
+				chipset_family = ATA_100a;
+			}
+		}
 	}
 
 	/* Make general config ops here
diff -urN linux-2.5.69-bk16/drivers/ide/pci/via82cxxx.c linux-2.5.69-bk17/drivers/ide/pci/via82cxxx.c
--- linux-2.5.69-bk16/drivers/ide/pci/via82cxxx.c	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk17/drivers/ide/pci/via82cxxx.c	2003-05-24 04:33:33.000000000 -0700
@@ -1,12 +1,12 @@
 /*
  *
- * Version 3.36
+ * Version 3.37
  *
  * VIA IDE driver for Linux. Supported southbridges:
  *
  *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
  *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
- *   vt8235
+ *   vt8235, vt8237
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
  *
@@ -74,9 +74,7 @@
 	u8 rev_max;
 	u16 flags;
 } via_isa_bridges[] = {
-#ifdef FUTURE_BRIDGES
-	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 },
-#endif
+	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, VIA_UDMA_100 },
@@ -148,7 +146,7 @@
 	via_print("----------VIA BusMastering IDE Configuration"
 		"----------------");
 
-	via_print("Driver Version:                     3.36");
+	via_print("Driver Version:                     3.37");
 	via_print("South Bridge:                       VIA %s",
 		via_config->name);
 
diff -urN linux-2.5.69-bk16/drivers/pci/quirks.c linux-2.5.69-bk17/drivers/pci/quirks.c
--- linux-2.5.69-bk16/drivers/pci/quirks.c	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/pci/quirks.c	2003-05-24 04:33:34.000000000 -0700
@@ -635,7 +635,22 @@
 	if(pdev->devfn == 0)
 		interrupt_line_quirk = 1;
 }
-	
+
+/*
+ *	Serverworks CSB5 IDE does not fully support native mode
+ */
+static void __init quirk_svwks_csb5ide(struct pci_dev *pdev)
+{
+	u8 prog;
+	pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
+	if (prog & 5) {
+		prog &= ~5;
+		pdev->class &= ~5;
+		pci_write_config_byte(pdev, PCI_CLASS_PROG, prog);
+		/* need to re-assign BARs for compat mode */
+		quirk_ide_bases(pdev);
+	}
+}
 
 /* This was originally an Alpha specific thing, but it really fits here.
  * The i82375 PCI/EISA bridge appears as non-classified. Fix that.
@@ -812,7 +827,9 @@
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_TOSHIBA,	0x605,	quirk_transparent_bridge },
 
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_CYRIX,	PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master },
-	
+
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide },
+
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82375,	quirk_eisa_bridge },
 
 	/*
diff -urN linux-2.5.69-bk16/drivers/usb/core/message.c linux-2.5.69-bk17/drivers/usb/core/message.c
--- linux-2.5.69-bk16/drivers/usb/core/message.c	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/core/message.c	2003-05-24 04:33:34.000000000 -0700
@@ -672,6 +672,7 @@
 {
 	int i, b;
 
+	/* NOTE:  affects all endpoints _except_ ep0 */
 	for (i=0; i<dev->actconfig->desc.bNumInterfaces; i++) {
 		struct usb_interface *ifp = dev->actconfig->interface + i;
 		struct usb_host_interface *as = ifp->altsetting + ifp->act_altsetting;
@@ -862,6 +863,7 @@
 		usb_settoggle (dev, ep, out, 0);
 		(out ? dev->epmaxpacketout : dev->epmaxpacketin) [ep]
 			= iface_as->endpoint [i].desc.wMaxPacketSize;
+		usb_endpoint_running (dev, ep, out);
 	}
 
 	return 0;
@@ -916,7 +918,7 @@
 
 	/* if it's already configured, clear out old state first. */
 	if (dev->state != USB_STATE_ADDRESS && disable) {
-		for (i = 0; i < 15; i++) {
+		for (i = 1 /* skip ep0 */; i < 15; i++) {
 			disable (dev, i);
 			disable (dev, USB_DIR_IN | i);
 		}
diff -urN linux-2.5.69-bk16/drivers/usb/gadget/ether.c linux-2.5.69-bk17/drivers/usb/gadget/ether.c
--- linux-2.5.69-bk16/drivers/usb/gadget/ether.c	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/gadget/ether.c	2003-05-24 04:33:34.000000000 -0700
@@ -1107,7 +1107,7 @@
 	}
 
 	/* respond with data transfer before status phase? */
-	if (value > 0) {
+	if (value >= 0) {
 		req->length = value;
 		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
 		if (value < 0) {
diff -urN linux-2.5.69-bk16/drivers/usb/gadget/net2280.c linux-2.5.69-bk17/drivers/usb/gadget/net2280.c
--- linux-2.5.69-bk16/drivers/usb/gadget/net2280.c	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/gadget/net2280.c	2003-05-24 04:33:34.000000000 -0700
@@ -393,7 +393,7 @@
 	struct net2280_request	*req;
 
 	ep = container_of (_ep, struct net2280_ep, ep);
-	if (!ep || !_req)
+	if (!_ep || !_req)
 		return;
 
 	req = container_of (_req, struct net2280_request, req);
@@ -442,7 +442,7 @@
 	struct net2280_ep	*ep;
 
 	ep = container_of (_ep, struct net2280_ep, ep);
-	if (!ep || (!ep->desc && ep->num != 0))
+	if (!_ep || (!ep->desc && ep->num != 0))
 		return 0;
 
 	*dma = DMA_ADDR_INVALID;
@@ -561,16 +561,12 @@
 	writel ((1 << FIFO_FLUSH), statp);
 	mb ();
 	tmp = readl (statp);
-	if (tmp & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) {
+	if (tmp & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
+			/* high speed did bulk NYET; fifo isn't filling */
+			&& ep->dev->gadget.speed == USB_SPEED_FULL) {
 		unsigned	usec;
 
-		if (ep->dev->gadget.speed == USB_SPEED_HIGH) {
-			if (ep->ep.maxpacket <= 512)
-				usec = 10;	/* 512 byte bulk */
-			else
-				usec = 21;	/* 1024 byte interrupt */
-		} else
-			usec = 50;		/* 64 byte bulk/interrupt */
+		usec = 50;		/* 64 byte bulk/interrupt */
 		handshake (statp, (1 << USB_OUT_PING_NAK_SENT),
 				(1 << USB_OUT_PING_NAK_SENT), usec);
 		/* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */
@@ -614,15 +610,13 @@
 	count = readl (&regs->ep_avail);
 	tmp = req->req.length - req->req.actual;
 	if (count > tmp) {
-		unsigned	over = tmp % ep->ep.maxpacket;
-
-		/* FIXME handle this consistently between PIO and DMA */
-		if (over) {
+		/* as with DMA, data overflow gets flushed */
+		if ((tmp % ep->ep.maxpacket) != 0) {
 			ERROR (ep->dev,
-				"%s out fifo %d bytes, over %d extra %d\n",
-				ep->ep.name, count, over, count - tmp);
+				"%s out fifo %d bytes, expected %d\n",
+				ep->ep.name, count, tmp);
 			req->req.status = -EOVERFLOW;
-			tmp -= over;
+			cleanup = 1;
 		}
 		count = tmp;
 	}
@@ -670,10 +664,12 @@
 
 	/* don't let DMA continue after a short OUT packet,
 	 * so overruns can't affect the next transfer.
+	 * in case of overruns on max-size packets, we can't
+	 * stop the fifo from filling but we can flush it.
 	 */
 	if (ep->is_in)
 		dmacount |= (1 << DMA_DIRECTION);
-	else if ((dmacount % ep->ep.maxpacket) != 0)
+	else
 		dmacount |= (1 << END_OF_CHAIN);
 
 	req->valid = valid;
@@ -897,8 +893,12 @@
 			start_dma (ep, req);
 		else {
 			/* maybe there's no control data, just status ack */
-			if (ep->num == 0 && _req->length == 0)
+			if (ep->num == 0 && _req->length == 0) {
+				allow_status (ep);
+				done (ep, req, 0);
+				VDEBUG (dev, "%s status ack\n", ep->ep.name);
 				goto done;
+			}
 
 			/* PIO ... stuff the fifo, or unblock it.  */
 			if (ep->is_in)
@@ -948,10 +948,9 @@
 
 	} /* else the irq handler advances the queue. */
 
-	if (req) {
-done:
+	if (req)
 		list_add_tail (&req->queue, &ep->queue);
-	}
+done:
 	spin_unlock_irqrestore (&dev->lock, flags);
 
 	/* pci writes may still be posted */
@@ -992,6 +991,8 @@
 		/* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short"
 		 * packets, including overruns, even when the transfer was
 		 * exactly the length requested (dmacount now zero).
+		 * FIXME there's an overrun case here too, where we expect
+		 * a short packet but receive a max length one (won't NAK).
 		 */
 		if (!ep->is_in && (req->req.length % ep->ep.maxpacket) != 0) {
 			req->dma_done = 1;
@@ -1186,7 +1187,8 @@
 		return -EINVAL;
 	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
 		return -ESHUTDOWN;
-	if ((ep->desc->bmAttributes & 0x03) == USB_ENDPOINT_XFER_ISOC)
+	if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03)
+						== USB_ENDPOINT_XFER_ISOC)
 		return -EINVAL;
 
 	VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
@@ -1712,7 +1714,7 @@
 
 static void ep0_start (struct net2280 *dev)
 {
-	writel (  (1 << SET_EP_HIDE_STATUS_PHASE)
+	writel (  (1 << CLEAR_EP_HIDE_STATUS_PHASE)
 		| (1 << CLEAR_NAK_OUT_PACKETS)
 		| (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
 		, &dev->epregs [0].ep_rsp);
@@ -1916,22 +1918,27 @@
 		if (ep->is_in) {
 			/* status; stop NAKing */
 			if (t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) {
-				if (ep->dev->protocol_stall)
+				if (ep->dev->protocol_stall) {
+					ep->stopped = 1;
 					set_halt (ep);
+				}
 				mode = 2;
-			/* reply to extra IN tokens with a zlp */
+			/* reply to extra IN data tokens with a zlp */
 			} else if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) {
 				if (ep->dev->protocol_stall) {
+					ep->stopped = 1;
 					set_halt (ep);
 					mode = 2;
-				} else if (!req)
+				} else if (!req && ep->stopped)
 					write_fifo (ep, 0);
 			}
 		} else {
 			/* status; stop NAKing */
 			if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) {
-				if (ep->dev->protocol_stall)
+				if (ep->dev->protocol_stall) {
+					ep->stopped = 1;
 					set_halt (ep);
+				}
 				mode = 2;
 			/* an extra OUT token is an error */
 			} else if (((t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT))
@@ -2031,6 +2038,10 @@
 
 		/* maybe advance queue to next request */
 		if (ep->num == 0) {
+			/* FIXME need mechanism (request flag?) so control OUT
+			 * can decide to stall ep0 after that done() returns,
+			 * from non-irq context
+			 */
 			allow_status (ep);
 			req = 0;
 		} else {
@@ -2171,6 +2182,7 @@
 			struct net2280_ep	*e;
 			u16			status;
 
+			/* hw handles device and interface status */
 			if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT))
 				goto delegate;
 			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0
@@ -2188,12 +2200,14 @@
 			set_fifo_bytecount (ep, u.r.wLength);
 			writel (status, &dev->epregs [0].ep_data);
 			allow_status (ep);
+			VDEBUG (dev, "%s stat %02x\n", ep->ep.name, status);
 			goto next_endpoints;
 			}
 			break;
 		case USB_REQ_CLEAR_FEATURE: {
 			struct net2280_ep	*e;
 
+			/* hw handles device features */
 			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
 				goto delegate;
 			if (u.r.wIndex != 0 /* HALT feature */
@@ -2202,11 +2216,15 @@
 			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
 				goto do_stall;
 			clear_halt (e);
+			allow_status (ep);
+			VDEBUG (dev, "%s clear halt\n", ep->ep.name);
+			goto next_endpoints;
 			}
 			break;
 		case USB_REQ_SET_FEATURE: {
 			struct net2280_ep	*e;
 
+			/* hw handles device features */
 			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
 				goto delegate;
 			if (u.r.wIndex != 0 /* HALT feature */
@@ -2215,6 +2233,9 @@
 			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
 				goto do_stall;
 			set_halt (e);
+			allow_status (ep);
+			VDEBUG (dev, "%s set halt\n", ep->ep.name);
+			goto next_endpoints;
 			}
 			break;
 		default:
@@ -2235,23 +2256,12 @@
 			VDEBUG (dev, "req %02x.%02x protocol STALL; stat %d\n",
 					u.r.bRequestType, u.r.bRequest, tmp);
 			dev->protocol_stall = 1;
-
-		/* when there's no data, queueing a response is optional */
-		} else if (list_empty (&ep->queue)) {
-			if (u.r.wLength == 0) {
-				/* done() not possible/requested */
-				allow_status (ep);
-			} else {
-				DEBUG (dev, "req %02x.%02x v%04x "
-					"gadget error, len %d, stat %d\n",
-					u.r.bRequestType, u.r.bRequest,
-					le16_to_cpu (u.r.wValue),
-					u.r.wLength, tmp);
-				dev->protocol_stall = 1;
-			}
 		}
 
-		/* some in/out token irq should follow; maybe stall then. */
+		/* some in/out token irq should follow; maybe stall then.
+		 * driver must queue a request (even zlp) or halt ep0
+		 * before the host times out.
+		 */
 	}
 
 next_endpoints:
diff -urN linux-2.5.69-bk16/drivers/usb/gadget/net2280.h linux-2.5.69-bk17/drivers/usb/gadget/net2280.h
--- linux-2.5.69-bk16/drivers/usb/gadget/net2280.h	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/gadget/net2280.h	2003-05-24 04:33:34.000000000 -0700
@@ -437,6 +437,8 @@
 
 /*-------------------------------------------------------------------------*/
 
+#ifdef	__KERNEL__
+
 /* indexed registers [11.10] are accessed indirectly
  * caller must own the device lock.
  */
@@ -457,6 +459,9 @@
 	/* posted, may not be visible yet */
 }
 
+#endif	/* __KERNEL__ */
+
+
 #define REG_DIAG		0x0
 #define     RETRY_COUNTER                                       16
 #define     FORCE_PCI_SERR                                      11
@@ -471,6 +476,8 @@
 #define REG_CHIPREV		0x03	/* in bcd */
 #define	REG_HS_NAK_RATE		0x0a	/* NAK per N uframes */
 
+#ifdef	__KERNEL__
+
 /* ep a-f highspeed and fullspeed maxpacket, addresses
  * computed from ep->num
  */
@@ -519,6 +526,7 @@
 	writel (  (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
 		| (1 << CLEAR_NAK_OUT_PACKETS_MODE)
 		, &ep->regs->ep_rsp);
+	ep->stopped = 1;
 }
 
 static inline void set_halt (struct net2280_ep *ep)
@@ -707,3 +715,4 @@
 		writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
 }
 
+#endif	/* __KERNEL__ */
diff -urN linux-2.5.69-bk16/drivers/usb/gadget/zero.c linux-2.5.69-bk17/drivers/usb/gadget/zero.c
--- linux-2.5.69-bk16/drivers/usb/gadget/zero.c	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/gadget/zero.c	2003-05-24 04:33:34.000000000 -0700
@@ -653,7 +653,7 @@
 	/* this endpoint is normally active while we're configured */
 	case -ECONNRESET:		/* request dequeued */
 	case -ESHUTDOWN:		/* disconnect from host */
-		DEBUG (dev, "%s gone (%d), %d/%d\n", ep->name, status,
+		VDEBUG (dev, "%s gone (%d), %d/%d\n", ep->name, status,
 				req->actual, req->length);
 		free_ep_req (ep, req);
 		return;
@@ -1035,9 +1035,6 @@
 		if (ctrl->bRequestType != 0)
 			break;
 		spin_lock (&dev->lock);
-		/* change hardware configuration!
-		 * no response queued, just zero status == success
-		 */
 		value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC);
 		spin_unlock (&dev->lock);
 		break;
@@ -1092,7 +1089,7 @@
 	}
 
 	/* respond with data transfer before status phase? */
-	if (value > 0) {
+	if (value >= 0) {
 		req->length = value;
 		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
 		if (value < 0) {
diff -urN linux-2.5.69-bk16/drivers/usb/host/uhci-hcd.c linux-2.5.69-bk17/drivers/usb/host/uhci-hcd.c
--- linux-2.5.69-bk16/drivers/usb/host/uhci-hcd.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/host/uhci-hcd.c	2003-05-24 04:33:34.000000000 -0700
@@ -61,7 +61,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v2.0"
+#define DRIVER_VERSION "v2.1"
 #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber"
 #define DRIVER_DESC "USB Universal Host Controller Interface driver"
 
@@ -91,9 +91,7 @@
 static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
 static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb);
 
-static int  ports_active(struct uhci_hcd *uhci);
-static void suspend_hc(struct uhci_hcd *uhci);
-static void wakeup_hc(struct uhci_hcd *uhci);
+static void hc_state_transitions(struct uhci_hcd *uhci);
 
 /* If a transfer is still active after this much time, turn off FSBR */
 #define IDLE_TIMEOUT	(HZ / 20)	/* 50 ms */
@@ -1757,9 +1755,8 @@
 		uhci->skel_term_qh->link = UHCI_PTR_TERM;
 	}
 
-	/* enter global suspend if nothing connected */
-	if (!uhci->is_suspended && !ports_active(uhci))
-		suspend_hc(uhci);
+	/* Poll for and perform state transitions */
+	hc_state_transitions(uhci);
 
 	init_stall_timer(hcd);
 }
@@ -1884,14 +1881,14 @@
 			err("%x: host system error, PCI problems?", io_addr);
 		if (status & USBSTS_HCPE)
 			err("%x: host controller process error. something bad happened", io_addr);
-		if ((status & USBSTS_HCH) && !uhci->is_suspended) {
+		if ((status & USBSTS_HCH) && uhci->state > 0) {
 			err("%x: host controller halted. very bad", io_addr);
 			/* FIXME: Reset the controller, fix the offending TD */
 		}
 	}
 
 	if (status & USBSTS_RD)
-		wakeup_hc(uhci);
+		uhci->resume_detect = 1;
 
 	uhci_free_pending_qhs(uhci);
 
@@ -1922,10 +1919,18 @@
 	unsigned int io_addr = uhci->io_addr;
 
 	/* Global reset for 50ms */
+	uhci->state = UHCI_RESET;
 	outw(USBCMD_GRESET, io_addr + USBCMD);
-	wait_ms(50);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout((HZ*50+999) / 1000);
+	set_current_state(TASK_RUNNING);
 	outw(0, io_addr + USBCMD);
-	wait_ms(10);
+
+	/* Another 10ms delay */
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout((HZ*10+999) / 1000);
+	set_current_state(TASK_RUNNING);
+	uhci->resume_detect = 0;
 }
 
 static void suspend_hc(struct uhci_hcd *uhci)
@@ -1933,34 +1938,49 @@
 	unsigned int io_addr = uhci->io_addr;
 
 	dbg("%x: suspend_hc", io_addr);
-
-	uhci->is_suspended = 1;
-	smp_wmb();
-
+	uhci->state = UHCI_SUSPENDED;
+	uhci->resume_detect = 0;
 	outw(USBCMD_EGSM, io_addr + USBCMD);
 }
 
 static void wakeup_hc(struct uhci_hcd *uhci)
 {
 	unsigned int io_addr = uhci->io_addr;
-	unsigned int status;
 
-	dbg("%x: wakeup_hc", io_addr);
+	switch (uhci->state) {
+		case UHCI_SUSPENDED:		/* Start the resume */
+			dbg("%x: wakeup_hc", io_addr);
+
+			/* Global resume for >= 20ms */
+			outw(USBCMD_FGR | USBCMD_EGSM, io_addr + USBCMD);
+			uhci->state = UHCI_RESUMING_1;
+			uhci->state_end = jiffies + (20*HZ+999) / 1000;
+			break;
 
-	/* Global resume for 20ms */
-	outw(USBCMD_FGR | USBCMD_EGSM, io_addr + USBCMD);
-	wait_ms(20);
-	outw(0, io_addr + USBCMD);
-	
-	/* wait for EOP to be sent */
-	status = inw(io_addr + USBCMD);
-	while (status & USBCMD_FGR)
-		status = inw(io_addr + USBCMD);
+		case UHCI_RESUMING_1:		/* End global resume */
+			uhci->state = UHCI_RESUMING_2;
+			outw(0, io_addr + USBCMD);
+			/* Falls through */
 
-	uhci->is_suspended = 0;
+		case UHCI_RESUMING_2:		/* Wait for EOP to be sent */
+			if (inw(io_addr + USBCMD) & USBCMD_FGR)
+				break;
 
-	/* Run and mark it configured with a 64-byte max packet */
-	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
+			/* Run for at least 1 second, and
+			 * mark it configured with a 64-byte max packet */
+			uhci->state = UHCI_RUNNING_GRACE;
+			uhci->state_end = jiffies + HZ;
+			outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP,
+					io_addr + USBCMD);
+			break;
+
+		case UHCI_RUNNING_GRACE:	/* Now allowed to suspend */
+			uhci->state = UHCI_RUNNING;
+			break;
+
+		default:
+			break;
+	}
 }
 
 static int ports_active(struct uhci_hcd *uhci)
@@ -1975,6 +1995,73 @@
 	return connection;
 }
 
+static int suspend_allowed(struct uhci_hcd *uhci)
+{
+	unsigned int io_addr = uhci->io_addr;
+	int i;
+
+	if (!uhci->hcd.pdev ||
+	     uhci->hcd.pdev->vendor != PCI_VENDOR_ID_INTEL ||
+	     uhci->hcd.pdev->device != PCI_DEVICE_ID_INTEL_82371AB_2)
+		return 1;
+
+	/* This is a 82371AB/EB/MB USB controller which has a bug that
+	 * causes false resume indications if any port has an
+	 * over current condition.  To prevent problems, we will not
+	 * allow a global suspend if any ports are OC.
+	 *
+	 * Some motherboards using the 82371AB/EB/MB (but not the USB portion)
+	 * appear to hardwire the over current inputs active to disable
+	 * the USB ports.
+	 */
+
+	/* check for over current condition on any port */
+	for (i = 0; i < uhci->rh_numports; i++) {
+		if (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_OC)
+			return 0;
+	}
+
+	return 1;
+}
+
+static void hc_state_transitions(struct uhci_hcd *uhci)
+{
+	switch (uhci->state) {
+		case UHCI_RUNNING:
+
+			/* global suspend if nothing connected for 1 second */
+			if (!ports_active(uhci) && suspend_allowed(uhci)) {
+				uhci->state = UHCI_SUSPENDING_GRACE;
+				uhci->state_end = jiffies + HZ;
+			}
+			break;
+
+		case UHCI_SUSPENDING_GRACE:
+			if (ports_active(uhci))
+				uhci->state = UHCI_RUNNING;
+			else if (time_after_eq(jiffies, uhci->state_end))
+				suspend_hc(uhci);
+			break;
+
+		case UHCI_SUSPENDED:
+
+			/* wakeup if requested by a device */
+			if (uhci->resume_detect)
+				wakeup_hc(uhci);
+			break;
+
+		case UHCI_RESUMING_1:
+		case UHCI_RESUMING_2:
+		case UHCI_RUNNING_GRACE:
+			if (time_after_eq(jiffies, uhci->state_end))
+				wakeup_hc(uhci);
+			break;
+
+		default:
+			break;
+	}
+}
+
 static void start_hc(struct uhci_hcd *uhci)
 {
 	unsigned int io_addr = uhci->io_addr;
@@ -2003,6 +2090,8 @@
 	outl(uhci->fl->dma_handle, io_addr + USBFLBASEADD);
 
 	/* Run and mark it configured with a 64-byte max packet */
+	uhci->state = UHCI_RUNNING_GRACE;
+	uhci->state_end = jiffies + HZ;
 	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
 
         uhci->hcd.state = USB_STATE_READY;
@@ -2101,8 +2190,6 @@
 	uhci->fsbr = 0;
 	uhci->fsbrtimeout = 0;
 
-	uhci->is_suspended = 0;
-
 	spin_lock_init(&uhci->qh_remove_list_lock);
 	INIT_LIST_HEAD(&uhci->qh_remove_list);
 
@@ -2335,7 +2422,11 @@
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 
-	suspend_hc(uhci);
+	/* Don't try to suspend broken motherboards, reset instead */
+	if (suspend_allowed(uhci))
+		suspend_hc(uhci);
+	else
+		reset_hc(uhci);
 	return 0;
 }
 
@@ -2345,8 +2436,13 @@
 
 	pci_set_master(uhci->hcd.pdev);
 
-	reset_hc(uhci);
-	start_hc(uhci);
+	if (uhci->state == UHCI_SUSPENDED)
+		uhci->resume_detect = 1;
+	else {
+		reset_hc(uhci);
+		start_hc(uhci);
+	}
+	uhci->hcd.state = USB_STATE_READY;
 	return 0;
 }
 #endif
diff -urN linux-2.5.69-bk16/drivers/usb/host/uhci-hcd.h linux-2.5.69-bk17/drivers/usb/host/uhci-hcd.h
--- linux-2.5.69-bk16/drivers/usb/host/uhci-hcd.h	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/host/uhci-hcd.h	2003-05-24 04:33:34.000000000 -0700
@@ -53,6 +53,7 @@
 #define   USBPORTSC_RD		0x0040	/* Resume Detect */
 #define   USBPORTSC_LSDA	0x0100	/* Low Speed Device Attached */
 #define   USBPORTSC_PR		0x0200	/* Port Reset */
+#define   USBPORTSC_OC		0x0400	/* Over Current condition */
 #define   USBPORTSC_SUSP	0x1000	/* Suspend */
 
 /* Legacy support register */
@@ -282,6 +283,29 @@
 	return 0;				/* int128 for 128-255 ms (Max.) */
 }
 
+/*
+ * Device states for the host controller.
+ *
+ * To prevent "bouncing" in the presence of electrical noise,
+ * we insist on a 1-second "grace" period, before switching to
+ * the RUNNING or SUSPENDED states, during which the state is
+ * not allowed to change.
+ *
+ * The resume process is divided into substates in order to avoid
+ * potentially length delays during the timer handler.
+ *
+ * States in which the host controller is halted must have values <= 0.
+ */
+enum uhci_state {
+	UHCI_RESET,
+	UHCI_RUNNING_GRACE,		/* Before RUNNING */
+	UHCI_RUNNING,			/* The normal state */
+	UHCI_SUSPENDING_GRACE,		/* Before SUSPENDED */
+	UHCI_SUSPENDED = -10,		/* When no devices are attached */
+	UHCI_RESUMING_1,
+	UHCI_RESUMING_2
+};
+
 #define hcd_to_uhci(hcd_ptr) container_of(hcd_ptr, struct uhci_hcd, hcd)
 
 /*
@@ -313,7 +337,10 @@
 	struct uhci_frame_list *fl;		/* P: uhci->frame_list_lock */
 	int fsbr;				/* Full speed bandwidth reclamation */
 	unsigned long fsbrtimeout;		/* FSBR delay */
-	int is_suspended;
+
+	enum uhci_state state;			/* FIXME: needs a spinlock */
+	unsigned long state_end;		/* Time of next transition */
+	int resume_detect;			/* Need a Global Resume */
 
 	/* Main list of URB's currently controlled by this HC */
 	spinlock_t urb_list_lock;
diff -urN linux-2.5.69-bk16/drivers/usb/misc/speedtch.c linux-2.5.69-bk17/drivers/usb/misc/speedtch.c
--- linux-2.5.69-bk16/drivers/usb/misc/speedtch.c	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/misc/speedtch.c	2003-05-24 04:33:34.000000000 -0700
@@ -1,7 +1,8 @@
 /******************************************************************************
- *  speedtouch.c  --  Alcatel SpeedTouch USB xDSL modem driver.
+ *  speedtouch.c  -  Alcatel SpeedTouch USB xDSL modem driver
  *
  *  Copyright (C) 2001, Alcatel
+ *  Copyright (C) 2003, Duncan Sands
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms of the GNU General Public License as published by the Free
@@ -40,7 +41,6 @@
  *		udsl_usb_send_data_context->urb to a pointer and adding code
  *		to alloc and free it
  *		- remove_wait_queue() added to udsl_atm_processqueue_thread()
- *		- Duncan Sands (duncan.sands@wanadoo.fr) is the new maintainer
  *
  *  1.5:	- fixed memory leak when atmsar_decode_aal5 returned NULL.
  *		(reported by stephen.robinson@zen.co.uk)
@@ -97,48 +97,65 @@
 #define DRIVER_DESC	"Alcatel SpeedTouch USB driver"
 #define DRIVER_VERSION	"1.6"
 
+static const char udsl_driver_name [] = "speedtch";
+
 #define SPEEDTOUCH_VENDORID		0x06b9
 #define SPEEDTOUCH_PRODUCTID		0x4061
 
-#define UDSL_NUMBER_RCV_URBS		1
-#define UDSL_NUMBER_SND_URBS		1
-#define UDSL_NUMBER_SND_BUFS		(2*UDSL_NUMBER_SND_URBS)
-#define UDSL_RCV_BUFFER_SIZE		(1*64) /* ATM cells */
-#define UDSL_SND_BUFFER_SIZE		(1*64) /* ATM cells */
-/* max should be (1500 IP mtu + 2 ppp bytes + 32 * 5 cellheader overhead) for
- * PPPoA and (1500 + 14 + 32*5 cellheader overhead) for PPPoE */
-#define UDSL_MAX_AAL5_MRU		2048
-
-#define UDSL_IOCTL_START		1
-#define UDSL_IOCTL_STOP			2
+#define UDSL_NUM_RCV_URBS		1
+#define UDSL_NUM_SND_URBS		1
+#define UDSL_NUM_RCV_BUFS		(2*UDSL_NUM_RCV_URBS)
+#define UDSL_NUM_SND_BUFS		(2*UDSL_NUM_SND_URBS)
+#define UDSL_RCV_BUF_SIZE		32 /* ATM cells */
+#define UDSL_SND_BUF_SIZE		64 /* ATM cells */
 
-/* endpoint declarations */
+#define UDSL_IOCTL_LINE_UP		1
+#define UDSL_IOCTL_LINE_DOWN		2
 
 #define UDSL_ENDPOINT_DATA_OUT		0x07
 #define UDSL_ENDPOINT_DATA_IN		0x87
 
 #define ATM_CELL_HEADER			(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
+#define UDSL_NUM_CELLS(x)		(((x) + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD)
 
-#define hex2int(c) ( (c >= '0')&&(c <= '9') ?  (c - '0') : ((c & 0xf)+9) )
-
-/* usb_device_id struct */
+#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
 
 static struct usb_device_id udsl_usb_ids [] = {
 	{ USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID) },
-	{ }			/* Terminating entry */
+	{ }
 };
 
 MODULE_DEVICE_TABLE (usb, udsl_usb_ids);
 
-/* context declarations */
+/* receive */
+
+struct udsl_receive_buffer {
+	struct list_head list;
+	unsigned char *base;
+	unsigned int filled_cells;
+};
 
 struct udsl_receiver {
 	struct list_head list;
-	struct sk_buff *skb;
+	struct udsl_receive_buffer *buffer;
 	struct urb *urb;
 	struct udsl_instance_data *instance;
 };
 
+struct udsl_vcc_data {
+	/* vpi/vci lookup */
+	struct list_head list;
+	short vpi;
+	int vci;
+	struct atm_vcc *vcc;
+
+	/* raw cell reassembly */
+	struct sk_buff *skb;
+	unsigned int max_pdu;
+};
+
+/* send */
+
 struct udsl_send_buffer {
 	struct list_head list;
 	unsigned char *base;
@@ -157,73 +174,55 @@
 	struct atm_skb_data atm_data;
 	unsigned int num_cells;
 	unsigned int num_entire;
-	unsigned char cell_header [ATM_CELL_HEADER];
 	unsigned int pdu_padding;
+	unsigned char cell_header [ATM_CELL_HEADER];
 	unsigned char aal5_trailer [ATM_AAL5_TRAILER];
 };
 
 #define UDSL_SKB(x)		((struct udsl_control *)(x)->cb)
 
-struct udsl_vcc_data {
-	/* vpi/vci lookup */
-	struct list_head list;
-	short vpi;
-	int vci;
-	struct atm_vcc *vcc;
-
-	/* raw cell reassembly */
-	unsigned short mtu;
-	struct sk_buff *reasBuffer;
-};
-
-/*
- * UDSL main driver data
- */
+/* main driver data */
 
 struct udsl_instance_data {
 	struct semaphore serialize;
 
-	/* usb device part */
+	/* USB device part */
 	struct usb_device *usb_dev;
 	char description [64];
 	int firmware_loaded;
 
-	/* atm device part */
+	/* ATM device part */
 	struct atm_dev *atm_dev;
 	struct list_head vcc_list;
 
-	/* receiving */
-	struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS];
+	/* receive */
+	struct udsl_receiver receivers [UDSL_NUM_RCV_URBS];
+	struct udsl_receive_buffer receive_buffers [UDSL_NUM_RCV_BUFS];
 
-	spinlock_t spare_receivers_lock;
+	spinlock_t receive_lock;
 	struct list_head spare_receivers;
-
-	spinlock_t completed_receivers_lock;
-	struct list_head completed_receivers;
+	struct list_head filled_receive_buffers;
 
 	struct tasklet_struct receive_tasklet;
+	struct list_head spare_receive_buffers;
 
-	/* sending */
-	struct udsl_sender all_senders [UDSL_NUMBER_SND_URBS];
-	struct udsl_send_buffer all_buffers [UDSL_NUMBER_SND_BUFS];
+	/* send */
+	struct udsl_sender senders [UDSL_NUM_SND_URBS];
+	struct udsl_send_buffer send_buffers [UDSL_NUM_SND_BUFS];
 
 	struct sk_buff_head sndqueue;
 
 	spinlock_t send_lock;
 	struct list_head spare_senders;
-	struct list_head spare_buffers;
+	struct list_head spare_send_buffers;
 
 	struct tasklet_struct send_tasklet;
 	struct sk_buff *current_skb;			/* being emptied */
 	struct udsl_send_buffer *current_buffer;	/* being filled */
-	struct list_head filled_buffers;
+	struct list_head filled_send_buffers;
 };
 
-static const char udsl_driver_name [] = "speedtch";
-
-/*
- * atm driver prototypes and structures
- */
+/* ATM */
 
 static void udsl_atm_dev_close (struct atm_dev *dev);
 static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci);
@@ -239,17 +238,17 @@
 	.ioctl =	udsl_atm_ioctl,
 	.send =		udsl_atm_send,
 	.proc_read =	udsl_atm_proc_read,
+	.owner =	THIS_MODULE,
 };
 
-/*
- * usb driver prototypes and structures
- */
-static int udsl_usb_probe (struct usb_interface *intf,
-			   const struct usb_device_id *id);
+/* USB */
+
+static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id);
 static void udsl_usb_disconnect (struct usb_interface *intf);
 static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data);
 
 static struct usb_driver udsl_usb_driver = {
+	.owner =	THIS_MODULE,
 	.name =		udsl_driver_name,
 	.probe =	udsl_usb_probe,
 	.disconnect =	udsl_usb_disconnect,
@@ -272,133 +271,110 @@
 	return NULL;
 }
 
-static struct sk_buff *udsl_decode_rawcell (struct udsl_instance_data *instance, struct sk_buff *skb, struct udsl_vcc_data **ctx)
+static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned char *source, unsigned int howmany)
 {
-	if (!instance || !skb || !ctx)
-		return NULL;
-	if (!skb->data || !skb->tail)
-		return NULL;
-
-	while (skb->len) {
-		unsigned char *cell = skb->data;
-		unsigned char *cell_payload;
-		struct udsl_vcc_data *vcc;
-		short vpi;
-		int vci;
-
-		vpi = ((cell[0] & 0x0f) << 4) | (cell[1] >> 4);
-		vci = ((cell[1] & 0x0f) << 12) | (cell[2] << 4) | (cell[3] >> 4);
-
-		vdbg ("udsl_decode_rawcell (0x%p, 0x%p, 0x%p) called", instance, skb, ctx);
-		vdbg ("udsl_decode_rawcell skb->data %p, skb->tail %p", skb->data, skb->tail);
-
-		/* here should the header CRC check be... */
-
-		if (!(vcc = udsl_find_vcc (instance, vpi, vci))) {
-			dbg ("udsl_decode_rawcell: no vcc found for packet on vpi %d, vci %d", vpi, vci);
-			__skb_pull (skb, min (skb->len, (unsigned) 53));
+	struct udsl_vcc_data *cached_vcc = NULL;
+	struct atm_vcc *vcc;
+	struct sk_buff *skb;
+	struct udsl_vcc_data *vcc_data;
+	int cached_vci = 0;
+	unsigned int i;
+	unsigned int length;
+	unsigned int pdu_length;
+	int pti;
+	int vci;
+	short cached_vpi = 0;
+	short vpi;
+
+	for (i = 0; i < howmany; i++, source += ATM_CELL_SIZE) {
+		vpi = ((source [0] & 0x0f) << 4) | (source [1] >> 4);
+		vci = ((source [1] & 0x0f) << 12) | (source [2] << 4) | (source [3] >> 4);
+		pti = (source [3] & 0x2) != 0;
+
+		vdbg ("udsl_extract_cells: vpi %hd, vci %d, pti %d", vpi, vci, pti);
+
+		if (cached_vcc && (vci == cached_vci) && (vpi == cached_vpi))
+			vcc_data = cached_vcc;
+		else if ((vcc_data = udsl_find_vcc (instance, vpi, vci))) {
+			cached_vcc = vcc_data;
+			cached_vpi = vpi;
+			cached_vci = vci;
 		} else {
-			vdbg ("udsl_decode_rawcell found vcc %p for packet on vpi %d, vci %d", vcc, vpi, vci);
+			dbg ("udsl_extract_cells: unknown vpi/vci (%hd/%d)!", vpi, vci);
+			continue;
+		}
 
-			if (skb->len >= 53) {
-				cell_payload = cell + 5;
+		vcc = vcc_data->vcc;
 
-				if (!vcc->reasBuffer)
-					vcc->reasBuffer = dev_alloc_skb (vcc->mtu);
+		if (!vcc_data->skb && !(vcc_data->skb = dev_alloc_skb (vcc_data->max_pdu))) {
+			dbg ("udsl_extract_cells: no memory for skb (vcc: 0x%p)!", vcc);
+			if (pti)
+				atomic_inc (&vcc->stats->rx_err);
+			continue;
+		}
 
-				/* if alloc fails, we just drop the cell. it is possible that we can still
-				 * receive cells on other vcc's
-				 */
-				if (vcc->reasBuffer) {
-					/* if (buffer overrun) discard received cells until now */
-					if ((vcc->reasBuffer->len) > (vcc->mtu - 48))
-						skb_trim (vcc->reasBuffer, 0);
-
-					/* copy data */
-					memcpy (vcc->reasBuffer->tail, cell_payload, 48);
-					skb_put (vcc->reasBuffer, 48);
-
-					/* check for end of buffer */
-					if (cell[3] & 0x2) {
-						struct sk_buff *tmp;
-
-						/* the aal5 buffer ends here, cut the buffer. */
-						/* buffer will always have at least one whole cell, so */
-						/* don't need to check return from skb_pull */
-						skb_pull (skb, 53);
-						*ctx = vcc;
-						tmp = vcc->reasBuffer;
-						vcc->reasBuffer = NULL;
-
-						vdbg ("udsl_decode_rawcell returns ATM_AAL5 pdu 0x%p with length %d", tmp, tmp->len);
-						return tmp;
-					}
-				}
-				/* flush the cell */
-				/* buffer will always contain at least one whole cell, so don't */
-				/* need to check return value from skb_pull */
-				skb_pull (skb, 53);
-			} else {
-				/* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
-				__skb_pull (skb, skb->len);
-				return NULL;
-			}
+		skb = vcc_data->skb;
+
+		if (skb->len + ATM_CELL_PAYLOAD > vcc_data->max_pdu) {
+			dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
+			/* discard cells already received */
+			skb_trim (skb, 0);
+			BUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
 		}
-	}
 
-	return NULL;
-}
+		memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
+		__skb_put (skb, ATM_CELL_PAYLOAD);
 
-static struct sk_buff *udsl_decode_aal5 (struct udsl_vcc_data *ctx, struct sk_buff *skb)
-{
-	uint crc = 0xffffffff;
-	uint length, pdu_crc, pdu_length;
+		if (pti) {
+			length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5];
 
-	vdbg ("udsl_decode_aal5 (0x%p, 0x%p) called", ctx, skb);
+			/* guard against overflow */
+			if (length > ATM_MAX_AAL5_PDU) {
+				dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)", length, vcc);
+				goto drop;
+			}
 
-	if (skb->len && (skb->len % 48))
-		return NULL;
+			pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD;
 
-	length = (skb->tail[-6] << 8) + skb->tail[-5];
-	pdu_crc =
-	    (skb->tail[-4] << 24) + (skb->tail[-3] << 16) + (skb->tail[-2] << 8) + skb->tail[-1];
-	pdu_length = ((length + 47 + 8) / 48) * 48;
+			if (skb->len < pdu_length) {
+				dbg ("udsl_extract_cells: bogus pdu_length %u (skb->len: %u, vcc: 0x%p)", pdu_length, skb->len, vcc);
+				goto drop;
+			}
 
-	vdbg ("udsl_decode_aal5: skb->len = %d, length = %d, pdu_crc = 0x%x, pdu_length = %d", skb->len, length, pdu_crc, pdu_length);
+			if (crc32_be (~0, skb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
+				dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)", vcc);
+				goto drop;
+			}
 
-	/* is skb long enough ? */
-	if (skb->len < pdu_length) {
-		atomic_inc (&ctx->vcc->stats->rx_err);
-		return NULL;
-	}
+			if (!atm_charge (vcc, skb->truesize)) {
+				dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)", skb->truesize);
+				goto drop_no_stats; /* atm_charge increments rx_drop */
+			}
 
-	/* is skb too long ? */
-	if (skb->len > pdu_length) {
-		dbg ("udsl_decode_aal5: Warning: readjusting illegal size %d -> %d", skb->len, pdu_length);
-		/* buffer is too long. we can try to recover
-		 * if we discard the first part of the skb.
-		 * the crc will decide whether this was ok
-		 */
-		skb_pull (skb, skb->len - pdu_length);
-	}
+			/* now that we are sure to send the skb, it is ok to change skb->data */
+			if (skb->len > pdu_length)
+				skb_pull (skb, skb->len - pdu_length); /* discard initial junk */
 
-	crc = ~crc32_be (crc, skb->data, pdu_length - 4);
+			skb_trim (skb, length); /* drop zero padding and trailer */
 
-	/* check crc */
-	if (pdu_crc != crc) {
-		dbg ("udsl_decode_aal5: crc check failed!");
-		atomic_inc (&ctx->vcc->stats->rx_err);
-		return NULL;
-	}
+			atomic_inc (&vcc->stats->rx);
 
-	/* pdu is ok */
-	skb_trim (skb, length);
+			PACKETDEBUG (skb->data, skb->len);
+
+			vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize);
+
+			vcc->push (vcc, skb);
 
-	/* update stats */
-	atomic_inc (&ctx->vcc->stats->rx);
+			vcc_data->skb = NULL;
 
-	vdbg ("udsl_decode_aal5 returns pdu 0x%p with length %d", skb, skb->len);
-	return skb;
+			continue;
+
+drop:
+			atomic_inc (&vcc->stats->rx_err);
+drop_no_stats:
+			skb_trim (skb, 0);
+		}
+	}
 }
 
 
@@ -406,7 +382,7 @@
 **  encode  **
 *************/
 
-static const unsigned char zeros[ATM_CELL_PAYLOAD];
+static const unsigned char zeros [ATM_CELL_PAYLOAD];
 
 static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb)
 {
@@ -421,7 +397,7 @@
 	ctrl->cell_header [3] = vcc->vci << 4;
 	ctrl->cell_header [4] = 0xec;
 
-	ctrl->num_cells = (skb->len + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD;
+	ctrl->num_cells = UDSL_NUM_CELLS (skb->len);
 	ctrl->num_entire = skb->len / ATM_CELL_PAYLOAD;
 
 	zero_padding = ctrl->num_cells * ATM_CELL_PAYLOAD - skb->len - ATM_AAL5_TRAILER;
@@ -490,8 +466,7 @@
 		memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
 		target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
 
-		if (--ctrl->num_cells)
-			BUG();
+		BUG_ON (--ctrl->num_cells);
 	}
 
 	memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
@@ -511,145 +486,89 @@
 
 static void udsl_complete_receive (struct urb *urb, struct pt_regs *regs)
 {
+	struct udsl_receive_buffer *buf;
 	struct udsl_instance_data *instance;
 	struct udsl_receiver *rcv;
 	unsigned long flags;
 
-	if (!urb || !(rcv = urb->context) || !(instance = rcv->instance)) {
+	if (!urb || !(rcv = urb->context)) {
 		dbg ("udsl_complete_receive: bad urb!");
 		return;
 	}
 
-	vdbg ("udsl_complete_receive entered (urb 0x%p, status %d)", urb, urb->status);
+	instance = rcv->instance;
+	buf = rcv->buffer;
+
+	buf->filled_cells = urb->actual_length / ATM_CELL_SIZE;
+
+	vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
+
+	BUG_ON (buf->filled_cells > UDSL_RCV_BUF_SIZE);
 
 	/* may not be in_interrupt() */
-	spin_lock_irqsave (&instance->completed_receivers_lock, flags);
-	list_add_tail (&rcv->list, &instance->completed_receivers);
-	tasklet_schedule (&instance->receive_tasklet);
-	spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
+	spin_lock_irqsave (&instance->receive_lock, flags);
+	list_add (&rcv->list, &instance->spare_receivers);
+	list_add_tail (&buf->list, &instance->filled_receive_buffers);
+	if (likely (!urb->status))
+		tasklet_schedule (&instance->receive_tasklet);
+	spin_unlock_irqrestore (&instance->receive_lock, flags);
 }
 
 static void udsl_process_receive (unsigned long data)
 {
+	struct udsl_receive_buffer *buf;
 	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
 	struct udsl_receiver *rcv;
-	unsigned char *data_start;
-	struct sk_buff *skb;
-	struct urb *urb;
-	struct udsl_vcc_data *atmsar_vcc = NULL;
-	struct sk_buff *new = NULL, *tmp = NULL;
 	int err;
 
-	vdbg ("udsl_process_receive entered");
-
-	spin_lock_irq (&instance->completed_receivers_lock);
-	while (!list_empty (&instance->completed_receivers)) {
-		rcv = list_entry (instance->completed_receivers.next, struct udsl_receiver, list);
-		list_del (&rcv->list);
-		spin_unlock_irq (&instance->completed_receivers_lock);
-
-		urb = rcv->urb;
-		vdbg ("udsl_process_receive: got packet %p with length %d and status %d", urb, urb->actual_length, urb->status);
-
-		switch (urb->status) {
-		case 0:
-			vdbg ("udsl_process_receive: processing urb with rcv %p, urb %p, skb %p", rcv, urb, rcv->skb);
-
-			/* update the skb structure */
-			skb = rcv->skb;
-			skb_trim (skb, 0);
-			skb_put (skb, urb->actual_length);
-			data_start = skb->data;
-
-			vdbg ("skb->len = %d", skb->len);
-			PACKETDEBUG (skb->data, skb->len);
-
-			while ((new = udsl_decode_rawcell (instance, skb, &atmsar_vcc))) {
-				vdbg ("(after cell processing)skb->len = %d", new->len);
-
-				tmp = new;
-				new = udsl_decode_aal5 (atmsar_vcc, new);
-
-				/* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
-				if (new) {
-					vdbg ("(after aal5 decap) skb->len = %d", new->len);
-					if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) {
-						PACKETDEBUG (new->data, new->len);
-						atmsar_vcc->vcc->push (atmsar_vcc->vcc, new);
-					} else {
-						dbg
-						    ("dropping incoming packet : vcc->sk->rcvbuf = %d, skb->true_size = %d",
-						     atmsar_vcc->vcc->sk->rcvbuf, new->truesize);
-						dev_kfree_skb (new);
-					}
-				} else {
-					dbg ("udsl_decode_aal5 returned NULL!");
-					dev_kfree_skb (tmp);
-				}
-			}
-
-			/* restore skb */
-			skb_push (skb, skb->data - data_start);
-
-			usb_fill_bulk_urb (urb,
-					   instance->usb_dev,
-					   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
-					   (unsigned char *) rcv->skb->data,
-					   UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE,
-					   udsl_complete_receive,
-					   rcv);
-			if (!(err = usb_submit_urb (urb, GFP_ATOMIC)))
-				break;
-			dbg ("udsl_process_receive: submission failed (%d)", err);
-			/* fall through */
-		default: /* error or urb unlinked */
-			vdbg ("udsl_process_receive: adding to spare_receivers");
-			spin_lock_irq (&instance->spare_receivers_lock);
-			list_add (&rcv->list, &instance->spare_receivers);
-			spin_unlock_irq (&instance->spare_receivers_lock);
+made_progress:
+	while (!list_empty (&instance->spare_receive_buffers)) {
+		spin_lock_irq (&instance->receive_lock);
+		if (list_empty (&instance->spare_receivers)) {
+			spin_unlock_irq (&instance->receive_lock);
 			break;
-		} /* switch */
-
-		spin_lock_irq (&instance->completed_receivers_lock);
-	} /* while */
-	spin_unlock_irq (&instance->completed_receivers_lock);
-	vdbg ("udsl_process_receive successful");
-}
-
-static void udsl_fire_receivers (struct udsl_instance_data *instance)
-{
-	struct list_head receivers, *pos, *n;
-
-	INIT_LIST_HEAD (&receivers);
-
-	down (&instance->serialize);
-
-	spin_lock_irq (&instance->spare_receivers_lock);
-	list_splice_init (&instance->spare_receivers, &receivers);
-	spin_unlock_irq (&instance->spare_receivers_lock);
+		}
+		rcv = list_entry (instance->spare_receivers.next, struct udsl_receiver, list);
+		list_del (&rcv->list);
+		spin_unlock_irq (&instance->receive_lock);
 
-	list_for_each_safe (pos, n, &receivers) {
-		struct udsl_receiver *rcv = list_entry (pos, struct udsl_receiver, list);
+		buf = list_entry (instance->spare_receive_buffers.next, struct udsl_receive_buffer, list);
+		list_del (&buf->list);
 
-		dbg ("udsl_fire_receivers: firing urb %p", rcv->urb);
+		rcv->buffer = buf;
 
 		usb_fill_bulk_urb (rcv->urb,
 				   instance->usb_dev,
 				   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
-				   (unsigned char *) rcv->skb->data,
-				   UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE,
+				   buf->base,
+				   UDSL_RCV_BUF_SIZE * ATM_CELL_SIZE,
 				   udsl_complete_receive,
 				   rcv);
 
-		if (usb_submit_urb (rcv->urb, GFP_KERNEL) < 0) {
-			dbg ("udsl_fire_receivers: submit failed!");
-			spin_lock_irq (&instance->spare_receivers_lock);
-			list_move (pos, &instance->spare_receivers);
-			spin_unlock_irq (&instance->spare_receivers_lock);
+		vdbg ("udsl_process_receive: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf);
+
+		if ((err = usb_submit_urb(rcv->urb, GFP_ATOMIC)) < 0) {
+			dbg ("udsl_process_receive: urb submission failed (%d)!", err);
+			list_add (&buf->list, &instance->spare_receive_buffers);
+			spin_lock_irq (&instance->receive_lock);
+			list_add (&rcv->list, &instance->spare_receivers);
+			spin_unlock_irq (&instance->receive_lock);
+			break;
 		}
 	}
 
-	up (&instance->serialize);
+	spin_lock_irq (&instance->receive_lock);
+	if (list_empty (&instance->filled_receive_buffers)) {
+		spin_unlock_irq (&instance->receive_lock);
+		return; /* done - no more buffers */
+	}
+	buf = list_entry (instance->filled_receive_buffers.next, struct udsl_receive_buffer, list);
+	list_del (&buf->list);
+	spin_unlock_irq (&instance->receive_lock);
+	vdbg ("udsl_process_receive: processing buf 0x%p", buf);
+	udsl_extract_cells (instance, buf->base, buf->filled_cells);
+	list_add (&buf->list, &instance->spare_receive_buffers);
+	goto made_progress;
 }
 
 
@@ -673,7 +592,7 @@
 	/* may not be in_interrupt() */
 	spin_lock_irqsave (&instance->send_lock, flags);
 	list_add (&snd->list, &instance->spare_senders);
-	list_add (&snd->buffer->list, &instance->spare_buffers);
+	list_add (&snd->buffer->list, &instance->spare_send_buffers);
 	tasklet_schedule (&instance->send_tasklet);
 	spin_unlock_irqrestore (&instance->send_lock, flags);
 }
@@ -681,17 +600,17 @@
 static void udsl_process_send (unsigned long data)
 {
 	struct udsl_send_buffer *buf;
-	int err;
 	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
-	unsigned int num_written;
 	struct sk_buff *skb;
 	struct udsl_sender *snd;
+	int err;
+	unsigned int num_written;
 
 made_progress:
 	spin_lock_irq (&instance->send_lock);
 	while (!list_empty (&instance->spare_senders)) {
-		if (!list_empty (&instance->filled_buffers)) {
-			buf = list_entry (instance->filled_buffers.next, struct udsl_send_buffer, list);
+		if (!list_empty (&instance->filled_send_buffers)) {
+			buf = list_entry (instance->filled_send_buffers.next, struct udsl_send_buffer, list);
 			list_del (&buf->list);
 		} else if ((buf = instance->current_buffer)) {
 			instance->current_buffer = NULL;
@@ -707,7 +626,7 @@
 				   instance->usb_dev,
 				   usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
 				   buf->base,
-				   (UDSL_SND_BUFFER_SIZE - buf->free_cells) * ATM_CELL_SIZE,
+				   (UDSL_SND_BUF_SIZE - buf->free_cells) * ATM_CELL_SIZE,
 				   udsl_complete_send,
 				   snd);
 
@@ -718,33 +637,32 @@
 			spin_lock_irq (&instance->send_lock);
 			list_add (&snd->list, &instance->spare_senders);
 			spin_unlock_irq (&instance->send_lock);
-			list_add (&buf->list, &instance->filled_buffers);
-			return;
+			list_add (&buf->list, &instance->filled_send_buffers);
+			return; /* bail out */
 		}
 
 		spin_lock_irq (&instance->send_lock);
 	} /* while */
 	spin_unlock_irq (&instance->send_lock);
 
-	if (!instance->current_skb && !(instance->current_skb = skb_dequeue (&instance->sndqueue))) {
+	if (!instance->current_skb && !(instance->current_skb = skb_dequeue (&instance->sndqueue)))
 		return; /* done - no more skbs */
-	}
 
 	skb = instance->current_skb;
 
 	if (!(buf = instance->current_buffer)) {
 		spin_lock_irq (&instance->send_lock);
-		if (list_empty (&instance->spare_buffers)) {
+		if (list_empty (&instance->spare_send_buffers)) {
 			instance->current_buffer = NULL;
 			spin_unlock_irq (&instance->send_lock);
 			return; /* done - no more buffers */
 		}
-		buf = list_entry (instance->spare_buffers.next, struct udsl_send_buffer, list);
+		buf = list_entry (instance->spare_send_buffers.next, struct udsl_send_buffer, list);
 		list_del (&buf->list);
 		spin_unlock_irq (&instance->send_lock);
 
 		buf->free_start = buf->base;
-		buf->free_cells = UDSL_SND_BUFFER_SIZE;
+		buf->free_cells = UDSL_SND_BUF_SIZE;
 
 		instance->current_buffer = buf;
 	}
@@ -754,7 +672,7 @@
 	vdbg ("udsl_process_send: wrote %u cells from skb 0x%p to buffer 0x%p", num_written, skb, buf);
 
 	if (!(buf->free_cells -= num_written)) {
-		list_add_tail (&buf->list, &instance->filled_buffers);
+		list_add_tail (&buf->list, &instance->filled_send_buffers);
 		instance->current_buffer = NULL;
 	}
 
@@ -766,7 +684,7 @@
 		if (vcc->pop)
 			vcc->pop (vcc, skb);
 		else
-			kfree_skb (skb);
+			dev_kfree_skb (skb);
 		instance->current_skb = NULL;
 
 		atomic_inc (&vcc->stats->tx);
@@ -788,7 +706,7 @@
 			if (vcc->pop)
 				vcc->pop (vcc, skb);
 			else
-				kfree_skb (skb);
+				dev_kfree_skb (skb);
 		}
 	spin_unlock_irq (&instance->sndqueue.lock);
 
@@ -799,7 +717,7 @@
 		if (vcc->pop)
 			vcc->pop (vcc, skb);
 		else
-			kfree_skb (skb);
+			dev_kfree_skb (skb);
 	}
 	tasklet_enable (&instance->send_tasklet);
 	dbg ("udsl_cancel_send done");
@@ -851,6 +769,7 @@
 
 	dbg ("udsl_atm_dev_close: queue has %u elements", instance->sndqueue.qlen);
 
+	tasklet_kill (&instance->receive_tasklet);
 	tasklet_kill (&instance->send_tasklet);
 	kfree (instance);
 	dev->dev_data = NULL;
@@ -871,8 +790,8 @@
 
 	if (!left--)
 		return sprintf (page, "MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-				atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
-				atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]);
+				atm_dev->esi [0], atm_dev->esi [1], atm_dev->esi [2],
+				atm_dev->esi [3], atm_dev->esi [4], atm_dev->esi [5]);
 
 	if (!left--)
 		return sprintf (page, "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
@@ -925,7 +844,7 @@
 		return -EINVAL;
 
 	/* only support AAL5 */
-	if (vcc->qos.aal != ATM_AAL5)
+	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU))
 		return -EINVAL;
 
 	if (!instance->firmware_loaded) {
@@ -949,7 +868,7 @@
 	new->vcc = vcc;
 	new->vpi = vpi;
 	new->vci = vci;
-	new->mtu = UDSL_MAX_AAL5_MRU;
+	new->max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
 
 	vcc->dev_data = new;
 	vcc->vpi = vpi;
@@ -965,7 +884,7 @@
 
 	up (&instance->serialize);
 
-	udsl_fire_receivers (instance);
+	tasklet_schedule (&instance->receive_tasklet);
 
 	dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, new->max_pdu);
 
@@ -994,9 +913,9 @@
 	list_del (&vcc_data->list);
 	tasklet_enable (&instance->receive_tasklet);
 
-	if (vcc_data->reasBuffer)
-		kfree_skb (vcc_data->reasBuffer);
-	vcc_data->reasBuffer = NULL;
+	if (vcc_data->skb)
+		dev_kfree_skb (vcc_data->skb);
+	vcc_data->skb = NULL;
 
 	kfree (vcc_data);
 	vcc->dev_data = NULL;
@@ -1041,7 +960,9 @@
 		instance->firmware_loaded = 1;
 	}
 	up (&instance->serialize);
-	udsl_fire_receivers (instance);
+
+	tasklet_schedule (&instance->receive_tasklet);
+
 	return 0;
 }
 
@@ -1057,10 +978,10 @@
 	}
 
 	switch (code) {
-	case UDSL_IOCTL_START:
+	case UDSL_IOCTL_LINE_UP:
 		instance->atm_dev->signal = ATM_PHY_SIG_FOUND;
 		return udsl_set_alternate (instance);
-	case UDSL_IOCTL_STOP:
+	case UDSL_IOCTL_LINE_DOWN:
 		instance->atm_dev->signal = ATM_PHY_SIG_LOST;
 		return 0;
 	default:
@@ -1101,31 +1022,25 @@
 
 	INIT_LIST_HEAD (&instance->vcc_list);
 
-	spin_lock_init (&instance->spare_receivers_lock);
+	spin_lock_init (&instance->receive_lock);
 	INIT_LIST_HEAD (&instance->spare_receivers);
-
-	spin_lock_init (&instance->completed_receivers_lock);
-	INIT_LIST_HEAD (&instance->completed_receivers);
+	INIT_LIST_HEAD (&instance->filled_receive_buffers);
 
 	tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance);
+	INIT_LIST_HEAD (&instance->spare_receive_buffers);
 
 	skb_queue_head_init (&instance->sndqueue);
 
 	spin_lock_init (&instance->send_lock);
 	INIT_LIST_HEAD (&instance->spare_senders);
-	INIT_LIST_HEAD (&instance->spare_buffers);
+	INIT_LIST_HEAD (&instance->spare_send_buffers);
 
 	tasklet_init (&instance->send_tasklet, udsl_process_send, (unsigned long) instance);
-	INIT_LIST_HEAD (&instance->filled_buffers);
+	INIT_LIST_HEAD (&instance->filled_send_buffers);
 
 	/* receive init */
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
-		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
-
-		if (!(rcv->skb = dev_alloc_skb (UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE))) {
-			dbg ("udsl_usb_probe: no memory for skb %d!", i);
-			goto fail;
-		}
+	for (i = 0; i < UDSL_NUM_RCV_URBS; i++) {
+		struct udsl_receiver *rcv = &(instance->receivers [i]);
 
 		if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) {
 			dbg ("udsl_usb_probe: no memory for receive urb %d!", i);
@@ -1135,13 +1050,22 @@
 		rcv->instance = instance;
 
 		list_add (&rcv->list, &instance->spare_receivers);
+	}
+
+	for (i = 0; i < UDSL_NUM_RCV_BUFS; i++) {
+		struct udsl_receive_buffer *buf = &(instance->receive_buffers [i]);
+
+		if (!(buf->base = kmalloc (UDSL_RCV_BUF_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) {
+			dbg ("udsl_usb_probe: no memory for receive buffer %d!", i);
+			goto fail;
+		}
 
-		dbg ("udsl_usb_probe: skb->truesize = %d (asked for %d)", rcv->skb->truesize, UDSL_RCV_BUF_SIZE * ATM_CELL_SIZE);
+		list_add (&buf->list, &instance->spare_receive_buffers);
 	}
 
 	/* send init */
-	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) {
-		struct udsl_sender *snd = &(instance->all_senders[i]);
+	for (i = 0; i < UDSL_NUM_SND_URBS; i++) {
+		struct udsl_sender *snd = &(instance->senders [i]);
 
 		if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) {
 			dbg ("udsl_usb_probe: no memory for send urb %d!", i);
@@ -1153,18 +1077,18 @@
 		list_add (&snd->list, &instance->spare_senders);
 	}
 
-	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++) {
-		struct udsl_send_buffer *buf = &(instance->all_buffers[i]);
+	for (i = 0; i < UDSL_NUM_SND_BUFS; i++) {
+		struct udsl_send_buffer *buf = &(instance->send_buffers [i]);
 
-		if (!(buf->base = kmalloc (UDSL_SND_BUFFER_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) {
+		if (!(buf->base = kmalloc (UDSL_SND_BUF_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) {
 			dbg ("udsl_usb_probe: no memory for send buffer %d!", i);
 			goto fail;
 		}
 
-		list_add (&buf->list, &instance->spare_buffers);
+		list_add (&buf->list, &instance->spare_send_buffers);
 	}
 
-	/* atm init */
+	/* ATM init */
 	if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) {
 		dbg ("udsl_usb_probe: failed to register ATM device!");
 		goto fail;
@@ -1174,14 +1098,14 @@
 	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
 	instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
 
-	/* tmp init atm device, set to 128kbit */
+	/* temp init ATM device, set to 128kbit */
 	instance->atm_dev->link_rate = 128 * 1000 / 424;
 
 	/* set MAC address, it is stored in the serial number */
 	memset (instance->atm_dev->esi, 0, sizeof (instance->atm_dev->esi));
 	if (usb_string (dev, dev->descriptor.iSerialNumber, mac_str, sizeof (mac_str)) == 12)
 		for (i = 0; i < 6; i++)
-			instance->atm_dev->esi[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1]));
+			instance->atm_dev->esi [i] = (hex2int (mac_str [i * 2]) * 16) + (hex2int (mac_str [i * 2 + 1]));
 
 	/* device description */
 	buf = instance->description;
@@ -1215,20 +1139,17 @@
 	return 0;
 
 fail:
-	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++)
-		kfree (instance->all_buffers[i].base);
+	for (i = 0; i < UDSL_NUM_SND_BUFS; i++)
+		kfree (instance->send_buffers [i].base);
 
-	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
-		usb_free_urb (instance->all_senders[i].urb);
+	for (i = 0; i < UDSL_NUM_SND_URBS; i++)
+		usb_free_urb (instance->senders [i].urb);
 
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
-		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
+	for (i = 0; i < UDSL_NUM_RCV_BUFS; i++)
+		kfree (instance->receive_buffers [i].base);
 
-		usb_free_urb (rcv->urb);
-
-		if (rcv->skb)
-			kfree_skb (rcv->skb);
-	}
+	for (i = 0; i < UDSL_NUM_RCV_URBS; i++)
+		usb_free_urb (instance->receivers [i].urb);
 
 	kfree (instance);
 
@@ -1239,7 +1160,7 @@
 {
 	struct udsl_instance_data *instance = usb_get_intfdata (intf);
 	struct list_head *pos;
-	unsigned int count = 0;
+	unsigned int count;
 	int result, i;
 
 	dbg ("udsl_usb_disconnect entered");
@@ -1251,38 +1172,25 @@
 		return;
 	}
 
-	tasklet_disable (&instance->receive_tasklet);
-
 	/* receive finalize */
-	down (&instance->serialize); /* vs udsl_fire_receivers */
-	/* no need to take the spinlock */
-	list_for_each (pos, &instance->spare_receivers)
-		if (++count > UDSL_NUMBER_RCV_URBS)
-			panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
-	INIT_LIST_HEAD (&instance->spare_receivers);
-	up (&instance->serialize);
-
-	dbg ("udsl_usb_disconnect: flushed %u spare receivers", count);
-
-	count = UDSL_NUMBER_RCV_URBS - count;
+	tasklet_disable (&instance->receive_tasklet);
 
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++)
-		if ((result = usb_unlink_urb (instance->all_receivers[i].urb)) < 0)
+	for (i = 0; i < UDSL_NUM_RCV_URBS; i++)
+		if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
 			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
 
 	/* wait for completion handlers to finish */
 	do {
-		unsigned int completed = 0;
-
-		spin_lock_irq (&instance->completed_receivers_lock);
-		list_for_each (pos, &instance->completed_receivers)
-			if (++completed > count)
+		count = 0;
+		spin_lock_irq (&instance->receive_lock);
+		list_for_each (pos, &instance->spare_receivers)
+			if (++count > UDSL_NUM_RCV_URBS)
 				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
-		spin_unlock_irq (&instance->completed_receivers_lock);
+		spin_unlock_irq (&instance->receive_lock);
 
-		dbg ("udsl_usb_disconnect: found %u completed receivers", completed);
+		dbg ("udsl_usb_disconnect: found %u spare receivers", count);
 
-		if (completed == count)
+		if (count == UDSL_NUM_RCV_URBS)
 			break;
 
 		set_current_state (TASK_RUNNING);
@@ -1290,37 +1198,36 @@
 	} while (1);
 
 	/* no need to take the spinlock */
-	INIT_LIST_HEAD (&instance->completed_receivers);
+	INIT_LIST_HEAD (&instance->filled_receive_buffers);
+	INIT_LIST_HEAD (&instance->spare_receive_buffers);
 
 	tasklet_enable (&instance->receive_tasklet);
-	tasklet_kill (&instance->receive_tasklet);
 
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
-		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
+	for (i = 0; i < UDSL_NUM_RCV_URBS; i++)
+		usb_free_urb (instance->receivers [i].urb);
 
-		usb_free_urb (rcv->urb);
-		kfree_skb (rcv->skb);
-	}
+	for (i = 0; i < UDSL_NUM_RCV_BUFS; i++)
+		kfree (instance->receive_buffers [i].base);
 
 	/* send finalize */
 	tasklet_disable (&instance->send_tasklet);
 
-	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
-		if ((result = usb_unlink_urb (instance->all_senders[i].urb)) < 0)
+	for (i = 0; i < UDSL_NUM_SND_URBS; i++)
+		if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
 			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
 
 	/* wait for completion handlers to finish */
 	do {
 		count = 0;
-		spin_lock (&instance->send_lock);
+		spin_lock_irq (&instance->send_lock);
 		list_for_each (pos, &instance->spare_senders)
-			if (++count > UDSL_NUMBER_SND_URBS)
+			if (++count > UDSL_NUM_SND_URBS)
 				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
-		spin_unlock (&instance->send_lock);
+		spin_unlock_irq (&instance->send_lock);
 
 		dbg ("udsl_usb_disconnect: found %u spare senders", count);
 
-		if (count == UDSL_NUMBER_SND_URBS)
+		if (count == UDSL_NUM_SND_URBS)
 			break;
 
 		set_current_state (TASK_RUNNING);
@@ -1329,22 +1236,22 @@
 
 	/* no need to take the spinlock */
 	INIT_LIST_HEAD (&instance->spare_senders);
-	INIT_LIST_HEAD (&instance->spare_buffers);
+	INIT_LIST_HEAD (&instance->spare_send_buffers);
 	instance->current_buffer = NULL;
 
 	tasklet_enable (&instance->send_tasklet);
 
-	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
-		usb_free_urb (instance->all_senders[i].urb);
+	for (i = 0; i < UDSL_NUM_SND_URBS; i++)
+		usb_free_urb (instance->senders [i].urb);
 
-	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++)
-		kfree (instance->all_buffers[i].base);
+	for (i = 0; i < UDSL_NUM_SND_BUFS; i++)
+		kfree (instance->send_buffers [i].base);
 
 	wmb ();
 	instance->usb_dev = NULL;
 
-	/* atm finalize */
-	shutdown_atm_dev (instance->atm_dev); /* frees instance */
+	/* ATM finalize */
+	shutdown_atm_dev (instance->atm_dev); /* frees instance, kills tasklets */
 }
 
 
@@ -1392,10 +1299,10 @@
 	int i = 0, j = 0;
 
 	for (i = 0; i < len;) {
-		buffer[0] = '\0';
+		buffer [0] = '\0';
 		sprintf (buffer, "%.3d :", i);
 		for (j = 0; (j < 16) && (i < len); j++, i++) {
-			sprintf (buffer, "%s %2.2x", buffer, data[i]);
+			sprintf (buffer, "%s %2.2x", buffer, data [i]);
 		}
 		dbg ("%s", buffer);
 	}
diff -urN linux-2.5.69-bk16/drivers/usb/storage/transport.c linux-2.5.69-bk17/drivers/usb/storage/transport.c
--- linux-2.5.69-bk16/drivers/usb/storage/transport.c	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/storage/transport.c	2003-05-24 04:33:34.000000000 -0700
@@ -988,7 +988,7 @@
 	US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n",
 		  le32_to_cpu(bcs.Signature), bcs.Tag, 
 		  bcs.Residue, bcs.Status);
-	if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) || 
+	if ((bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) && bcs.Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) || 
 	    bcs.Tag != bcb.Tag || 
 	    bcs.Status > US_BULK_STAT_PHASE) {
 		US_DEBUGP("Bulk logical error\n");
diff -urN linux-2.5.69-bk16/drivers/usb/storage/transport.h linux-2.5.69-bk17/drivers/usb/storage/transport.h
--- linux-2.5.69-bk16/drivers/usb/storage/transport.h	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/drivers/usb/storage/transport.h	2003-05-24 04:33:34.000000000 -0700
@@ -105,6 +105,8 @@
 
 #define US_BULK_CS_WRAP_LEN	13
 #define US_BULK_CS_SIGN		0x53425355	/* spells out 'USBS' */
+/* This is for Olympus Camedia digital cameras */
+#define US_BULK_CS_OLYMPUS_SIGN		0x55425355	/* spells out 'USBU' */
 #define US_BULK_STAT_OK		0
 #define US_BULK_STAT_FAIL	1
 #define US_BULK_STAT_PHASE	2
diff -urN linux-2.5.69-bk16/include/acpi/acconfig.h linux-2.5.69-bk17/include/acpi/acconfig.h
--- linux-2.5.69-bk16/include/acpi/acconfig.h	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acconfig.h	2003-05-24 04:33:34.000000000 -0700
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20030418
+#define ACPI_CA_VERSION                 0x20030522
 
 /* Maximum objects in the various object caches */
 
@@ -133,6 +133,11 @@
 
 #define ACPI_MAX_STRING_CONVERSION      200
 
+/* Length of _HID, _UID, and _CID values */
+
+#define ACPI_DEVICE_ID_LENGTH           0x09
+#define ACPI_MAX_CID_LENGTH             48
+
 /*
  * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
  */
diff -urN linux-2.5.69-bk16/include/acpi/acdebug.h linux-2.5.69-bk17/include/acpi/acdebug.h
--- linux-2.5.69-bk16/include/acpi/acdebug.h	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acdebug.h	2003-05-24 04:33:34.000000000 -0700
@@ -230,10 +230,6 @@
 	char                            *output_type);
 
 void
-acpi_db_decode_node (
-	struct acpi_namespace_node      *node);
-
-void
 acpi_db_display_result_object (
 	union acpi_operand_object       *obj_desc,
 	struct acpi_walk_state          *walk_state);
@@ -243,11 +239,6 @@
 	char                            *display_count_arg);
 
 void
-acpi_db_display_internal_object (
-	union acpi_operand_object       *obj_desc,
-	struct acpi_walk_state          *walk_state);
-
-void
 acpi_db_display_arguments (
 	void);
 
@@ -264,6 +255,10 @@
 	void);
 
 void
+acpi_db_display_object_type (
+	char                            *object_arg);
+
+void
 acpi_db_display_argument_object (
 	union acpi_operand_object       *obj_desc,
 	struct acpi_walk_state          *walk_state);
@@ -276,10 +271,6 @@
 acpi_db_get_pointer (
 	void                            *target);
 
-void
-acpi_db_decode_internal_object (
-	union acpi_operand_object       *obj_desc);
-
 
 /*
  * dbexec - debugger control method execution
diff -urN linux-2.5.69-bk16/include/acpi/acdisasm.h linux-2.5.69-bk17/include/acpi/acdisasm.h
--- linux-2.5.69-bk16/include/acpi/acdisasm.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk17/include/acpi/acdisasm.h	2003-05-24 04:33:34.000000000 -0700
@@ -0,0 +1,406 @@
+/******************************************************************************
+ *
+ * Name: acdisasm.h - AML disassembler
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2003, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef __ACDISASM_H__
+#define __ACDISASM_H__
+
+#include "amlresrc.h"
+
+
+#define BLOCK_NONE              0
+#define BLOCK_PAREN             1
+#define BLOCK_BRACE             2
+#define BLOCK_COMMA_LIST        4
+
+extern const char                       *acpi_gbl_io_decode[2];
+extern const char                       *acpi_gbl_word_decode[4];
+extern const char                       *acpi_gbl_consume_decode[2];
+extern const char                       *acpi_gbl_min_decode[2];
+extern const char                       *acpi_gbl_max_decode[2];
+extern const char                       *acpi_gbl_DECdecode[2];
+extern const char                       *acpi_gbl_RNGdecode[4];
+extern const char                       *acpi_gbl_MEMdecode[4];
+extern const char                       *acpi_gbl_RWdecode[2];
+extern const char                       *acpi_gbl_irq_decode[2];
+extern const char                       *acpi_gbl_HEdecode[2];
+extern const char                       *acpi_gbl_LLdecode[2];
+extern const char                       *acpi_gbl_SHRdecode[2];
+extern const char                       *acpi_gbl_TYPdecode[4];
+extern const char                       *acpi_gbl_BMdecode[2];
+extern const char                       *acpi_gbl_SIZdecode[4];
+extern const char                       *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES];
+extern const char                       *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES];
+extern const char                       *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES];
+extern const char                       *acpi_gbl_match_ops[ACPI_NUM_MATCH_OPS];
+
+
+struct acpi_op_walk_info
+{
+	u32                             level;
+	u32                             bit_offset;
+};
+
+typedef
+acpi_status (*asl_walk_callback) (
+	union acpi_parse_object             *op,
+	u32                                 level,
+	void                                *context);
+
+
+/*
+ * dmwalk
+ */
+
+void
+acpi_dm_walk_parse_tree (
+	union acpi_parse_object         *op,
+	asl_walk_callback               descending_callback,
+	asl_walk_callback               ascending_callback,
+	void                            *context);
+
+acpi_status
+acpi_dm_descending_op (
+	union acpi_parse_object         *op,
+	u32                             level,
+	void                            *context);
+
+acpi_status
+acpi_dm_ascending_op (
+	union acpi_parse_object         *op,
+	u32                             level,
+	void                            *context);
+
+
+/*
+ * dmopcode
+ */
+
+void
+acpi_dm_validate_name (
+	char                            *name,
+	union acpi_parse_object         *op);
+
+u32
+acpi_dm_dump_name (
+	char                            *name);
+
+void
+acpi_dm_unicode (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_disassemble (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *origin,
+	u32                             num_opcodes);
+
+void
+acpi_dm_namestring (
+	char                            *name);
+
+void
+acpi_dm_display_path (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_disassemble_one_op (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_op_walk_info        *info,
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_decode_internal_object (
+	union acpi_operand_object       *obj_desc);
+
+void
+acpi_dm_decode_node (
+	struct acpi_namespace_node      *node);
+
+u32
+acpi_dm_block_type (
+	union acpi_parse_object         *op);
+
+u32
+acpi_dm_list_type (
+	union acpi_parse_object         *op);
+
+acpi_status
+acpi_ps_display_object_pathname (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_method_flags (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_field_flags (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_address_space (
+	u8                              space_id);
+
+void
+acpi_dm_region_flags (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_match_op (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_match_keyword (
+	union acpi_parse_object         *op);
+
+u8
+acpi_dm_comma_if_list_member (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_comma_if_field_member (
+	union acpi_parse_object         *op);
+
+
+/*
+ * dmobject
+ */
+
+void
+acpi_dm_decode_node (
+	struct acpi_namespace_node      *node);
+
+void
+acpi_dm_display_internal_object (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_dm_display_arguments (
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_dm_display_locals (
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_dm_dump_method_info (
+	acpi_status                     status,
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+
+/*
+ * dmbuffer
+ */
+
+void
+acpi_is_eisa_id (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_eisa_id (
+	u32                             encoded_id);
+
+u8
+acpi_dm_is_unicode_buffer (
+	union acpi_parse_object         *op);
+
+u8
+acpi_dm_is_string_buffer (
+	union acpi_parse_object         *op);
+
+
+/*
+ * dmresrc
+ */
+
+void
+acpi_dm_disasm_byte_list (
+	u32                             level,
+	u8                              *byte_data,
+	u32                             byte_count);
+
+void
+acpi_dm_byte_list (
+	struct acpi_op_walk_info        *info,
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_resource_descriptor (
+	struct acpi_op_walk_info        *info,
+	u8                              *byte_data,
+	u32                             byte_count);
+
+u8
+acpi_dm_is_resource_descriptor (
+	union acpi_parse_object         *op);
+
+void
+acpi_dm_indent (
+	u32                             level);
+
+void
+acpi_dm_bit_list (
+	u16                             mask);
+
+void
+acpi_dm_decode_attribute (
+	u8                              attribute);
+
+/*
+ * dmresrcl
+ */
+
+void
+acpi_dm_io_flags (
+		u8                          flags);
+
+void
+acpi_dm_memory_flags (
+	u8                              flags,
+	u8                              specific_flags);
+
+void
+acpi_dm_word_descriptor (
+	struct asl_word_address_desc    *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_dword_descriptor (
+	struct asl_dword_address_desc   *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_qword_descriptor (
+	struct asl_qword_address_desc   *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_memory24_descriptor (
+	struct asl_memory_24_desc       *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_memory32_descriptor (
+	struct asl_memory_32_desc       *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_fixed_mem32_descriptor (
+	struct asl_fixed_memory_32_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_generic_register_descriptor (
+	struct asl_general_register_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_interrupt_descriptor (
+	struct asl_extended_xrupt_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_vendor_large_descriptor (
+	struct asl_large_vendor_desc    *resource,
+	u32                             length,
+	u32                             level);
+
+
+/*
+ * dmresrcs
+ */
+
+void
+acpi_dm_irq_descriptor (
+	struct asl_irq_format_desc      *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_dma_descriptor (
+	struct asl_dma_format_desc      *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_io_descriptor (
+	struct asl_io_port_desc         *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_fixed_io_descriptor (
+	struct asl_fixed_io_port_desc   *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_start_dependent_descriptor (
+	struct asl_start_dependent_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_end_dependent_descriptor (
+	struct asl_start_dependent_desc *resource,
+	u32                             length,
+	u32                             level);
+
+void
+acpi_dm_vendor_small_descriptor (
+	struct asl_small_vendor_desc    *resource,
+	u32                             length,
+	u32                             level);
+
+
+#endif  /* __ACDISASM_H__ */
diff -urN linux-2.5.69-bk16/include/acpi/acevents.h linux-2.5.69-bk17/include/acpi/acevents.h
--- linux-2.5.69-bk16/include/acpi/acevents.h	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acevents.h	2003-05-24 04:33:34.000000000 -0700
@@ -165,7 +165,7 @@
 	void                            *value);
 
 acpi_status
-acpi_ev_addr_handler_helper (
+acpi_ev_install_handler (
 	acpi_handle                     obj_handle,
 	u32                             level,
 	void                            *context,
diff -urN linux-2.5.69-bk16/include/acpi/acexcep.h linux-2.5.69-bk17/include/acpi/acexcep.h
--- linux-2.5.69-bk16/include/acpi/acexcep.h	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acexcep.h	2003-05-24 04:33:34.000000000 -0700
@@ -94,8 +94,9 @@
 #define AE_NO_GLOBAL_LOCK               (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
 #define AE_LOGICAL_ADDRESS              (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
 #define AE_ABORT_METHOD                 (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
+#define AE_SAME_HANDLER                 (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL)
 
-#define AE_CODE_ENV_MAX                 0x001C
+#define AE_CODE_ENV_MAX                 0x001D
 
 /*
  * Programmer exceptions
@@ -219,7 +220,8 @@
 	"AE_NO_HARDWARE_RESPONSE",
 	"AE_NO_GLOBAL_LOCK",
 	"AE_LOGICAL_ADDRESS",
-	"AE_ABORT_METHOD"
+	"AE_ABORT_METHOD",
+	"AE_SAME_HANDLER"
 };
 
 char const   *acpi_gbl_exception_names_pgm[] =
diff -urN linux-2.5.69-bk16/include/acpi/acglobal.h linux-2.5.69-bk17/include/acpi/acglobal.h
--- linux-2.5.69-bk16/include/acpi/acglobal.h	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acglobal.h	2003-05-24 04:33:34.000000000 -0700
@@ -105,6 +105,8 @@
  */
 ACPI_EXTERN u8                                  acpi_gbl_integer_bit_width;
 ACPI_EXTERN u8                                  acpi_gbl_integer_byte_width;
+ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1a_enable;
+ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1b_enable;
 
 /*
  * Since there may be multiple SSDTs and PSDTS, a single pointer is not
@@ -115,15 +117,15 @@
 /*
  * ACPI Table info arrays
  */
-extern      struct acpi_table_desc              acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
-extern      struct acpi_table_support           acpi_gbl_acpi_table_data[NUM_ACPI_TABLES];
+extern      struct acpi_table_list              acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
+extern      struct acpi_table_support           acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES];
 
 /*
  * Predefined mutex objects.  This array contains the
  * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
  * (The table maps local handles to the real OS handles)
  */
-ACPI_EXTERN struct acpi_mutex_info              acpi_gbl_acpi_mutex_info [NUM_MTX];
+ACPI_EXTERN struct acpi_mutex_info              acpi_gbl_mutex_info[NUM_MUTEX];
 
 
 /*****************************************************************************
@@ -134,8 +136,8 @@
 
 
 ACPI_EXTERN struct acpi_memory_list             acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS];
-ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_drv_notify;
-ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_sys_notify;
+ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_device_notify;
+ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_system_notify;
 ACPI_EXTERN acpi_init_handler                   acpi_gbl_init_handler;
 ACPI_EXTERN struct acpi_walk_state             *acpi_gbl_breakpoint_walk;
 ACPI_EXTERN acpi_handle                         acpi_gbl_global_lock_semaphore;
@@ -200,7 +202,7 @@
  ****************************************************************************/
 
 
-ACPI_EXTERN struct acpi_thread_state            *acpi_gbl_current_walk_list;
+ACPI_EXTERN struct acpi_thread_state           *acpi_gbl_current_walk_list;
 
 /* Control method single step flag */
 
@@ -213,7 +215,7 @@
  *
  ****************************************************************************/
 
-ACPI_EXTERN union acpi_parse_object             *acpi_gbl_parsed_namespace_root;
+ACPI_EXTERN union acpi_parse_object            *acpi_gbl_parsed_namespace_root;
 
 /*****************************************************************************
  *
@@ -234,8 +236,8 @@
 
 extern      struct acpi_fixed_event_info        acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
 ACPI_EXTERN struct acpi_fixed_event_handler     acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
-ACPI_EXTERN struct acpi_gpe_xrupt_info          *acpi_gbl_gpe_xrupt_list_head;
-ACPI_EXTERN struct acpi_gpe_block_info          *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
+ACPI_EXTERN struct acpi_gpe_xrupt_info         *acpi_gbl_gpe_xrupt_list_head;
+ACPI_EXTERN struct acpi_gpe_block_info         *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
 ACPI_EXTERN acpi_handle                         acpi_gbl_gpe_lock;
 
 
diff -urN linux-2.5.69-bk16/include/acpi/achware.h linux-2.5.69-bk17/include/acpi/achware.h
--- linux-2.5.69-bk16/include/acpi/achware.h	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/achware.h	2003-05-24 04:33:34.000000000 -0700
@@ -98,15 +98,13 @@
 acpi_hw_low_level_read (
 	u32                             width,
 	u32                             *value,
-	struct acpi_generic_address     *reg,
-	u32                             offset);
+	struct acpi_generic_address     *reg);
 
 acpi_status
 acpi_hw_low_level_write (
 	u32                             width,
 	u32                             value,
-	struct acpi_generic_address     *reg,
-	u32                             offset);
+	struct acpi_generic_address     *reg);
 
 acpi_status
 acpi_hw_clear_acpi_status (
diff -urN linux-2.5.69-bk16/include/acpi/aclocal.h linux-2.5.69-bk17/include/acpi/aclocal.h
--- linux-2.5.69-bk16/include/acpi/aclocal.h	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/aclocal.h	2003-05-24 04:33:34.000000000 -0700
@@ -87,8 +87,8 @@
 #define ACPI_MTX_DEBUG_CMD_COMPLETE     11
 #define ACPI_MTX_DEBUG_CMD_READY        12
 
-#define MAX_MTX                         12
-#define NUM_MTX                         MAX_MTX+1
+#define MAX_MUTEX                       12
+#define NUM_MUTEX                       MAX_MUTEX+1
 
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
@@ -140,12 +140,8 @@
 typedef u16                                     acpi_owner_id;
 #define ACPI_OWNER_TYPE_TABLE           0x0
 #define ACPI_OWNER_TYPE_METHOD          0x1
-#define ACPI_FIRST_METHOD_ID            0x0000
-#define ACPI_FIRST_TABLE_ID             0x8000
-
-/* TBD: [Restructure] get rid of the need for this! */
-
-#define TABLE_ID_DSDT                   (acpi_owner_id) 0x8000
+#define ACPI_FIRST_METHOD_ID            0x0001
+#define ACPI_FIRST_TABLE_ID             0xF000
 
 
 /* Field access granularities */
@@ -232,13 +228,18 @@
 	u64                             physical_address;
 	u32                             aml_length;
 	acpi_size                       length;
-	u32                             count;
 	acpi_owner_id                   table_id;
 	u8                              type;
 	u8                              allocation;
 	u8                              loaded_into_namespace;
 };
 
+struct acpi_table_list
+{
+	struct acpi_table_desc          *next;
+	u32                             count;
+};
+
 
 struct acpi_find_context
 {
@@ -855,16 +856,6 @@
 #define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE     0x8A
 
 
-/* String version of device HIDs and UIDs */
-
-#define ACPI_DEVICE_ID_LENGTH                   0x09
-
-struct acpi_device_id
-{
-	char                    buffer[ACPI_DEVICE_ID_LENGTH];
-};
-
-
 /*****************************************************************************
  *
  * Miscellaneous
diff -urN linux-2.5.69-bk16/include/acpi/acmacros.h linux-2.5.69-bk17/include/acpi/acmacros.h
--- linux-2.5.69-bk16/include/acpi/acmacros.h	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acmacros.h	2003-05-24 04:33:34.000000000 -0700
@@ -441,26 +441,6 @@
 
 
 /*
- * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions)
- *
- * 1) Address space
- * 2) Length in bytes -- convert to length in bits
- * 3) Bit offset is zero
- * 4) Reserved field is zero
- * 5) Expand address to 64 bits
- */
-#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d)   do {a.address_space_id = (u8) d;\
-												a.register_bit_width = (u8) ACPI_MUL_8 (b);\
-												a.register_bit_offset = 0;\
-												a.reserved = 0;\
-												ACPI_STORE_ADDRESS (a.address,(acpi_physical_address) c);} while (0)
-
-/* ACPI V1.0 entries -- address space is always I/O */
-
-#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c)  ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO)
-
-
-/*
  * Reporting macros that are never compiled out
  */
 
diff -urN linux-2.5.69-bk16/include/acpi/acnamesp.h linux-2.5.69-bk17/include/acpi/acnamesp.h
--- linux-2.5.69-bk16/include/acpi/acnamesp.h	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acnamesp.h	2003-05-24 04:33:34.000000000 -0700
@@ -201,6 +201,11 @@
 	char                            *name1,
 	char                            *name2);
 
+void
+acpi_ns_remove_reference (
+	struct acpi_namespace_node      *node);
+
+
 /*
  * Namespace modification - nsmodify
  */
diff -urN linux-2.5.69-bk16/include/acpi/acobject.h linux-2.5.69-bk17/include/acpi/acobject.h
--- linux-2.5.69-bk16/include/acpi/acobject.h	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acobject.h	2003-05-24 04:33:34.000000000 -0700
@@ -112,9 +112,9 @@
  * Common fields for objects that support ASL notifications
  */
 #define ACPI_COMMON_NOTIFY_INFO \
-	union acpi_operand_object               *sys_handler;        /* Handler for system notifies */\
-	union acpi_operand_object               *drv_handler;        /* Handler for driver notifies */\
-	union acpi_operand_object               *addr_handler;       /* Handler for Address space */
+	union acpi_operand_object               *system_notify;     /* Handler for system notifies */\
+	union acpi_operand_object               *device_notify;     /* Handler for driver notifies */\
+	union acpi_operand_object               *address_space;     /* Handler for Address space */
 
 
 /******************************************************************************
@@ -214,7 +214,7 @@
 	ACPI_OBJECT_COMMON_HEADER
 
 	u8                                      space_id;
-	union acpi_operand_object               *addr_handler;      /* Handler for system notifies */
+	union acpi_operand_object               *address_space;     /* Handler for region access */
 	struct acpi_namespace_node              *node;              /* containing object */
 	union acpi_operand_object               *next;
 	u32                                     length;
@@ -446,8 +446,8 @@
 	struct acpi_object_buffer_field         buffer_field;
 	struct acpi_object_bank_field           bank_field;
 	struct acpi_object_index_field          index_field;
-	struct acpi_object_notify_handler       notify_handler;
-	struct acpi_object_addr_handler         addr_handler;
+	struct acpi_object_notify_handler       notify;
+	struct acpi_object_addr_handler         address_space;
 	struct acpi_object_reference            reference;
 	struct acpi_object_extra                extra;
 	struct acpi_object_data                 data;
diff -urN linux-2.5.69-bk16/include/acpi/acpi_bus.h linux-2.5.69-bk17/include/acpi/acpi_bus.h
--- linux-2.5.69-bk16/include/acpi/acpi_bus.h	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acpi_bus.h	2003-05-24 04:33:34.000000000 -0700
@@ -186,6 +186,7 @@
 	acpi_bus_id		bus_id;		               /* Object name */
 	acpi_bus_address	bus_address;	                      /* _ADR */
 	acpi_hardware_id	hardware_id;	                      /* _HID */
+	struct acpi_compatible_id_list *cid_list;		     /* _CIDs */
 	acpi_unique_id		unique_id;	                      /* _UID */
 	acpi_device_name	device_name;	         /* Driver-determined */
 	acpi_device_class	device_class;	         /*        "          */
diff -urN linux-2.5.69-bk16/include/acpi/acpiosxf.h linux-2.5.69-bk17/include/acpi/acpiosxf.h
--- linux-2.5.69-bk16/include/acpi/acpiosxf.h	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acpiosxf.h	2003-05-24 04:33:34.000000000 -0700
@@ -290,12 +290,12 @@
 u8
 acpi_os_readable (
 	void                            *pointer,
-	u32                             length);
+	acpi_size                       length);
 
 u8
 acpi_os_writable (
 	void                            *pointer,
-	u32                             length);
+	acpi_size                       length);
 
 u32
 acpi_os_get_timer (
diff -urN linux-2.5.69-bk16/include/acpi/acpixf.h linux-2.5.69-bk17/include/acpi/acpixf.h
--- linux-2.5.69-bk16/include/acpi/acpixf.h	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acpixf.h	2003-05-24 04:33:34.000000000 -0700
@@ -228,8 +228,8 @@
 
 acpi_status
 acpi_get_object_info (
-	acpi_handle                     device,
-	struct acpi_device_info         *info);
+	acpi_handle                     handle,
+	struct acpi_buffer              *return_buffer);
 
 acpi_status
 acpi_get_next_object (
diff -urN linux-2.5.69-bk16/include/acpi/actables.h linux-2.5.69-bk17/include/acpi/actables.h
--- linux-2.5.69-bk16/include/acpi/actables.h	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/actables.h	2003-05-24 04:33:34.000000000 -0700
@@ -157,7 +157,7 @@
 acpi_status
 acpi_tb_recognize_table (
 	struct acpi_table_desc          *table_info,
-	u8                             search_type);
+	u8                              search_type);
 
 acpi_status
 acpi_tb_init_table_descriptor (
@@ -170,11 +170,11 @@
  */
 
 void
-acpi_tb_delete_acpi_tables (
+acpi_tb_delete_all_tables (
 	void);
 
 void
-acpi_tb_delete_acpi_table (
+acpi_tb_delete_tables_by_type (
 	acpi_table_type                 type);
 
 void
@@ -185,10 +185,6 @@
 acpi_tb_uninstall_table (
 	struct acpi_table_desc          *table_desc);
 
-void
-acpi_tb_free_acpi_tables_of_type (
-	struct acpi_table_desc          *table_info);
-
 
 /*
  * tbrsd - RSDP, RSDT utilities
diff -urN linux-2.5.69-bk16/include/acpi/actypes.h linux-2.5.69-bk17/include/acpi/actypes.h
--- linux-2.5.69-bk16/include/acpi/actypes.h	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/actypes.h	2003-05-24 04:33:34.000000000 -0700
@@ -407,7 +407,7 @@
 #define ACPI_TABLE_SSDT                 (acpi_table_type) 5
 #define ACPI_TABLE_XSDT                 (acpi_table_type) 6
 #define ACPI_TABLE_MAX                  6
-#define NUM_ACPI_TABLES                 (ACPI_TABLE_MAX+1)
+#define NUM_ACPI_TABLE_TYPES            (ACPI_TABLE_MAX+1)
 
 
 /*
@@ -747,7 +747,7 @@
 	u32                                 debug_level;
 	u32                                 debug_layer;
 	u32                                 num_table_types;
-	struct acpi_table_info              table_info [NUM_ACPI_TABLES];
+	struct acpi_table_info              table_info [NUM_ACPI_TABLE_TYPES];
 };
 
 
@@ -832,12 +832,35 @@
 #define ACPI_INTERRUPT_HANDLED          0x01
 
 
-/* Structure and flags for acpi_get_device_info */
+/* Common string version of device HIDs and UIDs */
 
-#define ACPI_VALID_HID                  0x1
-#define ACPI_VALID_UID                  0x2
-#define ACPI_VALID_ADR                  0x4
-#define ACPI_VALID_STA                  0x8
+struct acpi_device_id
+{
+	char                            value[ACPI_DEVICE_ID_LENGTH];
+};
+
+/* Common string version of device CIDs */
+
+struct acpi_compatible_id
+{
+	char                            value[ACPI_MAX_CID_LENGTH];
+};
+
+struct acpi_compatible_id_list
+{
+	u32                             count;
+	u32                             size;
+	struct acpi_compatible_id       id[1];
+};
+
+
+/* Structure and flags for acpi_get_object_info */
+
+#define ACPI_VALID_STA                  0x0001
+#define ACPI_VALID_ADR                  0x0002
+#define ACPI_VALID_HID                  0x0004
+#define ACPI_VALID_UID                  0x0008
+#define ACPI_VALID_CID                  0x0010
 
 
 #define ACPI_COMMON_OBJ_INFO \
@@ -851,15 +874,18 @@
 };
 
 
+/* Structure returned from Get Object Info */
+
 struct acpi_device_info
 {
 	ACPI_COMMON_OBJ_INFO;
 
-	u32                                 valid;              /*  Are the next bits legit? */
-	char                                hardware_id[9];     /*  _HID value if any */
-	char                                unique_id[9];       /*  _UID value if any */
-	acpi_integer                        address;            /*  _ADR value if any */
-	u32                                 current_status;     /*  _STA value */
+	u32                                 valid;              /* Indicates which fields are valid */
+	u32                                 current_status;     /* _STA value */
+	acpi_integer                        address;            /* _ADR value if any */
+	struct acpi_device_id               hardware_id;        /* _HID value if any */
+	struct acpi_device_id               unique_id;          /* _UID value if any */
+	struct acpi_compatible_id_list      compatibility_id;   /* List of _CIDs if any */
 };
 
 
diff -urN linux-2.5.69-bk16/include/acpi/acutils.h linux-2.5.69-bk17/include/acpi/acutils.h
--- linux-2.5.69-bk16/include/acpi/acutils.h	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk17/include/acpi/acutils.h	2003-05-24 04:33:34.000000000 -0700
@@ -488,7 +488,7 @@
 acpi_status
 acpi_ut_execute_CID (
 	struct acpi_namespace_node      *device_node,
-	struct acpi_device_id           *cid);
+	struct acpi_compatible_id_list **return_cid_list);
 
 acpi_status
 acpi_ut_execute_STA (
diff -urN linux-2.5.69-bk16/include/acpi/amlresrc.h linux-2.5.69-bk17/include/acpi/amlresrc.h
--- linux-2.5.69-bk16/include/acpi/amlresrc.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk17/include/acpi/amlresrc.h	2003-05-24 04:33:34.000000000 -0700
@@ -0,0 +1,329 @@
+
+/******************************************************************************
+ *
+ * Module Name: amlresrc.h - AML resource descriptors
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2003, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#ifndef __AMLRESRC_H
+#define __AMLRESRC_H
+
+
+#define ASL_RESNAME_ADDRESS                     "_ADR"
+#define ASL_RESNAME_ALIGNMENT                   "_ALN"
+#define ASL_RESNAME_ADDRESSSPACE                "_ASI"
+#define ASL_RESNAME_BASEADDRESS                 "_BAS"
+#define ASL_RESNAME_BUSMASTER                   "_BM_"  /* Master(1), Slave(0) */
+#define ASL_RESNAME_DECODE                      "_DEC"
+#define ASL_RESNAME_DMA                         "_DMA"
+#define ASL_RESNAME_DMATYPE                     "_TYP"  /* Compatible(0), A(1), B(2), F(3) */
+#define ASL_RESNAME_GRANULARITY                 "_GRA"
+#define ASL_RESNAME_INTERRUPT                   "_INT"
+#define ASL_RESNAME_INTERRUPTLEVEL              "_LL_"  /* active_lo(1), active_hi(0) */
+#define ASL_RESNAME_INTERRUPTSHARE              "_SHR"  /* Shareable(1), no_share(0) */
+#define ASL_RESNAME_INTERRUPTTYPE               "_HE_"  /* Edge(1), Level(0) */
+#define ASL_RESNAME_LENGTH                      "_LEN"
+#define ASL_RESNAME_MEMATTRIBUTES               "_MTP"  /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
+#define ASL_RESNAME_MEMTYPE                     "_MEM"  /* non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
+#define ASL_RESNAME_MAXADDR                     "_MAX"
+#define ASL_RESNAME_MINADDR                     "_MIN"
+#define ASL_RESNAME_MAXTYPE                     "_MAF"
+#define ASL_RESNAME_MINTYPE                     "_MIF"
+#define ASL_RESNAME_REGISTERBITOFFSET           "_RBO"
+#define ASL_RESNAME_REGISTERBITWIDTH            "_RBW"
+#define ASL_RESNAME_RANGETYPE                   "_RNG"
+#define ASL_RESNAME_READWRITETYPE               "_RW_"  /* read_only(0), Writeable (1) */
+#define ASL_RESNAME_TRANSLATION                 "_TRA"
+#define ASL_RESNAME_TRANSTYPE                   "_TRS"  /* Sparse(1), Dense(0) */
+#define ASL_RESNAME_TYPE                        "_TTP"  /* Translation(1), Static (0) */
+#define ASL_RESNAME_XFERTYPE                    "_SIz"  /* 8(0), 8_and16(1), 16(2) */
+
+
+/* Default sizes for "small" resource descriptors */
+
+#define ASL_RDESC_IRQ_SIZE                      0x02
+#define ASL_RDESC_DMA_SIZE                      0x02
+#define ASL_RDESC_ST_DEPEND_SIZE                0x00
+#define ASL_RDESC_END_DEPEND_SIZE               0x00
+#define ASL_RDESC_IO_SIZE                       0x07
+#define ASL_RDESC_FIXED_IO_SIZE                 0x03
+#define ASL_RDESC_END_TAG_SIZE                  0x01
+
+
+struct asl_resource_node
+{
+	u32                                 buffer_length;
+	void                                *buffer;
+	struct asl_resource_node            *next;
+};
+
+
+/*
+ * Resource descriptors defined in the ACPI specification.
+ *
+ * Alignment must be BYTE because these descriptors
+ * are used to overlay the AML byte stream.
+ */
+#pragma pack(1)
+
+struct asl_irq_format_desc
+{
+	u8                                  descriptor_type;
+	u16                                 irq_mask;
+	u8                                  flags;
+};
+
+
+struct asl_irq_noflags_desc
+{
+	u8                                  descriptor_type;
+	u16                                 irq_mask;
+};
+
+
+struct asl_dma_format_desc
+{
+	u8                                  descriptor_type;
+	u8                                  dma_channel_mask;
+	u8                                  flags;
+};
+
+
+struct asl_start_dependent_desc
+{
+	u8                                  descriptor_type;
+	u8                                  flags;
+};
+
+
+struct asl_start_dependent_noprio_desc
+{
+	u8                                  descriptor_type;
+};
+
+
+struct asl_end_dependent_desc
+{
+	u8                                  descriptor_type;
+};
+
+
+struct asl_io_port_desc
+{
+	u8                                  descriptor_type;
+	u8                                  information;
+	u16                                 address_min;
+	u16                                 address_max;
+	u8                                  alignment;
+	u8                                  length;
+};
+
+
+struct asl_fixed_io_port_desc
+{
+	u8                                  descriptor_type;
+	u16                                 base_address;
+	u8                                  length;
+};
+
+
+struct asl_small_vendor_desc
+{
+	u8                                  descriptor_type;
+	u8                                  vendor_defined[7];
+};
+
+
+struct asl_end_tag_desc
+{
+	u8                                  descriptor_type;
+	u8                                  checksum;
+};
+
+
+/* LARGE descriptors */
+
+struct asl_memory_24_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  information;
+	u16                                 address_min;
+	u16                                 address_max;
+	u16                                 alignment;
+	u16                                 range_length;
+};
+
+
+struct asl_large_vendor_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  vendor_defined[1];
+};
+
+
+struct asl_memory_32_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  information;
+	u32                                 address_min;
+	u32                                 address_max;
+	u32                                 alignment;
+	u32                                 range_length;
+};
+
+
+struct asl_fixed_memory_32_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  information;
+	u32                                 base_address;
+	u32                                 range_length;
+};
+
+
+struct asl_qword_address_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  resource_type;
+	u8                                  flags;
+	u8                                  specific_flags;
+	u64                                 granularity;
+	u64                                 address_min;
+	u64                                 address_max;
+	u64                                 translation_offset;
+	u64                                 address_length;
+	u8                                  optional_fields[2];
+};
+
+
+struct asl_dword_address_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  resource_type;
+	u8                                  flags;
+	u8                                  specific_flags;
+	u32                                 granularity;
+	u32                                 address_min;
+	u32                                 address_max;
+	u32                                 translation_offset;
+	u32                                 address_length;
+	u8                                  optional_fields[2];
+};
+
+
+struct asl_word_address_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  resource_type;
+	u8                                  flags;
+	u8                                  specific_flags;
+	u16                                 granularity;
+	u16                                 address_min;
+	u16                                 address_max;
+	u16                                 translation_offset;
+	u16                                 address_length;
+	u8                                  optional_fields[2];
+};
+
+
+struct asl_extended_xrupt_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  flags;
+	u8                                  table_length;
+	u32                                 interrupt_number[1];
+	/* res_source_index, res_source optional fields follow */
+};
+
+
+struct asl_general_register_desc
+{
+	u8                                  descriptor_type;
+	u16                                 length;
+	u8                                  address_space_id;
+	u8                                  bit_width;
+	u8                                  bit_offset;
+	u8                                  reserved;
+	u64                                 address;
+};
+
+/* restore default alignment */
+
+#pragma pack()
+
+/* Union of all resource descriptors, sow we can allocate the worst case */
+
+union asl_resource_desc
+{
+	struct asl_irq_format_desc          irq;
+	struct asl_dma_format_desc          dma;
+	struct asl_start_dependent_desc     std;
+	struct asl_end_dependent_desc       end;
+	struct asl_io_port_desc             iop;
+	struct asl_fixed_io_port_desc       fio;
+	struct asl_small_vendor_desc        smv;
+	struct asl_end_tag_desc             et;
+
+	struct asl_memory_24_desc           M24;
+	struct asl_large_vendor_desc        lgv;
+	struct asl_memory_32_desc           M32;
+	struct asl_fixed_memory_32_desc     F32;
+	struct asl_qword_address_desc       qas;
+	struct asl_dword_address_desc       das;
+	struct asl_word_address_desc        was;
+	struct asl_extended_xrupt_desc      exx;
+	struct asl_general_register_desc    grg;
+	u32                                 u32_item;
+	u16                                 u16_item;
+	u8                                  U8item;
+};
+
+
+#endif
+
diff -urN linux-2.5.69-bk16/include/asm-x86_64/apic.h linux-2.5.69-bk17/include/asm-x86_64/apic.h
--- linux-2.5.69-bk16/include/asm-x86_64/apic.h	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/apic.h	2003-05-24 04:33:34.000000000 -0700
@@ -9,7 +9,7 @@
 
 #ifdef CONFIG_X86_LOCAL_APIC
 
-#define APIC_DEBUG 1
+#define APIC_DEBUG 0
 
 #if APIC_DEBUG
 #define Dprintk(x...) printk(x)
diff -urN linux-2.5.69-bk16/include/asm-x86_64/calling.h linux-2.5.69-bk17/include/asm-x86_64/calling.h
--- linux-2.5.69-bk16/include/asm-x86_64/calling.h	2003-05-04 16:53:33.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/calling.h	2003-05-24 04:33:34.000000000 -0700
@@ -84,8 +84,9 @@
 	movq \offset+72(%rsp),%rax
 	.endm
 			
+#define REST_SKIP 6*8			
 	.macro SAVE_REST
-	subq $6*8,%rsp
+	subq $REST_SKIP,%rsp
 	movq %rbx,5*8(%rsp) 
 	movq %rbp,4*8(%rsp) 
 	movq %r12,3*8(%rsp) 
@@ -94,7 +95,6 @@
 	movq %r15,(%rsp) 
 	.endm		
 
-#define REST_SKIP 6*8
 	.macro RESTORE_REST
 	movq (%rsp),%r15
 	movq 1*8(%rsp),%r14
diff -urN linux-2.5.69-bk16/include/asm-x86_64/compat.h linux-2.5.69-bk17/include/asm-x86_64/compat.h
--- linux-2.5.69-bk16/include/asm-x86_64/compat.h	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/compat.h	2003-05-24 04:33:34.000000000 -0700
@@ -1,9 +1,11 @@
 #ifndef _ASM_X86_64_COMPAT_H
 #define _ASM_X86_64_COMPAT_H
+
 /*
  * Architecture specific compatibility types
  */
 #include <linux/types.h>
+#include <linux/sched.h>
 
 #define COMPAT_USER_HZ	100
 
diff -urN linux-2.5.69-bk16/include/asm-x86_64/debugreg.h linux-2.5.69-bk17/include/asm-x86_64/debugreg.h
--- linux-2.5.69-bk16/include/asm-x86_64/debugreg.h	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/debugreg.h	2003-05-24 04:33:34.000000000 -0700
@@ -58,7 +58,7 @@
    We can slow the instruction pipeline for instructions coming via the
    gdt or the ldt if we want to.  I am not sure why this is an advantage */
 
-#define DR_CONTROL_RESERVED (0xFFFFFFFFFC00) /* Reserved by Intel */
+#define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL) /* Reserved */
 #define DR_LOCAL_SLOWDOWN (0x100)   /* Local slow the pipeline */
 #define DR_GLOBAL_SLOWDOWN (0x200)  /* Global slow the pipeline */
 
diff -urN linux-2.5.69-bk16/include/asm-x86_64/e820.h linux-2.5.69-bk17/include/asm-x86_64/e820.h
--- linux-2.5.69-bk16/include/asm-x86_64/e820.h	2003-05-04 16:53:34.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/e820.h	2003-05-24 04:33:34.000000000 -0700
@@ -50,7 +50,7 @@
 extern unsigned long e820_end_of_ram(void);
 extern void e820_reserve_resources(void);
 extern void e820_print_map(char *who);
-extern int e820_mapped(unsigned long start, unsigned long end, int type);
+extern int e820_mapped(unsigned long start, unsigned long end, unsigned type);
 
 extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
 
diff -urN linux-2.5.69-bk16/include/asm-x86_64/floppy.h linux-2.5.69-bk17/include/asm-x86_64/floppy.h
--- linux-2.5.69-bk16/include/asm-x86_64/floppy.h	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/floppy.h	2003-05-24 04:33:34.000000000 -0700
@@ -64,7 +64,7 @@
 #endif
 	if(!doing_pdma) {
 		floppy_interrupt(irq, dev_id, regs);
-		return;
+		return IRQ_HANDLED;
 	}
 
 #ifdef TRACE_FLPY_INT
@@ -96,7 +96,7 @@
 	calls++;
 #endif
 	if(st == 0x20)
-		return;
+		return IRQ_HANDLED;
 	if(!(st & 0x20)) {
 		virtual_dma_residue += virtual_dma_count;
 		virtual_dma_count=0;
diff -urN linux-2.5.69-bk16/include/asm-x86_64/i387.h linux-2.5.69-bk17/include/asm-x86_64/i387.h
--- linux-2.5.69-bk16/include/asm-x86_64/i387.h	2003-05-04 16:53:29.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/i387.h	2003-05-24 04:33:34.000000000 -0700
@@ -17,6 +17,7 @@
 #include <asm/sigcontext.h>
 #include <asm/user.h>
 #include <asm/thread_info.h>
+#include <asm/uaccess.h>
 
 extern void fpu_init(void);
 extern void init_fpu(struct task_struct *child);
@@ -91,6 +92,8 @@
 		     ".previous"
 		     : [err] "=r" (err)
 		     : [fx] "r" (fx), "0" (0)); 
+	if (unlikely(err))
+		init_fpu(current);
 	return err;
 } 
 
@@ -109,6 +112,8 @@
 		     ".previous"
 		     : [err] "=r" (err)
 		     : [fx] "r" (fx), "0" (0)); 
+	if (unlikely(err))
+		__clear_user(fx, sizeof(struct i387_fxsave_struct));
 	return err;
 } 
 
diff -urN linux-2.5.69-bk16/include/asm-x86_64/ia32.h linux-2.5.69-bk17/include/asm-x86_64/ia32.h
--- linux-2.5.69-bk16/include/asm-x86_64/ia32.h	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/ia32.h	2003-05-24 04:33:34.000000000 -0700
@@ -133,6 +133,25 @@
 	} _sifields;
 } siginfo_t32;
 
+struct sigframe32
+{
+        u32 pretcode;
+        int sig;
+        struct sigcontext_ia32 sc;
+        struct _fpstate_ia32 fpstate;
+        unsigned int extramask[_COMPAT_NSIG_WORDS-1];
+};
+
+struct rt_sigframe32
+{
+        u32 pretcode;
+        int sig;
+        u32 pinfo;
+        u32 puc;
+        struct siginfo32 info;
+        struct ucontext_ia32 uc;
+        struct _fpstate_ia32 fpstate;
+};
 
 struct ustat32 {
 	__u32	f_tfree;
diff -urN linux-2.5.69-bk16/include/asm-x86_64/io.h linux-2.5.69-bk17/include/asm-x86_64/io.h
--- linux-2.5.69-bk16/include/asm-x86_64/io.h	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/io.h	2003-05-24 04:33:34.000000000 -0700
@@ -120,6 +120,7 @@
   #define __io_virt(x) ((void *)(x))
 #endif
 
+#ifndef __i386__
 /*
  * Change virtual addresses to physical addresses and vv.
  * These are pretty trivial
@@ -133,6 +134,7 @@
 {
 	return __va(address);
 }
+#endif
 
 /*
  * Change "struct page" to physical address.
@@ -259,6 +261,7 @@
 	return retval;
 }
 
+#ifndef __i386__
 /**
  *	isa_check_signature		-	find BIOS signatures
  *	@io_addr: mmio address to check 
@@ -288,6 +291,7 @@
 out:
 	return retval;
 }
+#endif
 
 /* Nothing to do */
 
diff -urN linux-2.5.69-bk16/include/asm-x86_64/irq.h linux-2.5.69-bk17/include/asm-x86_64/irq.h
--- linux-2.5.69-bk16/include/asm-x86_64/irq.h	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/irq.h	2003-05-24 04:33:34.000000000 -0700
@@ -32,4 +32,8 @@
 extern void disable_irq_nosync(unsigned int);
 extern void enable_irq(unsigned int);
 
+#ifdef CONFIG_X86_LOCAL_APIC
+#define ARCH_HAS_NMI_WATCHDOG		/* See include/linux/nmi.h */
+#endif
+
 #endif /* _ASM_IRQ_H */
diff -urN linux-2.5.69-bk16/include/asm-x86_64/page.h linux-2.5.69-bk17/include/asm-x86_64/page.h
--- linux-2.5.69-bk16/include/asm-x86_64/page.h	2003-05-04 16:53:00.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/page.h	2003-05-24 04:33:34.000000000 -0700
@@ -58,9 +58,13 @@
 #define __pte(x) ((pte_t) { (x) } )
 #define __pmd(x) ((pmd_t) { (x) } )
 #define __pgd(x) ((pgd_t) { (x) } )
-#define __level4(x) ((level4_t) { (x) } )
+#define __pml4(x) ((pml4_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
+extern unsigned long vm_stack_flags, vm_stack_flags32;
+extern unsigned long vm_data_default_flags, vm_data_default_flags32;
+extern unsigned long vm_force_exec32;
+
 #endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
@@ -119,9 +123,19 @@
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 
-#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
+#define __VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#define __VM_STACK_FLAGS 	(VM_GROWSDOWN | VM_READ | VM_WRITE | VM_EXEC | \
                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define VM_DATA_DEFAULT_FLAGS \
+	(test_thread_flag(TIF_IA32) ? vm_data_default_flags32 : \
+	  vm_data_default_flags) 
+
+#define VM_STACK_DEFAULT_FLAGS \
+	(test_thread_flag(TIF_IA32) ? vm_stack_flags32 : vm_stack_flags) 
+	
+
 #endif /* __KERNEL__ */
 
 #endif /* _X86_64_PAGE_H */
diff -urN linux-2.5.69-bk16/include/asm-x86_64/pci.h linux-2.5.69-bk17/include/asm-x86_64/pci.h
--- linux-2.5.69-bk16/include/asm-x86_64/pci.h	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/pci.h	2003-05-24 04:33:34.000000000 -0700
@@ -76,8 +76,8 @@
  * Once the device is given the dma address, the device owns this memory
  * until either pci_unmap_single or pci_dma_sync_single is performed.
  */
-extern dma_addr_t __pci_map_single(struct pci_dev *hwdev, void *ptr,
-			  size_t size, int direction, int flush);
+extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, 
+				 int direction);
 
 
 void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t addr,
@@ -126,8 +126,8 @@
 
 
 #else
-static inline dma_addr_t __pci_map_single(struct pci_dev *hwdev, void *ptr,
-					size_t size, int direction, int flush)
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+					size_t size, int direction)
 {
 	dma_addr_t addr; 
 
@@ -214,12 +214,6 @@
 extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 			 int nents, int direction);
 
-static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
-			  size_t size, int direction)
-{
-	return __pci_map_single(hwdev,ptr,size,direction,1); 
-}
-
 #define pci_unmap_page pci_unmap_single
 
 /* Return whether the given PCI device DMA address mask can
diff -urN linux-2.5.69-bk16/include/asm-x86_64/pda.h linux-2.5.69-bk17/include/asm-x86_64/pda.h
--- linux-2.5.69-bk16/include/asm-x86_64/pda.h	2003-05-04 16:53:12.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/pda.h	2003-05-24 04:33:34.000000000 -0700
@@ -46,11 +46,11 @@
 #define pda_to_op(op,field,val) do { \
        switch (sizeof_field(struct x8664_pda, field)) { 		\
 case 2: \
-asm volatile(op "w %0,%%gs:%c1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
+asm volatile(op "w %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
 case 4: \
-asm volatile(op "l %0,%%gs:%c1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
+asm volatile(op "l %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
 case 8: \
-asm volatile(op "q %0,%%gs:%c1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
+asm volatile(op "q %0,%%gs:%P1"::"r" (val),"i"(pda_offset(field)):"memory"); break; \
        default: __bad_pda_field(); 					\
        } \
        } while (0)
@@ -63,11 +63,11 @@
        typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \
        switch (sizeof_field(struct x8664_pda, field)) { 		\
 case 2: \
-asm volatile(op "w %%gs:%c1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
+asm volatile(op "w %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
 case 4: \
-asm volatile(op "l %%gs:%c1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
+asm volatile(op "l %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
 case 8: \
-asm volatile(op "q %%gs:%c1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
+asm volatile(op "q %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
        default: __bad_pda_field(); 					\
        } \
        ret__; })
diff -urN linux-2.5.69-bk16/include/asm-x86_64/pgtable.h linux-2.5.69-bk17/include/asm-x86_64/pgtable.h
--- linux-2.5.69-bk16/include/asm-x86_64/pgtable.h	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/pgtable.h	2003-05-24 04:33:34.000000000 -0700
@@ -28,6 +28,7 @@
 #define swapper_pg_dir NULL
 
 extern void paging_init(void);
+extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
 
 extern unsigned long pgkern_mask;
 
@@ -165,11 +166,11 @@
 #define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
 #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
 #define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_COPY    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
+#define PAGE_COPY PAGE_COPY_NOEXEC
 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-
 #define __PAGE_KERNEL \
 	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
 #define __PAGE_KERNEL_EXECUTABLE \
@@ -181,7 +182,7 @@
 #define __PAGE_KERNEL_VSYSCALL \
 	(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 #define __PAGE_KERNEL_LARGE \
-	(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PSE | _PAGE_NX)
+	(__PAGE_KERNEL | _PAGE_PSE)
 
 #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL)
 
@@ -241,6 +242,7 @@
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
+static inline int pte_user(pte_t pte)		{ return pte_val(pte) & _PAGE_USER; }
 extern inline int pte_read(pte_t pte)		{ return pte_val(pte) & _PAGE_USER; }
 extern inline int pte_exec(pte_t pte)		{ return pte_val(pte) & _PAGE_USER; }
 extern inline int pte_dirty(pte_t pte)		{ return pte_val(pte) & _PAGE_DIRTY; }
diff -urN linux-2.5.69-bk16/include/asm-x86_64/processor.h linux-2.5.69-bk17/include/asm-x86_64/processor.h
--- linux-2.5.69-bk16/include/asm-x86_64/processor.h	2003-05-04 16:53:55.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/processor.h	2003-05-24 04:33:34.000000000 -0700
@@ -218,14 +218,18 @@
 
 struct thread_struct {
 	unsigned long	rsp0;
-	unsigned long	rip;
 	unsigned long	rsp;
 	unsigned long 	userrsp;	/* Copy from PDA */ 
 	unsigned long	fs;
 	unsigned long	gs;
 	unsigned short	es, ds, fsindex, gsindex;	
 /* Hardware debugging registers */
-	unsigned long	debugreg[8];  /* %%db0-7 debug registers */
+	unsigned long	debugreg0;  
+	unsigned long	debugreg1;  
+	unsigned long	debugreg2;  
+	unsigned long	debugreg3;  
+	unsigned long	debugreg6;  
+	unsigned long	debugreg7;  
 /* fault info */
 	unsigned long	cr2, trap_no, error_code;
 /* floating point info */
@@ -304,17 +308,30 @@
 
 #define cpu_has_fpu 1
 
-#if 0
-/* disabled for now to work around opteron errata #91. Also gcc 3.2
-   doesn't like this in some cases. */
+/* Some early Opteron versions incorrectly fault on prefetch (errata #91). 
+   If this happens just jump back. */
 #define ARCH_HAS_PREFETCH
-#define prefetch(x) __builtin_prefetch((x),0,1)
-#endif
+static inline void prefetch(void *x) 
+{ 
+	asm volatile("2: prefetchnta %0\n1:\t" 
+		    ".section __ex_table,\"a\"\n\t"
+		    "  .align 8\n\t"
+		    "  .quad  2b,1b\n\t"
+		    ".previous" :: "m" (*(unsigned long *)x));
+} 
 
 #define ARCH_HAS_PREFETCHW
+static inline void prefetchw(void *x) 
+{ 
+	asm volatile("2: prefetchw %0\n1:\t" 
+		    ".section __ex_table,\"a\"\n\t"
+		    "  .align 8\n\t"
+		    "  .quad  2b,1b\n\t"
+		    ".previous" :: "m" (*(unsigned long *)x));
+} 
+
 #define ARCH_HAS_SPINLOCK_PREFETCH
 
-#define prefetchw(x) __builtin_prefetch((x),1,1)
 #define spin_lock_prefetch(x)  prefetchw(x)
 #define cpu_relax()   rep_nop()
 
diff -urN linux-2.5.69-bk16/include/asm-x86_64/segment.h linux-2.5.69-bk17/include/asm-x86_64/segment.h
--- linux-2.5.69-bk16/include/asm-x86_64/segment.h	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/segment.h	2003-05-24 04:33:34.000000000 -0700
@@ -18,6 +18,7 @@
 #define __USER_CS     0x33   /* 6*8+3 */ 
 #define __USER32_DS	__USER_DS 
 #define __KERNEL16_CS	(GDT_ENTRY_KERNELCS16 * 8)
+#define __KERNEL_COMPAT32_CS   0x8
 
 #define GDT_ENTRY_TLS 1
 #define GDT_ENTRY_TSS 8	/* needs two entries */
diff -urN linux-2.5.69-bk16/include/asm-x86_64/suspend.h linux-2.5.69-bk17/include/asm-x86_64/suspend.h
--- linux-2.5.69-bk16/include/asm-x86_64/suspend.h	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/suspend.h	2003-05-24 04:33:34.000000000 -0700
@@ -54,13 +54,6 @@
 extern unsigned long saved_esi;
 extern unsigned long saved_edi;
 
-static inline void acpi_save_register_state(unsigned long return_point)
-{
-	/* FIXME: This is probably no longer correct: we need to save all caller-saved registers */
-}
-
-#define acpi_restore_register_state()  do {} while (0)
-
 /* routines for saving/restoring kernel state */
 extern int acpi_save_state_mem(void);
 extern int acpi_save_state_disk(void);
diff -urN linux-2.5.69-bk16/include/asm-x86_64/system.h linux-2.5.69-bk17/include/asm-x86_64/system.h
--- linux-2.5.69-bk16/include/asm-x86_64/system.h	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/system.h	2003-05-24 04:33:34.000000000 -0700
@@ -16,9 +16,14 @@
 #define __STR(x) #x
 #define STR(x) __STR(x)
 
-#define __PUSH(x) "pushq %%" __STR(x) "\n\t"
-#define __POP(x)  "popq  %%" __STR(x) "\n\t"
+#define __SAVE(reg,offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
+#define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
 
+#ifdef CONFIG_X86_REMOTE_DEBUG
+
+/* full frame for the debug stub */
+/* Should be replaced with a dwarf2 cie/fde description, then gdb could
+   figure it out all by itself. */
 struct save_context_frame { 
 	unsigned long rbp; 
 	unsigned long rbx;
@@ -34,46 +39,64 @@
 	unsigned long r12;
 	unsigned long rdi;
 	unsigned long rsi;
+	unsigned long flags;
 }; 
 
-/* frame pointer must be last for get_wchan */
-/* It would be more efficient to let the compiler clobber most of these registers.
-   Clobbering all is not possible because that lets reload freak out. Even just 
-   clobbering six generates wrong code with gcc 3.1 for me so do it this way for now.
-   rbp needs to be always explicitly saved because gcc cannot clobber the
-   frame pointer and the scheduler is compiled with frame pointers. -AK */
 #define SAVE_CONTEXT \
-	__PUSH(rsi) __PUSH(rdi) \
-    __PUSH(r12) __PUSH(r13) __PUSH(r14) __PUSH(r15)  \
-	__PUSH(rdx) __PUSH(rcx) __PUSH(r8) __PUSH(r9) __PUSH(r10) __PUSH(r11)  \
-	__PUSH(rbx) __PUSH(rbp) 
+	"pushfq\n\t"							\
+	"subq $14*8,%%rsp\n\t" 						\
+	__SAVE(rbx, 12) __SAVE(rdi,  1)					\
+	__SAVE(rdx,  6) __SAVE(rcx,  7)					\
+	__SAVE(r8,   8) __SAVE(r9,   9)					\
+	__SAVE(r12,  2) __SAVE(r13,  3)					\
+	__SAVE(r14,  4) __SAVE(r15,  5)					\
+	__SAVE(r10, 10) __SAVE(r11, 11)					\
+	__SAVE(rsi, 0)  __SAVE(rbp, 13) 				\
+
+
 #define RESTORE_CONTEXT \
-	__POP(rbp) __POP(rbx) \
-	__POP(r11) __POP(r10) __POP(r9) __POP(r8) __POP(rcx) __POP(rdx) \
-	__POP(r15) __POP(r14) __POP(r13) __POP(r12) \
-	__POP(rdi) __POP(rsi)
+	__RESTORE(rbx, 12) __RESTORE(rdi,  1) 					\
+	__RESTORE(rdx,  6) __RESTORE(rcx,  7)					\
+	__RESTORE(r12,  2) __RESTORE(r13,  3)					\
+	__RESTORE(r14,  4) __RESTORE(r15,  5)					\
+	__RESTORE(r10, 10) __RESTORE(r11, 11)					\
+	__RESTORE(r8,   8) __RESTORE(r9,   9)					\
+	__RESTORE(rbp, 13) __RESTORE(rsi, 0) 		   		        \
+	"addq $14*8,%%rsp\n\t" 							\
+	"popfq\n\t"
+
+#define __EXTRA_CLOBBER 
 
-/* RED-PEN: pipeline stall on ret because it is not predicted */
-/* RED-PEN: the register saving could be optimized */
+#else
 /* frame pointer must be last for get_wchan */
+#define SAVE_CONTEXT    "pushfq ; pushq %%rbp ; movq %%rsi,%%rbp\n\t"
+#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popfq\n\t" 
+
+#define __EXTRA_CLOBBER  \
+	,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15"
+#endif
 
 #define switch_to(prev,next,last) \
 	asm volatile(SAVE_CONTEXT						    \
-		     "movq %%rsp,%[prevrsp]\n\t"				    \
-		     "movq %[nextrsp],%%rsp\n\t"				    \
-		     "movq $thread_return,%[prevrip]\n\t"			   \
-		     "pushq %[nextrip]\n\t"					    \
-		     "jmp __switch_to\n\t"		\
+		     "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */	  \
+		     "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */	  \
+		     "call __switch_to\n\t"					  \
 		     ".globl thread_return\n"					\
 		     "thread_return:\n\t"					    \
+		     "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"			  \
+		     "movq %P[thread_info](%%rsi),%%r8\n\t"			  \
+		     "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"			  \
+		     "movq %%rax,%%rdi\n\t" 					  \
+		     "jc   ret_from_fork\n\t"					  \
 		     RESTORE_CONTEXT						    \
-		     :[prevrsp] "=m" (prev->thread.rsp), 			    \
-		      [prevrip] "=m" (prev->thread.rip),		    	    \
-		      "=a" (last)						    \
-		     :[nextrsp] "m" (next->thread.rsp), 			    \
-		      [nextrip] "m" (next->thread.rip),				    \
-		      [next] "S" (next), [prev] "D" (prev)  			    \
-	             :"memory")
+		     : "=a" (last)					  	  \
+		     : [next] "S" (next), [prev] "D" (prev),			  \
+		       [threadrsp] "i" (offsetof(struct task_struct, thread.rsp)), \
+		       [ti_flags] "i" (offsetof(struct thread_info, flags)),\
+		       [tif_fork] "i" (TIF_FORK),			  \
+		       [thread_info] "i" (offsetof(struct task_struct, thread_info)), \
+		       [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))   \
+		     : "memory", "cc" __EXTRA_CLOBBER)
     
 extern void load_gs_index(unsigned); 
 
@@ -88,14 +111,14 @@
 		"2:\n"				\
 		".section .fixup,\"ax\"\n"	\
 		"3:\t"				\
-		"pushq $0 ; popq %% " #seg "\n\t"	\
+		"movl %1,%%" #seg "\n\t" 	\
 		"jmp 2b\n"			\
 		".previous\n"			\
 		".section __ex_table,\"a\"\n\t"	\
 		".align 8\n\t"			\
 		".quad 1b,3b\n"			\
 		".previous"			\
-		: :"r" (value))
+		: :"r" (value), "r" (0))
 
 #define set_debug(value,register) \
                 __asm__("movq %0,%%db" #register  \
@@ -298,4 +321,7 @@
 void disable_hlt(void);
 void enable_hlt(void);
 
+#define HAVE_EAT_KEY
+void eat_key(void);
+
 #endif
diff -urN linux-2.5.69-bk16/include/asm-x86_64/thread_info.h linux-2.5.69-bk17/include/asm-x86_64/thread_info.h
--- linux-2.5.69-bk16/include/asm-x86_64/thread_info.h	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/thread_info.h	2003-05-24 04:33:34.000000000 -0700
@@ -68,7 +68,7 @@
 static inline struct thread_info *stack_thread_info(void)
 {
 	struct thread_info *ti;
-	__asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~8191UL));
+	__asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));
 	return ti;
 }
 
@@ -104,6 +104,7 @@
 #define TIF_IRET		5	/* force IRET */
 #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_IA32		17	/* 32bit process */ 
+#define TIF_FORK		18	/* ret_from_fork */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
@@ -113,6 +114,7 @@
 #define _TIF_IRET		(1<<TIF_IRET)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_IA32		(1<<TIF_IA32)
+#define _TIF_FORK		(1<<TIF_FORK)
 
 #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
diff -urN linux-2.5.69-bk16/include/asm-x86_64/user.h linux-2.5.69-bk17/include/asm-x86_64/user.h
--- linux-2.5.69-bk16/include/asm-x86_64/user.h	2003-05-04 16:53:40.000000000 -0700
+++ linux-2.5.69-bk17/include/asm-x86_64/user.h	2003-05-24 04:33:34.000000000 -0700
@@ -52,13 +52,13 @@
 	unsigned short	swd;
 	unsigned short	twd; /* Note this is not the same as the 32bit/x87/FSAVE twd */
 	unsigned short	fop;
-	u64	rip;
-	u64	rdp;
-	u32	mxcsr;
-	u32	mxcsr_mask;
-	u32	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
-	u32	xmm_space[64];	/* 16*16 bytes for each XMM-reg = 256 bytes */
-	u32	padding[24];
+	__u64	rip;
+	__u64	rdp;
+	__u32	mxcsr;
+	__u32	mxcsr_mask;
+	__u32	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
+	__u32	xmm_space[64];	/* 16*16 bytes for each XMM-reg = 256 bytes */
+	__u32	padding[24];
 };
 
 /*
diff -urN linux-2.5.69-bk16/include/asm-x86_64/vsyscall32.h linux-2.5.69-bk17/include/asm-x86_64/vsyscall32.h
--- linux-2.5.69-bk16/include/asm-x86_64/vsyscall32.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk17/include/asm-x86_64/vsyscall32.h	2003-05-24 04:33:34.000000000 -0700
@@ -0,0 +1,13 @@
+#ifndef _ASM_VSYSCALL32_H
+#define _ASM_VSYSCALL32_H 1
+
+/* Values need to match arch/x86_64/ia32/vsyscall.lds */
+
+#define VSYSCALL32_BASE 0xffffe000UL
+#define VSYSCALL32_EHDR ((const struct elf32_hdr *) VSYSCALL32_BASE)
+
+#define VSYSCALL32_VSYSCALL ((void *)VSYSCALL32_BASE + 0x400) 
+#define VSYSCALL32_SIGRETURN ((void *)VSYSCALL32_BASE + 0x500) 
+#define VSYSCALL32_RTSIGRETURN ((void *)VSYSCALL32_BASE + 0x500) 
+
+#endif
diff -urN linux-2.5.69-bk16/include/linux/ide.h linux-2.5.69-bk17/include/linux/ide.h
--- linux-2.5.69-bk16/include/linux/ide.h	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk17/include/linux/ide.h	2003-05-24 04:33:34.000000000 -0700
@@ -886,6 +886,8 @@
 	
 	struct pnp_dev  *pnp_dev;	/* for PnP devices */
 
+	ide_startstop_t (*rw_disk)(ide_drive_t *, struct request *, sector_t);
+
 #if 0
 	ide_hwif_ops_t	*hwifops;
 #else
@@ -1001,6 +1003,7 @@
 
 	unsigned	noprobe    : 1;	/* don't probe for this interface */
 	unsigned	present    : 1;	/* this interface exists */
+	unsigned	hold       : 1; /* this interface is always present */
 	unsigned	serialized : 1;	/* serialized all channel operation */
 	unsigned	sharing_irq: 1;	/* 1 = sharing irq with another hwif */
 	unsigned	reset      : 1;	/* reset after probe */
@@ -1534,6 +1537,8 @@
 extern int set_transfer(ide_drive_t *, ide_task_t *);
 extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);
 
+ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block);
+
 /*
  * ide_system_bus_speed() returns what we think is the system VESA/PCI
  * bus speed (in MHz).  This is used for calculating interface PIO timings.
diff -urN linux-2.5.69-bk16/include/linux/pci_ids.h linux-2.5.69-bk17/include/linux/pci_ids.h
--- linux-2.5.69-bk16/include/linux/pci_ids.h	2003-05-24 04:33:29.000000000 -0700
+++ linux-2.5.69-bk17/include/linux/pci_ids.h	2003-05-24 04:33:34.000000000 -0700
@@ -557,6 +557,7 @@
 #define PCI_DEVICE_ID_SI_650		0x0650
 #define PCI_DEVICE_ID_SI_651		0x0651
 #define PCI_DEVICE_ID_SI_652		0x0652
+#define PCI_DEVICE_ID_SI_655		0x0655
 #define PCI_DEVICE_ID_SI_730		0x0730
 #define PCI_DEVICE_ID_SI_630_VGA	0x6300
 #define PCI_DEVICE_ID_SI_730_VGA	0x7300
@@ -1127,6 +1128,7 @@
 #define PCI_DEVICE_ID_VIA_8753_0	0x3128
 #define PCI_DEVICE_ID_VIA_8233A		0x3147
 #define PCI_DEVICE_ID_VIA_8752		0x3148
+#define PCI_DEVICE_ID_VIA_8237_SATA	0x3149
 #define PCI_DEVICE_ID_VIA_KN266		0x3156
 #define PCI_DEVICE_ID_VIA_8754		0x3168
 #define PCI_DEVICE_ID_VIA_8235		0x3177
@@ -1135,6 +1137,7 @@
 #define PCI_DEVICE_ID_VIA_8377_0	0x3189
 #define PCI_DEVICE_ID_VIA_KM400		0x3205
 #define PCI_DEVICE_ID_VIA_P4M400	0x3209
+#define PCI_DEVICE_ID_VIA_8237		0x3227
 #define PCI_DEVICE_ID_VIA_86C100A	0x6100
 #define PCI_DEVICE_ID_VIA_8231		0x8231
 #define PCI_DEVICE_ID_VIA_8231_4	0x8235
@@ -1893,6 +1896,7 @@
 #define PCI_DEVICE_ID_INTEL_82801DB_12  0x24cc
 #define PCI_DEVICE_ID_INTEL_82801DB_13	0x24cd
 #define PCI_DEVICE_ID_INTEL_82801EB_0	0x24d0
+#define PCI_DEVICE_ID_INTEL_82801EB_1	0x24d1
 #define PCI_DEVICE_ID_INTEL_82801EB_2	0x24d2
 #define PCI_DEVICE_ID_INTEL_82801EB_3	0x24d3
 #define PCI_DEVICE_ID_INTEL_82801EB_4	0x24d4
