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

diff -urN linux-2.5.63-bk4/Documentation/DocBook/Makefile linux-2.5.63-bk5/Documentation/DocBook/Makefile
--- linux-2.5.63-bk4/Documentation/DocBook/Makefile	Mon Feb 24 11:05:31 2003
+++ linux-2.5.63-bk5/Documentation/DocBook/Makefile	Mon Mar 31 12:18:55 2003
@@ -11,7 +11,7 @@
 	    kernel-locking.sgml via-audio.sgml mousedrivers.sgml \
 	    deviceiobook.sgml procfs-guide.sgml tulip-user.sgml \
 	    writing_usb_driver.sgml scsidrivers.sgml sis900.sgml \
-	    kernel-api.sgml journal-api.sgml lsm.sgml
+	    kernel-api.sgml journal-api.sgml lsm.sgml usb.sgml
 
 ###
 # The build process is as follows (targets):
diff -urN linux-2.5.63-bk4/Documentation/DocBook/kernel-api.tmpl linux-2.5.63-bk5/Documentation/DocBook/kernel-api.tmpl
--- linux-2.5.63-bk4/Documentation/DocBook/kernel-api.tmpl	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk5/Documentation/DocBook/kernel-api.tmpl	Mon Mar 31 12:18:55 2003
@@ -228,102 +228,6 @@
 -->
   </chapter>
 
-  <chapter id="usb">
-    <title>USB Devices</title>
-
-    <para>Drivers for USB devices talk to the "usbcore" APIs, and are
-    exposed through driver frameworks such as block, character,
-    or network devices.
-    There are two types of public "usbcore" APIs:  those intended for
-    general driver use, and those which are only public to drivers that
-    are part of the core.
-    The drivers that are part of the core are involved in managing a USB bus.
-    They include the "hub" driver, which manages trees of USB devices, and
-    several different kinds of "host controller" driver (HCD), which control
-    individual busses.
-    </para>
-
-    <para>The device model seen by USB drivers is relatively complex.
-    </para>
-     
-    <itemizedlist>
-
-	<listitem><para>USB supports four kinds of data transfer
-	(control, bulk, interrupt, and isochronous).  Two transfer
-	types use bandwidth as it's available (control and bulk),
-	while the other two types of transfer (interrupt and isochronous)
-	are scheduled to provide guaranteed bandwidth.
-	</para></listitem>
-
-	<listitem><para>The device description model includes one or more
-	"configurations" per device, only one of which is active at a time.
-	</para></listitem>
-
-	<listitem><para>Configurations have one or more "interface", each
-	of which may have "alternate settings".  Interfaces may be
-	standardized by USB "Class" specifications, or may be specific to
-	a vendor or device.</para>
-
-	<para>USB device drivers actually bind to interfaces, not devices.
-	Think of them as "interface drivers", though you
-	may not see many devices where the distinction is important.
-	Most USB devices are simple, with only one configuration,
-	one interface, and one alternate setting.
-	</para></listitem>
-
-	<listitem><para>Interfaces have one or more "endpoints", each of
-	which supports one type and direction of data transfer such as
-	"bulk out" or "interrupt in".  The entire configuration may have
-	up to sixteen endpoints in each direction, allocated as needed
-	among all the interfaces.
-	</para></listitem>
-
-	<listitem><para>Data transfer on USB is packetized; each endpoint
-	has a maximum packet size.
-	Drivers must often be aware of conventions such as flagging the end
-	of bulk transfers using "short" (including zero length) packets.
-	</para></listitem>
-
-	<listitem><para>The Linux USB API supports synchronous calls for
-	control and bulk messaging.
-	It also supports asynchnous calls for all kinds of data transfer,
-	using request structures called "URBs" (USB Request Blocks).
-	</para></listitem>
-
-    </itemizedlist>
-
-    <para>Accordingly, the USB Core API exposed to device drivers
-    covers quite a lot of territory.  You'll probably need to consult
-    the USB 2.0 specification, available online from www.usb.org at
-    no cost, as well as class or device specifications.
-    </para>
-
-    <sect1><title>Data Types and Macros</title>
-!Iinclude/linux/usb.h
-    </sect1>
-
-    <sect1><title>USB Core APIs</title>
-!Edrivers/usb/core/urb.c
-<!-- FIXME: Removed for now since no structured comments in source
-X!Edrivers/usb/core/config.c
--->
-!Edrivers/usb/core/message.c
-!Edrivers/usb/core/file.c
-!Edrivers/usb/core/usb.c
-    </sect1>
-
-    <sect1><title>Host Controller APIs</title>
-    <para>These APIs are only for use by host controller drivers,
-    most of which implement standard register interfaces such as
-    EHCI, OHCI, or UHCI.
-    </para>
-!Edrivers/usb/core/hcd.c
-!Edrivers/usb/core/hcd-pci.c
-!Edrivers/usb/core/buffer.c
-    </sect1>
-
-  </chapter>
-
   <chapter id="uart16x50">
      <title>16x50 UART Driver</title>
 !Edrivers/serial/core.c
diff -urN linux-2.5.63-bk4/Documentation/DocBook/usb.tmpl linux-2.5.63-bk5/Documentation/DocBook/usb.tmpl
--- linux-2.5.63-bk4/Documentation/DocBook/usb.tmpl	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk5/Documentation/DocBook/usb.tmpl	Mon Mar 31 12:18:55 2003
@@ -0,0 +1,294 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
+<book id="Linux-USB-API">
+ <bookinfo>
+  <title>The Linux-USB Host Side API</title>
+  
+  <legalnotice>
+   <para>
+     This documentation 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.
+   </para>
+      
+   <para>
+     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.
+   </para>
+      
+   <para>
+     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
+   </para>
+      
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+<chapter id="intro">
+    <title>Introduction to USB on Linux</title>
+
+    <para>A Universal Serial Bus (USB) is used to connect a host,
+    such as a PC or workstation, to a number of peripheral
+    devices.  USB uses a tree structure, with the host at the
+    root (the system's master), hubs as interior nodes, and
+    peripheral devices as leaves (and slaves).
+    Modern PCs support several such trees of USB devices, usually
+    one USB 2.0 tree (480 Mbit/sec each) with
+    a few USB 1.1 trees (12 Mbit/sec each) that are used when you
+    connect a USB 1.1 device directly to the machine's "root hub".
+    </para>
+
+    <para>That master/slave asymmetry was designed in part for
+    ease of use.  It is not physically possible to assemble
+    (legal) USB cables incorrectly:  all upstream "to-the-host"
+    connectors are the rectangular type, matching the sockets on
+    root hubs, and the downstream type are the squarish type
+    (or they are built in to the peripheral).
+    Software doesn't need to deal with distributed autoconfiguration
+    since the pre-designated master node manages all that.
+    At the electrical level, bus protocol overhead is reduced by
+    eliminating arbitration and moving scheduling into host software.
+    </para>
+
+    <para>USB 1.0 was announced in January 1996, and was revised
+    as USB 1.1 (with improvements in hub specification and
+    support for interrupt-out transfers) in September 1998.
+    USB 2.0 was released in April 2000, including high speed
+    transfers and transaction translating hubs (used for USB 1.1
+    and 1.0 backward compatibility).
+    </para>
+
+    <para>USB support was added to Linux early in the 2.2 kernel series
+    shortly before the 2.3 development forked off.  Updates
+    from 2.3 were regularly folded back into 2.2 releases, bringing
+    new features such as <filename>/sbin/hotplug</filename> support,
+    more drivers, and more robustness.
+    The 2.5 kernel series continued such improvements, and also
+    worked on USB 2.0 support,
+    higher performance,
+    better consistency between host controller drivers,
+    API simplification (to make bugs less likely),
+    and providing internal "kerneldoc" documentation.
+    </para>
+
+    <para>Linux can run inside USB devices as well as on
+    the hosts that control the devices.
+    Because the Linux 2.x USB support evolved to support mass market
+    platforms such as Apple Macintosh or PC-compatible systems,
+    it didn't address design concerns for those types of USB systems.
+    So it can't be used inside mass-market PDAs, or other peripherals.
+    USB device drivers running inside those Linux peripherals
+    don't do the same things as the ones running inside hosts,
+    and so they've been given a different name:
+    they're called <emphasis>gadget drivers</emphasis>.
+    This document does not present gadget drivers.
+    </para>
+
+    </chapter>
+
+<chapter id="host">
+    <title>USB Host-Side API Model</title>
+
+    <para>Host-side drivers for USB devices talk to the "usbcore" APIs.
+    There are two types of public "usbcore" APIs, targetted at two different
+    layers of USB driver.  Those are
+    <emphasis>general purpose</emphasis> drivers, exposed through
+    driver frameworks such as block, character, or network devices;
+    and drivers that are <emphasis>part of the core</emphasis>,
+    which are involved in managing a USB bus.
+    Such core drivers include the <emphasis>hub</emphasis> driver,
+    which manages trees of USB devices, and several different kinds
+    of <emphasis>host controller driver (HCD)</emphasis>,
+    which control individual busses.
+    </para>
+
+    <para>The device model seen by USB drivers is relatively complex.
+    </para>
+     
+    <itemizedlist>
+
+	<listitem><para>USB supports four kinds of data transfer
+	(control, bulk, interrupt, and isochronous).  Two transfer
+	types use bandwidth as it's available (control and bulk),
+	while the other two types of transfer (interrupt and isochronous)
+	are scheduled to provide guaranteed bandwidth.
+	</para></listitem>
+
+	<listitem><para>The device description model includes one or more
+	"configurations" per device, only one of which is active at a time.
+	Devices that are capable of high speed operation must also support
+	full speed configurations, along with a way to ask about the
+	"other speed" configurations that might be used.
+	</para></listitem>
+
+	<listitem><para>Configurations have one or more "interface", each
+	of which may have "alternate settings".  Interfaces may be
+	standardized by USB "Class" specifications, or may be specific to
+	a vendor or device.</para>
+
+	<para>USB device drivers actually bind to interfaces, not devices.
+	Think of them as "interface drivers", though you
+	may not see many devices where the distinction is important.
+	<emphasis>Most USB devices are simple, with only one configuration,
+	one interface, and one alternate setting.</emphasis>
+	</para></listitem>
+
+	<listitem><para>Interfaces have one or more "endpoints", each of
+	which supports one type and direction of data transfer such as
+	"bulk out" or "interrupt in".  The entire configuration may have
+	up to sixteen endpoints in each direction, allocated as needed
+	among all the interfaces.
+	</para></listitem>
+
+	<listitem><para>Data transfer on USB is packetized; each endpoint
+	has a maximum packet size.
+	Drivers must often be aware of conventions such as flagging the end
+	of bulk transfers using "short" (including zero length) packets.
+	</para></listitem>
+
+	<listitem><para>The Linux USB API supports synchronous calls for
+	control and bulk messaging.
+	It also supports asynchnous calls for all kinds of data transfer,
+	using request structures called "URBs" (USB Request Blocks).
+	</para></listitem>
+
+    </itemizedlist>
+
+    <para>Accordingly, the USB Core API exposed to device drivers
+    covers quite a lot of territory.  You'll probably need to consult
+    the USB 2.0 specification, available online from www.usb.org at
+    no cost, as well as class or device specifications.
+    </para>
+
+    <para>The only host-side drivers that actually touch hardware
+    (reading/writing registers, handling IRQs, and so on) are the HCDs.
+    In theory, all HCDs provide the same functionality through the same
+    API.  In practice, that's becoming more true on the 2.5 kernels,
+    but there are still differences that crop up especially with
+    fault handling.  Different controllers don't necessarily report
+    the same aspects of failures, and recovery from faults (including
+    software-induced ones like unlinking an URB) isn't yet fully
+    consistent.
+    Device driver authors should make a point of doing disconnect
+    testing (while the device is active) with each different host
+    controller driver, to make sure drivers don't have bugs of
+    their own as well as to make sure they aren't relying on some
+    HCD-specific behavior.
+    (You will need external USB 1.1 and/or
+    USB 2.0 hubs to perform all those tests.)
+    </para>
+
+    </chapter>
+
+<chapter><title>USB-Standard Types</title>
+
+    <para>In <filename>&lt;linux/usb_ch9.h&gt;</filename> you will find
+    the USB data types defined in chapter 9 of the USB specification.
+    These data types are used throughout USB, and in APIs including
+    this host side API, gadget APIs, and usbfs.
+    </para>
+
+!Iinclude/linux/usb_ch9.h
+
+    </chapter>
+
+<chapter><title>Host-Side Data Types and Macros</title>
+
+    <para>The host side API exposes several layers to drivers, some of
+    which are more necessary than others.
+    These support lifecycle models for host side drivers
+    and devices, and support passing buffers through usbcore to
+    some HCD that performs the I/O for the device driver.
+    </para>
+
+
+!Iinclude/linux/usb.h
+
+    </chapter>
+
+    <chapter><title>USB Core APIs</title>
+
+    <para>There are two basic I/O models in the USB API.
+    The most elemental one is asynchronous:  drivers submit requests
+    in the form of an URB, and the URB's completion callback
+    handle the next step.
+    All USB transfer types support that model, although there
+    are special cases for control URBs (which always have setup
+    and status stages, but may not have a data stage) and
+    isochronous URBs (which allow large packets and include
+    per-packet fault reports).
+    Built on top of that is synchronous API support, where a
+    driver calls a routine that allocates one or more URBs,
+    submits them, and waits until they complete.
+    There are synchronous wrappers for single-buffer control
+    and bulk transfers (which are awkward to use in some
+    driver disconnect scenarios), and for scatterlist based
+    streaming i/o (bulk or interrupt).
+    </para>
+
+    <para>USB drivers need to provide buffers that can be
+    used for DMA, although they don't necessarily need to
+    provide the DMA mapping themselves.
+    There are APIs to use used when allocating DMA buffers,
+    which can prevent use of bounce buffers on some systems.
+    In some cases, drivers may be able to rely on 64bit DMA
+    to eliminate another kind of bounce buffer.
+    </para>
+
+!Edrivers/usb/core/urb.c
+!Edrivers/usb/core/message.c
+!Edrivers/usb/core/file.c
+!Edrivers/usb/core/usb.c
+    </chapter>
+
+    <chapter><title>Host Controller APIs</title>
+
+    <para>These APIs are only for use by host controller drivers,
+    most of which implement standard register interfaces such as
+    EHCI, OHCI, or UHCI.
+    UHCI was one of the first interfaces, designed by Intel and
+    also used by VIA; it doesn't do much in hardware.
+    OHCI was designed later, to have the hardware do more work
+    (bigger transfers, tracking protocol state, and so on).
+    EHCI was designed with USB 2.0; its design has features that
+    resemble OHCI (hardware does much more work) as well as
+    UHCI (some parts of ISO support, TD list processing).
+    </para>
+
+    <para>There are host controllers other than the "big three",
+    although most PCI based controllers (and a few non-PCI based
+    ones) use one of those interfaces.
+    Not all host controllers use DMA; some use PIO, and there
+    is also a simulator.
+    </para>
+
+    <para>The same basic APIs are available to drivers for all
+    those controllers.  
+    For historical reasons they are in two layers:
+    <structname>struct usb_bus</structname> is a rather thin
+    layer that became available in the 2.2 kernels, while
+    <structname>struct usb_hcd</structname> is a more featureful
+    layer (available in later 2.4 kernels and in 2.5) that
+    lets HCDs share common code, to shrink driver size
+    and significantly reduce hcd-specific behaviors.
+    </para>
+
+!Edrivers/usb/core/hcd.c
+!Edrivers/usb/core/hcd-pci.c
+!Edrivers/usb/core/buffer.c
+    </chapter>
+
+</book>
+<!-- vim:syntax=sgml:sw=4
+-->
diff -urN linux-2.5.63-bk4/Documentation/kernel-parameters.txt linux-2.5.63-bk5/Documentation/kernel-parameters.txt
--- linux-2.5.63-bk4/Documentation/kernel-parameters.txt	Mon Feb 24 11:06:03 2003
+++ linux-2.5.63-bk5/Documentation/kernel-parameters.txt	Mon Mar 31 12:18:55 2003
@@ -516,6 +516,14 @@
 			[KNL,BOOT] Force usage of a specific region of memory
 			Region of memory to be used, from ss to ss+nn.
 
+	mem=nn[KMG]#ss[KMG]
+			[KNL,BOOT,ACPI] Mark specific memory as ACPI data.
+			Region of memory to be used, from ss to ss+nn.
+
+	mem=nn[KMG]$ss[KMG]
+			[KNL,BOOT,ACPI] Mark specific memory as reserved.
+			Region of memory to be used, from ss to ss+nn.
+
 	mem=nopentium	[BUGS=IA-32] Disable usage of 4MB pages for kernel
 			memory.
 
diff -urN linux-2.5.63-bk4/Makefile linux-2.5.63-bk5/Makefile
--- linux-2.5.63-bk4/Makefile	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/Makefile	Mon Mar 31 12:18:55 2003
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 63
-EXTRAVERSION = bk4
+EXTRAVERSION = bk5
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.63-bk4/arch/i386/Kconfig linux-2.5.63-bk5/arch/i386/Kconfig
--- linux-2.5.63-bk4/arch/i386/Kconfig	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/arch/i386/Kconfig	Mon Mar 31 12:18:55 2003
@@ -342,11 +342,6 @@
 	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
 	default y
 
-config X86_TSC
-	bool
-	depends on MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2
-	default y
-
 config X86_GOOD_APIC
 	bool
 	depends on MK7 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8
@@ -500,6 +495,11 @@
 	depends on NUMA
 	default y
 
+config X86_TSC
+	bool
+	depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2) && !X86_NUMAQ
+	default y
+
 config X86_MCE
 	bool "Machine Check Exception"
 	---help---
diff -urN linux-2.5.63-bk4/arch/i386/kernel/acpi/wakeup.S linux-2.5.63-bk5/arch/i386/kernel/acpi/wakeup.S
--- linux-2.5.63-bk4/arch/i386/kernel/acpi/wakeup.S	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/arch/i386/kernel/acpi/wakeup.S	Mon Mar 31 12:18:55 2003
@@ -319,6 +319,31 @@
 	pushl saved_context_eflags ; popfl
 	ret
 
+ENTRY(do_suspend_lowlevel_s4bios)
+	cmpl $0,4(%esp)
+	jne ret_point
+	call save_processor_state
+
+	movl %esp, saved_context_esp
+	movl %eax, saved_context_eax
+	movl %ebx, saved_context_ebx
+	movl %ecx, saved_context_ecx
+	movl %edx, saved_context_edx
+	movl %ebp, saved_context_ebp
+	movl %esi, saved_context_esi
+	movl %edi, saved_context_edi
+	pushfl ; popl saved_context_eflags
+
+	movl $ret_point,saved_eip
+	movl %esp,saved_esp
+	movl %ebp,saved_ebp
+	movl %ebx,saved_ebx
+	movl %edi,saved_edi
+	movl %esi,saved_esi
+
+	call acpi_enter_sleep_state_s4bios
+	ret
+
 ALIGN
 # saved registers
 saved_gdt:	.long	0,0
diff -urN linux-2.5.63-bk4/arch/i386/kernel/i386_ksyms.c linux-2.5.63-bk5/arch/i386/kernel/i386_ksyms.c
--- linux-2.5.63-bk4/arch/i386/kernel/i386_ksyms.c	Mon Feb 24 11:06:02 2003
+++ linux-2.5.63-bk5/arch/i386/kernel/i386_ksyms.c	Mon Mar 31 12:18:55 2003
@@ -68,7 +68,6 @@
 EXPORT_SYMBOL(MCA_bus);
 #ifdef CONFIG_DISCONTIGMEM
 EXPORT_SYMBOL(node_data);
-EXPORT_SYMBOL(pfn_to_nid);
 #endif
 #ifdef CONFIG_X86_NUMAQ
 EXPORT_SYMBOL(xquad_portio);
diff -urN linux-2.5.63-bk4/arch/i386/kernel/mpparse.c linux-2.5.63-bk5/arch/i386/kernel/mpparse.c
--- linux-2.5.63-bk4/arch/i386/kernel/mpparse.c	Mon Feb 24 11:05:15 2003
+++ linux-2.5.63-bk5/arch/i386/kernel/mpparse.c	Mon Mar 31 12:18:55 2003
@@ -110,7 +110,7 @@
 	if (!(m->mpc_cpuflag & CPU_ENABLED))
 		return;
 
-	apicid = mpc_apic_id(m, translation_table[mpc_record]->trans_quad);
+	apicid = mpc_apic_id(m, translation_table[mpc_record]);
 
 	if (m->mpc_featureflag&(1<<0))
 		Dprintk("    Floating point unit present.\n");
diff -urN linux-2.5.63-bk4/arch/i386/kernel/numaq.c linux-2.5.63-bk5/arch/i386/kernel/numaq.c
--- linux-2.5.63-bk4/arch/i386/kernel/numaq.c	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk5/arch/i386/kernel/numaq.c	Mon Mar 31 12:18:55 2003
@@ -27,6 +27,7 @@
 #include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/mmzone.h>
+#include <linux/module.h>
 #include <asm/numaq.h>
 
 /* These are needed before the pgdat's are created */
@@ -82,19 +83,7 @@
  * physnode_map[8- ] = -1;
  */
 int physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1};
-
-#define PFN_TO_ELEMENT(pfn) (pfn / PAGES_PER_ELEMENT)
-#define PA_TO_ELEMENT(pa) (PFN_TO_ELEMENT(pa >> PAGE_SHIFT))
-
-int pfn_to_nid(unsigned long pfn)
-{
-	int nid = physnode_map[PFN_TO_ELEMENT(pfn)];
-
-	if (nid == -1)
-		BUG(); /* address is not present */
-
-	return nid;
-}
+EXPORT_SYMBOL(physnode_map);
 
 /*
  * for each node mark the regions
diff -urN linux-2.5.63-bk4/arch/i386/kernel/setup.c linux-2.5.63-bk5/arch/i386/kernel/setup.c
--- linux-2.5.63-bk4/arch/i386/kernel/setup.c	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/arch/i386/kernel/setup.c	Mon Mar 31 12:18:55 2003
@@ -552,6 +552,12 @@
 				if (*from == '@') {
 					start_at = memparse(from+1, &from);
 					add_memory_region(start_at, mem_size, E820_RAM);
+				} else if (*from == '#') {
+					start_at = memparse(from+1, &from);
+					add_memory_region(start_at, mem_size, E820_ACPI);
+				} else if (*from == '$') {
+					start_at = memparse(from+1, &from);
+					add_memory_region(start_at, mem_size, E820_RESERVED);
 				} else {
 					limit_regions(mem_size);
 					userdef=1;
diff -urN linux-2.5.63-bk4/arch/i386/mm/discontig.c linux-2.5.63-bk5/arch/i386/mm/discontig.c
--- linux-2.5.63-bk4/arch/i386/mm/discontig.c	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/arch/i386/mm/discontig.c	Mon Mar 31 12:18:55 2003
@@ -48,6 +48,14 @@
 extern unsigned long totalram_pages;
 extern unsigned long totalhigh_pages;
 
+#define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
+
+unsigned long node_remap_start_pfn[MAX_NUMNODES];
+unsigned long node_remap_size[MAX_NUMNODES];
+unsigned long node_remap_offset[MAX_NUMNODES];
+void *node_remap_start_vaddr[MAX_NUMNODES];
+void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
+
 /*
  * Find the highest page frame number we have available for the node
  */
@@ -65,12 +73,13 @@
  */
 static void __init allocate_pgdat(int nid)
 {
-	unsigned long node_datasz;
-
-	node_datasz = PFN_UP(sizeof(struct pglist_data));
-	NODE_DATA(nid) = (pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT));
-	min_low_pfn += node_datasz;
-	memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
+	if (nid)
+		NODE_DATA(nid) = (pg_data_t *)node_remap_start_vaddr[nid];
+	else {
+		NODE_DATA(nid) = (pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT));
+		min_low_pfn += PFN_UP(sizeof(pg_data_t));
+		memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+	}
 }
 
 /*
@@ -113,14 +122,6 @@
 	}
 }
 
-#define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
-
-unsigned long node_remap_start_pfn[MAX_NUMNODES];
-unsigned long node_remap_size[MAX_NUMNODES];
-unsigned long node_remap_offset[MAX_NUMNODES];
-void *node_remap_start_vaddr[MAX_NUMNODES];
-extern void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
-
 void __init remap_numa_kva(void)
 {
 	void *vaddr;
@@ -145,7 +146,7 @@
 	for (nid = 1; nid < numnodes; nid++) {
 		/* calculate the size of the mem_map needed in bytes */
 		size = (node_end_pfn[nid] - node_start_pfn[nid] + 1) 
-			* sizeof(struct page);
+			* sizeof(struct page) + sizeof(pg_data_t);
 		/* convert size to large (pmd size) pages, rounding up */
 		size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES;
 		/* now the roundup is correct, convert to PAGE_SIZE pages */
@@ -195,9 +196,9 @@
 	printk("Low memory ends at vaddr %08lx\n",
 			(ulong) pfn_to_kaddr(max_low_pfn));
 	for (nid = 0; nid < numnodes; nid++) {
-		allocate_pgdat(nid);
 		node_remap_start_vaddr[nid] = pfn_to_kaddr(
 			highstart_pfn - node_remap_offset[nid]);
+		allocate_pgdat(nid);
 		printk ("node %d will remap to vaddr %08lx - %08lx\n", nid,
 			(ulong) node_remap_start_vaddr[nid],
 			(ulong) pfn_to_kaddr(highstart_pfn
@@ -251,13 +252,6 @@
 	 */
 	find_smp_config();
 
-	/*insert other nodes into pgdat_list*/
-	for (nid = 1; nid < numnodes; nid++){       
-		NODE_DATA(nid)->pgdat_next = pgdat_list;
-		pgdat_list = NODE_DATA(nid);
-	}
-       
-
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (LOADER_TYPE && INITRD_START) {
 		if (INITRD_START + INITRD_SIZE <= (system_max_low_pfn << PAGE_SHIFT)) {
@@ -282,6 +276,18 @@
 {
 	int nid;
 
+	/*
+	 * Insert nodes into pgdat_list backward so they appear in order.
+	 * Clobber node 0's links and NULL out pgdat_list before starting.
+	 */
+	pgdat_list = NULL;
+	for (nid = numnodes - 1; nid >= 0; nid--) {       
+		if (nid)
+			memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+		NODE_DATA(nid)->pgdat_next = pgdat_list;
+		pgdat_list = NODE_DATA(nid);
+	}
+
 	for (nid = 0; nid < numnodes; nid++) {
 		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
 		unsigned long *zholes_size;
@@ -314,13 +320,18 @@
 		 * normal bootmem allocator, but other nodes come from the
 		 * remapped KVA area - mbligh
 		 */
-		if (nid)
-			free_area_init_node(nid, NODE_DATA(nid), 
-				node_remap_start_vaddr[nid], zones_size, 
-				start, zholes_size);
-		else
+		if (!nid)
 			free_area_init_node(nid, NODE_DATA(nid), 0, 
 				zones_size, start, zholes_size);
+		else {
+			unsigned long lmem_map;
+			lmem_map = (unsigned long)node_remap_start_vaddr[nid];
+			lmem_map += sizeof(pg_data_t) + PAGE_SIZE - 1;
+			lmem_map &= PAGE_MASK;
+			free_area_init_node(nid, NODE_DATA(nid), 
+				(struct page *)lmem_map, zones_size, 
+				start, zholes_size);
+		}
 	}
 	return;
 }
diff -urN linux-2.5.63-bk4/arch/i386/pci/numa.c linux-2.5.63-bk5/arch/i386/pci/numa.c
--- linux-2.5.63-bk4/arch/i386/pci/numa.c	Mon Feb 24 11:05:11 2003
+++ linux-2.5.63-bk5/arch/i386/pci/numa.c	Mon Mar 31 12:18:55 2003
@@ -17,7 +17,7 @@
 {
 	unsigned long flags;
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (!value || (bus > MAX_MP_BUSSES) || (dev > 31) || (fn > 7) || (reg > 255))
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -45,7 +45,7 @@
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if ((bus > MAX_MP_BUSSES) || (dev > 31) || (fn > 7) || (reg > 255)) 
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
diff -urN linux-2.5.63-bk4/drivers/acpi/Kconfig linux-2.5.63-bk5/drivers/acpi/Kconfig
--- linux-2.5.63-bk4/drivers/acpi/Kconfig	Mon Feb 24 11:06:02 2003
+++ linux-2.5.63-bk5/drivers/acpi/Kconfig	Mon Mar 31 12:18:55 2003
@@ -6,6 +6,7 @@
 
 config ACPI
 	bool "ACPI Support" if X86
+	depends on !X86_VISWS
 	default y if IA64 && (!IA64_HP_SIM || IA64_SGI_SN)
 	---help---
 	  Advanced Configuration and Power Interface (ACPI) support for 
diff -urN linux-2.5.63-bk4/drivers/acpi/acpi_ksyms.c linux-2.5.63-bk5/drivers/acpi/acpi_ksyms.c
--- linux-2.5.63-bk4/drivers/acpi/acpi_ksyms.c	Mon Feb 24 11:05:15 2003
+++ linux-2.5.63-bk5/drivers/acpi/acpi_ksyms.c	Mon Mar 31 12:18:55 2003
@@ -76,6 +76,7 @@
 EXPORT_SYMBOL(acpi_release_global_lock);
 EXPORT_SYMBOL(acpi_get_current_resources);
 EXPORT_SYMBOL(acpi_get_possible_resources);
+EXPORT_SYMBOL(acpi_walk_resources);
 EXPORT_SYMBOL(acpi_set_current_resources);
 EXPORT_SYMBOL(acpi_enable_event);
 EXPORT_SYMBOL(acpi_disable_event);
@@ -86,6 +87,7 @@
 EXPORT_SYMBOL(acpi_get_register);
 EXPORT_SYMBOL(acpi_set_register);
 EXPORT_SYMBOL(acpi_enter_sleep_state);
+EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
 EXPORT_SYMBOL(acpi_get_system_info);
 EXPORT_SYMBOL(acpi_get_devices);
 
diff -urN linux-2.5.63-bk4/drivers/acpi/ec.c linux-2.5.63-bk5/drivers/acpi/ec.c
--- linux-2.5.63-bk4/drivers/acpi/ec.c	Mon Feb 24 11:05:33 2003
+++ linux-2.5.63-bk5/drivers/acpi/ec.c	Mon Mar 31 12:18:55 2003
@@ -644,15 +644,46 @@
 }
 
 
+static acpi_status
+acpi_ec_io_ports (
+	struct acpi_resource	*resource,
+	void			*context)
+{
+	struct acpi_ec		*ec = (struct acpi_ec *) context;
+	struct acpi_generic_address *addr;
+
+	if (resource->id != ACPI_RSTYPE_IO) {
+		return AE_OK;
+	}
+
+	/*
+	 * The first address region returned is the data port, and
+	 * the second address region returned is the status/command
+	 * port.
+	 */
+	if (ec->data_addr.register_bit_width == 0) {
+		addr = &ec->data_addr;
+	} else if (ec->command_addr.register_bit_width == 0) {
+		addr = &ec->command_addr;
+	} else {
+		return AE_CTRL_TERMINATE;
+	}
+
+	addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
+	addr->register_bit_width = 8;
+	addr->register_bit_offset = 0;
+	addr->address = resource->data.io.min_base_address;
+
+	return AE_OK;
+}
+
+
 static int
 acpi_ec_start (
 	struct acpi_device	*device)
 {
-	int			result = 0;
 	acpi_status		status = AE_OK;
 	struct acpi_ec		*ec = NULL;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	struct acpi_resource	*resource = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_start");
 
@@ -667,33 +698,13 @@
 	/*
 	 * Get I/O port addresses. Convert to GAS format.
 	 */
-	status = acpi_get_current_resources(ec->handle, &buffer);
-	if (ACPI_FAILURE(status)) {
+	status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
+		acpi_ec_io_ports, ec);
+	if (ACPI_FAILURE(status) || ec->command_addr.register_bit_width == 0) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
 		return_VALUE(-ENODEV);
 	}
 
-	resource = (struct acpi_resource *) buffer.pointer;
-	if (!resource || (resource->id != ACPI_RSTYPE_IO)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid or missing resource\n"));
-		result = -ENODEV;
-		goto end;
-	}
-	ec->data_addr.address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
-	ec->data_addr.register_bit_width = 8;
-	ec->data_addr.register_bit_offset = 0;
-	ec->data_addr.address = resource->data.io.min_base_address;
-
-	resource = ACPI_NEXT_RESOURCE(resource);
-	if (!resource || (resource->id != ACPI_RSTYPE_IO)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid or missing resource\n"));
-		result = -ENODEV;
-		goto end;
-	}
-	ec->command_addr.address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
-	ec->command_addr.register_bit_width = 8;
-	ec->command_addr.register_bit_offset = 0;
-	ec->command_addr.address = resource->data.io.min_base_address;
 	ec->status_addr = ec->command_addr;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
@@ -706,8 +717,7 @@
 	status = acpi_install_gpe_handler(ec->gpe_bit,
 		ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
 	if (ACPI_FAILURE(status)) {
-		result = -ENODEV;
-		goto end;
+		return_VALUE(-ENODEV);
 	}
 
 	status = acpi_install_address_space_handler (ec->handle,
@@ -715,13 +725,10 @@
 			&acpi_ec_space_setup, ec);
 	if (ACPI_FAILURE(status)) {
 		acpi_remove_gpe_handler(ec->gpe_bit, &acpi_ec_gpe_handler);
-		result = -ENODEV;
-		goto end;
+		return_VALUE(-ENODEV);
 	}
-end:
-	acpi_os_free(buffer.pointer);
 
-	return_VALUE(result);
+	return_VALUE(AE_OK);
 }
 
 
diff -urN linux-2.5.63-bk4/drivers/acpi/events/Makefile linux-2.5.63-bk5/drivers/acpi/events/Makefile
--- linux-2.5.63-bk4/drivers/acpi/events/Makefile	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk5/drivers/acpi/events/Makefile	Mon Mar 31 12:18:55 2003
@@ -4,6 +4,6 @@
 
 obj-y := evevent.o  evregion.o  evsci.o    evxfevnt.o \
 	 evmisc.o   evrgnini.o  evxface.o  evxfregn.o \
-	 evgpe.o
+	 evgpe.o    evgpeblk.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff -urN linux-2.5.63-bk4/drivers/acpi/events/evevent.c linux-2.5.63-bk5/drivers/acpi/events/evevent.c
--- linux-2.5.63-bk4/drivers/acpi/events/evevent.c	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/drivers/acpi/events/evevent.c	Mon Mar 31 12:18:55 2003
@@ -110,7 +110,7 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Install handlers for the SCI, Global Lock, and GPEs.
+ * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
  *
  ******************************************************************************/
 
@@ -133,16 +133,6 @@
 				acpi_format_exception (status)));
 		return_ACPI_STATUS (status);
 	}
-
-	/* Install handlers for control method GPE handlers (_Lxx, _Exx) */
-
-	status = acpi_ev_init_gpe_control_methods ();
-	if (ACPI_FAILURE (status)) {
-		ACPI_REPORT_ERROR ((
-				"Unable to initialize GPE control methods, %s\n",
-				acpi_format_exception (status)));
-		return_ACPI_STATUS (status);
-	}
 
 	/* Install the handler for the Global Lock */
 
diff -urN linux-2.5.63-bk4/drivers/acpi/events/evgpe.c linux-2.5.63-bk5/drivers/acpi/events/evgpe.c
--- linux-2.5.63-bk4/drivers/acpi/events/evgpe.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/drivers/acpi/events/evgpe.c	Mon Mar 31 12:18:55 2003
@@ -51,401 +51,54 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_gpe_initialize
+ * FUNCTION:    acpi_ev_get_gpe_event_info
  *
- * PARAMETERS:  None
- *
- * RETURN:      Status
+ * PARAMETERS:  gpe_number      - Raw GPE number
  *
- * DESCRIPTION: Initialize the GPE data structures
+ * RETURN:      None.
  *
- ******************************************************************************/
-
-acpi_status
-acpi_ev_gpe_initialize (void)
-{
-	acpi_native_uint                i;
-	acpi_native_uint                j;
-	u32                             gpe_block;
-	u32                             gpe_register;
-	u32                             gpe_number_index;
-	u32                             gpe_number;
-	struct acpi_gpe_register_info   *gpe_register_info;
-	acpi_status                     status;
-
-
-	ACPI_FUNCTION_TRACE ("ev_gpe_initialize");
-
-
-	/*
-	 * Initialize the GPE Block globals
-	 *
-	 * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,
-	 * section "General-Purpose Event Registers", we have:
-	 *
-	 * "Each register block contains two registers of equal length
-	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
-	 *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
-	 *  The length of the GPE1_STS and GPE1_EN registers is equal to
-	 *  half the GPE1_LEN. If a generic register block is not supported
-	 *  then its respective block pointer and block length values in the
-	 *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
-	 *  to be the same size."
-	 */
-	acpi_gbl_gpe_block_info[0].register_count = 0;
-	acpi_gbl_gpe_block_info[1].register_count = 0;
-
-	acpi_gbl_gpe_block_info[0].block_address = &acpi_gbl_FADT->xgpe0_blk;
-	acpi_gbl_gpe_block_info[1].block_address = &acpi_gbl_FADT->xgpe1_blk;
-
-	acpi_gbl_gpe_block_info[0].block_base_number = 0;
-	acpi_gbl_gpe_block_info[1].block_base_number = acpi_gbl_FADT->gpe1_base;
-
-
-	/*
-	 * Determine the maximum GPE number for this machine.
-	 *
-	 * Note: both GPE0 and GPE1 are optional, and either can exist without
-	 * the other.
-	 * If EITHER the register length OR the block address are zero, then that
-	 * particular block is not supported.
-	 */
-	if (acpi_gbl_FADT->xgpe0_blk.register_bit_width && acpi_gbl_FADT->xgpe0_blk.address) {
-		/* GPE block 0 exists (has both length and address > 0) */
-
-		acpi_gbl_gpe_block_info[0].register_count = (u16) (acpi_gbl_FADT->xgpe0_blk.register_bit_width / (ACPI_GPE_REGISTER_WIDTH * 2));
-		acpi_gbl_gpe_number_max               = (acpi_gbl_gpe_block_info[0].register_count * ACPI_GPE_REGISTER_WIDTH) - 1;
-	}
-
-	if (acpi_gbl_FADT->xgpe1_blk.register_bit_width && acpi_gbl_FADT->xgpe1_blk.address) {
-		/* GPE block 1 exists (has both length and address > 0) */
-
-		acpi_gbl_gpe_block_info[1].register_count = (u16) (acpi_gbl_FADT->xgpe1_blk.register_bit_width / (ACPI_GPE_REGISTER_WIDTH * 2));
-
-		/* Check for GPE0/GPE1 overlap (if both banks exist) */
-
-		if ((acpi_gbl_gpe_block_info[0].register_count) &&
-			(acpi_gbl_gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
-			ACPI_REPORT_ERROR ((
-				"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n",
-				acpi_gbl_gpe_number_max, acpi_gbl_FADT->gpe1_base,
-				acpi_gbl_FADT->gpe1_base + ((acpi_gbl_gpe_block_info[1].register_count * ACPI_GPE_REGISTER_WIDTH) - 1)));
-
-			/* Ignore GPE1 block by setting the register count to zero */
-
-			acpi_gbl_gpe_block_info[1].register_count = 0;
-		}
-		else {
-			/*
-			 * GPE0 and GPE1 do not have to be contiguous in the GPE number space,
-			 * But, GPE0 always starts at zero.
-			 */
-			acpi_gbl_gpe_number_max = acpi_gbl_FADT->gpe1_base +
-					 ((acpi_gbl_gpe_block_info[1].register_count * ACPI_GPE_REGISTER_WIDTH) - 1);
-		}
-	}
-
-	/* Exit if there are no GPE registers */
-
-	acpi_gbl_gpe_register_count = acpi_gbl_gpe_block_info[0].register_count +
-			 acpi_gbl_gpe_block_info[1].register_count;
-	if (!acpi_gbl_gpe_register_count) {
-		/* GPEs are not required by ACPI, this is OK */
-
-		ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
-		return_ACPI_STATUS (AE_OK);
-	}
-
-	/* Check for Max GPE number out-of-range */
-
-	if (acpi_gbl_gpe_number_max > ACPI_GPE_MAX) {
-		ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
-			acpi_gbl_gpe_number_max));
-		return_ACPI_STATUS (AE_BAD_VALUE);
-	}
-
-	/* Allocate the GPE number-to-index translation table */
-
-	acpi_gbl_gpe_number_to_index = ACPI_MEM_CALLOCATE (
-			   sizeof (struct acpi_gpe_index_info) *
-			   ((acpi_size) acpi_gbl_gpe_number_max + 1));
-	if (!acpi_gbl_gpe_number_to_index) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Could not allocate the gpe_number_to_index table\n"));
-		return_ACPI_STATUS (AE_NO_MEMORY);
-	}
-
-	/* Set the Gpe index table to GPE_INVALID */
-
-	ACPI_MEMSET (acpi_gbl_gpe_number_to_index, (int) ACPI_GPE_INVALID,
-			sizeof (struct acpi_gpe_index_info) * ((acpi_size) acpi_gbl_gpe_number_max + 1));
-
-	/* Allocate the GPE register information block */
-
-	acpi_gbl_gpe_register_info = ACPI_MEM_CALLOCATE (
-			  (acpi_size) acpi_gbl_gpe_register_count *
-			  sizeof (struct acpi_gpe_register_info));
-	if (!acpi_gbl_gpe_register_info) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Could not allocate the gpe_register_info table\n"));
-		goto error_exit1;
-	}
-
-	/*
-	 * Allocate the GPE dispatch handler block.  There are eight distinct GPEs
-	 * per register.  Initialization to zeros is sufficient.
-	 */
-	acpi_gbl_gpe_number_info = ACPI_MEM_CALLOCATE (
-			  ((acpi_size) acpi_gbl_gpe_register_count * ACPI_GPE_REGISTER_WIDTH) *
-			  sizeof (struct acpi_gpe_number_info));
-	if (!acpi_gbl_gpe_number_info) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_number_info table\n"));
-		goto error_exit2;
-	}
-
-	/*
-	 * Initialize the GPE information and validation tables.  A goal of these
-	 * tables is to hide the fact that there are two separate GPE register sets
-	 * in a given gpe hardware block, the status registers occupy the first half,
-	 * and the enable registers occupy the second half.  Another goal is to hide
-	 * the fact that there may be multiple GPE hardware blocks.
-	 */
-	gpe_register = 0;
-	gpe_number_index = 0;
-
-	for (gpe_block = 0; gpe_block < ACPI_MAX_GPE_BLOCKS; gpe_block++) {
-		for (i = 0; i < acpi_gbl_gpe_block_info[gpe_block].register_count; i++) {
-			gpe_register_info = &acpi_gbl_gpe_register_info[gpe_register];
-
-			/* Init the Register info for this entire GPE register (8 GPEs) */
-
-			gpe_register_info->base_gpe_number = (u8) (acpi_gbl_gpe_block_info[gpe_block].block_base_number
-					   + (i * ACPI_GPE_REGISTER_WIDTH));
-
-			ACPI_STORE_ADDRESS (gpe_register_info->status_address.address,
-					   (acpi_gbl_gpe_block_info[gpe_block].block_address->address
-							  + i));
-
-			ACPI_STORE_ADDRESS (gpe_register_info->enable_address.address,
-					   (acpi_gbl_gpe_block_info[gpe_block].block_address->address
-							  + i
-							  + acpi_gbl_gpe_block_info[gpe_block].register_count));
-
-			gpe_register_info->status_address.address_space_id = acpi_gbl_gpe_block_info[gpe_block].block_address->address_space_id;
-			gpe_register_info->enable_address.address_space_id = acpi_gbl_gpe_block_info[gpe_block].block_address->address_space_id;
-			gpe_register_info->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
-			gpe_register_info->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
-			gpe_register_info->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
-			gpe_register_info->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
-
-			/* Init the Index mapping info for each GPE number within this register */
-
-			for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
-				gpe_number = gpe_register_info->base_gpe_number + (u32) j;
-				acpi_gbl_gpe_number_to_index[gpe_number].number_index = (u8) gpe_number_index;
-
-				acpi_gbl_gpe_number_info[gpe_number_index].bit_mask = acpi_gbl_decode_to8bit[j];
-				gpe_number_index++;
-			}
-
-			/*
-			 * Clear the status/enable registers.  Note that status registers
-			 * are cleared by writing a '1', while enable registers are cleared
-			 * by writing a '0'.
-			 */
-			status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00, &gpe_register_info->enable_address, 0);
-			if (ACPI_FAILURE (status)) {
-				return_ACPI_STATUS (status);
-			}
-
-			status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF, &gpe_register_info->status_address, 0);
-			if (ACPI_FAILURE (status)) {
-				return_ACPI_STATUS (status);
-			}
-
-			gpe_register++;
-		}
-
-		if (i) {
-			/* Dump info about this valid GPE block */
-
-			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE Block%d: %X registers at %8.8X%8.8X\n",
-				(s32) gpe_block, acpi_gbl_gpe_block_info[0].register_count,
-				ACPI_HIDWORD (acpi_gbl_gpe_block_info[gpe_block].block_address->address),
-				ACPI_LODWORD (acpi_gbl_gpe_block_info[gpe_block].block_address->address)));
-
-			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE Block%d defined as GPE%d to GPE%d\n",
-				(s32) gpe_block,
-				(u32) acpi_gbl_gpe_block_info[gpe_block].block_base_number,
-				(u32) (acpi_gbl_gpe_block_info[gpe_block].block_base_number +
-					((acpi_gbl_gpe_block_info[gpe_block].register_count * ACPI_GPE_REGISTER_WIDTH) -1))));
-		}
-	}
-
-	return_ACPI_STATUS (AE_OK);
-
-
-	/* Error cleanup */
-
-error_exit2:
-	ACPI_MEM_FREE (acpi_gbl_gpe_register_info);
-
-error_exit1:
-	ACPI_MEM_FREE (acpi_gbl_gpe_number_to_index);
-	return_ACPI_STATUS (AE_NO_MEMORY);
-}
-
-
-/*******************************************************************************
+ * DESCRIPTION: Returns the event_info struct
+ *              associated with this GPE.
  *
- * FUNCTION:    acpi_ev_save_method_info
- *
- * PARAMETERS:  None
- *
- * RETURN:      None
- *
- * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
- *              control method under the _GPE portion of the namespace.
- *              Extract the name and GPE type from the object, saving this
- *              information for quick lookup during GPE dispatch
- *
- *              The name of each GPE control method is of the form:
- *                  "_Lnn" or "_Enn"
- *              Where:
- *                  L      - means that the GPE is level triggered
- *                  E      - means that the GPE is edge triggered
- *                  nn     - is the GPE number [in HEX]
+ * TBD: this function will go away when full support of GPE block devices
+ *      is implemented!
  *
  ******************************************************************************/
 
-static acpi_status
-acpi_ev_save_method_info (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *obj_desc,
-	void                            **return_value)
+struct acpi_gpe_event_info *
+acpi_ev_get_gpe_event_info (
+	u32                             gpe_number)
 {
-	u32                             gpe_number;
-	struct acpi_gpe_number_info     *gpe_number_info;
-	char                            name[ACPI_NAME_SIZE + 1];
-	u8                              type;
-	acpi_status                     status;
-
-
-	ACPI_FUNCTION_NAME ("ev_save_method_info");
-
-
-	/* Extract the name from the object and convert to a string */
+	struct acpi_gpe_block_info      *gpe_block;
 
-	ACPI_MOVE_UNALIGNED32_TO_32 (name,
-			 &((struct acpi_namespace_node *) obj_handle)->name.integer);
-	name[ACPI_NAME_SIZE] = 0;
 
-	/*
-	 * Edge/Level determination is based on the 2nd character of the method name
-	 */
-	switch (name[1]) {
-	case 'L':
-		type = ACPI_EVENT_LEVEL_TRIGGERED;
-		break;
-
-	case 'E':
-		type = ACPI_EVENT_EDGE_TRIGGERED;
-		break;
+	/* Examine GPE Block 0 */
 
-	default:
-		/* Unknown method type, just ignore it! */
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n",
-			name));
-		return (AE_OK);
+	gpe_block = acpi_gbl_gpe_block_list_head;
+	if (!gpe_block) {
+		return (NULL);
 	}
 
-	/* Convert the last two characters of the name to the GPE Number */
-
-	gpe_number = ACPI_STRTOUL (&name[2], NULL, 16);
-	if (gpe_number == ACPI_UINT32_MAX) {
-		/* Conversion failed; invalid method, just ignore it */
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)\n",
-			name));
-		return (AE_OK);
+	if ((gpe_number >= gpe_block->block_base_number) &&
+		(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
+		return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
 	}
 
-	/* Get GPE index and ensure that we have a valid GPE number */
-
-	gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number);
-	if (!gpe_number_info) {
-		/* Not valid, all we can do here is ignore it */
+	/* Examine GPE Block 1 */
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"GPE number associated with method is not valid %s\n",
-			name));
-		return (AE_OK);
+	gpe_block = gpe_block->next;
+	if (!gpe_block) {
+		return (NULL);
 	}
 
-	/*
-	 * Now we can add this information to the gpe_number_info block
-	 * for use during dispatch of this GPE.
-	 */
-	gpe_number_info->type     = type;
-	gpe_number_info->method_node = (struct acpi_namespace_node *) obj_handle;
-
-	/*
-	 * Enable the GPE (SCIs should be disabled at this point)
-	 */
-	status = acpi_hw_enable_gpe (gpe_number);
-	if (ACPI_FAILURE (status)) {
-		return (status);
+	if ((gpe_number >= gpe_block->block_base_number) &&
+		(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
+		return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %2.2X\n",
-		name, gpe_number));
-	return (AE_OK);
+	return (NULL);
 }
 
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_init_gpe_control_methods
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Obtain the control methods associated with the GPEs.
- *              NOTE: Must be called AFTER namespace initialization!
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ev_init_gpe_control_methods (void)
-{
-	acpi_status                     status;
-
-
-	ACPI_FUNCTION_TRACE ("ev_init_gpe_control_methods");
-
-
-	/* Get a permanent handle to the _GPE object */
-
-	status = acpi_get_handle (NULL, "\\_GPE", &acpi_gbl_gpe_obj_handle);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
-
-	/* Traverse the namespace under \_GPE to find all methods there */
-
-	status = acpi_walk_namespace (ACPI_TYPE_METHOD, acpi_gbl_gpe_obj_handle,
-			  ACPI_UINT32_MAX, acpi_ev_save_method_info,
-			  NULL, NULL);
-
-	return_ACPI_STATUS (status);
-}
-
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_gpe_detect
@@ -470,62 +123,74 @@
 	struct acpi_gpe_register_info   *gpe_register_info;
 	u32                             in_value;
 	acpi_status                     status;
+	struct acpi_gpe_block_info      *gpe_block;
 
 
 	ACPI_FUNCTION_NAME ("ev_gpe_detect");
 
 
-	/*
-	 * Read all of the 8-bit GPE status and enable registers
-	 * in both of the register blocks, saving all of it.
-	 * Find all currently active GP events.
-	 */
-	for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
-		gpe_register_info = &acpi_gbl_gpe_register_info[i];
+	/* Examine all GPE blocks attached to this interrupt level */
 
-		status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, &gpe_register_info->status_address, 0);
-		gpe_register_info->status = (u8) in_value;
-		if (ACPI_FAILURE (status)) {
-			return (ACPI_INTERRUPT_NOT_HANDLED);
-		}
+	gpe_block = acpi_gbl_gpe_block_list_head;
+	while (gpe_block) {
+		/*
+		 * Read all of the 8-bit GPE status and enable registers
+		 * in this GPE block, saving all of them.
+		 * Find all currently active GP events.
+		 */
+		for (i = 0; i < gpe_block->register_count; i++) {
+			/* Get the next status/enable pair */
 
-		status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, &gpe_register_info->enable_address, 0);
-		gpe_register_info->enable = (u8) in_value;
-		if (ACPI_FAILURE (status)) {
-			return (ACPI_INTERRUPT_NOT_HANDLED);
-		}
+			gpe_register_info = &gpe_block->register_info[i];
+
+			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
+					 &gpe_register_info->status_address, 0);
+			gpe_register_info->status = (u8) in_value;
+			if (ACPI_FAILURE (status)) {
+				return (ACPI_INTERRUPT_NOT_HANDLED);
+			}
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
-			"GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X\n",
-			ACPI_HIDWORD (gpe_register_info->enable_address.address),
-			ACPI_LODWORD (gpe_register_info->enable_address.address),
-			gpe_register_info->enable,
-			gpe_register_info->status));
-
-		/* First check if there is anything active at all in this register */
-
-		enabled_status_byte = (u8) (gpe_register_info->status &
-				   gpe_register_info->enable);
-		if (!enabled_status_byte) {
-			/* No active GPEs in this register, move on */
+			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
+					 &gpe_register_info->enable_address, 0);
+			gpe_register_info->enable = (u8) in_value;
+			if (ACPI_FAILURE (status)) {
+				return (ACPI_INTERRUPT_NOT_HANDLED);
+			}
 
-			continue;
-		}
+			ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+				"GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X\n",
+				ACPI_HIDWORD (gpe_register_info->enable_address.address),
+				ACPI_LODWORD (gpe_register_info->enable_address.address),
+				gpe_register_info->enable,
+				gpe_register_info->status));
+
+			/* First check if there is anything active at all in this register */
+
+			enabled_status_byte = (u8) (gpe_register_info->status &
+					   gpe_register_info->enable);
+			if (!enabled_status_byte) {
+				/* No active GPEs in this register, move on */
+
+				continue;
+			}
 
-		/* Now look at the individual GPEs in this byte register */
+			/* Now look at the individual GPEs in this byte register */
 
-		for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) {
-			/* Examine one GPE bit */
+			for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) {
+				/* Examine one GPE bit */
 
-			if (enabled_status_byte & bit_mask) {
-				/*
-				 * Found an active GPE.  Dispatch the event to a handler
-				 * or method.
-				 */
-				int_status |= acpi_ev_gpe_dispatch (
-						  gpe_register_info->base_gpe_number + j);
+				if (enabled_status_byte & bit_mask) {
+					/*
+					 * Found an active GPE. Dispatch the event to a handler
+					 * or method.
+					 */
+					int_status |= acpi_ev_gpe_dispatch (
+							  &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) +j]);
+				}
 			}
 		}
+
+		gpe_block = gpe_block->next;
 	}
 
 	return (int_status);
@@ -536,7 +201,7 @@
  *
  * FUNCTION:    acpi_ev_asynch_execute_gpe_method
  *
- * PARAMETERS:  gpe_number      - The 0-based GPE number
+ * PARAMETERS:  gpe_event_info - Info for this GPE
  *
  * RETURN:      None
  *
@@ -552,20 +217,14 @@
 acpi_ev_asynch_execute_gpe_method (
 	void                            *context)
 {
-	u32                             gpe_number = (u32) ACPI_TO_INTEGER (context);
-	u32                             gpe_number_index;
-	struct acpi_gpe_number_info     gpe_number_info;
+	struct acpi_gpe_event_info      *gpe_event_info = (void *) context;
+	u32                             gpe_number = 0;
 	acpi_status                     status;
 
 
 	ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");
 
 
-	gpe_number_index = acpi_ev_get_gpe_number_index (gpe_number);
-	if (gpe_number_index == ACPI_GPE_INVALID) {
-		return_VOID;
-	}
-
 	/*
 	 * Take a snapshot of the GPE info for this level - we copy the
 	 * info to prevent a race condition with remove_handler.
@@ -575,40 +234,38 @@
 		return_VOID;
 	}
 
-	gpe_number_info = acpi_gbl_gpe_number_info [gpe_number_index];
 	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
 	if (ACPI_FAILURE (status)) {
 		return_VOID;
 	}
 
-	if (gpe_number_info.method_node) {
+	if (gpe_event_info->method_node) {
 		/*
 		 * Invoke the GPE Method (_Lxx, _Exx):
 		 * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
 		 */
-		status = acpi_ns_evaluate_by_handle (gpe_number_info.method_node, NULL, NULL);
+		status = acpi_ns_evaluate_by_handle (gpe_event_info->method_node, NULL, NULL);
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2.2X]\n",
 				acpi_format_exception (status),
-				gpe_number_info.method_node->name.ascii, gpe_number));
+				gpe_event_info->method_node->name.ascii, gpe_number));
 		}
 	}
 
-	if (gpe_number_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {
+	if (gpe_event_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
 		/*
 		 * GPE is level-triggered, we clear the GPE status bit after handling
 		 * the event.
 		 */
-		status = acpi_hw_clear_gpe (gpe_number);
+		status = acpi_hw_clear_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
 			return_VOID;
 		}
 	}
 
-	/*
-	 * Enable the GPE.
-	 */
-	(void) acpi_hw_enable_gpe (gpe_number);
+	/* Enable this GPE */
+
+	(void) acpi_hw_enable_gpe (gpe_event_info);
 	return_VOID;
 }
 
@@ -617,7 +274,7 @@
  *
  * FUNCTION:    acpi_ev_gpe_dispatch
  *
- * PARAMETERS:  gpe_number      - The 0-based GPE number
+ * PARAMETERS:  gpe_event_info - info for this GPE
  *
  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
  *
@@ -629,9 +286,9 @@
 
 u32
 acpi_ev_gpe_dispatch (
-	u32                             gpe_number)
+	struct acpi_gpe_event_info      *gpe_event_info)
 {
-	struct acpi_gpe_number_info     *gpe_number_info;
+	u32                             gpe_number = 0; /* TBD: remove */
 	acpi_status                     status;
 
 
@@ -639,23 +296,14 @@
 
 
 	/*
-	 * We don't have to worry about mutex on gpe_number_info because we are
-	 * executing at interrupt level.
-	 */
-	gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number);
-	if (!gpe_number_info) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GPE[%X] is not a valid event\n", gpe_number));
-		return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
-	}
-
-	/*
 	 * If edge-triggered, clear the GPE status bit now.  Note that
 	 * level-triggered events are cleared after the GPE is serviced.
 	 */
-	if (gpe_number_info->type & ACPI_EVENT_EDGE_TRIGGERED) {
-		status = acpi_hw_clear_gpe (gpe_number);
+	if (gpe_event_info->type & ACPI_EVENT_EDGE_TRIGGERED) {
+		status = acpi_hw_clear_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n", gpe_number));
+			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n",
+				gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
 	}
@@ -667,19 +315,20 @@
 	 * If there is neither a handler nor a method, we disable the level to
 	 * prevent further events from coming in here.
 	 */
-	if (gpe_number_info->handler) {
+	if (gpe_event_info->handler) {
 		/* Invoke the installed handler (at interrupt level) */
 
-		gpe_number_info->handler (gpe_number_info->context);
+		gpe_event_info->handler (gpe_event_info->context);
 	}
-	else if (gpe_number_info->method_node) {
+	else if (gpe_event_info->method_node) {
 		/*
 		 * Disable GPE, so it doesn't keep firing before the method has a
 		 * chance to run.
 		 */
-		status = acpi_hw_disable_gpe (gpe_number);
+		status = acpi_hw_disable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n", gpe_number));
+			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n",
+				gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
 
@@ -688,22 +337,27 @@
 		 */
 		if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
 				 acpi_ev_asynch_execute_gpe_method,
-				 ACPI_TO_POINTER (gpe_number)))) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled\n", gpe_number));
+				 gpe_event_info))) {
+			ACPI_REPORT_ERROR ((
+				"acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled\n",
+				gpe_number));
 		}
 	}
 	else {
 		/* No handler or method to run! */
 
-		ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: No handler or method for GPE[%2.2X], disabling event\n", gpe_number));
+		ACPI_REPORT_ERROR ((
+			"acpi_ev_gpe_dispatch: No handler or method for GPE[%2.2X], disabling event\n",
+			gpe_number));
 
 		/*
 		 * Disable the GPE.  The GPE will remain disabled until the ACPI
 		 * Core Subsystem is restarted, or the handler is reinstalled.
 		 */
-		status = acpi_hw_disable_gpe (gpe_number);
+		status = acpi_hw_disable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n", gpe_number));
+			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n",
+				gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
 	}
@@ -711,10 +365,11 @@
 	/*
 	 * It is now safe to clear level-triggered evnets.
 	 */
-	if (gpe_number_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
-		status = acpi_hw_clear_gpe (gpe_number);
+	if (gpe_event_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
+		status = acpi_hw_clear_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n", gpe_number));
+			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n",
+				gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
 	}
diff -urN linux-2.5.63-bk4/drivers/acpi/events/evgpeblk.c linux-2.5.63-bk5/drivers/acpi/events/evgpeblk.c
--- linux-2.5.63-bk4/drivers/acpi/events/evgpeblk.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk5/drivers/acpi/events/evgpeblk.c	Mon Mar 31 12:18:55 2003
@@ -0,0 +1,545 @@
+/******************************************************************************
+ *
+ * Module Name: evgpeblk - GPE block creation and initialization.
+ *
+ *****************************************************************************/
+
+/*
+ * 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.
+ */
+
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evgpe")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_save_method_info
+ *
+ * PARAMETERS:  Callback from walk_namespace
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
+ *              control method under the _GPE portion of the namespace.
+ *              Extract the name and GPE type from the object, saving this
+ *              information for quick lookup during GPE dispatch
+ *
+ *              The name of each GPE control method is of the form:
+ *                  "_Lnn" or "_Enn"
+ *              Where:
+ *                  L      - means that the GPE is level triggered
+ *                  E      - means that the GPE is edge triggered
+ *                  nn     - is the GPE number [in HEX]
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ev_save_method_info (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *obj_desc,
+	void                            **return_value)
+{
+	struct acpi_gpe_block_info      *gpe_block = (void *) obj_desc;
+	struct acpi_gpe_event_info      *gpe_event_info;
+	u32                             gpe_number;
+	char                            name[ACPI_NAME_SIZE + 1];
+	u8                              type;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_NAME ("ev_save_method_info");
+
+
+	/* Extract the name from the object and convert to a string */
+
+	ACPI_MOVE_UNALIGNED32_TO_32 (name,
+			 &((struct acpi_namespace_node *) obj_handle)->name.integer);
+	name[ACPI_NAME_SIZE] = 0;
+
+	/*
+	 * Edge/Level determination is based on the 2nd character of the method name
+	 */
+	switch (name[1]) {
+	case 'L':
+		type = ACPI_EVENT_LEVEL_TRIGGERED;
+		break;
+
+	case 'E':
+		type = ACPI_EVENT_EDGE_TRIGGERED;
+		break;
+
+	default:
+		/* Unknown method type, just ignore it! */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n",
+			name));
+		return (AE_OK);
+	}
+
+	/* Convert the last two characters of the name to the GPE Number */
+
+	gpe_number = ACPI_STRTOUL (&name[2], NULL, 16);
+	if (gpe_number == ACPI_UINT32_MAX) {
+		/* Conversion failed; invalid method, just ignore it */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not extract GPE number from name: %s (name is not of form _Lnn or _Enn)\n",
+			name));
+		return (AE_OK);
+	}
+
+	/* Ensure that we have a valid GPE number for this GPE block */
+
+	if ((gpe_number < gpe_block->block_base_number) ||
+		(gpe_number >= (gpe_block->register_count * 8))) {
+		/* Not valid, all we can do here is ignore it */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"GPE number associated with method %s is not valid\n", name));
+		return (AE_OK);
+	}
+
+	/*
+	 * Now we can add this information to the gpe_event_info block
+	 * for use during dispatch of this GPE.
+	 */
+	gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
+
+	gpe_event_info->type     = type;
+	gpe_event_info->method_node = (struct acpi_namespace_node *) obj_handle;
+
+	/*
+	 * Enable the GPE (SCIs should be disabled at this point)
+	 */
+	status = acpi_hw_enable_gpe (gpe_event_info);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %2.2X\n",
+		name, gpe_number));
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_gpe_block
+ *
+ * PARAMETERS:  gpe_block   - New GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install new GPE block with mutex support
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_install_gpe_block (
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	struct acpi_gpe_block_info      *next_gpe_block;
+	acpi_status                     status;
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Install the new block at the end of the global list */
+
+	if (acpi_gbl_gpe_block_list_head) {
+		next_gpe_block = acpi_gbl_gpe_block_list_head;
+		while (next_gpe_block->next) {
+			next_gpe_block = next_gpe_block->next;
+		}
+
+		next_gpe_block->next = gpe_block;
+		gpe_block->previous = next_gpe_block;
+	}
+	else {
+		acpi_gbl_gpe_block_list_head = gpe_block;
+	}
+
+	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_create_gpe_info_blocks
+ *
+ * PARAMETERS:  gpe_block   - New GPE block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create the register_info and event_info blocks for this GPE block
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_create_gpe_info_blocks (
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	struct acpi_gpe_register_info   *gpe_register_info = NULL;
+	struct acpi_gpe_event_info      *gpe_event_info = NULL;
+	struct acpi_gpe_event_info      *this_event;
+	struct acpi_gpe_register_info   *this_register;
+	acpi_native_uint                i;
+	acpi_native_uint                j;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_create_gpe_info_blocks");
+
+
+	/* Allocate the GPE register information block */
+
+	gpe_register_info = ACPI_MEM_CALLOCATE (
+			  (acpi_size) gpe_block->register_count *
+			  sizeof (struct acpi_gpe_register_info));
+	if (!gpe_register_info) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not allocate the gpe_register_info table\n"));
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/*
+	 * Allocate the GPE event_info block. There are eight distinct GPEs
+	 * per register.  Initialization to zeros is sufficient.
+	 */
+	gpe_event_info = ACPI_MEM_CALLOCATE (
+			   ((acpi_size) gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) *
+			   sizeof (struct acpi_gpe_event_info));
+	if (!gpe_event_info) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_event_info table\n"));
+		status = AE_NO_MEMORY;
+		goto error_exit;
+	}
+
+	/*
+	 * Initialize the GPE Register and Event structures.  A goal of these
+	 * tables is to hide the fact that there are two separate GPE register sets
+	 * in a given gpe hardware block, the status registers occupy the first half,
+	 * and the enable registers occupy the second half.  Another goal is to hide
+	 * the fact that there may be multiple GPE hardware blocks.
+	 */
+	this_register = gpe_register_info;
+	this_event   = gpe_event_info;
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		/* Init the register_info for this GPE register (8 GPEs) */
+
+		this_register->base_gpe_number = (u8) (gpe_block->block_base_number +
+				   (i * ACPI_GPE_REGISTER_WIDTH));
+
+		ACPI_STORE_ADDRESS (this_register->status_address.address,
+				 (gpe_block->block_address.address
+				 + i));
+
+		ACPI_STORE_ADDRESS (this_register->enable_address.address,
+				 (gpe_block->block_address.address
+				 + i
+				 + gpe_block->register_count));
+
+		this_register->status_address.address_space_id = gpe_block->block_address.address_space_id;
+		this_register->enable_address.address_space_id = gpe_block->block_address.address_space_id;
+		this_register->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
+		this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
+		this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
+		this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
+
+		/* Init the event_info for each GPE within this register */
+
+		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+			this_event->bit_mask = acpi_gbl_decode_to8bit[j];
+			this_event->register_info = this_register;
+			this_event++;
+		}
+
+		/*
+		 * Clear the status/enable registers.  Note that status registers
+		 * are cleared by writing a '1', while enable registers are cleared
+		 * by writing a '0'.
+		 */
+		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00,
+				 &this_register->enable_address, 0);
+		if (ACPI_FAILURE (status)) {
+			goto error_exit;
+		}
+
+		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF,
+				 &this_register->status_address, 0);
+		if (ACPI_FAILURE (status)) {
+			goto error_exit;
+		}
+
+		this_register++;
+	}
+
+	gpe_block->register_info = gpe_register_info;
+	gpe_block->event_info  = gpe_event_info;
+
+	return_ACPI_STATUS (AE_OK);
+
+
+error_exit:
+
+	if (gpe_register_info) {
+		ACPI_MEM_FREE (gpe_register_info);
+	}
+	if (gpe_event_info) {
+		ACPI_MEM_FREE (gpe_event_info);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_create_gpe_block
+ *
+ * PARAMETERS:  TBD
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create and Install a block of GPE registers
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_create_gpe_block (
+	char                            *pathname,
+	struct acpi_generic_address     *gpe_block_address,
+	u32                             register_count,
+	u8                              gpe_block_base_number,
+	u32                             interrupt_level)
+{
+	struct acpi_gpe_block_info      *gpe_block;
+	acpi_status                     status;
+	acpi_handle                     obj_handle;
+
+
+	ACPI_FUNCTION_TRACE ("ev_create_gpe_block");
+
+
+	if (!register_count) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Get a handle to the parent object for this GPE block */
+
+	status = acpi_get_handle (NULL, pathname, &obj_handle);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Allocate a new GPE block */
+
+	gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info));
+	if (!gpe_block) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Initialize the new GPE block */
+
+	gpe_block->register_count = register_count;
+	gpe_block->block_base_number = gpe_block_base_number;
+
+	ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address));
+
+	/* Create the register_info and event_info sub-structures */
+
+	status = acpi_ev_create_gpe_info_blocks (gpe_block);
+	if (ACPI_FAILURE (status)) {
+		ACPI_MEM_FREE (gpe_block);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Install the new block in the global list(s) */
+	/* TBD: Install block in the interrupt handler list */
+
+	status = acpi_ev_install_gpe_block (gpe_block);
+	if (ACPI_FAILURE (status)) {
+		ACPI_MEM_FREE (gpe_block);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Dump info about this GPE block */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block: %X registers at %8.8X%8.8X\n",
+		gpe_block->register_count,
+		ACPI_HIDWORD (gpe_block->block_address.address),
+		ACPI_LODWORD (gpe_block->block_address.address)));
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block defined as GPE%d to GPE%d\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_walk_namespace (ACPI_TYPE_METHOD, obj_handle,
+			  ACPI_UINT32_MAX, acpi_ev_save_method_info,
+			  gpe_block, NULL);
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_gpe_initialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the GPE data structures
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_gpe_initialize (void)
+{
+	u32                             register_count0 = 0;
+	u32                             register_count1 = 0;
+	u32                             gpe_number_max = 0;
+
+
+	ACPI_FUNCTION_TRACE ("ev_gpe_initialize");
+
+
+	/*
+	 * Initialize the GPE Blocks defined in the FADT
+	 *
+	 * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,
+	 * section "General-Purpose Event Registers", we have:
+	 *
+	 * "Each register block contains two registers of equal length
+	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
+	 *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
+	 *  The length of the GPE1_STS and GPE1_EN registers is equal to
+	 *  half the GPE1_LEN. If a generic register block is not supported
+	 *  then its respective block pointer and block length values in the
+	 *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
+	 *  to be the same size."
+	 */
+
+	/*
+	 * Determine the maximum GPE number for this machine.
+	 *
+	 * Note: both GPE0 and GPE1 are optional, and either can exist without
+	 * the other.
+	 * If EITHER the register length OR the block address are zero, then that
+	 * particular block is not supported.
+	 */
+	if (acpi_gbl_FADT->gpe0_blk_len &&
+		acpi_gbl_FADT->xgpe0_blk.address) {
+		/* GPE block 0 exists (has both length and address > 0) */
+
+		register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2);
+
+		gpe_number_max = (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
+
+		acpi_ev_create_gpe_block ("\\_GPE", &acpi_gbl_FADT->xgpe0_blk,
+			register_count0, 0, acpi_gbl_FADT->sci_int);
+	}
+
+	if (acpi_gbl_FADT->gpe1_blk_len &&
+		acpi_gbl_FADT->xgpe1_blk.address) {
+		/* GPE block 1 exists (has both length and address > 0) */
+
+		register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2);
+
+		/* Check for GPE0/GPE1 overlap (if both banks exist) */
+
+		if ((register_count0) &&
+			(gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
+			ACPI_REPORT_ERROR ((
+				"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n",
+				gpe_number_max, acpi_gbl_FADT->gpe1_base,
+				acpi_gbl_FADT->gpe1_base +
+				((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
+
+			/* Ignore GPE1 block by setting the register count to zero */
+
+			register_count1 = 0;
+		}
+		else {
+			acpi_ev_create_gpe_block ("\\_GPE", &acpi_gbl_FADT->xgpe1_blk,
+				register_count1, acpi_gbl_FADT->gpe1_base, acpi_gbl_FADT->sci_int);
+
+			/*
+			 * GPE0 and GPE1 do not have to be contiguous in the GPE number space,
+			 * But, GPE0 always starts at zero.
+			 */
+			gpe_number_max = acpi_gbl_FADT->gpe1_base +
+					   ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
+		}
+	}
+
+	/* Exit if there are no GPE registers */
+
+	if ((register_count0 + register_count1) == 0) {
+		/* GPEs are not required by ACPI, this is OK */
+
+		ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Check for Max GPE number out-of-range */
+
+	if (gpe_number_max > ACPI_GPE_MAX) {
+		ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
+			gpe_number_max));
+		return_ACPI_STATUS (AE_BAD_VALUE);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff -urN linux-2.5.63-bk4/drivers/acpi/events/evmisc.c linux-2.5.63-bk5/drivers/acpi/events/evmisc.c
--- linux-2.5.63-bk4/drivers/acpi/events/evmisc.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/drivers/acpi/events/evmisc.c	Mon Mar 31 12:18:55 2003
@@ -86,84 +86,6 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_get_gpe_register_info
- *
- * PARAMETERS:  gpe_number      - Raw GPE number
- *
- * RETURN:      Pointer to the info struct for this GPE register.
- *
- * DESCRIPTION: Returns the register index (index into the GPE register info
- *              table) associated with this GPE.
- *
- ******************************************************************************/
-
-struct acpi_gpe_register_info *
-acpi_ev_get_gpe_register_info (
-	u32                             gpe_number)
-{
-
-	if (gpe_number > acpi_gbl_gpe_number_max) {
-		return (NULL);
-	}
-
-	return (&acpi_gbl_gpe_register_info [ACPI_DIV_8 (acpi_gbl_gpe_number_to_index[gpe_number].number_index)]);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_get_gpe_number_info
- *
- * PARAMETERS:  gpe_number      - Raw GPE number
- *
- * RETURN:      None.
- *
- * DESCRIPTION: Returns the number index (index into the GPE number info table)
- *              associated with this GPE.
- *
- ******************************************************************************/
-
-struct acpi_gpe_number_info *
-acpi_ev_get_gpe_number_info (
-	u32                             gpe_number)
-{
-
-	if (gpe_number > acpi_gbl_gpe_number_max) {
-		return (NULL);
-	}
-
-	return (&acpi_gbl_gpe_number_info [acpi_gbl_gpe_number_to_index[gpe_number].number_index]);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_get_gpe_number_index
- *
- * PARAMETERS:  gpe_number      - Raw GPE number
- *
- * RETURN:      None.
- *
- * DESCRIPTION: Returns the number index (index into the GPE number info table)
- *              associated with this GPE.
- *
- ******************************************************************************/
-
-u32
-acpi_ev_get_gpe_number_index (
-	u32                             gpe_number)
-{
-
-	if (gpe_number > acpi_gbl_gpe_number_max) {
-		return (ACPI_GPE_INVALID);
-	}
-
-	return (acpi_gbl_gpe_number_to_index[gpe_number].number_index);
-}
-
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ev_queue_notify_request
  *
  * PARAMETERS:
@@ -601,6 +523,9 @@
 {
 	acpi_native_uint                i;
 	acpi_status                     status;
+	struct acpi_gpe_block_info      *gpe_block;
+	struct acpi_gpe_block_info      *next_gpe_block;
+	struct acpi_gpe_event_info      *gpe_event_info;
 
 
 	ACPI_FUNCTION_TRACE ("ev_terminate");
@@ -625,13 +550,19 @@
 		/*
 		 * Disable all GPEs
 		 */
-		for (i = 0; i < acpi_gbl_gpe_number_max; i++) {
-			if (acpi_ev_get_gpe_number_index ((u32)i) != ACPI_GPE_INVALID) {
-				status = acpi_hw_disable_gpe((u32) i);
+		gpe_block = acpi_gbl_gpe_block_list_head;
+		while (gpe_block) {
+			gpe_event_info = gpe_block->event_info;
+			for (i = 0; i < (gpe_block->register_count * 8); i++) {
+				status = acpi_hw_disable_gpe (gpe_event_info);
 				if (ACPI_FAILURE (status)) {
 					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable GPE %d\n", (u32) i));
 				}
+
+				gpe_event_info++;
 			}
+
+			gpe_block = gpe_block->next;
 		}
 
 		/*
@@ -654,21 +585,16 @@
 	}
 
 	/*
-	 * Free global tables, etc.
+	 * Free global GPE blocks and related info structures
 	 */
-	if (acpi_gbl_gpe_register_info) {
-		ACPI_MEM_FREE (acpi_gbl_gpe_register_info);
-		acpi_gbl_gpe_register_info = NULL;
-	}
-
-	if (acpi_gbl_gpe_number_info) {
-		ACPI_MEM_FREE (acpi_gbl_gpe_number_info);
-		acpi_gbl_gpe_number_info = NULL;
-	}
+	gpe_block = acpi_gbl_gpe_block_list_head;
+	while (gpe_block) {
+		next_gpe_block = gpe_block->next;
+		ACPI_MEM_FREE (gpe_block->event_info);
+		ACPI_MEM_FREE (gpe_block->register_info);
+		ACPI_MEM_FREE (gpe_block);
 
-	if (acpi_gbl_gpe_number_to_index) {
-		ACPI_MEM_FREE (acpi_gbl_gpe_number_to_index);
-		acpi_gbl_gpe_number_to_index = NULL;
+		gpe_block = next_gpe_block;
 	}
 
 	return_VOID;
diff -urN linux-2.5.63-bk4/drivers/acpi/events/evsci.c linux-2.5.63-bk5/drivers/acpi/events/evsci.c
--- linux-2.5.63-bk4/drivers/acpi/events/evsci.c	Mon Feb 24 11:05:36 2003
+++ linux-2.5.63-bk5/drivers/acpi/events/evsci.c	Mon Mar 31 12:18:55 2003
@@ -69,38 +69,24 @@
 	void                            *context)
 {
 	u32                             interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
-	u32                             value;
-	acpi_status                     status;
 
 
 	ACPI_FUNCTION_TRACE("ev_sci_handler");
 
 
 	/*
-	 * Make sure that ACPI is enabled by checking SCI_EN.  Note that we are
-	 * required to treat the SCI interrupt as sharable, level, active low.
+	 * We are guaranteed by the ACPI CA initialization/shutdown code that
+	 * if this interrupt handler is installed, ACPI is enabled.
 	 */
-	status = acpi_get_register (ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_DO_NOT_LOCK);
-	if (ACPI_FAILURE (status)) {
-		return (ACPI_INTERRUPT_NOT_HANDLED);
-	}
-
-	if (!value) {
-		/* ACPI is not enabled;  this interrupt cannot be for us */
-
-		return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
-	}
 
 	/*
 	 * Fixed acpi_events:
-	 * -------------
 	 * Check for and dispatch any Fixed acpi_events that have occurred
 	 */
 	interrupt_handled |= acpi_ev_fixed_event_detect ();
 
 	/*
 	 * GPEs:
-	 * -----
 	 * Check for and dispatch any GPEs that have occurred
 	 */
 	interrupt_handled |= acpi_ev_gpe_detect ();
diff -urN linux-2.5.63-bk4/drivers/acpi/events/evxface.c linux-2.5.63-bk5/drivers/acpi/events/evxface.c
--- linux-2.5.63-bk4/drivers/acpi/events/evxface.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/drivers/acpi/events/evxface.c	Mon Mar 31 12:18:55 2003
@@ -492,7 +492,7 @@
 	void                            *context)
 {
 	acpi_status                     status;
-	struct acpi_gpe_number_info     *gpe_number_info;
+	struct acpi_gpe_event_info      *gpe_event_info;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
@@ -506,8 +506,8 @@
 
 	/* Ensure that we have a valid GPE number */
 
-	gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number);
-	if (!gpe_number_info) {
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
+	if (!gpe_event_info) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
@@ -518,25 +518,25 @@
 
 	/* Make sure that there isn't a handler there already */
 
-	if (gpe_number_info->handler) {
+	if (gpe_event_info->handler) {
 		status = AE_ALREADY_EXISTS;
 		goto cleanup;
 	}
 
 	/* Install the handler */
 
-	gpe_number_info->handler = handler;
-	gpe_number_info->context = context;
-	gpe_number_info->type  = (u8) type;
+	gpe_event_info->handler = handler;
+	gpe_event_info->context = context;
+	gpe_event_info->type  = (u8) type;
 
 	/* Clear the GPE (of stale events), the enable it */
 
-	status = acpi_hw_clear_gpe (gpe_number);
+	status = acpi_hw_clear_gpe (gpe_event_info);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
 	}
 
-	status = acpi_hw_enable_gpe (gpe_number);
+	status = acpi_hw_enable_gpe (gpe_event_info);
 
 
 cleanup:
@@ -564,7 +564,7 @@
 	acpi_gpe_handler                handler)
 {
 	acpi_status                     status;
-	struct acpi_gpe_number_info     *gpe_number_info;
+	struct acpi_gpe_event_info      *gpe_event_info;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
@@ -578,14 +578,14 @@
 
 	/* Ensure that we have a valid GPE number */
 
-	gpe_number_info = acpi_ev_get_gpe_number_info (gpe_number);
-	if (!gpe_number_info) {
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
+	if (!gpe_event_info) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
 	/* Disable the GPE before removing the handler */
 
-	status = acpi_hw_disable_gpe (gpe_number);
+	status = acpi_hw_disable_gpe (gpe_event_info);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -597,16 +597,16 @@
 
 	/* Make sure that the installed handler is the same */
 
-	if (gpe_number_info->handler != handler) {
-		(void) acpi_hw_enable_gpe (gpe_number);
+	if (gpe_event_info->handler != handler) {
+		(void) acpi_hw_enable_gpe (gpe_event_info);
 		status = AE_BAD_PARAMETER;
 		goto cleanup;
 	}
 
 	/* Remove the handler */
 
-	gpe_number_info->handler = NULL;
-	gpe_number_info->context = NULL;
+	gpe_event_info->handler = NULL;
+	gpe_event_info->context = NULL;
 
 
 cleanup:
diff -urN linux-2.5.63-bk4/drivers/acpi/events/evxfevnt.c linux-2.5.63-bk5/drivers/acpi/events/evxfevnt.c
--- linux-2.5.63-bk4/drivers/acpi/events/evxfevnt.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk5/drivers/acpi/events/evxfevnt.c	Mon Mar 31 12:18:55 2003
@@ -163,6 +163,7 @@
 {
 	acpi_status                     status = AE_OK;
 	u32                             value;
+	struct acpi_gpe_event_info      *gpe_event_info;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_enable_event");
@@ -209,19 +210,20 @@
 
 		/* Ensure that we have a valid GPE number */
 
-		if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) {
+		gpe_event_info = acpi_ev_get_gpe_event_info (event);
+		if (!gpe_event_info) {
 			return_ACPI_STATUS (AE_BAD_PARAMETER);
 		}
 
 		/* Enable the requested GPE number */
 
-		status = acpi_hw_enable_gpe (event);
+		status = acpi_hw_enable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
 
 		if (flags & ACPI_EVENT_WAKE_ENABLE) {
-			acpi_hw_enable_gpe_for_wakeup (event);
+			acpi_hw_enable_gpe_for_wakeup (gpe_event_info);
 		}
 		break;
 
@@ -257,6 +259,7 @@
 {
 	acpi_status                     status = AE_OK;
 	u32                             value;
+	struct acpi_gpe_event_info      *gpe_event_info;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_disable_event");
@@ -301,7 +304,8 @@
 
 		/* Ensure that we have a valid GPE number */
 
-		if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) {
+		gpe_event_info = acpi_ev_get_gpe_event_info (event);
+		if (!gpe_event_info) {
 			return_ACPI_STATUS (AE_BAD_PARAMETER);
 		}
 
@@ -311,10 +315,10 @@
 		 */
 
 		if (flags & ACPI_EVENT_WAKE_DISABLE) {
-			acpi_hw_disable_gpe_for_wakeup (event);
+			acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
 		}
 		else {
-			status = acpi_hw_disable_gpe (event);
+			status = acpi_hw_disable_gpe (gpe_event_info);
 		}
 		break;
 
@@ -346,6 +350,7 @@
 	u32                             type)
 {
 	acpi_status                     status = AE_OK;
+	struct acpi_gpe_event_info      *gpe_event_info;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_clear_event");
@@ -375,11 +380,12 @@
 
 		/* Ensure that we have a valid GPE number */
 
-		if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) {
+		gpe_event_info = acpi_ev_get_gpe_event_info (event);
+		if (!gpe_event_info) {
 			return_ACPI_STATUS (AE_BAD_PARAMETER);
 		}
 
-		status = acpi_hw_clear_gpe (event);
+		status = acpi_hw_clear_gpe (gpe_event_info);
 		break;
 
 
@@ -415,6 +421,7 @@
 	acpi_event_status               *event_status)
 {
 	acpi_status                     status = AE_OK;
+	struct acpi_gpe_event_info      *gpe_event_info;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_get_event_status");
@@ -447,7 +454,8 @@
 
 		/* Ensure that we have a valid GPE number */
 
-		if (acpi_ev_get_gpe_number_index (event) == ACPI_GPE_INVALID) {
+		gpe_event_info = acpi_ev_get_gpe_event_info (event);
+		if (!gpe_event_info) {
 			return_ACPI_STATUS (AE_BAD_PARAMETER);
 		}
 
@@ -464,3 +472,4 @@
 	return_ACPI_STATUS (status);
 }
 
+
diff -urN linux-2.5.63-bk4/drivers/acpi/hardware/hwgpe.c linux-2.5.63-bk5/drivers/acpi/hardware/hwgpe.c
--- linux-2.5.63-bk4/drivers/acpi/hardware/hwgpe.c	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk5/drivers/acpi/hardware/hwgpe.c	Mon Mar 31 12:18:55 2003
@@ -51,26 +51,6 @@
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_hw_get_gpe_bit_mask
- *
- * PARAMETERS:  gpe_number      - The GPE
- *
- * RETURN:      Gpe register bitmask for this gpe level
- *
- * DESCRIPTION: Get the bitmask for this GPE
- *
- ******************************************************************************/
-
-u8
-acpi_hw_get_gpe_bit_mask (
-	u32                             gpe_number)
-{
-	return (acpi_gbl_gpe_number_info [acpi_ev_get_gpe_number_index (gpe_number)].bit_mask);
-}
-
-
-/******************************************************************************
- *
  * FUNCTION:    acpi_hw_enable_gpe
  *
  * PARAMETERS:  gpe_number      - The GPE
@@ -83,37 +63,29 @@
 
 acpi_status
 acpi_hw_enable_gpe (
-	u32                             gpe_number)
+	struct acpi_gpe_event_info      *gpe_event_info)
 {
 	u32                             in_byte;
 	acpi_status                     status;
-	struct acpi_gpe_register_info   *gpe_register_info;
 
 
 	ACPI_FUNCTION_ENTRY ();
 
 
-	/* Get the info block for the entire GPE register */
-
-	gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
-	if (!gpe_register_info) {
-		return (AE_BAD_PARAMETER);
-	}
-
 	/*
 	 * Read the current value of the register, set the appropriate bit
 	 * to enable the GPE, and write out the new register.
 	 */
 	status = acpi_hw_low_level_read (8, &in_byte,
-			  &gpe_register_info->enable_address, 0);
+			  &gpe_event_info->register_info->enable_address, 0);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
 
 	/* Write with the new GPE bit enabled */
 
-	status = acpi_hw_low_level_write (8, (in_byte | acpi_hw_get_gpe_bit_mask (gpe_number)),
-			  &gpe_register_info->enable_address, 0);
+	status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask),
+			  &gpe_event_info->register_info->enable_address, 0);
 
 	return (status);
 }
@@ -134,7 +106,7 @@
 
 void
 acpi_hw_enable_gpe_for_wakeup (
-	u32                             gpe_number)
+	struct acpi_gpe_event_info      *gpe_event_info)
 {
 	struct acpi_gpe_register_info   *gpe_register_info;
 
@@ -144,7 +116,7 @@
 
 	/* Get the info block for the entire GPE register */
 
-	gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
+	gpe_register_info = gpe_event_info->register_info;
 	if (!gpe_register_info) {
 		return;
 	}
@@ -152,7 +124,7 @@
 	/*
 	 * Set the bit so we will not disable this when sleeping
 	 */
-	gpe_register_info->wake_enable |= acpi_hw_get_gpe_bit_mask (gpe_number);
+	gpe_register_info->wake_enable |= gpe_event_info->bit_mask;
 }
 
 
@@ -170,7 +142,7 @@
 
 acpi_status
 acpi_hw_disable_gpe (
-	u32                             gpe_number)
+	struct acpi_gpe_event_info      *gpe_event_info)
 {
 	u32                             in_byte;
 	acpi_status                     status;
@@ -182,7 +154,7 @@
 
 	/* Get the info block for the entire GPE register */
 
-	gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
+	gpe_register_info = gpe_event_info->register_info;
 	if (!gpe_register_info) {
 		return (AE_BAD_PARAMETER);
 	}
@@ -199,13 +171,13 @@
 
 	/* Write the byte with this GPE bit cleared */
 
-	status = acpi_hw_low_level_write (8, (in_byte & ~(acpi_hw_get_gpe_bit_mask (gpe_number))),
+	status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)),
 			  &gpe_register_info->enable_address, 0);
 	if (ACPI_FAILURE (status)) {
 		return (status);
 	}
 
-	acpi_hw_disable_gpe_for_wakeup(gpe_number);
+	acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
 	return (AE_OK);
 }
 
@@ -225,7 +197,7 @@
 
 void
 acpi_hw_disable_gpe_for_wakeup (
-	u32                             gpe_number)
+	struct acpi_gpe_event_info      *gpe_event_info)
 {
 	struct acpi_gpe_register_info   *gpe_register_info;
 
@@ -235,7 +207,7 @@
 
 	/* Get the info block for the entire GPE register */
 
-	gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
+	gpe_register_info = gpe_event_info->register_info;
 	if (!gpe_register_info) {
 		return;
 	}
@@ -243,7 +215,7 @@
 	/*
 	 * Clear the bit so we will disable this when sleeping
 	 */
-	gpe_register_info->wake_enable &= ~(acpi_hw_get_gpe_bit_mask (gpe_number));
+	gpe_register_info->wake_enable &= ~(gpe_event_info->bit_mask);
 }
 
 
@@ -261,28 +233,20 @@
 
 acpi_status
 acpi_hw_clear_gpe (
-	u32                             gpe_number)
+	struct acpi_gpe_event_info      *gpe_event_info)
 {
 	acpi_status                     status;
-	struct acpi_gpe_register_info   *gpe_register_info;
 
 
 	ACPI_FUNCTION_ENTRY ();
 
 
-	/* Get the info block for the entire GPE register */
-
-	gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
-	if (!gpe_register_info) {
-		return (AE_BAD_PARAMETER);
-	}
-
 	/*
 	 * Write a one to the appropriate bit in the status register to
 	 * clear this GPE.
 	 */
-	status = acpi_hw_low_level_write (8, acpi_hw_get_gpe_bit_mask (gpe_number),
-			  &gpe_register_info->status_address, 0);
+	status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask,
+			  &gpe_event_info->register_info->status_address, 0);
 
 	return (status);
 }
@@ -308,6 +272,7 @@
 	u32                             in_byte;
 	u8                              bit_mask;
 	struct acpi_gpe_register_info   *gpe_register_info;
+	struct acpi_gpe_event_info      *gpe_event_info;
 	acpi_status                     status;
 	acpi_event_status               local_event_status = 0;
 
@@ -319,16 +284,18 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	/* Get the info block for the entire GPE register */
-
-	gpe_register_info = acpi_ev_get_gpe_register_info (gpe_number);
-	if (!gpe_register_info) {
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_number);
+	if (!gpe_event_info) {
 		return (AE_BAD_PARAMETER);
 	}
 
+	/* Get the info block for the entire GPE register */
+
+	gpe_register_info = gpe_event_info->register_info;
+
 	/* Get the register bitmask for this GPE */
 
-	bit_mask = acpi_hw_get_gpe_bit_mask (gpe_number);
+	bit_mask = gpe_event_info->bit_mask;
 
 	/* GPE Enabled? */
 
@@ -375,7 +342,7 @@
  *
  * DESCRIPTION: Disable all non-wakeup GPEs
  *              Call with interrupts disabled. The interrupt handler also
- *              modifies acpi_gbl_gpe_register_info[i].Enable, so it should not be
+ *              modifies gpe_register_info->Enable, so it should not be
  *              given the chance to run until after non-wake GPEs are
  *              re-enabled.
  *
@@ -389,40 +356,49 @@
 	struct acpi_gpe_register_info   *gpe_register_info;
 	u32                             in_value;
 	acpi_status                     status;
+	struct acpi_gpe_block_info      *gpe_block;
 
 
 	ACPI_FUNCTION_ENTRY ();
 
 
-	for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
-		/* Get the info block for the entire GPE register */
+	gpe_block = acpi_gbl_gpe_block_list_head;
+	while (gpe_block) {
+		/* Get the register info for the entire GPE block */
 
-		gpe_register_info = &acpi_gbl_gpe_register_info[i];
+		gpe_register_info = gpe_block->register_info;
 		if (!gpe_register_info) {
 			return (AE_BAD_PARAMETER);
 		}
 
-		/*
-		 * Read the enabled status of all GPEs. We
-		 * 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);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
-
-		gpe_register_info->enable = (u8) in_value;
+		for (i = 0; i < gpe_block->register_count; i++) {
+			/*
+			 * Read the enabled status of all GPEs. We
+			 * 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);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+			gpe_register_info->enable = (u8) in_value;
+
+			/*
+			 * Disable all GPEs except wakeup GPEs.
+			 */
+			status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
+					&gpe_register_info->enable_address, 0);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
 
-		/*
-		 * Disable all GPEs except wakeup GPEs.
-		 */
-		status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
-				&gpe_register_info->enable_address, 0);
-		if (ACPI_FAILURE (status)) {
-			return (status);
+			gpe_register_info++;
 		}
+
+		gpe_block = gpe_block->next;
 	}
+
 	return (AE_OK);
 }
 
@@ -446,28 +422,37 @@
 	u32                             i;
 	struct acpi_gpe_register_info   *gpe_register_info;
 	acpi_status                     status;
+	struct acpi_gpe_block_info      *gpe_block;
 
 
 	ACPI_FUNCTION_ENTRY ();
 
 
-	for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
-		/* Get the info block for the entire GPE register */
+	gpe_block = acpi_gbl_gpe_block_list_head;
+	while (gpe_block) {
+		/* Get the register info for the entire GPE block */
 
-		gpe_register_info = &acpi_gbl_gpe_register_info[i];
+		gpe_register_info = gpe_block->register_info;
 		if (!gpe_register_info) {
 			return (AE_BAD_PARAMETER);
 		}
 
-		/*
-		 * We previously stored the enabled status of all GPEs.
-		 * Blast them back in.
-		 */
-		status = acpi_hw_low_level_write (8, gpe_register_info->enable,
-				 &gpe_register_info->enable_address, 0);
-		if (ACPI_FAILURE (status)) {
-			return (status);
+		for (i = 0; i < gpe_block->register_count; i++) {
+			/*
+			 * We previously stored the enabled status of all GPEs.
+			 * Blast them back in.
+			 */
+			status = acpi_hw_low_level_write (8, gpe_register_info->enable,
+					 &gpe_register_info->enable_address, 0);
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+
+			gpe_register_info++;
 		}
+
+		gpe_block = gpe_block->next;
 	}
+
 	return (AE_OK);
 }
diff -urN linux-2.5.63-bk4/drivers/acpi/hardware/hwregs.c linux-2.5.63-bk5/drivers/acpi/hardware/hwregs.c
--- linux-2.5.63-bk4/drivers/acpi/hardware/hwregs.c	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/drivers/acpi/hardware/hwregs.c	Mon Mar 31 12:18:55 2003
@@ -67,8 +67,8 @@
 acpi_hw_clear_acpi_status (void)
 {
 	acpi_native_uint                i;
-	acpi_native_uint                gpe_block;
 	acpi_status                     status;
+	struct acpi_gpe_block_info      *gpe_block;
 
 
 	ACPI_FUNCTION_TRACE ("hw_clear_acpi_status");
@@ -100,16 +100,19 @@
 		}
 	}
 
-	/* Clear the GPE Bits */
+	/* Clear the GPE Bits in all GPE registers in all GPE blocks */
 
-	for (gpe_block = 0; gpe_block < ACPI_MAX_GPE_BLOCKS; gpe_block++) {
-		for (i = 0; i < acpi_gbl_gpe_block_info[gpe_block].register_count; i++) {
+	gpe_block = acpi_gbl_gpe_block_list_head;
+	while (gpe_block) {
+		for (i = 0; i < gpe_block->register_count; i++) {
 			status = acpi_hw_low_level_write (8, 0xFF,
-					 acpi_gbl_gpe_block_info[gpe_block].block_address, (u32) i);
+					 &gpe_block->register_info[i].status_address, (u32) i);
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
 			}
 		}
+
+		gpe_block = gpe_block->next;
 	}
 
 unlock_and_exit:
diff -urN linux-2.5.63-bk4/drivers/acpi/hardware/hwsleep.c linux-2.5.63-bk5/drivers/acpi/hardware/hwsleep.c
--- linux-2.5.63-bk4/drivers/acpi/hardware/hwsleep.c	Mon Feb 24 11:05:06 2003
+++ linux-2.5.63-bk5/drivers/acpi/hardware/hwsleep.c	Mon Mar 31 12:18:55 2003
@@ -250,7 +250,7 @@
 
 	/* Get current value of PM1A control */
 
-	status = acpi_hw_register_read (ACPI_MTX_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+	status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -268,12 +268,12 @@
 
 	/* Write #1: fill in SLP_TYP data */
 
-	status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -287,12 +287,12 @@
 
 	ACPI_FLUSH_CPU_CACHE ();
 
-	status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -308,7 +308,7 @@
 		 */
 		acpi_os_stall (10000000);
 
-		status = acpi_hw_register_write (ACPI_MTX_LOCK, ACPI_REGISTER_PM1_CONTROL,
+		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL,
 				 sleep_enable_reg_info->access_bit_mask);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
@@ -318,7 +318,7 @@
 	/* Wait until we enter sleep state */
 
 	do {
-		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_LOCK);
+		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -327,7 +327,7 @@
 
 	} while (!in_value);
 
-	status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
+	status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -335,6 +335,51 @@
 	return_ACPI_STATUS (AE_OK);
 }
 
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_enter_sleep_state_s4bios
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform a S4 bios request.
+ *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enter_sleep_state_s4bios (
+	void)
+{
+	u32                             in_value;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
+
+	acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+	acpi_hw_clear_acpi_status();
+
+	acpi_hw_disable_non_wakeup_gpes();
+
+	ACPI_FLUSH_CPU_CACHE();
+
+	status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (acpi_integer) acpi_gbl_FADT->S4bios_req, 8);
+
+	do {
+		acpi_os_stall(1000);
+		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	} while (!in_value);
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_leave_sleep_state
diff -urN linux-2.5.63-bk4/drivers/acpi/osl.c linux-2.5.63-bk5/drivers/acpi/osl.c
--- linux-2.5.63-bk4/drivers/acpi/osl.c	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk5/drivers/acpi/osl.c	Mon Mar 31 12:18:55 2003
@@ -514,10 +514,12 @@
 
 /* TODO: Change code to take advantage of driver model more */
 void
-acpi_os_derive_pci_id (
+acpi_os_derive_pci_id_2 (
 	acpi_handle		rhandle,        /* upper bound  */
 	acpi_handle		chandle,        /* current node */
-	struct acpi_pci_id	**id)
+	struct acpi_pci_id	**id,
+	int			*is_bridge,
+	u8			*bus_number)
 {
 	acpi_handle		handle;
 	struct acpi_pci_id	*pci_id = *id;
@@ -528,7 +530,7 @@
 
 	acpi_get_parent(chandle, &handle);
 	if (handle != rhandle) {
-		acpi_os_derive_pci_id(rhandle, handle, &pci_id);
+		acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, bus_number);
 
 		status = acpi_get_type(handle, &type);
 		if ( (ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE) )
@@ -539,17 +541,42 @@
 			pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (temp));
 			pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp));
 
+			if (*is_bridge)
+				pci_id->bus = *bus_number;
+
 			/* any nicer way to get bus number of bridge ? */
 			status = acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8, 8);
-			if (ACPI_SUCCESS(status) && (tu8 & 0x7f) == 1) {
+			if (ACPI_SUCCESS(status) &&
+			    ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) {
+				status = acpi_os_read_pci_configuration(pci_id, 0x18, &tu8, 8);
+				if (!ACPI_SUCCESS(status)) {
+					/* Certainly broken...  FIX ME */
+					return;
+				}
+				*is_bridge = 1;
+				pci_id->bus = tu8;
 				status = acpi_os_read_pci_configuration(pci_id, 0x19, &tu8, 8);
-				if (ACPI_SUCCESS(status))
-					pci_id->bus = tu8;
-			}
+				if (ACPI_SUCCESS(status)) {
+					*bus_number = tu8;
+				}
+			} else
+				*is_bridge = 0;
 		}
 	}
 }
 
+void
+acpi_os_derive_pci_id (
+	acpi_handle		rhandle,        /* upper bound  */
+	acpi_handle		chandle,        /* current node */
+	struct acpi_pci_id	**id)
+{
+	int is_bridge = 1;
+	u8 bus_number = (*id)->bus;
+
+	acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
+}
+
 #else /*!CONFIG_ACPI_PCI*/
 
 acpi_status
diff -urN linux-2.5.63-bk4/drivers/acpi/pci_link.c linux-2.5.63-bk5/drivers/acpi/pci_link.c
--- linux-2.5.63-bk4/drivers/acpi/pci_link.c	Mon Feb 24 11:05:07 2003
+++ linux-2.5.63-bk5/drivers/acpi/pci_link.c	Mon Mar 31 12:18:55 2003
@@ -90,42 +90,25 @@
                             PCI Link Device Management
    -------------------------------------------------------------------------- */
 
-static int
-acpi_pci_link_get_possible (
-	struct acpi_pci_link	*link)
+static acpi_status
+acpi_pci_link_check_possible (
+	struct acpi_resource	*resource,
+	void			*context)
 {
-	int                     result = 0;
-	acpi_status		status = AE_OK;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	struct acpi_resource	*resource = NULL;
+	struct acpi_pci_link	*link = (struct acpi_pci_link *) context;
 	int			i = 0;
 
-	ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible");
-
-	if (!link)
-		return_VALUE(-EINVAL);
-
-	status = acpi_get_possible_resources(link->handle, &buffer);
-	if (ACPI_FAILURE(status) || !buffer.pointer) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n"));
-		result = -ENODEV;
-		goto end;
-	}
-
-	resource = (struct acpi_resource *) buffer.pointer;
-
-	/* skip past dependent function resource (if present) */
-	if (resource->id == ACPI_RSTYPE_START_DPF)
-		resource = ACPI_NEXT_RESOURCE(resource);
+	ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible");
 
 	switch (resource->id) {
+	case ACPI_RSTYPE_START_DPF:
+		return AE_OK;
 	case ACPI_RSTYPE_IRQ:
 	{
 		struct acpi_resource_irq *p = &resource->data.irq;
 		if (!p || !p->number_of_interrupts) {
 			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n"));
-			result = -ENODEV;
-			goto end;
+			return AE_OK;
 		}
 		for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
 			if (!p->interrupts[i]) {
@@ -143,8 +126,7 @@
 		if (!p || !p->number_of_interrupts) {
 			ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
 				"Blank IRQ resource\n"));
-			result = -ENODEV;
-			goto end;
+			return AE_OK;
 		}
 		for (i = 0; (i<p->number_of_interrupts && i<ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
 			if (!p->interrupts[i]) {
@@ -159,18 +141,76 @@
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
 			"Resource is not an IRQ entry\n"));
-		result = -ENODEV;
-		goto end;
-		break;
+		return AE_OK;
 	}
-	
+
+	return AE_CTRL_TERMINATE;
+}
+
+
+static int
+acpi_pci_link_get_possible (
+	struct acpi_pci_link	*link)
+{
+	acpi_status		status;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible");
+
+	if (!link)
+		return_VALUE(-EINVAL);
+
+	status = acpi_walk_resources(link->handle, METHOD_NAME__PRS,
+			acpi_pci_link_check_possible, link);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n"));
+		return_VALUE(-ENODEV);
+	}
+
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"Found %d possible IRQs\n", link->irq.possible_count));
 
-end:
-	acpi_os_free(buffer.pointer);
+	return_VALUE(0);
+}
 
-	return_VALUE(result);
+
+static acpi_status
+acpi_pci_link_check_current (
+	struct acpi_resource	*resource,
+	void			*context)
+{
+	int			*irq = (int *) context;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_check_current");
+
+	switch (resource->id) {
+	case ACPI_RSTYPE_IRQ:
+	{
+		struct acpi_resource_irq *p = &resource->data.irq;
+		if (!p || !p->number_of_interrupts) {
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+				"Blank IRQ resource\n"));
+			return AE_OK;
+		}
+		*irq = p->interrupts[0];
+		break;
+	}
+	case ACPI_RSTYPE_EXT_IRQ:
+	{
+		struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
+		if (!p || !p->number_of_interrupts) {
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+				"Blank IRQ resource\n"));
+			return AE_OK;
+		}
+		*irq = p->interrupts[0];
+		break;
+	}
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Resource isn't an IRQ\n"));
+		return AE_OK;
+	}
+	return AE_CTRL_TERMINATE;
 }
 
 
@@ -180,8 +220,6 @@
 {
 	int			result = 0;
 	acpi_status		status = AE_OK;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	struct acpi_resource	*resource = NULL;
 	int			irq = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_link_get_current");
@@ -206,47 +244,16 @@
 	 * Query and parse _CRS to get the current IRQ assignment. 
 	 */
 
-	status = acpi_get_current_resources(link->handle, &buffer);
+	status = acpi_walk_resources(link->handle, METHOD_NAME__CRS,
+			acpi_pci_link_check_current, &irq);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _CRS\n"));
 		result = -ENODEV;
 		goto end;
 	}
-	resource = (struct acpi_resource *) buffer.pointer;
-
-	switch (resource->id) {
-	case ACPI_RSTYPE_IRQ:
-	{
-		struct acpi_resource_irq *p = &resource->data.irq;
-		if (!p || !p->number_of_interrupts) {
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
-				"Blank IRQ resource\n"));
-			result = -ENODEV;
-			goto end;
-		}
-		irq = p->interrupts[0];
-		break;
-	}
-	case ACPI_RSTYPE_EXT_IRQ:
-	{
-		struct acpi_resource_ext_irq *p = &resource->data.extended_irq;
-		if (!p || !p->number_of_interrupts) {
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-				"Blank IRQ resource\n"));
-			result = -ENODEV;
-			goto end;
-		}
-		irq = p->interrupts[0];
-		break;
-	}
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Resource isn't an IRQ\n"));
-		result = -ENODEV;
-		goto end;
-	}
 
 	if (!irq) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid use of IRQ 0\n"));
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No IRQ resource found\n"));
 		result = -ENODEV;
 		goto end;
 	}
@@ -263,8 +270,6 @@
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
 
 end:
-	acpi_os_free(buffer.pointer);
-
 	return_VALUE(result);
 }
 
diff -urN linux-2.5.63-bk4/drivers/acpi/processor.c linux-2.5.63-bk5/drivers/acpi/processor.c
--- linux-2.5.63-bk4/drivers/acpi/processor.c	Mon Feb 24 11:05:37 2003
+++ linux-2.5.63-bk5/drivers/acpi/processor.c	Mon Mar 31 12:18:55 2003
@@ -1560,7 +1560,7 @@
 	acpi_status		status = 0;
 	union acpi_object	object = {0};
 	struct acpi_buffer	buffer = {sizeof(union acpi_object), &object};
-	static int		cpu_count = 0;
+	static int		cpu_index = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_info");
 
@@ -1570,6 +1570,13 @@
 	if (num_online_cpus() > 1)
 		errata.smp = TRUE;
 
+	/*
+	 *  Extra Processor objects may be enumerated on MP systems with
+	 *  less than the max # of CPUs. They should be ignored.
+	 */
+	if ((cpu_index + 1) > num_online_cpus())
+		return_VALUE(-ENODEV);
+
 	acpi_processor_errata(pr);
 
 	/*
@@ -1601,7 +1608,7 @@
 	 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
 	 *	>>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
 	 */
-	pr->id = cpu_count++;
+	pr->id = cpu_index++;
 	pr->acpi_id = object.processor.proc_id;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, 
@@ -1609,21 +1616,17 @@
 
 	if (!object.processor.pblk_address)
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
-	else if (object.processor.pblk_length < 4)
+	else if (object.processor.pblk_length != 6)
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n",
 			object.processor.pblk_length));
 	else {
 		pr->throttling.address = object.processor.pblk_address;
 		pr->throttling.duty_offset = acpi_fadt.duty_offset;
 		pr->throttling.duty_width = acpi_fadt.duty_width;
-
-		if (object.processor.pblk_length >= 5)
-			pr->power.states[ACPI_STATE_C2].address =
-				object.processor.pblk_address + 4;
-
-		if (object.processor.pblk_length >= 6)
-			pr->power.states[ACPI_STATE_C3].address =
-				object.processor.pblk_address + 5;
+		pr->power.states[ACPI_STATE_C2].address =
+			object.processor.pblk_address + 4;
+		pr->power.states[ACPI_STATE_C3].address =
+			object.processor.pblk_address + 5;
 	}
 
 	acpi_processor_get_power_info(pr);
diff -urN linux-2.5.63-bk4/drivers/acpi/resources/rsutils.c linux-2.5.63-bk5/drivers/acpi/resources/rsutils.c
--- linux-2.5.63-bk4/drivers/acpi/resources/rsutils.c	Mon Feb 24 11:05:06 2003
+++ linux-2.5.63-bk5/drivers/acpi/resources/rsutils.c	Mon Mar 31 12:18:55 2003
@@ -214,6 +214,60 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_rs_get_method_data
+ *
+ * PARAMETERS:  Handle          - a handle to the containing object
+ *              ret_buffer      - a pointer to a buffer structure for the
+ *                                  results
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
+ *              object contained in an object specified by the handle passed in
+ *
+ *              If the function fails an appropriate status will be returned
+ *              and the contents of the callers buffer is undefined.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_rs_get_method_data (
+	acpi_handle                     handle,
+	char                            *path,
+	struct acpi_buffer              *ret_buffer)
+{
+	union acpi_operand_object       *obj_desc;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("rs_get_method_data");
+
+
+	/* Parameters guaranteed valid by caller */
+
+	/*
+	 * Execute the method, no parameters
+	 */
+	status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Make the call to create a resource linked list from the
+	 * byte stream buffer that comes back from the method
+	 * execution.
+	 */
+	status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
+
+	/* On exit, we must delete the object returned by evaluate_object */
+
+	acpi_ut_remove_reference (obj_desc);
+	return_ACPI_STATUS (status);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_rs_set_srs_method_data
  *
  * PARAMETERS:  Handle          - a handle to the containing object
diff -urN linux-2.5.63-bk4/drivers/acpi/resources/rsxface.c linux-2.5.63-bk5/drivers/acpi/resources/rsxface.c
--- linux-2.5.63-bk4/drivers/acpi/resources/rsxface.c	Mon Feb 24 11:05:37 2003
+++ linux-2.5.63-bk5/drivers/acpi/resources/rsxface.c	Mon Mar 31 12:18:55 2003
@@ -212,6 +212,90 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_walk_resources
+ *
+ * PARAMETERS:  device_handle   - a handle to the device object for the
+ *                                device we are querying
+ *              Path            - method name of the resources we want
+ *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
+ *              user_function   - called for each resource
+ *              Context         - passed to user_function
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieves the current or possible resource list for the
+ *              specified device.  The user_function is called once for
+ *              each resource in the list.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_walk_resources (
+	acpi_handle                             device_handle,
+	char                                    *path,
+	ACPI_WALK_RESOURCE_CALLBACK     user_function,
+	void                                    *context)
+{
+	acpi_status                         status;
+	struct acpi_buffer                  buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_resource                *resource;
+
+	ACPI_FUNCTION_TRACE ("acpi_walk_resources");
+
+
+	if (!device_handle ||
+		(ACPI_STRNCMP (path, METHOD_NAME__CRS, sizeof (METHOD_NAME__CRS)) &&
+		ACPI_STRNCMP (path, METHOD_NAME__PRS, sizeof (METHOD_NAME__PRS)))) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	status = acpi_rs_get_method_data (device_handle, path, &buffer);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	resource = (struct acpi_resource *) buffer.pointer;
+	for (;;) {
+		if (!resource || resource->id == ACPI_RSTYPE_END_TAG) {
+			break;
+		}
+
+		status = user_function (resource, context);
+
+		switch (status) {
+		case AE_OK:
+		case AE_CTRL_DEPTH:
+
+			/* Just keep going */
+			status = AE_OK;
+			break;
+
+		case AE_CTRL_TERMINATE:
+
+			/* Exit now, with OK stats */
+
+			status = AE_OK;
+			goto cleanup;
+
+		default:
+
+			/* All others are valid exceptions */
+
+			goto cleanup;
+		}
+
+		resource = ACPI_NEXT_RESOURCE (resource);
+	}
+
+cleanup:
+
+	acpi_os_free (buffer.pointer);
+
+	return_ACPI_STATUS (status);
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_set_current_resources
  *
  * PARAMETERS:  device_handle   - a handle to the device object for the
@@ -252,3 +336,64 @@
 	status = acpi_rs_set_srs_method_data (device_handle, in_buffer);
 	return_ACPI_STATUS (status);
 }
+
+#define COPY_FIELD(out, in, field)  out->field = in->field
+#define COPY_ADDRESS(out, in)                      \
+	COPY_FIELD(out, in, resource_type);             \
+	COPY_FIELD(out, in, producer_consumer);         \
+	COPY_FIELD(out, in, decode);                    \
+	COPY_FIELD(out, in, min_address_fixed);         \
+	COPY_FIELD(out, in, max_address_fixed);         \
+	COPY_FIELD(out, in, attribute);                 \
+	COPY_FIELD(out, in, granularity);               \
+	COPY_FIELD(out, in, min_address_range);         \
+	COPY_FIELD(out, in, max_address_range);         \
+	COPY_FIELD(out, in, address_translation_offset); \
+	COPY_FIELD(out, in, address_length);            \
+	COPY_FIELD(out, in, resource_source);
+
+/*******************************************************************************
+*
+* FUNCTION:    acpi_resource_to_address64
+*
+* PARAMETERS:  resource                - Pointer to a resource
+*              out                     - Pointer to the users's return
+*                                        buffer (a struct
+*                                        struct acpi_resource_address64)
+*
+* RETURN:      Status
+*
+* DESCRIPTION: If the resource is an address16, address32, or address64,
+*              copy it to the address64 return buffer.  This saves the
+*              caller from having to duplicate code for different-sized
+*              addresses.
+*
+******************************************************************************/
+
+acpi_status
+acpi_resource_to_address64 (
+	struct acpi_resource            *resource,
+	struct acpi_resource_address64 *out)
+{
+	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;
+		COPY_ADDRESS(out, address16);
+		break;
+	case ACPI_RSTYPE_ADDRESS32:
+		address32 = (struct acpi_resource_address32 *) &resource->data;
+		COPY_ADDRESS(out, address32);
+		break;
+	case ACPI_RSTYPE_ADDRESS64:
+		address64 = (struct acpi_resource_address64 *) &resource->data;
+		COPY_ADDRESS(out, address64);
+		break;
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+	return (AE_OK);
+}
diff -urN linux-2.5.63-bk4/drivers/acpi/sleep/main.c linux-2.5.63-bk5/drivers/acpi/sleep/main.c
--- linux-2.5.63-bk4/drivers/acpi/sleep/main.c	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk5/drivers/acpi/sleep/main.c	Mon Mar 31 12:18:55 2003
@@ -183,14 +183,21 @@
 		status = acpi_enter_sleep_state(state);
 		break;
 
-	case ACPI_STATE_S2:
 #ifdef CONFIG_SOFTWARE_SUSPEND
+	case ACPI_STATE_S2:
 	case ACPI_STATE_S3:
 		do_suspend_lowlevel(0);
+		break;
 #endif
+	case ACPI_STATE_S4:
+		do_suspend_lowlevel_s4bios(0);
+		break;
+	default:
+		printk(KERN_WARNING PREFIX "don't know how to handle %d state.\n", state);
 		break;
 	}
 	local_irq_restore(flags);
+	printk(KERN_CRIT "Back to C!\n");
 
 	return status;
 }
@@ -211,21 +218,31 @@
 	if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
 		return AE_ERROR;
 
+	/* Since we handle S4OS via a different path (swsusp), give up if no s4bios. */
+	if (state == ACPI_STATE_S4 && !acpi_gbl_FACS->S4bios_f)
+		return AE_ERROR;
+
+	/*
+	 * TBD: S1 can be done without device_suspend.  Make a CONFIG_XX
+	 * to handle however when S1 failed without device_suspend.
+	 */
 	freeze_processes();		/* device_suspend needs processes to be stopped */
 
 	/* do we have a wakeup address for S2 and S3? */
-	if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) {
+	/* Here, we support only S4BIOS, those we set the wakeup address */
+	/* S4OS is only supported for now via swsusp.. */
+	if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3 || ACPI_STATE_S4) {
 		if (!acpi_wakeup_address)
 			return AE_ERROR;
 		acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address);
 	}
 
-	acpi_enter_sleep_state_prep(state);
-
 	status = acpi_system_save_state(state);
 	if (!ACPI_SUCCESS(status))
 		return status;
 
+	acpi_enter_sleep_state_prep(state);
+
 	/* disable interrupts and flush caches */
 	ACPI_DISABLE_IRQS();
 	ACPI_FLUSH_CPU_CACHE();
@@ -237,8 +254,8 @@
 	 * mode. So, we run these unconditionaly to make sure we have a usable system
 	 * no matter what.
 	 */
-	acpi_system_restore_state(state);
 	acpi_leave_sleep_state(state);
+	acpi_system_restore_state(state);
 
 	/* make sure interrupts are enabled */
 	ACPI_ENABLE_IRQS();
@@ -268,6 +285,10 @@
 			sleep_states[i] = 1;
 			printk(" S%d", i);
 		}
+		if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f) {
+			sleep_states[i] = 1;
+			printk(" S4bios");
+		}
 	}
 	printk(")\n");
 
diff -urN linux-2.5.63-bk4/drivers/acpi/sleep/proc.c linux-2.5.63-bk5/drivers/acpi/sleep/proc.c
--- linux-2.5.63-bk4/drivers/acpi/sleep/proc.c	Mon Feb 24 11:05:36 2003
+++ linux-2.5.63-bk5/drivers/acpi/sleep/proc.c	Mon Mar 31 12:18:55 2003
@@ -27,8 +27,11 @@
 	ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
 
 	for (i = 0; i <= ACPI_STATE_S5; i++) {
-		if (sleep_states[i])
+		if (sleep_states[i]) {
 			seq_printf(seq,"S%d ", i);
+			if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
+				seq_printf(seq, "S4bios ");
+		}
 	}
 
 	seq_puts(seq, "\n");
diff -urN linux-2.5.63-bk4/drivers/acpi/tables/tbconvrt.c linux-2.5.63-bk5/drivers/acpi/tables/tbconvrt.c
--- linux-2.5.63-bk4/drivers/acpi/tables/tbconvrt.c	Mon Feb 24 11:05:16 2003
+++ linux-2.5.63-bk5/drivers/acpi/tables/tbconvrt.c	Mon Mar 31 12:18:55 2003
@@ -239,9 +239,8 @@
 	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,  local_fadt->gpe0_blk_len, local_fadt->V1_gpe0_blk);
-	ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk,  local_fadt->gpe1_blk_len, local_fadt->V1_gpe1_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);
 }
 
 
@@ -314,15 +313,16 @@
 
 	if (!(local_fadt->xgpe0_blk.address)) {
 		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk,
-			local_fadt->gpe0_blk_len, local_fadt->V1_gpe0_blk);
+			0, local_fadt->V1_gpe0_blk);
 	}
 
 	if (!(local_fadt->xgpe1_blk.address)) {
 		ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk,
-			local_fadt->gpe1_blk_len, local_fadt->V1_gpe1_blk);
+			0, local_fadt->V1_gpe1_blk);
 	}
 }
 
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_convert_table_fadt
diff -urN linux-2.5.63-bk4/drivers/acpi/tables.c linux-2.5.63-bk5/drivers/acpi/tables.c
--- linux-2.5.63-bk4/drivers/acpi/tables.c	Mon Feb 24 11:05:16 2003
+++ linux-2.5.63-bk5/drivers/acpi/tables.c	Mon Mar 31 12:18:55 2003
@@ -379,6 +379,7 @@
 
 		sdt.pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
 
+		/* map in just the header */
 		header = (struct acpi_table_header *)
 			__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
 
@@ -387,6 +388,15 @@
 			return -ENODEV;
 		}
 
+		/* remap in the entire table before processing */
+		mapped_xsdt = (struct acpi_table_xsdt *)
+			__acpi_map_table(sdt.pa, header->length);
+		if (!mapped_xsdt) {
+			printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
+			return -ENODEV;
+		}
+		header = &mapped_xsdt->header;
+
 		if (strncmp(header->signature, "XSDT", 4)) {
 			printk(KERN_WARNING PREFIX "XSDT signature incorrect\n");
 			return -ENODEV;
@@ -404,15 +414,6 @@
 			sdt.count = ACPI_MAX_TABLES;
 		}
 
-		mapped_xsdt = (struct acpi_table_xsdt *)
-			__acpi_map_table(sdt.pa, header->length);
-		if (!mapped_xsdt) {
-			printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
-			return -ENODEV;
-		}
-
-		header = &mapped_xsdt->header;
-
 		for (i = 0; i < sdt.count; i++)
 			sdt.entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
 	}
@@ -425,6 +426,7 @@
 
 		sdt.pa = rsdp->rsdt_address;
 
+		/* map in just the header */
 		header = (struct acpi_table_header *)
 			__acpi_map_table(sdt.pa, sizeof(struct acpi_table_header));
 		if (!header) {
@@ -432,6 +434,15 @@
 			return -ENODEV;
 		}
 
+		/* remap in the entire table before processing */
+		mapped_rsdt = (struct acpi_table_rsdt *)
+			__acpi_map_table(sdt.pa, header->length);
+		if (!mapped_rsdt) {
+			printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
+			return -ENODEV;
+		}
+		header = &mapped_rsdt->header;
+
 		if (strncmp(header->signature, "RSDT", 4)) {
 			printk(KERN_WARNING PREFIX "RSDT signature incorrect\n");
 			return -ENODEV;
@@ -449,15 +460,6 @@
 			sdt.count = ACPI_MAX_TABLES;
 		}
 
-		mapped_rsdt = (struct acpi_table_rsdt *)
-			__acpi_map_table(sdt.pa, header->length);
-		if (!mapped_rsdt) {
-			printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
-			return -ENODEV;
-		}
-
-		header = &mapped_rsdt->header;
-
 		for (i = 0; i < sdt.count; i++)
 			sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
 	}
@@ -471,12 +473,20 @@
 
 	for (i = 0; i < sdt.count; i++) {
 
+		/* map in just the header */
 		header = (struct acpi_table_header *)
 			__acpi_map_table(sdt.entry[i].pa,
 				sizeof(struct acpi_table_header));
 		if (!header)
 			continue;
 
+		/* remap in the entire table before processing */
+		header = (struct acpi_table_header *)
+			__acpi_map_table(sdt.entry[i].pa,
+				header->length);
+		if (!header)
+			continue;
+	               
 		acpi_table_print(header, sdt.entry[i].pa);
 
 		if (acpi_table_compute_checksum(header, header->length)) {
diff -urN linux-2.5.63-bk4/drivers/acpi/utilities/utcopy.c linux-2.5.63-bk5/drivers/acpi/utilities/utcopy.c
--- linux-2.5.63-bk4/drivers/acpi/utilities/utcopy.c	Mon Feb 24 11:05:29 2003
+++ linux-2.5.63-bk5/drivers/acpi/utilities/utcopy.c	Mon Mar 31 12:18:55 2003
@@ -645,11 +645,11 @@
 
 		/*
 		 * Allocate and copy the actual buffer if and only if:
-		 * 1) There is a valid buffer (length > 0)
+		 * 1) There is a valid buffer pointer
 		 * 2) The buffer is not static (not in an ACPI table) (in this case,
 		 *    the actual pointer was already copied above)
 		 */
-		if ((source_desc->buffer.length) &&
+		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) {
@@ -665,11 +665,11 @@
 
 		/*
 		 * Allocate and copy the actual string if and only if:
-		 * 1) There is a valid string (length > 0)
+		 * 1) There is a valid string pointer
 		 * 2) The string is not static (not in an ACPI table) (in this case,
 		 *    the actual pointer was already copied above)
 		 */
-		if ((source_desc->string.length) &&
+		if ((source_desc->string.pointer) &&
 			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
 			dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
 			if (!dest_desc->string.pointer) {
diff -urN linux-2.5.63-bk4/drivers/acpi/utilities/utglobal.c linux-2.5.63-bk5/drivers/acpi/utilities/utglobal.c
--- linux-2.5.63-bk4/drivers/acpi/utilities/utglobal.c	Mon Feb 24 11:05:08 2003
+++ linux-2.5.63-bk5/drivers/acpi/utilities/utglobal.c	Mon Mar 31 12:18:55 2003
@@ -729,6 +729,10 @@
 		acpi_gbl_acpi_mutex_info[i].use_count = 0;
 	}
 
+	/* GPE support */
+
+	acpi_gbl_gpe_block_list_head        = NULL;
+
 	/* Global notify handlers */
 
 	acpi_gbl_sys_notify.handler         = NULL;
@@ -766,8 +770,6 @@
 
 	/* Hardware oriented */
 
-	acpi_gbl_gpe_register_info          = NULL;
-	acpi_gbl_gpe_number_info            = NULL;
 	acpi_gbl_events_initialized         = FALSE;
 
 	/* Namespace */
diff -urN linux-2.5.63-bk4/drivers/hotplug/acpiphp_glue.c linux-2.5.63-bk5/drivers/hotplug/acpiphp_glue.c
--- linux-2.5.63-bk4/drivers/hotplug/acpiphp_glue.c	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/drivers/hotplug/acpiphp_glue.c	Mon Mar 31 12:18:55 2003
@@ -229,136 +229,55 @@
 /* decode ACPI _CRS data and convert into our internal resource list
  * TBD: _TRA, etc.
  */
-static void
-decode_acpi_resource (struct acpi_resource *resource, struct acpiphp_bridge *bridge)
+static acpi_status
+decode_acpi_resource (struct acpi_resource *resource, void *context)
 {
-	struct acpi_resource_address16 *address16_data;
-	struct acpi_resource_address32 *address32_data;
-	struct acpi_resource_address64 *address64_data;
+	struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
+	struct acpi_resource_address64 address;
 	struct pci_resource *res;
 
-	u32 resource_type, producer_consumer, address_length;
-	u64 min_address_range, max_address_range;
-	u16 cache_attribute = 0;
-
-	int done = 0, found;
-
-	/* shut up gcc */
-	resource_type = producer_consumer = address_length = 0;
-	min_address_range = max_address_range = 0;
-
-	while (!done) {
-		found = 0;
-
-		switch (resource->id) {
-		case ACPI_RSTYPE_ADDRESS16:
-			address16_data = (struct acpi_resource_address16 *)&resource->data;
-			resource_type = address16_data->resource_type;
-			producer_consumer = address16_data->producer_consumer;
-			min_address_range = address16_data->min_address_range;
-			max_address_range = address16_data->max_address_range;
-			address_length = address16_data->address_length;
-			if (resource_type == ACPI_MEMORY_RANGE)
-				cache_attribute = address16_data->attribute.memory.cache_attribute;
-			found = 1;
-			break;
+	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS64)
+		return AE_OK;
+
+	acpi_resource_to_address64(resource, &address);
+
+	if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
+		dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type, address.min_address_range, address.max_address_range);
+		res = acpiphp_make_resource(address.min_address_range,
+				    address.address_length);
+		if (!res) {
+			err("out of memory\n");
+			return AE_OK;
+		}
 
-		case ACPI_RSTYPE_ADDRESS32:
-			address32_data = (struct acpi_resource_address32 *)&resource->data;
-			resource_type = address32_data->resource_type;
-			producer_consumer = address32_data->producer_consumer;
-			min_address_range = address32_data->min_address_range;
-			max_address_range = address32_data->max_address_range;
-			address_length = address32_data->address_length;
-			if (resource_type == ACPI_MEMORY_RANGE)
-				cache_attribute = address32_data->attribute.memory.cache_attribute;
-			found = 1;
+		switch (address.resource_type) {
+		case ACPI_MEMORY_RANGE:
+			if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
+				res->next = bridge->p_mem_head;
+				bridge->p_mem_head = res;
+			} else {
+				res->next = bridge->mem_head;
+				bridge->mem_head = res;
+			}
 			break;
-
-		case ACPI_RSTYPE_ADDRESS64:
-			address64_data = (struct acpi_resource_address64 *)&resource->data;
-			resource_type = address64_data->resource_type;
-			producer_consumer = address64_data->producer_consumer;
-			min_address_range = address64_data->min_address_range;
-			max_address_range = address64_data->max_address_range;
-			address_length = address64_data->address_length;
-			if (resource_type == ACPI_MEMORY_RANGE)
-				cache_attribute = address64_data->attribute.memory.cache_attribute;
-			found = 1;
+		case ACPI_IO_RANGE:
+			res->next = bridge->io_head;
+			bridge->io_head = res;
 			break;
-
-		case ACPI_RSTYPE_END_TAG:
-			done = 1;
+		case ACPI_BUS_NUMBER_RANGE:
+			res->next = bridge->bus_head;
+			bridge->bus_head = res;
 			break;
-
 		default:
-			/* ignore */
+			/* invalid type */
+			kfree(res);
 			break;
 		}
-
-		resource = (struct acpi_resource *)((char*)resource + resource->length);
-
-		if (found && producer_consumer == ACPI_PRODUCER && address_length > 0) {
-			switch (resource_type) {
-			case ACPI_MEMORY_RANGE:
-				if (cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
-					dbg("resource type: prefetchable memory 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
-					res = acpiphp_make_resource(min_address_range,
-							    address_length);
-					if (!res) {
-						err("out of memory\n");
-						return;
-					}
-					res->next = bridge->p_mem_head;
-					bridge->p_mem_head = res;
-				} else {
-					dbg("resource type: memory 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
-					res = acpiphp_make_resource(min_address_range,
-							    address_length);
-					if (!res) {
-						err("out of memory\n");
-						return;
-					}
-					res->next = bridge->mem_head;
-					bridge->mem_head = res;
-				}
-				break;
-			case ACPI_IO_RANGE:
-				dbg("resource type: io 0x%x - 0x%x\n", (u32)min_address_range, (u32)max_address_range);
-				res = acpiphp_make_resource(min_address_range,
-						    address_length);
-				if (!res) {
-					err("out of memory\n");
-					return;
-				}
-				res->next = bridge->io_head;
-				bridge->io_head = res;
-				break;
-			case ACPI_BUS_NUMBER_RANGE:
-				dbg("resource type: bus number %d - %d\n", (u32)min_address_range, (u32)max_address_range);
-				res = acpiphp_make_resource(min_address_range,
-						    address_length);
-				if (!res) {
-					err("out of memory\n");
-					return;
-				}
-				res->next = bridge->bus_head;
-				bridge->bus_head = res;
-				break;
-			default:
-				/* invalid type */
-				break;
-			}
-		}
 	}
 
-	acpiphp_resource_sort_and_combine(&bridge->io_head);
-	acpiphp_resource_sort_and_combine(&bridge->mem_head);
-	acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
-	acpiphp_resource_sort_and_combine(&bridge->bus_head);
-
-	dbg("ACPI _CRS resource:\n");
-	acpiphp_dump_resource(bridge);
+	return AE_OK;
 }
 
 
@@ -476,9 +395,6 @@
 static void add_host_bridge (acpi_handle *handle, int seg, int bus)
 {
 	acpi_status status;
-	struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
-				      .pointer = NULL};
-
 	struct acpiphp_bridge *bridge;
 
 	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
@@ -501,7 +417,8 @@
 
 	/* decode resources */
 
-	status = acpi_get_current_resources(handle, &buffer);
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+		decode_acpi_resource, bridge);
 
 	if (ACPI_FAILURE(status)) {
 		err("failed to decode bridge resources\n");
@@ -509,8 +426,13 @@
 		return;
 	}
 
-	decode_acpi_resource(buffer.pointer, bridge);
-	kfree(buffer.pointer);
+	acpiphp_resource_sort_and_combine(&bridge->io_head);
+	acpiphp_resource_sort_and_combine(&bridge->mem_head);
+	acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
+	acpiphp_resource_sort_and_combine(&bridge->bus_head);
+
+	dbg("ACPI _CRS resource:\n");
+	acpiphp_dump_resource(bridge);
 
 	if (bridge->bus_head) {
 		bridge->bus = bridge->bus_head->base;
diff -urN linux-2.5.63-bk4/drivers/scsi/scsi_scan.c linux-2.5.63-bk5/drivers/scsi/scsi_scan.c
--- linux-2.5.63-bk4/drivers/scsi/scsi_scan.c	Mon Mar 31 12:18:52 2003
+++ linux-2.5.63-bk5/drivers/scsi/scsi_scan.c	Mon Mar 31 12:18:55 2003
@@ -1338,7 +1338,7 @@
 	scsi_release_request(sreq);
  out_free_sdev:
 	if (res == SCSI_SCAN_LUN_PRESENT) {
-		if (*sdevp)
+		if (sdevp)
 			*sdevp = sdev;
 	} else {
 		if (q) {
diff -urN linux-2.5.63-bk4/drivers/usb/class/usb-midi.h linux-2.5.63-bk5/drivers/usb/class/usb-midi.h
--- linux-2.5.63-bk4/drivers/usb/class/usb-midi.h	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/drivers/usb/class/usb-midi.h	Mon Mar 31 12:18:55 2003
@@ -41,6 +41,7 @@
 #define USBMIDI_ROLAND_UA100G		0x0000
 #define USBMIDI_ROLAND_MPU64		0x0002
 #define USBMIDI_ROLAND_SC8850		0x0003
+#define USBMIDI_ROLAND_SC8820		0x0007
 #define USBMIDI_ROLAND_UM2		0x0005
 #define USBMIDI_ROLAND_UM1		0x0009
 #define USBMIDI_ROLAND_PC300		0x0008
@@ -104,6 +105,13 @@
     { { 0x01, 15 }, {-1, -1} },
   },
 
+  { /* Roland SC8820 */
+    "Roland SC8820",
+    USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8820, 2, -1,
+    { { 0x81, 17 }, {-1, -1} },
+    { { 0x01, 17 }, {-1, -1} },
+  },
+
   { /* YAMAHA MU1000 */
     "YAMAHA MU1000",
     USB_VENDOR_ID_YAMAHA, USBMIDI_YAMAHA_MU1000, 0, -1, 
diff -urN linux-2.5.63-bk4/drivers/usb/core/driverfs.c linux-2.5.63-bk5/drivers/usb/core/driverfs.c
--- linux-2.5.63-bk4/drivers/usb/core/driverfs.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk5/drivers/usb/core/driverfs.c	Mon Mar 31 12:18:55 2003
@@ -183,15 +183,21 @@
 }									\
 static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
 
+usb_intf_attr (bInterfaceNumber, "%02x\n")
 usb_intf_attr (bAlternateSetting, "%2d\n")
+usb_intf_attr (bNumEndpoints, "%02x\n")
 usb_intf_attr (bInterfaceClass, "%02x\n")
 usb_intf_attr (bInterfaceSubClass, "%02x\n")
 usb_intf_attr (bInterfaceProtocol, "%02x\n")
+usb_intf_attr (iInterface, "%02x\n")
 
 void usb_create_driverfs_intf_files (struct usb_interface *intf)
 {
+	device_create_file (&intf->dev, &dev_attr_bInterfaceNumber);
 	device_create_file (&intf->dev, &dev_attr_bAlternateSetting);
+	device_create_file (&intf->dev, &dev_attr_bNumEndpoints);
 	device_create_file (&intf->dev, &dev_attr_bInterfaceClass);
 	device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass);
 	device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol);
+	device_create_file (&intf->dev, &dev_attr_iInterface);
 }
diff -urN linux-2.5.63-bk4/drivers/usb/core/hcd.h linux-2.5.63-bk5/drivers/usb/core/hcd.h
--- linux-2.5.63-bk4/drivers/usb/core/hcd.h	Mon Feb 24 11:05:15 2003
+++ linux-2.5.63-bk5/drivers/usb/core/hcd.h	Mon Mar 31 12:18:55 2003
@@ -254,6 +254,10 @@
 extern void usb_destroy_configuration(struct usb_device *dev);
 extern int usb_set_address(struct usb_device *dev);
 
+/* use these only before the device's address has been set */
+#define usb_snddefctrl(dev)		((PIPE_CONTROL << 30) | __create_pipe(dev,0))
+#define usb_rcvdefctrl(dev)		((PIPE_CONTROL << 30) | __create_pipe(dev,0) | USB_DIR_IN)
+
 /*-------------------------------------------------------------------------*/
 
 /*
diff -urN linux-2.5.63-bk4/drivers/usb/core/hub.c linux-2.5.63-bk5/drivers/usb/core/hub.c
--- linux-2.5.63-bk4/drivers/usb/core/hub.c	Mon Feb 24 11:05:31 2003
+++ linux-2.5.63-bk5/drivers/usb/core/hub.c	Mon Mar 31 12:18:55 2003
@@ -1148,7 +1148,7 @@
 	int ret;
 
 	/* Kill the thread */
-	ret = kill_proc(khubd_pid, SIGTERM, 1);
+	ret = kill_proc(khubd_pid, SIGKILL, 1);
 
 	wait_for_completion(&khubd_exited);
 
diff -urN linux-2.5.63-bk4/drivers/usb/host/ehci-dbg.c linux-2.5.63-bk5/drivers/usb/host/ehci-dbg.c
--- linux-2.5.63-bk4/drivers/usb/host/ehci-dbg.c	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ehci-dbg.c	Mon Mar 31 12:18:55 2003
@@ -605,8 +605,10 @@
 	}
 
 #ifdef EHCI_STATS
-	temp = snprintf (next, size, "irq normal %ld err %ld reclaim %ld\n",
-		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim);
+	temp = snprintf (next, size,
+		"irq normal %ld err %ld reclaim %ld (lost %ld)\n",
+		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
+		ehci->stats.lost_iaa);
 	size -= temp;
 	next += temp;
 
diff -urN linux-2.5.63-bk4/drivers/usb/host/ehci-hcd.c linux-2.5.63-bk5/drivers/usb/host/ehci-hcd.c
--- linux-2.5.63-bk4/drivers/usb/host/ehci-hcd.c	Mon Feb 24 11:05:36 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ehci-hcd.c	Mon Mar 31 12:18:55 2003
@@ -260,6 +260,7 @@
 
 		if (status & STS_IAA) {
 			ehci_vdbg (ehci, "lost IAA\n");
+			COUNT (ehci->stats.lost_iaa);
 			writel (STS_IAA, &ehci->regs->status);
 			ehci->reclaim_ready = 1;
 		}
@@ -547,8 +548,9 @@
 	ehci_mem_cleanup (ehci);
 
 #ifdef	EHCI_STATS
-	ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld\n",
-		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim);
+	ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
+		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
+		ehci->stats.lost_iaa);
 	ehci_dbg (ehci, "complete %ld unlink %ld\n",
 		ehci->stats.complete, ehci->stats.unlink);
 #endif
diff -urN linux-2.5.63-bk4/drivers/usb/host/ehci-q.c linux-2.5.63-bk5/drivers/usb/host/ehci-q.c
--- linux-2.5.63-bk4/drivers/usb/host/ehci-q.c	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ehci-q.c	Mon Mar 31 12:18:55 2003
@@ -800,6 +800,7 @@
 				&& !usb_pipecontrol (urb->pipe)) {
 			/* "never happens": drivers do stall cleanup right */
 			if (qh->qh_state != QH_STATE_IDLE
+					&& !list_empty (&qh->qtd_list)
 					&& qh->qh_state != QH_STATE_COMPLETING)
 				ehci_warn (ehci, "clear toggle dev%d "
 						"ep%d%s: not idle\n",
@@ -1014,6 +1015,7 @@
 scan_async (struct ehci_hcd *ehci, struct pt_regs *regs)
 {
 	struct ehci_qh		*qh;
+	int			unlink_delay = 0;
 
 	if (!++(ehci->stamp))
 		ehci->stamp++;
@@ -1040,17 +1042,25 @@
 				}
 			}
 
-			/* unlink idle entries, reducing HC PCI usage as
-			 * well as HCD schedule-scanning costs.
-			 *
-			 * FIXME don't unlink idle entries so quickly; it
-			 * can penalize (common) half duplex protocols.
+			/* unlink idle entries, reducing HC PCI usage as well
+			 * as HCD schedule-scanning costs.  delay for any qh
+			 * we just scanned, there's a not-unusual case that it
+			 * doesn't stay idle for long.
+			 * (plus, avoids some kind of re-activation race.)
 			 */
-			if (list_empty (&qh->qtd_list) && !ehci->reclaim) {
-				start_unlink_async (ehci, qh);
+			if (list_empty (&qh->qtd_list)) {
+				if (qh->stamp == ehci->stamp)
+					unlink_delay = 1;
+				else if (!ehci->reclaim) {
+					start_unlink_async (ehci, qh);
+					unlink_delay = 0;
+				}
 			}
 
 			qh = qh->qh_next.qh;
 		} while (qh);
 	}
+
+	if (unlink_delay && !timer_pending (&ehci->watchdog))
+		mod_timer (&ehci->watchdog, jiffies + EHCI_WATCHDOG_JIFFIES/2);
 }
diff -urN linux-2.5.63-bk4/drivers/usb/host/ehci.h linux-2.5.63-bk5/drivers/usb/host/ehci.h
--- linux-2.5.63-bk4/drivers/usb/host/ehci.h	Mon Feb 24 11:05:41 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ehci.h	Mon Mar 31 12:18:55 2003
@@ -27,6 +27,7 @@
 	unsigned long		normal;
 	unsigned long		error;
 	unsigned long		reclaim;
+	unsigned long		lost_iaa;
 
 	/* termination of urbs from core */
 	unsigned long		complete;
diff -urN linux-2.5.63-bk4/drivers/usb/host/ohci-dbg.c linux-2.5.63-bk5/drivers/usb/host/ohci-dbg.c
--- linux-2.5.63-bk4/drivers/usb/host/ohci-dbg.c	Mon Feb 24 11:05:42 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ohci-dbg.c	Mon Mar 31 12:18:55 2003
@@ -1,51 +1,50 @@
 /*
  * OHCI HCD (Host Controller Driver) for USB.
- * 
+ *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * 
+ *
  * This file is licenced under the GPL.
- * $Id: ohci-dbg.c,v 1.4 2002/03/27 20:40:40 dbrownell Exp $
  */
- 
+
 /*-------------------------------------------------------------------------*/
 
 #ifdef DEBUG
 
 #define edstring(ed_type) ({ char *temp; \
 	switch (ed_type) { \
-	case PIPE_CONTROL:	temp = "CTRL"; break; \
-	case PIPE_BULK:		temp = "BULK"; break; \
-	case PIPE_INTERRUPT:	temp = "INTR"; break; \
-	default: 		temp = "ISOC"; break; \
+	case PIPE_CONTROL:	temp = "ctrl"; break; \
+	case PIPE_BULK:		temp = "bulk"; break; \
+	case PIPE_INTERRUPT:	temp = "intr"; break; \
+	default: 		temp = "isoc"; break; \
 	}; temp;})
 #define pipestring(pipe) edstring(usb_pipetype(pipe))
 
-/* debug| print the main components of an URB     
+/* debug| print the main components of an URB
  * small: 0) header + data packets 1) just header
  */
 static void __attribute__((unused))
 urb_print (struct urb * urb, char * str, int small)
 {
 	unsigned int pipe= urb->pipe;
-	
+
 	if (!urb->dev || !urb->dev->bus) {
 		dbg("%s URB: no dev", str);
 		return;
 	}
-	
+
 #ifndef	OHCI_VERBOSE_DEBUG
 	if (urb->status != 0)
 #endif
-	dbg("%s %p dev:%d,ep=%d-%c,%s,flags:%x,len:%d/%d,stat:%d", 
+	dbg("%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d",
 		    str,
 		    urb,
 		    usb_pipedevice (pipe),
-		    usb_pipeendpoint (pipe), 
-		    usb_pipeout (pipe)? 'O': 'I',
+		    usb_pipeendpoint (pipe),
+		    usb_pipeout (pipe)? "out" : "in",
 		    pipestring (pipe),
-		    urb->transfer_flags, 
-		    urb->actual_length, 
+		    urb->transfer_flags,
+		    urb->actual_length,
 		    urb->transfer_buffer_length,
 		    urb->status);
 
@@ -55,27 +54,43 @@
 
 		if (usb_pipecontrol (pipe)) {
 			printk (KERN_DEBUG __FILE__ ": setup(8):");
-			for (i = 0; i < 8 ; i++) 
+			for (i = 0; i < 8 ; i++)
 				printk (" %02x", ((__u8 *) urb->setup_packet) [i]);
 			printk ("\n");
 		}
 		if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
-			printk (KERN_DEBUG __FILE__ ": data(%d/%d):", 
-				urb->actual_length, 
+			printk (KERN_DEBUG __FILE__ ": data(%d/%d):",
+				urb->actual_length,
 				urb->transfer_buffer_length);
-			len = usb_pipeout (pipe)? 
+			len = usb_pipeout (pipe)?
 						urb->transfer_buffer_length: urb->actual_length;
-			for (i = 0; i < 16 && i < len; i++) 
+			for (i = 0; i < 16 && i < len; i++)
 				printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]);
 			printk ("%s stat:%d\n", i < len? "...": "", urb->status);
 		}
-	} 
+	}
 #endif
 }
 
-static void ohci_dump_intr_mask (struct device *dev, char *label, __u32 mask)
+#define ohci_dbg_sw(ohci, next, size, format, arg...) \
+	do { \
+	if (next) { \
+		unsigned s_len; \
+		s_len = snprintf (*next, *size, format, ## arg ); \
+		*size -= s_len; *next += s_len; \
+	} else \
+		ohci_dbg(ohci,format, ## arg ); \
+	} while (0);
+
+
+static void ohci_dump_intr_mask (
+	struct ohci_hcd *ohci,
+	char *label,
+	u32 mask,
+	char **next,
+	unsigned *size)
 {
-	dev_dbg (dev, "%s: 0x%08x%s%s%s%s%s%s%s%s%s\n",
+	ohci_dbg_sw (ohci, next, size, "%s 0x%08x%s%s%s%s%s%s%s%s%s\n",
 		label,
 		mask,
 		(mask & OHCI_INTR_MIE) ? " MIE" : "",
@@ -90,10 +105,15 @@
 		);
 }
 
-static void maybe_print_eds (struct device *dev, char *label, __u32 value)
+static void maybe_print_eds (
+	struct ohci_hcd *ohci,
+	char *label,
+	u32 value,
+	char **next,
+	unsigned *size)
 {
 	if (value)
-		dev_dbg (dev, "%s %08x\n", label, value);
+		ohci_dbg_sw (ohci, next, size, "%s %08x\n", label, value);
 }
 
 static char *hcfs2string (int state)
@@ -108,19 +128,22 @@
 }
 
 // dump control and status registers
-static void ohci_dump_status (struct ohci_hcd *controller)
+static void
+ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
 {
 	struct ohci_regs	*regs = controller->regs;
-	struct device		*dev = controller->hcd.controller;
-	__u32			temp;
+	u32			temp;
 
 	temp = readl (&regs->revision) & 0xff;
-	dev_dbg (dev, "OHCI %d.%d, %s legacy support registers\n",
+	ohci_dbg_sw (controller, next, size,
+		"OHCI %d.%d, %s legacy support registers\n",
 		0x03 & (temp >> 4), (temp & 0x0f),
 		(temp & 0x10) ? "with" : "NO");
 
 	temp = readl (&regs->control);
-	dev_dbg (dev, "control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n", temp,
+	ohci_dbg_sw (controller, next, size,
+		"control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n",
+		temp,
 		(temp & OHCI_CTRL_RWE) ? " RWE" : "",
 		(temp & OHCI_CTRL_RWC) ? " RWC" : "",
 		(temp & OHCI_CTRL_IR) ? " IR" : "",
@@ -133,7 +156,8 @@
 		);
 
 	temp = readl (&regs->cmdstatus);
-	dev_dbg (dev, "cmdstatus: 0x%08x SOC=%d%s%s%s%s\n", temp,
+	ohci_dbg_sw (controller, next, size,
+		"cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp,
 		(temp & OHCI_SOC) >> 16,
 		(temp & OHCI_OCR) ? " OCR" : "",
 		(temp & OHCI_BLF) ? " BLF" : "",
@@ -141,25 +165,59 @@
 		(temp & OHCI_HCR) ? " HCR" : ""
 		);
 
-	ohci_dump_intr_mask (dev, "intrstatus", readl (&regs->intrstatus));
-	ohci_dump_intr_mask (dev, "intrenable", readl (&regs->intrenable));
+	ohci_dump_intr_mask (controller, "intrstatus",
+			readl (&regs->intrstatus), next, size);
+	ohci_dump_intr_mask (controller, "intrenable",
+			readl (&regs->intrenable), next, size);
 	// intrdisable always same as intrenable
-	// ohci_dump_intr_mask (dev, "intrdisable", readl (&regs->intrdisable));
 
-	maybe_print_eds (dev, "ed_periodcurrent", readl (&regs->ed_periodcurrent));
+	maybe_print_eds (controller, "ed_periodcurrent",
+			readl (&regs->ed_periodcurrent), next, size);
 
-	maybe_print_eds (dev, "ed_controlhead", readl (&regs->ed_controlhead));
-	maybe_print_eds (dev, "ed_controlcurrent", readl (&regs->ed_controlcurrent));
-
-	maybe_print_eds (dev, "ed_bulkhead", readl (&regs->ed_bulkhead));
-	maybe_print_eds (dev, "ed_bulkcurrent", readl (&regs->ed_bulkcurrent));
+	maybe_print_eds (controller, "ed_controlhead",
+			readl (&regs->ed_controlhead), next, size);
+	maybe_print_eds (controller, "ed_controlcurrent",
+			readl (&regs->ed_controlcurrent), next, size);
+
+	maybe_print_eds (controller, "ed_bulkhead",
+			readl (&regs->ed_bulkhead), next, size);
+	maybe_print_eds (controller, "ed_bulkcurrent",
+			readl (&regs->ed_bulkcurrent), next, size);
+
+	maybe_print_eds (controller, "donehead",
+			readl (&regs->donehead), next, size);
+}
+
+#define dbg_port_sw(hc,num,value,next,size) \
+	ohci_dbg_sw (hc, next, size, \
+		"roothub.portstatus [%d] " \
+		"0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
+		num, temp, \
+		(temp & RH_PS_PRSC) ? " PRSC" : "", \
+		(temp & RH_PS_OCIC) ? " OCIC" : "", \
+		(temp & RH_PS_PSSC) ? " PSSC" : "", \
+		(temp & RH_PS_PESC) ? " PESC" : "", \
+		(temp & RH_PS_CSC) ? " CSC" : "", \
+ 		\
+		(temp & RH_PS_LSDA) ? " LSDA" : "", \
+		(temp & RH_PS_PPS) ? " PPS" : "", \
+		(temp & RH_PS_PRS) ? " PRS" : "", \
+		(temp & RH_PS_POCI) ? " POCI" : "", \
+		(temp & RH_PS_PSS) ? " PSS" : "", \
+ 		\
+		(temp & RH_PS_PES) ? " PES" : "", \
+		(temp & RH_PS_CCS) ? " CCS" : "" \
+		);
 
-	maybe_print_eds (dev, "donehead", readl (&regs->donehead));
-}
 
-static void ohci_dump_roothub (struct ohci_hcd *controller, int verbose)
+static void
+ohci_dump_roothub (
+	struct ohci_hcd *controller,
+	int verbose,
+	char **next,
+	unsigned *size)
 {
-	__u32			temp, ndp, i;
+	u32			temp, ndp, i;
 
 	temp = roothub_a (controller);
 	if (temp == ~(u32)0)
@@ -167,8 +225,8 @@
 	ndp = (temp & RH_A_NDP);
 
 	if (verbose) {
-		dev_dbg (controller->hcd.controller,
-			"roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d\n", temp,
+		ohci_dbg_sw (controller, next, size,
+			"roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d\n", temp,
 			((temp & RH_A_POTPGT) >> 24) & 0xff,
 			(temp & RH_A_NOCP) ? " NOCP" : "",
 			(temp & RH_A_OCPM) ? " OCPM" : "",
@@ -178,15 +236,15 @@
 			ndp
 			);
 		temp = roothub_b (controller);
-		dev_dbg (controller->hcd.controller,
-			"roothub.b: %08x PPCM=%04x DR=%04x\n",
+		ohci_dbg_sw (controller, next, size,
+			"roothub.b %08x PPCM=%04x DR=%04x\n",
 			temp,
 			(temp & RH_B_PPCM) >> 16,
 			(temp & RH_B_DR)
 			);
 		temp = roothub_status (controller);
-		dev_dbg (controller->hcd.controller,
-			"roothub.status: %08x%s%s%s%s%s%s\n",
+		ohci_dbg_sw (controller, next, size,
+			"roothub.status %08x%s%s%s%s%s%s\n",
 			temp,
 			(temp & RH_HS_CRWE) ? " CRWE" : "",
 			(temp & RH_HS_OCIC) ? " OCIC" : "",
@@ -196,34 +254,33 @@
 			(temp & RH_HS_LPS) ? " LPS" : ""
 			);
 	}
-	
+
 	for (i = 0; i < ndp; i++) {
 		temp = roothub_portstatus (controller, i);
-		dbg_port (controller, "", i, temp);
+		dbg_port_sw (controller, i, temp, next, size);
 	}
 }
 
 static void ohci_dump (struct ohci_hcd *controller, int verbose)
 {
-	dev_dbg (controller->hcd.controller,
-		"OHCI controller state\n");
+	ohci_dbg (controller, "OHCI controller state\n");
 
 	// dumps some of the state we know about
-	ohci_dump_status (controller);
+	ohci_dump_status (controller, NULL, 0);
 	if (controller->hcca)
-		dev_dbg (controller->hcd.controller,
+		ohci_dbg (controller,
 			"hcca frame #%04x\n", controller->hcca->frame_no);
-	ohci_dump_roothub (controller, 1);
+	ohci_dump_roothub (controller, 1, NULL, 0);
 }
 
 static const char data0 [] = "DATA0";
 static const char data1 [] = "DATA1";
 
-static void ohci_dump_td (char *label, struct td *td)
+static void ohci_dump_td (struct ohci_hcd *ohci, char *label, struct td *td)
 {
 	u32	tmp = le32_to_cpup (&td->hwINFO);
 
-	dbg ("%s td %p%s; urb %p index %d; hw next td %08x",
+	ohci_dbg (ohci, "%s td %p%s; urb %p index %d; hw next td %08x",
 		label, td,
 		(tmp & TD_DONE) ? " (DONE)" : "",
 		td->urb, td->index,
@@ -244,28 +301,28 @@
 		case TD_DP_OUT: pid = "OUT"; break;
 		default: pid = "(bad pid)"; break;
 		}
-		dbg ("     info %08x CC=%x %s DI=%d %s %s", tmp,
+		ohci_dbg (ohci, "     info %08x CC=%x %s DI=%d %s %s", tmp,
 			TD_CC_GET(tmp), /* EC, */ toggle,
 			(tmp & TD_DI) >> 21, pid,
 			(tmp & TD_R) ? "R" : "");
 		cbp = le32_to_cpup (&td->hwCBP);
 		be = le32_to_cpup (&td->hwBE);
-		dbg ("     cbp %08x be %08x (len %d)", cbp, be,
+		ohci_dbg (ohci, "     cbp %08x be %08x (len %d)", cbp, be,
 			cbp ? (be + 1 - cbp) : 0);
 	} else {
 		unsigned	i;
-		dbg ("     info %08x CC=%x FC=%d DI=%d SF=%04x", tmp,
+		ohci_dbg (ohci, "     info %08x CC=%x FC=%d DI=%d SF=%04x", tmp,
 			TD_CC_GET(tmp),
 			(tmp >> 24) & 0x07,
 			(tmp & TD_DI) >> 21,
 			tmp & 0x0000ffff);
-		dbg ("     bp0 %08x be %08x",
+		ohci_dbg (ohci, "     bp0 %08x be %08x",
 			le32_to_cpup (&td->hwCBP) & ~0x0fff,
 			le32_to_cpup (&td->hwBE));
 		for (i = 0; i < MAXPSW; i++) {
 			u16	psw = le16_to_cpup (&td->hwPSW [i]);
 			int	cc = (psw >> 12) & 0x0f;
-			dbg ("       psw [%d] = %2x, CC=%x %s=%d", i,
+			ohci_dbg (ohci, "       psw [%d] = %2x, CC=%x %s=%d", i,
 				psw, cc,
 				(cc >= 0x0e) ? "OFFSET" : "SIZE",
 				psw & 0x0fff);
@@ -280,8 +337,8 @@
 	u32	tmp = ed->hwINFO;
 	char	*type = "";
 
-	dbg ("%s: %s, ed %p state 0x%x type %s; next ed %08x",
-		ohci->hcd.self.bus_name, label,
+	ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x",
+		label,
 		ed, ed->state, edstring (ed->type),
 		le32_to_cpup (&ed->hwNextED));
 	switch (tmp & (ED_IN|ED_OUT)) {
@@ -289,7 +346,8 @@
 	case ED_IN: type = "-IN"; break;
 	/* else from TDs ... control */
 	}
-	dbg ("  info %08x MAX=%d%s%s%s%s EP=%d%s DEV=%d", le32_to_cpu (tmp),
+	ohci_dbg (ohci,
+		"  info %08x MAX=%d%s%s%s%s EP=%d%s DEV=%d", le32_to_cpu (tmp),
 		0x03ff & (le32_to_cpu (tmp) >> 16),
 		(tmp & ED_DEQUEUE) ? " DQ" : "",
 		(tmp & ED_ISO) ? " ISO" : "",
@@ -298,7 +356,7 @@
 		0x000f & (le32_to_cpu (tmp) >> 7),
 		type,
 		0x007f & le32_to_cpu (tmp));
-	dbg ("  tds: head %08x %s%s tail %08x%s",
+	ohci_dbg (ohci, "  tds: head %08x %s%s tail %08x%s",
 		tmp = le32_to_cpup (&ed->hwHeadP),
 		(ed->hwHeadP & ED_C) ? data1 : data0,
 		(ed->hwHeadP & ED_H) ? " HALT" : "",
@@ -313,21 +371,33 @@
 		list_for_each (tmp, &ed->td_list) {
 			struct td		*td;
 			td = list_entry (tmp, struct td, td_list);
-			ohci_dump_td ("  ->", td);
+			ohci_dump_td (ohci, "  ->", td);
 		}
 	}
 }
 
-#define DRIVERFS_DEBUG_FILES 		/* only on 2.5 versions */
-
 #else
 static inline void ohci_dump (struct ohci_hcd *controller, int verbose) {}
 
+#undef OHCI_VERBOSE_DEBUG
+
 #endif /* DEBUG */
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef DRIVERFS_DEBUG_FILES
+#ifdef STUB_DEBUG_FILES
+
+static inline void create_debug_files (struct ohci_hcd *bus) { }
+static inline void remove_debug_files (struct ohci_hcd *bus) { }
+
+#else
+
+static inline struct ohci_hcd *dev_to_ohci (struct device *dev)
+{
+	struct usb_hcd	*hcd = dev_get_drvdata (dev);
+
+	return hcd_to_ohci (hcd);
+}
 
 static ssize_t
 show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
@@ -349,7 +419,7 @@
 		struct td		*td;
 
 		temp = snprintf (buf, size,
-			"ed/%p %cs dev%d ep%d-%s max %d %08x%s%s %s",
+			"ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s",
 			ed,
 			(info & ED_LOWSPEED) ? 'l' : 'f',
 			scratch & 0x7f,
@@ -465,7 +535,7 @@
 				u32	scratch = cpu_to_le32p (&ed->hwINFO);
 
 				temp = snprintf (next, size,
-					" (%cs dev%d%s ep%d-%s"
+					" (%cs dev%d%s ep%d%s"
 					" max %d %08x%s%s)",
 					(info & ED_LOWSPEED) ? 'l' : 'f',
 					scratch & 0x7f,
@@ -508,26 +578,89 @@
 
 #undef DBG_SCHED_LIMIT
 
+static ssize_t
+show_registers (struct device *dev, char *buf)
+{
+	struct ohci_hcd		*ohci;
+	struct ohci_regs	*regs;
+	unsigned long		flags;
+	unsigned		temp, size;
+	char			*next;
+	u32			rdata;
+
+	ohci = dev_to_ohci(dev);
+	regs = ohci->regs;
+	next = buf;
+	size = PAGE_SIZE;
+
+	spin_lock_irqsave (&ohci->lock, flags);
+
+	/* dump driver info, then registers in spec order */
+
+	ohci_dbg_sw (ohci, &next, &size,
+		"%s version " DRIVER_VERSION "\n", hcd_name);
+
+	ohci_dump_status(ohci, &next, &size);
+
+	/* hcca */
+	if (ohci->hcca)
+		ohci_dbg_sw (ohci, &next, &size,
+			"hcca frame 0x%04x\n", ohci->hcca->frame_no);
+
+	/* other registers mostly affect frame timings */
+	rdata = readl (&regs->fminterval);
+	temp = snprintf (next, size,
+			"fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n",
+			rdata, (rdata >> 31) ? " FIT" : "",
+			(rdata >> 16) & 0xefff, rdata & 0xffff);
+	size -= temp;
+	next += temp;
+
+	rdata = readl (&regs->fmremaining);
+	temp = snprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n",
+			rdata, (rdata >> 31) ? " FRT" : "",
+			rdata & 0x3fff);
+	size -= temp;
+	next += temp;
+
+	rdata = readl (&regs->periodicstart);
+	temp = snprintf (next, size, "periodicstart 0x%04x\n",
+			rdata & 0x3fff);
+	size -= temp;
+	next += temp;
+
+	rdata = readl (&regs->lsthresh);
+	temp = snprintf (next, size, "lsthresh 0x%04x\n",
+			rdata & 0x3fff);
+	size -= temp;
+	next += temp;
+
+	/* roothub */
+	ohci_dump_roothub (ohci, 1, &next, &size);
+
+	spin_unlock_irqrestore (&ohci->lock, flags);
+
+	return PAGE_SIZE - size;
+}
+static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
+
+
 static inline void create_debug_files (struct ohci_hcd *bus)
 {
 	device_create_file (bus->hcd.controller, &dev_attr_async);
 	device_create_file (bus->hcd.controller, &dev_attr_periodic);
-	// registers
-	dev_dbg (bus->hcd.controller, "created debug files\n");
+	device_create_file (bus->hcd.controller, &dev_attr_registers);
+	ohci_dbg (bus, "created debug files\n");
 }
 
 static inline void remove_debug_files (struct ohci_hcd *bus)
 {
 	device_remove_file (bus->hcd.controller, &dev_attr_async);
 	device_remove_file (bus->hcd.controller, &dev_attr_periodic);
+	device_remove_file (bus->hcd.controller, &dev_attr_registers);
 }
 
-#else /* empty stubs for creating those files */
-
-static inline void create_debug_files (struct ohci_hcd *bus) { }
-static inline void remove_debug_files (struct ohci_hcd *bus) { }
-
-#endif /* DRIVERFS_DEBUG_FILES */
+#endif
 
 /*-------------------------------------------------------------------------*/
 
diff -urN linux-2.5.63-bk4/drivers/usb/host/ohci-hcd.c linux-2.5.63-bk5/drivers/usb/host/ohci-hcd.c
--- linux-2.5.63-bk4/drivers/usb/host/ohci-hcd.c	Mon Feb 24 11:05:06 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ohci-hcd.c	Mon Mar 31 12:18:55 2003
@@ -17,6 +17,8 @@
  *
  * History:
  * 
+ * 2003/02/24 show registers in sysfs (Kevin Brosius)
+ *
  * 2002/09/03 get rid of ed hashtables, rework periodic scheduling and
  * 	bandwidth accounting; if debugging, show schedules in driverfs
  * 2002/07/19 fixes to management of ED and schedule state.
@@ -105,11 +107,10 @@
  * TO DO:
  *
  *	- "disabled" and "sleeping" should be in hcd->state
- *	- bandwidth alloc to generic code
  *	- lots more testing!!
  */
 
-#define DRIVER_VERSION "2002-Sep-17"
+#define DRIVER_VERSION "2003 Feb 24"
 #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
 #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
 
@@ -125,6 +126,8 @@
 
 /*-------------------------------------------------------------------------*/
 
+static const char	hcd_name [] = "ohci-hcd";
+
 #include "ohci.h"
 
 static inline void disable (struct ohci_hcd *ohci)
@@ -275,6 +278,7 @@
 	urb_print (urb, "UNLINK", 1);
 #endif		  
 
+	spin_lock_irqsave (&ohci->lock, flags);
 	if (!ohci->disabled) {
 		urb_priv_t  *urb_priv;
 
@@ -282,21 +286,24 @@
 		 * handed to us, flag it for unlink and giveback, and force
 		 * some upcoming INTR_SF to call finish_unlinks()
 		 */
-		spin_lock_irqsave (&ohci->lock, flags);
 		urb_priv = urb->hcpriv;
 		if (urb_priv) {
 			urb_priv->state = URB_DEL; 
 			if (urb_priv->ed->state == ED_OPER)
 				start_urb_unlink (ohci, urb_priv->ed);
 		}
-		spin_unlock_irqrestore (&ohci->lock, flags);
 	} else {
 		/*
 		 * with HC dead, we won't respect hc queue pointers
 		 * any more ... just clean up every urb's memory.
 		 */
-		finish_urb (ohci, urb, NULL);
+		if (urb->hcpriv) {
+			spin_unlock (&ohci->lock);
+			finish_urb (ohci, urb, NULL);
+			spin_lock (&ohci->lock);
+		}
 	}
+	spin_unlock_irqrestore (&ohci->lock, flags);
 	return 0;
 }
 
@@ -332,9 +339,11 @@
 			td_free (ohci, ed->dummy);
 			break;
 		default:
-			err ("%s-%s ed %p (#%d) not unlinked; disconnect() bug? %d",
-				ohci->hcd.self.bus_name, udev->devpath, ed,
-				i, ed->state);
+			ohci_err (ohci,
+				"dev %s ep%d-%s linked; disconnect() bug?\n",
+				udev->devpath,
+				(i >> 1) & 0x0f, (i & 1) ? "out" : "in");
+
 			/* ED_OPER: some driver disconnect() is broken,
 			 * it didn't even start its unlinks much less wait
 			 * for their completions.
@@ -354,8 +363,10 @@
 #ifdef DEBUG
 	/* a driver->disconnect() returned before its unlinks completed? */
 	if (in_interrupt ()) {
-		warn ("disconnect() bug for dev usb-%s-%s ep 0x%x", 
-			ohci->hcd.self.bus_name, udev->devpath, i);
+		ohci_warn (ohci,
+			"driver disconnect() bug %s ep%d-%s\n", 
+			udev->devpath,
+			(i >> 1) & 0x0f, (i & 1) ? "out" : "in");
 	}
 #endif
 
@@ -381,9 +392,12 @@
 {
 	u32 temp;
 
-	/* SMM owns the HC?  not for long! */
+	/* SMM owns the HC?  not for long!
+	 * On PA-RISC, PDC can leave IR set incorrectly; ignore it there.
+	 */
+#ifndef __hppa__
 	if (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
-		dev_dbg (ohci->hcd.controller, "USB HC TakeOver from BIOS/SMM\n");
+		ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n");
 
 		/* this timeout is arbitrary.  we make it long, so systems
 		 * depending on usb keyboards may be usable even if the
@@ -396,17 +410,18 @@
 		while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
 			wait_ms (10);
 			if (--temp == 0) {
-				dev_err (ohci->hcd.controller, "USB HC TakeOver failed!\n");
+				ohci_err (ohci, "USB HC TakeOver failed!\n");
 				return -1;
 			}
 		}
 	}
+#endif
 
 	/* Disable HC interrupts */
 	writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
 
-	dev_dbg (ohci->hcd.controller, "USB HC reset_hc %s: ctrl = 0x%x ;\n",
-		ohci->hcd.self.bus_name,
+	ohci_dbg (ohci, "USB HC reset_hc %s: ctrl = 0x%x ;\n",
+		hcd_to_bus (&ohci->hcd)->bus_name,
 		readl (&ohci->regs->control));
 
   	/* Reset USB (needed by some controllers); RemoteWakeupConnected
@@ -422,7 +437,7 @@
 	temp = 30;	/* ... allow extra time */
 	while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
 		if (--temp == 0) {
-			dev_err (ohci->hcd.controller, "USB HC reset timed out!");
+			ohci_err (ohci, "USB HC reset timed out!\n");
 			return -1;
 		}
 		udelay (1);
@@ -451,8 +466,9 @@
  */
 static int hc_start (struct ohci_hcd *ohci)
 {
-  	u32			mask;
+  	u32			mask, tmp;
   	struct usb_device	*udev;
+  	struct usb_bus		*bus;
 
 	spin_lock_init (&ohci->lock);
 	ohci->disabled = 1;
@@ -478,7 +494,7 @@
 	 */
 	if ((readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
 			|| !readl (&ohci->regs->periodicstart)) {
-		err ("%s init err", ohci->hcd.self.bus_name);
+		ohci_err (ohci, "init err\n");
 		return -EOVERFLOW;
 	}
 
@@ -493,9 +509,20 @@
 	writel (mask, &ohci->regs->intrstatus);
 	writel (mask, &ohci->regs->intrenable);
 
-	/* hub power always on: required for AMD-756 and some Mac platforms */
-	writel ((roothub_a (ohci) | RH_A_NPS) & ~(RH_A_PSM | RH_A_OCPM),
-		&ohci->regs->roothub.a);
+	/* handle root hub init quirks ... */
+	tmp = roothub_a (ohci);
+	tmp &= ~(RH_A_PSM | RH_A_OCPM);
+	if (ohci->flags & OHCI_QUIRK_SUPERIO) {
+		/* NSC 87560 and maybe others */
+		tmp |= RH_A_NOCP;
+		tmp &= ~(RH_A_POTPGT | RH_A_NPS);
+	} else {
+		/* hub power always on; required for AMD-756 and some
+		 * Mac platforms, use this mode everywhere by default
+		 */
+		tmp |= RH_A_NPS;
+	}
+	writel (tmp, &ohci->regs->roothub.a);
 	writel (RH_HS_LPSC, &ohci->regs->roothub.status);
 	writel (0, &ohci->regs->roothub.b);
 
@@ -503,7 +530,8 @@
 	mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
  
 	/* connect the virtual root hub */
-	ohci->hcd.self.root_hub = udev = usb_alloc_dev (NULL, &ohci->hcd.self);
+	bus = hcd_to_bus (&ohci->hcd);
+	bus->root_hub = udev = usb_alloc_dev (NULL, bus);
 	ohci->hcd.state = USB_STATE_READY;
 	if (!udev) {
 		disable (ohci);
@@ -514,9 +542,9 @@
 
 	usb_connect (udev);
 	udev->speed = USB_SPEED_FULL;
-	if (usb_register_root_hub (udev, ohci->hcd.controller) != 0) {
+	if (hcd_register_root (&ohci->hcd) != 0) {
 		usb_put_dev (udev);
-		ohci->hcd.self.root_hub = NULL;
+		bus->root_hub = NULL;
 		disable (ohci);
 		ohci->hc_control &= ~OHCI_CTRL_HCFS;
 		writel (ohci->hc_control, &ohci->regs->control);
@@ -545,7 +573,7 @@
 	/* cardbus/... hardware gone before remove() */
 	} else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
 		disable (ohci);
-		dbg ("%s device removed!", hcd->self.bus_name);
+		ohci_dbg (ohci, "device removed!\n");
 		return;
 
 	/* interrupt for some other device? */
@@ -553,13 +581,9 @@
 		return;
 	} 
 
-
-	// dbg ("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no));
-
 	if (ints & OHCI_INTR_UE) {
 		disable (ohci);
-		err ("OHCI Unrecoverable Error, %s disabled",
-				hcd->self.bus_name);
+		ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
 		// e.g. due to PCI Master/Target Abort
 
 		ohci_dump (ohci, 1);
@@ -579,7 +603,8 @@
 	 */
 	spin_lock (&ohci->lock);
 	if (ohci->ed_rm_list)
-		finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no), ptregs);
+		finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no),
+				ptregs);
 	if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list)
 		writel (OHCI_INTR_SF, &regs->intrdisable);	
 	spin_unlock (&ohci->lock);
@@ -594,7 +619,7 @@
 {	
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
 
-	dev_dbg (hcd->controller, "stop %s controller%s\n",
+	ohci_dbg (ohci, "stop %s controller%s\n",
 		hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
 		ohci->disabled ? " (disabled)" : ""
 		);
@@ -629,8 +654,8 @@
 
 	ohci->disabled = 1;
 	ohci->sleeping = 0;
-	if (ohci->hcd.self.root_hub)
-		usb_disconnect (&ohci->hcd.self.root_hub);
+	if (hcd_to_bus (&ohci->hcd)->root_hub)
+		usb_disconnect (&hcd_to_bus (&ohci->hcd)->root_hub);
 	
 	/* empty the interrupt branches */
 	for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0;
@@ -644,18 +669,16 @@
 	ohci->ed_bulktail    = NULL;
 
 	if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
-		err ("can't restart %s, %d", ohci->hcd.self.bus_name, temp);
+		ohci_err (ohci, "can't restart, %d\n", temp);
 		return temp;
 	} else
-		dbg ("restart %s completed", ohci->hcd.self.bus_name);
+		ohci_dbg (ohci, "restart complete\n");
 	return 0;
 }
 #endif
 
 /*-------------------------------------------------------------------------*/
 
-static const char	hcd_name [] = "ohci-hcd";
-
 #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
 
 MODULE_AUTHOR (DRIVER_AUTHOR);
diff -urN linux-2.5.63-bk4/drivers/usb/host/ohci-hub.c linux-2.5.63-bk5/drivers/usb/host/ohci-hub.c
--- linux-2.5.63-bk4/drivers/usb/host/ohci-hub.c	Mon Feb 24 11:05:09 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ohci-hub.c	Mon Mar 31 12:18:55 2003
@@ -5,7 +5,6 @@
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
  * 
  * This file is licenced under GPL
- * $Id: ohci-hub.c,v 1.3 2002/03/22 16:04:54 dbrownell Exp $
  */
 
 /*-------------------------------------------------------------------------*/
@@ -41,7 +40,7 @@
 /*-------------------------------------------------------------------------*/
 
 #define dbg_port(hc,label,num,value) \
-	dev_dbg (hc->hcd.controller, \
+	ohci_dbg (hc, \
 		"%s roothub.portstatus [%d] " \
 		"= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
 		label, num, temp, \
@@ -76,9 +75,8 @@
 	if (ports > MAX_ROOT_PORTS) {
 		if (ohci->disabled)
 			return -ESHUTDOWN;
-		err ("%s bogus NDP=%d, rereads as NDP=%d",
-			hcd->self.bus_name, ports,
-			readl (&ohci->regs->roothub.a) & RH_A_NDP);
+		ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
+			ports, readl (&ohci->regs->roothub.a) & RH_A_NDP);
 		/* retry later; "should not happen" */
 		return 0;
 	}
@@ -159,7 +157,7 @@
 	u16		wLength
 ) {
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ports = hcd->self.root_hub->maxchild;
+	int		ports = hcd_to_bus (hcd)->root_hub->maxchild;
 	u32		temp;
 	int		retval = 0;
 
diff -urN linux-2.5.63-bk4/drivers/usb/host/ohci-mem.c linux-2.5.63-bk5/drivers/usb/host/ohci-mem.c
--- linux-2.5.63-bk4/drivers/usb/host/ohci-mem.c	Mon Feb 24 11:05:36 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ohci-mem.c	Mon Mar 31 12:18:55 2003
@@ -115,8 +115,8 @@
 		prev = &(*prev)->td_hash;
 	if (*prev)
 		*prev = td->td_hash;
-	else
-		dev_dbg (hc->hcd.controller, "bad hash for td %p\n", td);
+	else if ((td->hwINFO & TD_DONE) != 0)
+		ohci_dbg (hc, "no hash for td %p\n", td);
 	pci_pool_free (hc->td_cache, td, td->td_dma);
 }
 
diff -urN linux-2.5.63-bk4/drivers/usb/host/ohci-pci.c linux-2.5.63-bk5/drivers/usb/host/ohci-pci.c
--- linux-2.5.63-bk4/drivers/usb/host/ohci-pci.c	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ohci-pci.c	Mon Mar 31 12:18:55 2003
@@ -29,17 +29,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-struct ohci_hcd *dev_to_ohci(struct device *dev) {
-	struct pci_dev *pdev = 
-		container_of (dev, struct pci_dev, dev);
-	struct ohci_hcd	*ohci = 
-		container_of (pci_get_drvdata (pdev), struct ohci_hcd, hcd);
-
-	return ohci;
-}
-
-/*-------------------------------------------------------------------------*/
-
 static int __devinit
 ohci_pci_start (struct usb_hcd *hcd)
 {
@@ -55,22 +44,43 @@
 		/* AMD 756, for most chips (early revs), corrupts register
 		 * values on read ... so enable the vendor workaround.
 		 */
-		if (hcd->pdev->vendor == 0x1022
+		if (hcd->pdev->vendor == PCI_VENDOR_ID_AMD
 				&& hcd->pdev->device == 0x740c) {
 			ohci->flags = OHCI_QUIRK_AMD756;
-			info ("%s: AMD756 erratum 4 workaround",
-				hcd->self.bus_name);
+			ohci_info (ohci, "AMD756 erratum 4 workaround\n");
 		}
 
+		/* FIXME for some of the early AMD 760 southbridges, OHCI
+		 * won't work at all.  blacklist them.
+		 */
+
 		/* Apple's OHCI driver has a lot of bizarre workarounds
 		 * for this chip.  Evidently control and bulk lists
 		 * can get confused.  (B&W G3 models, and ...)
 		 */
-		else if (hcd->pdev->vendor == 0x1045
+		else if (hcd->pdev->vendor == PCI_VENDOR_ID_OPTI
 				&& hcd->pdev->device == 0xc861) {
-			info ("%s: WARNING: OPTi workarounds unavailable",
-				hcd->self.bus_name);
+			ohci_info (ohci,
+				"WARNING: OPTi workarounds unavailable\n");
+		}
+
+		/* Check for NSC87560. We have to look at the bridge (fn1) to
+		 * identify the USB (fn2). This quirk might apply to more or
+		 * even all NSC stuff.
+		 */
+		else if (hcd->pdev->vendor == PCI_VENDOR_ID_NS) {
+			struct pci_dev	*b, *hc;
+
+			hc = hcd->pdev;
+			b  = pci_find_slot (hc->bus->number,
+					PCI_DEVFN (PCI_SLOT (hc->devfn), 1));
+			if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
+					&& b->vendor == PCI_VENDOR_ID_NS) {
+				ohci->flags |= OHCI_QUIRK_SUPERIO;
+				ohci_info (ohci, "Using NSC SuperIO setup\n");
+			}
 		}
+	
 	}
 
         memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
@@ -86,7 +96,7 @@
 	}
 
 	if (hc_start (ohci) < 0) {
-		err ("can't start %s", ohci->hcd.self.bus_name);
+		ohci_err (ohci, "can't start\n");
 		ohci_stop (hcd);
 		return -EBUSY;
 	}
@@ -106,13 +116,13 @@
 	u16			cmd;
 
 	if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
-		dbg ("can't suspend %s (state is %s)", hcd->self.bus_name,
+		ohci_dbg (ohci, "can't suspend (state is %s)\n",
 			hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
 		return -EIO;
 	}
 
 	/* act as if usb suspend can always be used */
-	dbg ("%s: suspend to %d", hcd->self.bus_name, state);
+	ohci_dbg (ohci, "suspend to %d\n", state);
 	ohci->sleeping = 1;
 
 	/* First stop processing */
@@ -147,16 +157,16 @@
 
 	switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
 		case OHCI_USB_RESET:
-			dbg ("%s suspend->reset ?", hcd->self.bus_name);
+			ohci_dbg (ohci, "suspend->reset ?\n");
 			break;
 		case OHCI_USB_RESUME:
-			dbg ("%s suspend->resume ?", hcd->self.bus_name);
+			ohci_dbg (ohci, "suspend->resume ?\n");
 			break;
 		case OHCI_USB_OPER:
-			dbg ("%s suspend->operational ?", hcd->self.bus_name);
+			ohci_dbg (ohci, "suspend->operational ?\n");
 			break;
 		case OHCI_USB_SUSPEND:
-			dbg ("%s suspended", hcd->self.bus_name);
+			ohci_dbg (ohci, "suspended\n");
 			break;
 	}
 
@@ -204,7 +214,7 @@
 
 #ifdef DEBUG
 	/* the registers may look crazy here */
-	ohci_dump_status (ohci);
+	ohci_dump_status (ohci, 0, 0);
 #endif
 
 	/* Re-enable bus mastering */
@@ -213,13 +223,13 @@
 	switch (temp) {
 
 	case OHCI_USB_RESET:	// lost power
-		info ("USB restart: %s", hcd->self.bus_name);
+		ohci_info (ohci, "USB restart\n");
 		retval = hc_restart (ohci);
 		break;
 
 	case OHCI_USB_SUSPEND:	// host wakeup
 	case OHCI_USB_RESUME:	// remote wakeup
-		info ("USB continue: %s from %s wakeup", hcd->self.bus_name,
+		ohci_info (ohci, "USB continue from %s wakeup\n",
 			 (temp == OHCI_USB_SUSPEND)
 				? "host" : "remote");
 		ohci->hc_control = OHCI_USB_RESUME;
@@ -232,7 +242,7 @@
 		temp = readl (&ohci->regs->control);
 		temp = ohci->hc_control & OHCI_CTRL_HCFS;
 		if (temp != OHCI_USB_RESUME) {
-			err ("controller %s won't resume", hcd->self.bus_name);
+			ohci_err (ohci, "controller won't resume\n");
 			ohci->disabled = 1;
 			retval = -EIO;
 			break;
@@ -278,11 +288,12 @@
 		writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus);
 
 // ohci_dump_status (ohci);
-dbg ("sleeping = %d, disabled = %d", ohci->sleeping, ohci->disabled);
+ohci_dbg (ohci, "sleeping = %d, disabled = %d\n",
+		ohci->sleeping, ohci->disabled);
 		break;
 
 	default:
-		warn ("odd PCI resume for %s", hcd->self.bus_name);
+		ohci_warn (ohci, "odd PCI resume\n");
 	}
 	return retval;
 }
@@ -373,11 +384,11 @@
  
 static int __init ohci_hcd_pci_init (void) 
 {
-	dbg (DRIVER_INFO " (PCI)");
+	printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name);
 	if (usb_disabled())
 		return -ENODEV;
 
-	dbg ("block sizes: ed %d td %d",
+	printk (KERN_DEBUG "%s: block sizes: ed %d td %d\n", hcd_name,
 		sizeof (struct ed), sizeof (struct td));
 	return pci_module_init (&ohci_pci_driver);
 }
diff -urN linux-2.5.63-bk4/drivers/usb/host/ohci-q.c linux-2.5.63-bk5/drivers/usb/host/ohci-q.c
--- linux-2.5.63-bk4/drivers/usb/host/ohci-q.c	Mon Feb 24 11:05:44 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ohci-q.c	Mon Mar 31 12:18:55 2003
@@ -30,29 +30,28 @@
 /*
  * URB goes back to driver, and isn't reissued.
  * It's completely gone from HC data structures.
- * PRECONDITION:  no locks held  (Giveback can call into HCD.)
+ * PRECONDITION:  no locks held, irqs blocked  (Giveback can call into HCD.)
  */
-static void finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
+static void
+finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
 {
-	unsigned long	flags;
-
 	// ASSERT (urb->hcpriv != 0);
 
 	urb_free_priv (ohci, urb->hcpriv);
 	urb->hcpriv = NULL;
 
-	spin_lock_irqsave (&urb->lock, flags);
+	spin_lock (&urb->lock);
 	if (likely (urb->status == -EINPROGRESS))
 		urb->status = 0;
-	spin_unlock_irqrestore (&urb->lock, flags);
+	spin_unlock (&urb->lock);
 
 	// what lock protects these?
 	switch (usb_pipetype (urb->pipe)) {
 	case PIPE_ISOCHRONOUS:
-		ohci->hcd.self.bandwidth_isoc_reqs--;
+		hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs--;
 		break;
 	case PIPE_INTERRUPT:
-		ohci->hcd.self.bandwidth_int_reqs--;
+		hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs--;
 		break;
 	}
 
@@ -110,12 +109,9 @@
 {
 	unsigned	i;
 
-#ifdef OHCI_VERBOSE_DEBUG
-	dbg ("%s: link %sed %p branch %d [%dus.], interval %d",
-		ohci->hcd.self.bus_name,
+	ohci_vdbg (ohci, "link %sed %p branch %d [%dus.], interval %d\n",
 		(ed->hwINFO & ED_ISO) ? "iso " : "",
 		ed, ed->branch, ed->load, ed->interval);
-#endif
 
 	for (i = ed->branch; i < NUM_INTS; i += ed->interval) {
 		struct ed	**prev = &ohci->periodic [i];
@@ -143,7 +139,7 @@
 		}
 		ohci->load [i] += ed->load;
 	}
-	ohci->hcd.self.bandwidth_allocated += ed->load / ed->interval;
+	hcd_to_bus (&ohci->hcd)->bandwidth_allocated += ed->load / ed->interval;
 }
 
 /* link an ed into one of the HC chains */
@@ -206,7 +202,7 @@
 	default:
 		branch = balance (ohci, ed->interval, ed->load);
 		if (branch < 0) {
-			dev_dbg (ohci->hcd.controller,
+			ohci_dbg (ohci,
 				"ERR %d, interval %d msecs, load %d\n",
 				branch, ed->interval, ed->load);
 			// FIXME if there are TDs queued, fail them!
@@ -244,14 +240,11 @@
 		}
 		ohci->load [i] -= ed->load;
 	}	
-	ohci->hcd.self.bandwidth_allocated -= ed->load / ed->interval;
+	hcd_to_bus (&ohci->hcd)->bandwidth_allocated -= ed->load / ed->interval;
 
-#ifdef OHCI_VERBOSE_DEBUG
-	dbg ("%s: unlink %sed %p branch %d [%dus.], interval %d",
-		ohci->hcd.self.bus_name,
+	ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",
 		(ed->hwINFO & ED_ISO) ? "iso " : "",
 		ed, ed->branch, ed->load, ed->interval);
-#endif
 }
 
 /* unlink an ed from one of the HC chains. 
@@ -576,7 +569,7 @@
 	 */
 	case PIPE_INTERRUPT:
 		/* ... and periodic urbs have extra accounting */
-		ohci->hcd.self.bandwidth_int_reqs++;
+		hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs++;
 		/* FALLTHROUGH */
 	case PIPE_BULK:
 		info = is_out
@@ -644,7 +637,7 @@
 				data + urb->iso_frame_desc [cnt].offset,
 				urb->iso_frame_desc [cnt].length, urb, cnt);
 		}
-		ohci->hcd.self.bandwidth_isoc_reqs++;
+		hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs++;
 		break;
 	}
 	// ASSERT (urb_priv->length == cnt);
@@ -687,11 +680,10 @@
 		urb->iso_frame_desc [td->index].actual_length = dlen;
 		urb->iso_frame_desc [td->index].status = cc_to_error [cc];
 
-#ifdef VERBOSE_DEBUG
 		if (cc != TD_CC_NOERROR)
-			dbg ("  urb %p iso TD %p (%d) len %d CC %d",
+			ohci_vdbg (ohci,
+				"urb %p iso td %p (%d) len %d cc %d\n",
 				urb, td, 1 + td->index, dlen, cc);
-#endif
 
 	/* BULK, INT, CONTROL ... drivers see aggregate length/status,
 	 * except that "setup" bytes aren't counted and "short" transfers
@@ -730,13 +722,12 @@
 					- td->data_dma;
 		}
 
-#ifdef VERBOSE_DEBUG
 		if (cc != TD_CC_NOERROR && cc < 0x0E)
-			dbg ("  urb %p TD %p (%d) CC %d, len=%d/%d",
+			ohci_vdbg (ohci,
+				"urb %p td %p (%d) cc %d, len=%d/%d\n",
 				urb, td, 1 + td->index, cc,
 				urb->actual_length,
 				urb->transfer_buffer_length);
-#endif
   	}
 }
 
@@ -791,14 +782,18 @@
 		ed->hwHeadP = next->hwNextTD | toggle;
 	}
 
-	/* help for troubleshooting: */
-	dev_dbg (&urb->dev->dev,
-		"urb %p usb-%s-%s ep-%d-%s cc %d --> status %d\n",
-		urb,
-		urb->dev->bus->bus_name, urb->dev->devpath,
-		usb_pipeendpoint (urb->pipe),
-		usb_pipein (urb->pipe) ? "IN" : "OUT",
-		cc, cc_to_error [cc]);
+	/* help for troubleshooting:  report anything that
+	 * looks odd ... that doesn't include protocol stalls
+	 * (or maybe some other things)
+	 */
+	if (cc != TD_CC_STALL || !usb_pipecontrol (urb->pipe))
+		ohci_dbg (ohci,
+			"urb %p path %s ep%d%s %08x cc %d --> status %d\n",
+			urb, urb->dev->devpath,
+			usb_pipeendpoint (urb->pipe),
+			usb_pipein (urb->pipe) ? "in" : "out",
+			le32_to_cpu (td->hwINFO),
+			cc, cc_to_error [cc]);
 
 	return rev;
 }
@@ -826,8 +821,7 @@
 
 		td = dma_to_td (ohci, td_dma);
 		if (!td) {
-			err ("%s bad entry %8x",
-				ohci->hcd.self.bus_name, td_dma);
+			ohci_err (ohci, "bad entry %8x\n", td_dma);
 			break;
 		}
 
@@ -855,7 +849,8 @@
 #define tick_before(t1,t2) ((((s16)(t1))-((s16)(t2))) < 0)
 
 /* there are some urbs/eds to unlink; called in_irq(), with HCD locked */
-static void finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
+static void
+finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
 {
 	struct ed	*ed, **last;
 
@@ -983,7 +978,8 @@
  * path is finish_unlinks(), which unlinks URBs using ed_rm_list, instead of
  * scanning the (re-reversed) donelist as this does.
  */
-static void dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs)
+static void
+dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs)
 {
 	unsigned long	flags;
 
@@ -1000,9 +996,9 @@
 
 		/* If all this urb's TDs are done, call complete() */
   		if (urb_priv->td_cnt == urb_priv->length) {
-     			spin_unlock_irqrestore (&ohci->lock, flags);
+     			spin_unlock (&ohci->lock);
   			finish_urb (ohci, urb, regs);
-  			spin_lock_irqsave (&ohci->lock, flags);
+  			spin_lock (&ohci->lock);
   		}
 
 		/* clean schedule:  unlink EDs that are no longer busy */
diff -urN linux-2.5.63-bk4/drivers/usb/host/ohci-sa1111.c linux-2.5.63-bk5/drivers/usb/host/ohci-sa1111.c
--- linux-2.5.63-bk4/drivers/usb/host/ohci-sa1111.c	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ohci-sa1111.c	Mon Mar 31 12:18:55 2003
@@ -3,7 +3,7 @@
  *
  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
  * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
- * (C) Hewlett-Packard Company
+ * (C) Copyright 2002 Hewlett-Packard Company
  * 
  * SA1111 Bus Glue
  *
@@ -27,14 +27,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-struct ohci_hcd *dev_to_ohci(struct device *dev) {
-	struct usb_hcd *hcd = dev->driver_data;
-
-	return hcd_to_ohci(hcd);
-}
-
-/*-------------------------------------------------------------------------*/
-
 static void sa1111_start_hc(struct sa1111_dev *dev)
 {
 	unsigned int usb_rst = 0;
diff -urN linux-2.5.63-bk4/drivers/usb/host/ohci.h linux-2.5.63-bk5/drivers/usb/host/ohci.h
--- linux-2.5.63-bk4/drivers/usb/host/ohci.h	Mon Feb 24 11:06:02 2003
+++ linux-2.5.63-bk5/drivers/usb/host/ohci.h	Mon Mar 31 12:18:55 2003
@@ -372,6 +372,7 @@
 
 	unsigned long		flags;		/* for HC bugs */
 #define	OHCI_QUIRK_AMD756	0x01			/* erratum #4 */
+#define	OHCI_QUIRK_SUPERIO	0x02			/* natsemi */
 	// there are also chip quirks/bugs in init logic
 
 	/*
@@ -382,4 +383,24 @@
 
 #define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd)
 
-struct ohci_hcd *dev_to_ohci(struct device *);
+/*-------------------------------------------------------------------------*/
+
+#ifndef DEBUG
+#define STUB_DEBUG_FILES
+#endif	/* DEBUG */
+
+#define ohci_dbg(ohci, fmt, args...) \
+	dev_dbg ((ohci)->hcd.controller , fmt , ## args )
+#define ohci_err(ohci, fmt, args...) \
+	dev_err ((ohci)->hcd.controller , fmt , ## args )
+#define ohci_info(ohci, fmt, args...) \
+	dev_info ((ohci)->hcd.controller , fmt , ## args )
+#define ohci_warn(ohci, fmt, args...) \
+	dev_warn ((ohci)->hcd.controller , fmt , ## args )
+
+#ifdef OHCI_VERBOSE_DEBUG
+#	define ohci_vdbg ohci_dbg
+#else
+#	define ohci_vdbg(ohci, fmt, args...) do { } while (0)
+#endif
+
diff -urN linux-2.5.63-bk4/drivers/usb/image/scanner.c linux-2.5.63-bk5/drivers/usb/image/scanner.c
--- linux-2.5.63-bk4/drivers/usb/image/scanner.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk5/drivers/usb/image/scanner.c	Mon Mar 31 12:18:55 2003
@@ -1,7 +1,7 @@
 /* -*- linux-c -*- */
 
 /* 
- * Driver for USB Scanners (linux-2.5.60)
+ * Driver for USB Scanners (linux-2.5.64)
  *
  * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
  * Copyright (C) 2002, 2003 Henning Meier-Geinitz
@@ -346,6 +346,11 @@
  *    - Print ids and device number when a device was detected.
  *    - Don't print errors when the device is busy.
  *      
+ * 0.4.11  2003-02-25
+ *    - Added vendor/product ids for Artec, Avision, Brother, Medion, Primax,
+ *      Prolink, Fujitsu, Plustek, and SYSCAN scanners.
+ *    - Fixed generation of devfs names if dynamic minors are disabled.
+ *
  * TODO
  *    - Performance
  *    - Select/poll methods
@@ -1052,7 +1057,7 @@
 	scn->scn_minor = scn_minor;
 	scn->isopen = 0;
 
-	sprintf(name, "scanner%d", scn->scn_minor);
+	sprintf(name, "scanner%d", scn->scn_minor - SCN_BASE_MNR);
 	
 	scn->devfs = devfs_register(usb_devfs_handle, name,
 				    DEVFS_FL_DEFAULT, USB_MAJOR,
diff -urN linux-2.5.63-bk4/drivers/usb/image/scanner.h linux-2.5.63-bk5/drivers/usb/image/scanner.h
--- linux-2.5.63-bk4/drivers/usb/image/scanner.h	Mon Feb 24 11:05:16 2003
+++ linux-2.5.63-bk5/drivers/usb/image/scanner.h	Mon Mar 31 12:18:55 2003
@@ -1,5 +1,5 @@
 /*
- * Driver for USB Scanners (linux-2.5.60)
+ * Driver for USB Scanners (linux-2.5.64)
  *
  * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
  * Previously maintained by Brian Beattie
@@ -44,7 +44,7 @@
 
 // #define DEBUG
 
-#define DRIVER_VERSION "0.4.10"
+#define DRIVER_VERSION "0.4.11"
 #define DRIVER_DESC "USB Scanner Driver"
 
 #include <linux/usb.h>
@@ -99,7 +99,13 @@
 	/* Artec */
 	{ USB_DEVICE(0x05d8, 0x4001) },	/* Ultima 2000 */
 	{ USB_DEVICE(0x05d8, 0x4002) }, /* Ultima 2000 (GT6801 based) */
+	{ USB_DEVICE(0x05d8, 0x4003) }, /* E+ 48U */
+	{ USB_DEVICE(0x05d8, 0x4004) }, /* E+ Pro */
+	/* Avision */
+	{ USB_DEVICE(0x0638, 0x0a10) },	/* iVina FB1600 (=Umax Astra 4500) */
 	/* Benq: see Acer */
+	/* Brother */
+	{ USB_DEVICE(0x04f9, 0x0111) },	/* MFC 6800 */
 	/* Canon */
 	{ USB_DEVICE(0x04a9, 0x2201) }, /* CanoScan FB320U */
 	{ USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */
@@ -117,6 +123,10 @@
 	/* Compaq */
 	{ USB_DEVICE(0x049f, 0x0021) },	/* S200 */
 	/* Epson -- See Seiko/Epson below */
+	/* Fujitsu */
+	{ USB_DEVICE(0x04c5, 0x1041) }, /* fi-4220c USB/SCSI info:mza@mu-tec.de */
+	{ USB_DEVICE(0x04c5, 0x1042) }, /* fi-4120c USB/SCSI info:mza@mu-tec.de */
+	{ USB_DEVICE(0x04c5, 0x1029) }, /* fi-4010c USB AVision info:mza@mu-tec.de */
 	/* Genius */
 	{ USB_DEVICE(0x0458, 0x2001) },	/* ColorPage Vivid Pro */
 	{ USB_DEVICE(0x0458, 0x2007) },	/* ColorPage HR6 V2 */
@@ -149,6 +159,8 @@
 	{ USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
 	/* Lexmark */
 	{ USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */
+	/* Medion */
+	{ USB_DEVICE(0x0461, 0x0377) },	/* MD 5345 - repackaged Primax? */
 	/* Memorex */
 	{ USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */
 	/* Microtek */
@@ -202,7 +214,8 @@
 	{ USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */
 	{ USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */
-	{ USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U */
+	{ USB_DEVICE(0x07b3, 0x0400) }, /* OpticPro 1248U */
+	{ USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U (another one) */
 	/* Primax/Colorado */
 	{ USB_DEVICE(0x0461, 0x0300) },	/* G2-300 #1 */
 	{ USB_DEVICE(0x0461, 0x0301) },	/* G2E-300 #1 */
@@ -210,12 +223,15 @@
 	{ USB_DEVICE(0x0461, 0x0303) },	/* G2E-300 #2 */
 	{ USB_DEVICE(0x0461, 0x0340) },	/* Colorado USB 9600 */
 	{ USB_DEVICE(0x0461, 0x0341) },	/* Colorado 600u */
+	{ USB_DEVICE(0x0461, 0x0347) },	/* Primascan Colorado 2600u */
 	{ USB_DEVICE(0x0461, 0x0360) },	/* Colorado USB 19200 */
 	{ USB_DEVICE(0x0461, 0x0361) },	/* Colorado 1200u */
 	{ USB_DEVICE(0x0461, 0x0380) },	/* G2-600 #1 */
 	{ USB_DEVICE(0x0461, 0x0381) },	/* ReadyScan 636i */
 	{ USB_DEVICE(0x0461, 0x0382) },	/* G2-600 #2 */
 	{ USB_DEVICE(0x0461, 0x0383) },	/* G2E-600 */
+	/* Prolink */
+	{ USB_DEVICE(0x06dc, 0x0014) }, /* Winscan Pro 2448U */
 	/* Relisis */
 	// { USB_DEVICE(0x0475, 0x0103) },	/* Episode - undetected endpoint */
 	/* Seiko/Epson Corp. */
@@ -241,6 +257,8 @@
 	{ USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */
 	{ USB_DEVICE(0x04b8, 0x0801) }, /* Stylus CX5200 */
 	{ USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */
+	/* SYSCAN */
+	{ USB_DEVICE(0x0a82, 0x4600) }, /* TravelScan 460/464 */
 	/* Umax */
 	{ USB_DEVICE(0x1606, 0x0010) },	/* Astra 1220U */
 	{ USB_DEVICE(0x1606, 0x0030) },	/* Astra 2000U */
diff -urN linux-2.5.63-bk4/drivers/usb/input/Kconfig linux-2.5.63-bk5/drivers/usb/input/Kconfig
--- linux-2.5.63-bk4/drivers/usb/input/Kconfig	Mon Feb 24 11:05:39 2003
+++ linux-2.5.63-bk5/drivers/usb/input/Kconfig	Mon Mar 31 12:18:55 2003
@@ -159,6 +159,20 @@
 	  The module will be called wacom.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
+config USB_KBTAB
+	tristate "KB Gear JamStudio tablet support"
+	depends on USB && INPUT
+	help
+	  Say Y here if you want to use the USB version of the KB Gear
+	  JamStudio tablet.  Make sure to say Y to "Mouse support"
+	  (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+	  (CONFIG_INPUT_EVDEV) as well.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called kbtab.o.  If you want to compile it as a
+	  module, say M here and read <file:Documentation/modules.txt>.
+
 config USB_POWERMATE
 	tristate "Griffin PowerMate and Contour Jog support"
 	depends on USB && INPUT
diff -urN linux-2.5.63-bk4/drivers/usb/input/Makefile linux-2.5.63-bk5/drivers/usb/input/Makefile
--- linux-2.5.63-bk4/drivers/usb/input/Makefile	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/drivers/usb/input/Makefile	Mon Mar 31 12:18:55 2003
@@ -31,5 +31,6 @@
 obj-$(CONFIG_USB_KBD)		+= usbkbd.o
 obj-$(CONFIG_USB_MOUSE)		+= usbmouse.o
 obj-$(CONFIG_USB_WACOM)		+= wacom.o
+obj-$(CONFIG_USB_KBTAB)		+= kbtab.o
 obj-$(CONFIG_USB_POWERMATE)	+= powermate.o
 obj-$(CONFIG_USB_XPAD)		+= xpad.o
diff -urN linux-2.5.63-bk4/drivers/usb/input/hid-core.c linux-2.5.63-bk5/drivers/usb/input/hid-core.c
--- linux-2.5.63-bk4/drivers/usb/input/hid-core.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/drivers/usb/input/hid-core.c	Mon Mar 31 12:18:55 2003
@@ -1304,6 +1304,10 @@
 #define USB_DEVICE_ID_WACOM_PL		0x0030
 #define USB_DEVICE_ID_WACOM_INTUOS2	0x0040
 
+#define USB_VENDOR_ID_KBGEAR            0x084e
+#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO  0x1001
+
+
 #define USB_VENDOR_ID_AIPTEK		0x08ca
 #define USB_DEVICE_ID_AIPTEK_6000	0x0020
 
@@ -1355,6 +1359,7 @@
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_6000, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
diff -urN linux-2.5.63-bk4/drivers/usb/input/kbtab.c linux-2.5.63-bk5/drivers/usb/input/kbtab.c
--- linux-2.5.63-bk4/drivers/usb/input/kbtab.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk5/drivers/usb/input/kbtab.c	Mon Mar 31 12:18:55 2003
@@ -0,0 +1,229 @@
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+
+/*
+ * Version Information
+ * v0.0.1 - Original, extremely basic version, 2.4.xx only
+ * v0.0.2 - Updated, works with 2.5.62 and 2.4.20;
+ *           - added pressure-threshold modules param code from
+ *              Alex Perry <alex.perry@ieee.org>
+ */
+
+#define DRIVER_VERSION "v0.0.2"
+#define DRIVER_AUTHOR "Josh Myer <josh@joshisanerd.com>"
+#define DRIVER_DESC "USB KB Gear JamStudio Tablet driver"
+#define DRIVER_LICENSE "GPL"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
+
+#define USB_VENDOR_ID_KBGEAR	0x084e
+
+static int       kb_pressure_click = 0x10;
+MODULE_PARM     (kb_pressure_click,"i");
+MODULE_PARM_DESC(kb_pressure_click,
+		 "pressure threshold for clicks");
+
+struct kbtab {
+	signed char *data;
+	dma_addr_t data_dma;
+	struct input_dev dev;
+	struct usb_device *usbdev;
+	struct urb *irq;
+	int open;
+	int x, y;
+	int button;
+	int pressure;
+	__u32 serial[2];
+	char phys[32];
+};
+
+static void kbtab_irq(struct urb *urb, struct pt_regs *regs)
+{
+	struct kbtab *kbtab = urb->context;
+	unsigned char *data = kbtab->data;
+	struct input_dev *dev = &kbtab->dev;
+	int retval;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+		goto exit;
+	}
+
+	kbtab->x = (data[2] << 8) + data[1];
+	kbtab->y = (data[4] << 8) + data[3];
+
+	kbtab->pressure = (data[5]);
+
+	input_report_key(dev, BTN_TOOL_PEN, 1);
+
+	input_report_abs(dev, ABS_X, kbtab->x);
+	input_report_abs(dev, ABS_Y, kbtab->y);
+	/*input_report_abs(dev, ABS_PRESSURE, kbtab->pressure);*/
+
+	/*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/
+	input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
+	
+	input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0);
+	
+	input_sync(dev);
+
+ exit:
+	retval = usb_submit_urb (urb, GFP_ATOMIC);
+	if (retval)
+		err ("%s - usb_submit_urb failed with result %d",
+		     __FUNCTION__, retval);
+}
+
+struct usb_device_id kbtab_ids[] = {
+	{ USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), driver_info : 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, kbtab_ids);
+
+static int kbtab_open(struct input_dev *dev)
+{
+	struct kbtab *kbtab = dev->private;
+
+	if (kbtab->open++)
+		return 0;
+
+	kbtab->irq->dev = kbtab->usbdev;
+	if (usb_submit_urb(kbtab->irq, GFP_KERNEL))
+		return -EIO;
+
+	return 0;
+}
+
+static void kbtab_close(struct input_dev *dev)
+{
+	struct kbtab *kbtab = dev->private;
+
+	if (!--kbtab->open)
+		usb_unlink_urb(kbtab->irq);
+}
+
+static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *dev = interface_to_usbdev(intf);
+	struct usb_endpoint_descriptor *endpoint;
+	struct kbtab *kbtab;
+	char path[64];
+
+	if (!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL)))
+		return -ENOMEM;
+	memset(kbtab, 0, sizeof(struct kbtab));
+
+	kbtab->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kbtab->data_dma);
+	if (!kbtab->data) {
+		kfree(kbtab);
+		return -ENOMEM;
+	}
+
+	kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
+	if (!kbtab->irq) {
+		usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
+		kfree(kbtab);
+		return -ENOMEM;
+	}
+
+	kbtab->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
+	kbtab->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+
+	kbtab->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+
+	kbtab->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
+
+	kbtab->dev.mscbit[0] |= BIT(MSC_SERIAL);
+
+	kbtab->dev.absmax[ABS_X] = 0x2000;
+	kbtab->dev.absmax[ABS_Y] = 0x1750;
+	kbtab->dev.absmax[ABS_PRESSURE] = 0xff;
+	
+	kbtab->dev.absfuzz[ABS_X] = 4;
+	kbtab->dev.absfuzz[ABS_Y] = 4;
+
+	kbtab->dev.private = kbtab;
+	kbtab->dev.open = kbtab_open;
+	kbtab->dev.close = kbtab_close;
+
+	usb_make_path(dev, path, 64);
+	sprintf(kbtab->phys, "%s/input0", path);
+
+	kbtab->dev.name = "KB Gear Tablet";
+	kbtab->dev.phys = kbtab->phys;
+	kbtab->dev.id.bustype = BUS_USB;
+	kbtab->dev.id.vendor = dev->descriptor.idVendor;
+	kbtab->dev.id.product = dev->descriptor.idProduct;
+	kbtab->dev.id.version = dev->descriptor.bcdDevice;
+	kbtab->usbdev = dev;
+
+	endpoint = &intf->altsetting[0].endpoint[0].desc;
+
+	usb_fill_int_urb(kbtab->irq, dev,
+			 usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+			 kbtab->data, 8,
+			 kbtab_irq, kbtab, endpoint->bInterval);
+	kbtab->irq->transfer_dma = kbtab->data_dma;
+	kbtab->irq->transfer_flags |= URB_NO_DMA_MAP;
+
+	input_register_device(&kbtab->dev);
+
+	printk(KERN_INFO "input: KB Gear Tablet on %s\n",  path);
+
+	usb_set_intfdata(intf, kbtab);
+
+	return 0;
+}
+
+static void kbtab_disconnect(struct usb_interface *intf)
+{
+	struct kbtab *kbtab = usb_get_intfdata (intf);
+
+	usb_set_intfdata(intf, NULL);
+	if (kbtab) {
+		usb_unlink_urb(kbtab->irq);
+		input_unregister_device(&kbtab->dev);
+		usb_free_urb(kbtab->irq);
+		usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
+		kfree(kbtab);
+	}
+}
+
+static struct usb_driver kbtab_driver = {
+	.name =		"kbtab",
+	.probe =	kbtab_probe,
+	.disconnect =	kbtab_disconnect,
+	.id_table =	kbtab_ids,
+};
+
+static int __init kbtab_init(void)
+{
+	usb_register(&kbtab_driver);
+	info(DRIVER_VERSION ":" DRIVER_DESC);
+	return 0;
+}
+
+static void __exit kbtab_exit(void)
+{
+	usb_deregister(&kbtab_driver);
+}
+
+module_init(kbtab_init);
+module_exit(kbtab_exit);
diff -urN linux-2.5.63-bk4/drivers/usb/misc/rio500.c linux-2.5.63-bk5/drivers/usb/misc/rio500.c
--- linux-2.5.63-bk4/drivers/usb/misc/rio500.c	Mon Feb 24 11:05:36 2003
+++ linux-2.5.63-bk5/drivers/usb/misc/rio500.c	Mon Mar 31 12:18:55 2003
@@ -332,7 +332,7 @@
 				}
 				interruptible_sleep_on_timeout(&rio-> wait_q, NAK_TIMEOUT);
 				continue;
-			} else if (!result & partial) {
+			} else if (!result && partial) {
 				obuf += partial;
 				thistime -= partial;
 			} else
diff -urN linux-2.5.63-bk4/drivers/usb/misc/speedtouch.c linux-2.5.63-bk5/drivers/usb/misc/speedtouch.c
--- linux-2.5.63-bk4/drivers/usb/misc/speedtouch.c	Mon Feb 24 11:06:02 2003
+++ linux-2.5.63-bk5/drivers/usb/misc/speedtouch.c	Mon Mar 31 12:18:55 2003
@@ -56,7 +56,6 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <asm/uaccess.h>
-#include <linux/usb.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/atm.h>
@@ -69,11 +68,7 @@
 #define DEBUG_PACKET 1
 */
 
-#ifdef DEBUG
-#define PDEBUG(arg...)  printk(KERN_DEBUG __FILE__ ": " arg)
-#else
-#define PDEBUG(arg...)
-#endif
+#include <linux/usb.h>
 
 
 #ifdef DEBUG_PACKET
@@ -161,6 +156,7 @@
 
 	/* usb device part */
 	struct usb_device *usb_dev;
+	char description [64];
 	int firmware_loaded;
 
 	/* atm device part */
@@ -324,16 +320,16 @@
 	unsigned long flags;
 
 	if (!urb || !(rcv = urb->context) || !(instance = rcv->instance)) {
-		PDEBUG ("udsl_complete_receive: bad urb!\n");
+		dbg ("udsl_complete_receive: bad urb!");
 		return;
 	}
 
-	PDEBUG ("udsl_complete_receive entered (urb 0x%p, status %d)\n", urb, urb->status);
+	dbg ("udsl_complete_receive entered (urb 0x%p, status %d)", urb, urb->status);
 
-	tasklet_schedule (&instance->receive_tasklet);
 	/* 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);
 }
 
@@ -349,7 +345,7 @@
 	struct sk_buff *new = NULL, *tmp = NULL;
 	int err;
 
-	PDEBUG ("udsl_process_receive entered\n");
+	dbg ("udsl_process_receive entered");
 
 	spin_lock_irqsave (&instance->completed_receivers_lock, flags);
 	while (!list_empty (&instance->completed_receivers)) {
@@ -358,11 +354,11 @@
 		spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
 
 		urb = rcv->urb;
-		PDEBUG ("udsl_process_receive: got packet %p with length %d and status %d\n", urb, urb->actual_length, urb->status);
+		dbg ("udsl_process_receive: got packet %p with length %d and status %d", urb, urb->actual_length, urb->status);
 
 		switch (urb->status) {
 		case 0:
-			PDEBUG ("udsl_process_receive: processing urb with rcv %p, urb %p, skb %p\n", rcv, urb, rcv->skb);
+			dbg ("udsl_process_receive: processing urb with rcv %p, urb %p, skb %p", rcv, urb, rcv->skb);
 
 			/* update the skb structure */
 			skb = rcv->skb;
@@ -370,13 +366,13 @@
 			skb_put (skb, urb->actual_length);
 			data_start = skb->data;
 
-			PDEBUG ("skb->len = %d\n", skb->len);
+			dbg ("skb->len = %d", skb->len);
 			PACKETDEBUG (skb->data, skb->len);
 
 			while ((new =
 				atmsar_decode_rawcell (instance->atmsar_vcc_list, skb,
 						       &atmsar_vcc)) != NULL) {
-				PDEBUG ("(after cell processing)skb->len = %d\n", new->len);
+				dbg ("(after cell processing)skb->len = %d", new->len);
 
 				switch (atmsar_vcc->type) {
 				case ATMSAR_TYPE_AAL5:
@@ -385,19 +381,19 @@
 
 					/* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
 					if (new) {
-						PDEBUG ("(after aal5 decap) skb->len = %d\n", new->len);
+						dbg ("(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 {
-							PDEBUG
-							    ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d\n",
+							dbg
+							    ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d",
 							     atomic_read (&atmsar_vcc->vcc->rx_inuse),
 							     atmsar_vcc->vcc->sk->rcvbuf, new->truesize);
 							dev_kfree_skb (new);
 						}
 					} else {
-						PDEBUG ("atmsar_decode_aal5 returned NULL!\n");
+						dbg ("atmsar_decode_aal5 returned NULL!");
 						dev_kfree_skb (tmp);
 					}
 					break;
@@ -422,10 +418,10 @@
 					   rcv);
 			if (!(err = usb_submit_urb (urb, GFP_ATOMIC)))
 				break;
-			PDEBUG ("udsl_process_receive: submission failed (%d)\n", err);
+			dbg ("udsl_process_receive: submission failed (%d)", err);
 			/* fall through */
 		default: /* error or urb unlinked */
-			PDEBUG ("udsl_process_receive: adding to spare_receivers\n");
+			dbg ("udsl_process_receive: adding to spare_receivers");
 			spin_lock_irqsave (&instance->spare_receivers_lock, flags);
 			list_add (&rcv->list, &instance->spare_receivers);
 			spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
@@ -435,7 +431,7 @@
 		spin_lock_irqsave (&instance->completed_receivers_lock, flags);
 	} /* while */
 	spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
-	PDEBUG ("udsl_process_receive successful\n");
+	dbg ("udsl_process_receive successful");
 }
 
 static void udsl_fire_receivers (struct udsl_instance_data *instance)
@@ -454,7 +450,7 @@
 	list_for_each_safe (pos, n, &receivers) {
 		struct udsl_receiver *rcv = list_entry (pos, struct udsl_receiver, list);
 
-		PDEBUG ("udsl_fire_receivers: firing urb %p\n", rcv->urb);
+		dbg ("udsl_fire_receivers: firing urb %p", rcv->urb);
 
 		usb_fill_bulk_urb (rcv->urb,
 				   instance->usb_dev,
@@ -465,7 +461,7 @@
 				   rcv);
 
 		if (usb_submit_urb (rcv->urb, GFP_KERNEL) < 0) {
-			PDEBUG ("udsl_fire_receivers: submit failed!\n");
+			dbg ("udsl_fire_receivers: submit failed!");
 			spin_lock_irqsave (&instance->spare_receivers_lock, flags);
 			list_move (pos, &instance->spare_receivers);
 			spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
@@ -487,17 +483,17 @@
 	unsigned long flags;
 
 	if (!urb || !(snd = urb->context) || !(instance = snd->instance)) {
-		PDEBUG ("udsl_complete_send: bad urb!\n");
+		dbg ("udsl_complete_send: bad urb!");
 		return;
 	}
 
-	PDEBUG ("udsl_complete_send entered (urb 0x%p, status %d)\n", urb, urb->status);
+	dbg ("udsl_complete_send entered (urb 0x%p, status %d)", urb, urb->status);
 
-	tasklet_schedule (&instance->send_tasklet);
 	/* 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);
+	tasklet_schedule (&instance->send_tasklet);
 	spin_unlock_irqrestore (&instance->send_lock, flags);
 }
 
@@ -513,7 +509,7 @@
 	struct udsl_sender *snd;
 	unsigned char *target;
 
-	PDEBUG ("udsl_process_send entered\n");
+	dbg ("udsl_process_send entered");
 
 made_progress:
 	spin_lock_irqsave (&instance->send_lock, flags);
@@ -521,10 +517,10 @@
 		if (!list_empty (&instance->filled_buffers)) {
 			buf = list_entry (instance->filled_buffers.next, struct udsl_send_buffer, list);
 			list_del (&buf->list);
-			PDEBUG ("sending filled buffer (0x%p)\n", buf);
+			dbg ("sending filled buffer (0x%p)", buf);
 		} else if ((buf = instance->current_buffer)) {
 			instance->current_buffer = NULL;
-			PDEBUG ("sending current buffer (0x%p)\n", buf);
+			dbg ("sending current buffer (0x%p)", buf);
 		} else /* all buffers empty */
 			break;
 
@@ -541,10 +537,10 @@
 				   udsl_complete_send,
 				   snd);
 
-		PDEBUG ("submitting urb 0x%p, contains %d cells\n", snd->urb, UDSL_SND_BUFFER_SIZE - buf->free_cells);
+		dbg ("submitting urb 0x%p, contains %d cells", snd->urb, UDSL_SND_BUFFER_SIZE - buf->free_cells);
 
 		if ((err = usb_submit_urb(snd->urb, GFP_ATOMIC)) < 0) {
-			PDEBUG ("submission failed (%d)!\n", err);
+			dbg ("submission failed (%d)!", err);
 			spin_lock_irqsave (&instance->send_lock, flags);
 			list_add (&snd->list, &instance->spare_senders);
 			spin_unlock_irqrestore (&instance->send_lock, flags);
@@ -557,7 +553,7 @@
 	spin_unlock_irqrestore (&instance->send_lock, flags);
 
 	if (!instance->current_skb && !(instance->current_skb = skb_dequeue (&instance->sndqueue))) {
-		PDEBUG ("done - no more skbs\n");
+		dbg ("done - no more skbs");
 		return;
 	}
 
@@ -568,7 +564,7 @@
 		if (list_empty (&instance->spare_buffers)) {
 			instance->current_buffer = NULL;
 			spin_unlock_irqrestore (&instance->send_lock, flags);
-			PDEBUG ("done - no more buffers\n");
+			dbg ("done - no more buffers");
 			return;
 		}
 		buf = list_entry (instance->spare_buffers.next, struct udsl_send_buffer, list);
@@ -584,7 +580,7 @@
 	cells_to_write = min (buf->free_cells, UDSL_SKB (skb)->num_cells);
 	target = buf->free_start;
 
-	PDEBUG ("writing %u cells from skb 0x%p to buffer 0x%p\n", cells_to_write, skb, buf);
+	dbg ("writing %u cells from skb 0x%p to buffer 0x%p", cells_to_write, skb, buf);
 
 	for (i = 0; i < cells_to_write; i++)
 		target = udsl_write_cell (skb, target);
@@ -593,15 +589,15 @@
 	if (!(buf->free_cells -= cells_to_write)) {
 		list_add_tail (&buf->list, &instance->filled_buffers);
 		instance->current_buffer = NULL;
-		PDEBUG ("queued filled buffer\n");
+		dbg ("queued filled buffer");
 	}
 
-	PDEBUG ("buffer contains %d cells, %d left\n", UDSL_SND_BUFFER_SIZE - buf->free_cells, buf->free_cells);
+	dbg ("buffer contains %d cells, %d left", UDSL_SND_BUFFER_SIZE - buf->free_cells, buf->free_cells);
 
 	if (!UDSL_SKB (skb)->num_cells) {
 		struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc;
 
-		PDEBUG ("discarding empty skb\n");
+		dbg ("discarding empty skb");
 		if (vcc->pop)
 			vcc->pop (vcc, skb);
 		else
@@ -620,11 +616,11 @@
 	unsigned long flags;
 	struct sk_buff *skb, *n;
 
-	PDEBUG ("udsl_cancel_send entered\n");
+	dbg ("udsl_cancel_send entered");
 	spin_lock_irqsave (&instance->sndqueue.lock, flags);
 	for (skb = instance->sndqueue.next, n = skb->next; skb != (struct sk_buff *)&instance->sndqueue; skb = n, n = skb->next)
 		if (UDSL_SKB (skb)->atm_data.vcc == vcc) {
-			PDEBUG ("popping skb 0x%p\n", skb);
+			dbg ("popping skb 0x%p", skb);
 			__skb_unlink (skb, &instance->sndqueue);
 			if (vcc->pop)
 				vcc->pop (vcc, skb);
@@ -635,7 +631,7 @@
 
 	tasklet_disable (&instance->send_tasklet);
 	if ((skb = instance->current_skb) && (UDSL_SKB (skb)->atm_data.vcc == vcc)) {
-		PDEBUG ("popping current skb (0x%p)\n", skb);
+		dbg ("popping current skb (0x%p)", skb);
 		instance->current_skb = NULL;
 		if (vcc->pop)
 			vcc->pop (vcc, skb);
@@ -643,30 +639,30 @@
 			kfree_skb (skb);
 	}
 	tasklet_enable (&instance->send_tasklet);
-	PDEBUG ("udsl_cancel_send done\n");
+	dbg ("udsl_cancel_send done");
 }
 
 static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
 {
 	struct udsl_instance_data *instance = vcc->dev->dev_data;
 
-	PDEBUG ("udsl_atm_send called (skb 0x%p, len %u)\n", skb, skb->len);
+	dbg ("udsl_atm_send called (skb 0x%p, len %u)", skb, skb->len);
 
-	if (!instance) {
-		PDEBUG ("NULL instance!\n");
-		return -EINVAL;
+	if (!instance || !instance->usb_dev) {
+		dbg ("NULL data!");
+		return -ENODEV;
 	}
 
 	if (!instance->firmware_loaded)
 		return -EAGAIN;
 
 	if (vcc->qos.aal != ATM_AAL5) {
-		PDEBUG ("unsupported ATM type %d!\n", vcc->qos.aal);
+		dbg ("unsupported ATM type %d!", vcc->qos.aal);
 		return -EINVAL;
 	}
 
 	if (skb->len > ATM_MAX_AAL5_PDU) {
-		PDEBUG ("packet too long (%d vs %d)!\n", skb->len, ATM_MAX_AAL5_PDU);
+		dbg ("packet too long (%d vs %d)!", skb->len, ATM_MAX_AAL5_PDU);
 		return -EINVAL;
 	}
 
@@ -695,16 +691,17 @@
 	struct udsl_instance_data *instance = dev->dev_data;
 
 	if (!instance) {
-		PDEBUG ("udsl_atm_dev_close: NULL instance!\n");
+		dbg ("udsl_atm_dev_close: NULL instance!");
 		return;
 	}
 
-	PDEBUG ("udsl_atm_dev_close: queue has %u elements\n", instance->sndqueue.qlen);
+	dbg ("udsl_atm_dev_close: queue has %u elements", instance->sndqueue.qlen);
 
-	PDEBUG ("udsl_atm_dev_close: killing tasklet\n");
+	dbg ("udsl_atm_dev_close: killing tasklet");
 	tasklet_kill (&instance->send_tasklet);
-	PDEBUG ("udsl_atm_dev_close: freeing instance\n");
+	dbg ("udsl_atm_dev_close: freeing instance");
 	kfree (instance);
+	dev->dev_data = NULL;
 }
 
 
@@ -720,13 +717,15 @@
 	int left = *pos;
 
 	if (!instance) {
-		PDEBUG ("NULL instance!\n");
+		dbg ("NULL instance!");
 		return -ENODEV;
 	}
 
 	if (!left--)
-		return sprintf (page, "SpeedTouch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
-				instance->usb_dev->bus->bus_name, instance->usb_dev->devpath,
+		return sprintf (page, "%s\n", instance->description);
+
+	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]);
 
@@ -738,6 +737,30 @@
 				atomic_read (&atm_dev->stats.aal5.rx_err),
 				atomic_read (&atm_dev->stats.aal5.rx_drop));
 
+	if (!left--) {
+		switch (atm_dev->signal) {
+		case ATM_PHY_SIG_FOUND:
+			sprintf (page, "Line up");
+			break;
+		case ATM_PHY_SIG_LOST:
+			sprintf (page, "Line down");
+			break;
+		default:
+			sprintf (page, "Line state unknown");
+			break;
+		}
+
+		if (instance->usb_dev) {
+			if (!instance->firmware_loaded)
+				strcat (page, ", no firmware\n");
+			else
+				strcat (page, ", firmware loaded\n");
+		} else
+			strcat (page, ", disconnected\n");
+
+		return strlen (page);
+	}
+
 	return 0;
 }
 
@@ -752,10 +775,10 @@
 {
 	struct udsl_instance_data *instance = vcc->dev->dev_data;
 
-	PDEBUG ("udsl_atm_open called\n");
+	dbg ("udsl_atm_open called");
 
-	if (!instance) {
-		PDEBUG ("NULL instance!\n");
+	if (!instance || !instance->usb_dev) {
+		dbg ("NULL data!");
 		return -ENODEV;
 	}
 
@@ -784,7 +807,7 @@
 	if (instance->firmware_loaded)
 		udsl_fire_receivers (instance);
 
-	PDEBUG ("udsl_atm_open successfull\n");
+	dbg ("udsl_atm_open successful");
 	return 0;
 }
 
@@ -792,10 +815,10 @@
 {
 	struct udsl_instance_data *instance = vcc->dev->dev_data;
 
-	PDEBUG ("udsl_atm_close called\n");
+	dbg ("udsl_atm_close called");
 
 	if (!instance) {
-		PDEBUG ("NULL instance!\n");
+		dbg ("NULL instance!");
 		return;
 	}
 
@@ -814,7 +837,7 @@
 
 	MOD_DEC_USE_COUNT;
 
-	PDEBUG ("udsl_atm_close successfull\n");
+	dbg ("udsl_atm_close successful");
 	return;
 }
 
@@ -837,10 +860,10 @@
 {
 	struct udsl_instance_data *instance = usb_get_intfdata (intf);
 
-	PDEBUG ("udsl_usb_ioctl entered\n");
+	dbg ("udsl_usb_ioctl entered");
 
 	if (!instance) {
-		PDEBUG ("NULL instance!\n");
+		dbg ("NULL instance!");
 		return -ENODEV;
 	}
 
@@ -869,10 +892,10 @@
 	int ifnum = intf->altsetting->desc.bInterfaceNumber;
 	struct udsl_instance_data *instance;
 	unsigned char mac_str [13];
-	unsigned char mac [6];
-	int i;
+	int i, length;
+	char *buf;
 
-	PDEBUG ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d\n",
+	dbg ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d",
 		dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
 
 	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
@@ -880,11 +903,11 @@
 	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
 		return -ENODEV;
 
-	PDEBUG ("Device Accepted\n");
+	dbg ("Device Accepted");
 
 	/* instance init */
 	if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) {
-		PDEBUG ("No memory for Instance data!\n");
+		dbg ("No memory for Instance data!");
 		return -ENOMEM;
 	}
 
@@ -916,12 +939,12 @@
 		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
 
 		if (!(rcv->skb = dev_alloc_skb (UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE))) {
-			PDEBUG ("No memory for skb %d!\n", i);
+			dbg ("No memory for skb %d!", i);
 			goto fail;
 		}
 
 		if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) {
-			PDEBUG ("No memory for receive urb %d!\n", i);
+			dbg ("No memory for receive urb %d!", i);
 			goto fail;
 		}
 
@@ -929,7 +952,7 @@
 
 		list_add (&rcv->list, &instance->spare_receivers);
 
-		PDEBUG ("skb->truesize = %d (asked for %d)\n", rcv->skb->truesize, UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE);
+		dbg ("skb->truesize = %d (asked for %d)", rcv->skb->truesize, UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE);
 	}
 
 	/* send init */
@@ -937,7 +960,7 @@
 		struct udsl_sender *snd = &(instance->all_senders[i]);
 
 		if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) {
-			PDEBUG ("No memory for send urb %d!\n", i);
+			dbg ("No memory for send urb %d!", i);
 			goto fail;
 		}
 
@@ -950,7 +973,7 @@
 		struct udsl_send_buffer *buf = &(instance->all_buffers[i]);
 
 		if (!(buf->base = kmalloc (UDSL_SND_BUFFER_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) {
-			PDEBUG ("No memory for send buffer %d!\n", i);
+			dbg ("No memory for send buffer %d!", i);
 			goto fail;
 		}
 
@@ -959,28 +982,47 @@
 
 	/* atm init */
 	if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) {
-		PDEBUG ("failed to register ATM device!\n");
+		dbg ("failed to register ATM device!");
 		goto fail;
 	}
 
 	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
 	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
-	instance->atm_dev->signal = ATM_PHY_SIG_LOST;
+	instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
 
 	/* tmp init atm device, set to 128kbit */
 	instance->atm_dev->link_rate = 128 * 1000 / 424;
 
 	/* set MAC address, it is stored in the serial number */
-	usb_string (instance->usb_dev, instance->usb_dev->descriptor.iSerialNumber, mac_str, 13);
-	for (i = 0; i < 6; i++)
-		mac[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1]));
+	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]));
+
+	/* device description */
+	buf = instance->description;
+	length = sizeof (instance->description);
+
+	if ((i = usb_string (dev, dev->descriptor.iProduct, buf, length)) < 0)
+		goto finish;
 
-	PDEBUG ("MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+	buf += i;
+	length -= i;
 
-	memcpy (instance->atm_dev->esi, mac, 6);
+	i = snprintf (buf, length, " (");
+	buf += i;
+	length -= i;
 
-	wmb ();
+	if (length <= 0 || (i = usb_make_path (dev, buf, length)) < 0)
+		goto finish;
 
+	buf += i;
+	length -= i;
+
+	snprintf (buf, length, ")");
+
+finish:
+	/* ready for ATM callbacks */
 	instance->atm_dev->dev_data = instance;
 
 	usb_set_intfdata (intf, instance);
@@ -1016,12 +1058,12 @@
 	unsigned int count = 0;
 	int result, i;
 
-	PDEBUG ("disconnecting\n");
+	dbg ("disconnecting");
 
 	usb_set_intfdata (intf, NULL);
 
 	if (!instance) {
-		PDEBUG ("NULL instance!\n");
+		dbg ("NULL instance!");
 		return;
 	}
 
@@ -1036,13 +1078,13 @@
 	INIT_LIST_HEAD (&instance->spare_receivers);
 	up (&instance->serialize);
 
-	PDEBUG ("udsl_usb_disconnect: flushed %u spare receivers\n", count);
+	dbg ("udsl_usb_disconnect: flushed %u spare receivers", count);
 
 	count = UDSL_NUMBER_RCV_URBS - count;
 
 	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++)
 		if ((result = usb_unlink_urb (instance->all_receivers[i].urb)) < 0)
-			PDEBUG ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d\n", i, result);
+			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
 
 	/* wait for completion handlers to finish */
 	do {
@@ -1054,7 +1096,7 @@
 				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
 		spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
 
-		PDEBUG ("udsl_usb_disconnect: found %u completed receivers\n", completed);
+		dbg ("udsl_usb_disconnect: found %u completed receivers", completed);
 
 		if (completed == count)
 			break;
@@ -1062,14 +1104,14 @@
 		yield ();
 	} while (1);
 
-	PDEBUG ("udsl_usb_disconnect: flushing\n");
+	dbg ("udsl_usb_disconnect: flushing");
 	/* no need to take the spinlock */
 	INIT_LIST_HEAD (&instance->completed_receivers);
 
 	tasklet_enable (&instance->receive_tasklet);
 	tasklet_kill (&instance->receive_tasklet);
 
-	PDEBUG ("udsl_usb_disconnect: freeing receivers\n");
+	dbg ("udsl_usb_disconnect: freeing receivers");
 	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
 		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
 
@@ -1082,7 +1124,7 @@
 
 	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
 		if ((result = usb_unlink_urb (instance->all_senders[i].urb)) < 0)
-			PDEBUG ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d\n", i, result);
+			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
 
 	/* wait for completion handlers to finish */
 	do {
@@ -1093,7 +1135,7 @@
 				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
 		spin_unlock_irqrestore (&instance->send_lock, flags);
 
-		PDEBUG ("udsl_usb_disconnect: found %u spare senders\n", count);
+		dbg ("udsl_usb_disconnect: found %u spare senders", count);
 
 		if (count == UDSL_NUMBER_SND_URBS)
 			break;
@@ -1101,7 +1143,7 @@
 		yield ();
 	} while (1);
 
-	PDEBUG ("udsl_usb_disconnect: flushing\n");
+	dbg ("udsl_usb_disconnect: flushing");
 	/* no need to take the spinlock */
 	INIT_LIST_HEAD (&instance->spare_senders);
 	INIT_LIST_HEAD (&instance->spare_buffers);
@@ -1109,16 +1151,18 @@
 
 	tasklet_enable (&instance->send_tasklet);
 
-	PDEBUG ("udsl_usb_disconnect: freeing senders\n");
+	dbg ("udsl_usb_disconnect: freeing senders");
 	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
 		usb_free_urb (instance->all_senders[i].urb);
 
-	PDEBUG ("udsl_usb_disconnect: freeing buffers\n");
+	dbg ("udsl_usb_disconnect: freeing buffers");
 	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++)
 		kfree (instance->all_buffers[i].base);
 
+	instance->usb_dev = NULL;
+
 	/* atm finalize */
-	shutdown_atm_dev (instance->atm_dev);
+	shutdown_atm_dev (instance->atm_dev); /* frees instance */
 }
 
 
@@ -1132,7 +1176,7 @@
 {
 	struct sk_buff *skb; /* dummy for sizeof */
 
-	PDEBUG ("udsl_usb_init: driver version " DRIVER_VERSION "\n");
+	dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
 
 	if (sizeof (struct udsl_control) > sizeof (skb->cb)) {
 		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
@@ -1144,7 +1188,7 @@
 
 static void __exit udsl_usb_cleanup (void)
 {
-	PDEBUG ("udsl_usb_cleanup\n");
+	dbg ("udsl_usb_cleanup");
 
 	usb_deregister (&udsl_usb_driver);
 }
@@ -1175,7 +1219,7 @@
 		for (j = 0; (j < 16) && (i < len); j++, i++) {
 			sprintf (buffer, "%s %2.2x", buffer, data[i]);
 		}
-		PDEBUG ("%s\n", buffer);
+		dbg ("%s", buffer);
 	}
 	return i;
 }
diff -urN linux-2.5.63-bk4/drivers/usb/misc/usblcd.c linux-2.5.63-bk5/drivers/usb/misc/usblcd.c
--- linux-2.5.63-bk4/drivers/usb/misc/usblcd.c	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk5/drivers/usb/misc/usblcd.c	Mon Mar 31 12:18:55 2003
@@ -153,7 +153,7 @@
 				}
 				interruptible_sleep_on_timeout(&lcd-> wait_q, NAK_TIMEOUT);
 				continue;
-			} else if (!result & partial) {
+			} else if (!result && partial) {
 				obuf += partial;
 				thistime -= partial;
 			} else
diff -urN linux-2.5.63-bk4/drivers/usb/misc/usbtest.c linux-2.5.63-bk5/drivers/usb/misc/usbtest.c
--- linux-2.5.63-bk4/drivers/usb/misc/usbtest.c	Mon Feb 24 11:05:46 2003
+++ linux-2.5.63-bk5/drivers/usb/misc/usbtest.c	Mon Mar 31 12:18:55 2003
@@ -552,6 +552,7 @@
  *   (b) protocol stalls (control-only) will autorecover.
  *       it's quite not like bulk/intr; no halt clearing.
  *   (c) short control reads are reported and handled.
+ *   (d) queues are always processed in-order
  */
 
 struct ctrl_ctx {
@@ -563,66 +564,68 @@
 	int			status;
 	struct urb		**urb;
 	struct usbtest_param	*param;
+	int			last;
+};
+
+#define NUM_SUBCASES	13		/* how many test subcases here? */
+
+struct subcase {
+	struct usb_ctrlrequest	setup;
+	int			number;
+	int			expected;
 };
 
 static void ctrl_complete (struct urb *urb, struct pt_regs *regs)
 {
 	struct ctrl_ctx		*ctx = urb->context;
 	struct usb_ctrlrequest	*reqp;
+	struct subcase		*subcase;
 	int			status = urb->status;
 
 	reqp = (struct usb_ctrlrequest *)urb->setup_packet;
+	subcase = container_of (reqp, struct subcase, setup);
 
 	spin_lock (&ctx->lock);
 	ctx->count--;
 	ctx->pending--;
 
-	/* FIXME verify that the completions are in the right sequence.
-	 * we could store the test number with the setup packet, that
-	 * buffer has extra space.
+	/* queue must transfer and complete in fifo order, unless
+	 * usb_unlink_urb() is used to unlink something not at the
+	 * physical queue head (not tested).
 	 */
-
-	switch (status) {
-	case 0:			/* success */
-	case -EREMOTEIO:	/* short read */
-		if (reqp->bRequestType == (USB_DIR_IN|USB_RECIP_DEVICE)
-				&& reqp->bRequest == USB_REQ_GET_DESCRIPTOR
-				&& ((le16_to_cpu (reqp->wValue) >> 8)
-					== USB_DT_DEVICE)) {
-			if (reqp->wLength > USB_DT_DEVICE_SIZE
-					&& status == -EREMOTEIO)
-				status = 0;
-			else if (reqp->wLength == USB_DT_DEVICE_SIZE
-					&& status != 0)
-				status = -EIO;
-			if (status)
-				goto error;
-		}
-		break;
-	case -ECONNRESET:	/* async unlink */
-		break;
-	case -EPIPE: 		/* (protocol) stall */
-		if (reqp->bRequestType == (USB_DIR_IN|USB_RECIP_INTERFACE)
-				&& reqp->bRequest == USB_REQ_GET_INTERFACE)
+	if (subcase->number > 0) {
+		if ((subcase->number - ctx->last) != 1) {
+			dbg ("subcase %d completed out of order, last %d",
+					subcase->number, ctx->last);
+			status = -EDOM;
+			goto error;
+		}
+	}
+	ctx->last = subcase->number;
+
+	/* succeed or fault in only one way? */
+	if (status == subcase->expected)
+		status = 0;
+
+	/* async unlink for cleanup? */
+	else if (status != -ECONNRESET) {
+
+		/* some faults are allowed, not required */
+		if (subcase->expected > 0 && (
+			  ((urb->status == -subcase->expected	/* happened */
+			   || urb->status == 0))))		/* didn't */
 			status = 0;
-		else if (reqp->bRequestType == (USB_DIR_IN|USB_RECIP_DEVICE)
-				&& reqp->bRequest == USB_REQ_GET_DESCRIPTOR) {
-			switch (le16_to_cpu (reqp->wValue) >> 8) {
-			case USB_DT_DEVICE_QUALIFIER:
-			case USB_DT_OTHER_SPEED_CONFIG:
-			case USB_DT_INTERFACE:
-			case USB_DT_ENDPOINT:
-				status = 0;
-			}
-		} else if (reqp->bRequestType == USB_RECIP_ENDPOINT
-				&& reqp->bRequest == USB_REQ_CLEAR_FEATURE)
+		/* sometimes more than one fault is allowed */
+		else if (subcase->number == 12 && status == -EPIPE)
 			status = 0;
-		/* some stalls we plan on; others would be errors */
-		if (status == 0)
-			break;
-		/* else FALLTHROUGH */
+		else
+			dbg ("subtest %d error, status %d",
+					subcase->number, status);
+	}
+
+	/* unexpected status codes mean errors; ideally, in hardware */
+	if (status) {
 error:
-	default:		/* this fault's an error */
 		if (ctx->status == 0) {
 			int		i;
 
@@ -631,10 +634,8 @@
 					reqp->bRequestType, reqp->bRequest,
 					status, ctx->count);
 
-			/* FIXME use this "unlink everything" exit route
-			 * in all cases, not just for fault cleanup.
-			 * it'll be another test mode, but one that makes
-			 * testing be more consistent.
+			/* FIXME this "unlink everything" exit route should
+			 * be a separate test case.
 			 */
 
 			/* unlink whatever's still pending */
@@ -688,6 +689,7 @@
 	context.pending = 0;
 	context.status = -ENOMEM;
 	context.param = param;
+	context.last = -1;
 
 	/* allocate and init the urbs we'll queue.
 	 * as with bulk/intr sglists, sglen is the queue depth; it also
@@ -701,7 +703,9 @@
 		int			pipe = usb_rcvctrlpipe (udev, 0);
 		unsigned		len;
 		struct urb		*u;
-		struct usb_ctrlrequest	req, *reqp;
+		struct usb_ctrlrequest	req;
+		struct subcase		*reqp;
+		int			expected = 0;
 
 		/* requests here are mostly expected to succeed on any
 		 * device, but some are chosen to trigger protocol stalls
@@ -711,7 +715,7 @@
 		req.bRequest = USB_REQ_GET_DESCRIPTOR;
 		req.bRequestType = USB_DIR_IN|USB_RECIP_DEVICE;
 
-		switch (i % 12 /* number of subtest cases here */) {
+		switch (i % NUM_SUBCASES) {
 		case 0:		// get device descriptor
 			req.wValue = cpu_to_le16 (USB_DT_DEVICE << 8);
 			len = sizeof (struct usb_device_descriptor);
@@ -725,6 +729,7 @@
 			req.bRequestType = USB_DIR_IN|USB_RECIP_INTERFACE;
 			// index = 0 means first interface
 			len = 1;
+			expected = EPIPE;
 			break;
 		case 3:		// get interface status
 			req.bRequest = USB_REQ_GET_STATUS;
@@ -740,6 +745,8 @@
 		case 5:		// get device qualifier (MAY STALL)
 			req.wValue = cpu_to_le16 (USB_DT_DEVICE_QUALIFIER << 8);
 			len = sizeof (struct usb_qualifier_descriptor);
+			if (udev->speed != USB_SPEED_HIGH)
+				expected = EPIPE;
 			break;
 		case 6:		// get first config descriptor, plus interface
 			req.wValue = cpu_to_le16 ((USB_DT_CONFIG << 8) | 0);
@@ -750,6 +757,7 @@
 			req.wValue = cpu_to_le16 (USB_DT_INTERFACE << 8);
 			// interface == 0
 			len = sizeof (struct usb_interface_descriptor);
+			expected = -EPIPE;
 			break;
 		// NOTE: two consecutive stalls in the queue here.
 		// that tests fault recovery a bit more aggressively.
@@ -760,6 +768,7 @@
 			// wIndex 0 == ep0 (shouldn't halt!)
 			len = 0;
 			pipe = usb_sndctrlpipe (udev, 0);
+			expected = EPIPE;
 			break;
 		case 9:		// get endpoint status
 			req.bRequest = USB_REQ_GET_STATUS;
@@ -770,18 +779,21 @@
 		case 10:	// trigger short read (EREMOTEIO)
 			req.wValue = cpu_to_le16 ((USB_DT_CONFIG << 8) | 0);
 			len = 1024;
+			expected = -EREMOTEIO;
 			break;
 		// NOTE: two consecutive _different_ faults in the queue.
 		case 11:	// get endpoint descriptor (ALWAYS STALLS)
 			req.wValue = cpu_to_le16 (USB_DT_ENDPOINT << 8);
 			// endpoint == 0
 			len = sizeof (struct usb_interface_descriptor);
+			expected = -EPIPE;
 			break;
 		// NOTE: sometimes even a third fault in the queue!
 		case 12:	// get string 0 descriptor (MAY STALL)
 			req.wValue = cpu_to_le16 (USB_DT_STRING << 8);
 			// string == 0, for language IDs
 			len = sizeof (struct usb_interface_descriptor);
+			expected = EREMOTEIO;	// or EPIPE, if no strings
 			break;
 		default:
 			err ("bogus number of ctrl queue testcases!");
@@ -793,12 +805,14 @@
 		if (!u)
 			goto cleanup;
 
-		reqp = usb_buffer_alloc (udev, sizeof req, SLAB_KERNEL,
+		reqp = usb_buffer_alloc (udev, sizeof *reqp, SLAB_KERNEL,
 				&u->setup_dma);
 		if (!reqp)
 			goto cleanup;
-		*reqp = req;
-		u->setup_packet = (char *) reqp;
+		reqp->setup = req;
+		reqp->number = i % NUM_SUBCASES;
+		reqp->expected = expected;
+		u->setup_packet = (char *) &reqp->setup;
 
 		u->context = &context;
 		u->complete = ctrl_complete;
@@ -839,6 +853,7 @@
 	kfree (urb);
 	return context.status;
 }
+#undef NUM_SUBCASES
 
 
 /*-------------------------------------------------------------------------*/
@@ -886,7 +901,16 @@
 	 * hcd states and code paths, even with little other system load.
 	 */
 	wait_ms (jiffies % (2 * INTERRUPT_RATE));
+retry:
 	retval = usb_unlink_urb (urb);
+	if (retval == -EBUSY) {
+		/* we can't unlink urbs while they're completing.
+		 * "normal" drivers would prevent resubmission, but
+		 * since we're testing unlink paths, we can't.
+		 */
+		dbg ("unlink retry");
+		goto retry;
+	}
 	if (!(retval == 0 || retval == -EINPROGRESS)) {
 		dbg ("submit/unlink fail %d", retval);
 		return retval;
@@ -1309,7 +1333,13 @@
 	.alt		= 1,
 };
 
-/* ezusb family device with dedicated usb test firmware*/
+/* ezusb family device with dedicated usb test firmware,
+ * or a peripheral running Linux and 'zero.c' test firmware.
+ *
+ * FIXME usbtest should read the descriptors, since compatible
+ * test firmware might run on hardware (pxa250 for one) that
+ * can't configure an ep2in-bulk.
+ */
 static struct usbtest_info fw_info = {
 	.name		= "usb test device",
 	.ep_in		= 2,
diff -urN linux-2.5.63-bk4/drivers/usb/serial/Kconfig linux-2.5.63-bk5/drivers/usb/serial/Kconfig
--- linux-2.5.63-bk4/drivers/usb/serial/Kconfig	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/Kconfig	Mon Mar 31 12:18:55 2003
@@ -246,6 +246,12 @@
 	  The module will be called keyspan. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
+config USB_SERIAL_KEYSPAN_MPR
+	bool "USB Keyspan MPR Firmware"
+	depends on USB_SERIAL_KEYSPAN
+	help
+	  Say Y here to include firmware for the Keyspan MPR converter.
+
 config USB_SERIAL_KEYSPAN_USA28
 	bool "USB Keyspan USA-28 Firmware"
 	depends on USB_SERIAL_KEYSPAN
@@ -312,6 +318,12 @@
 	help
 	  Say Y here to include firmware for the USA-49W converter.
 
+config USB_SERIAL_KEYSPAN_USA49WLC
+	bool "USB Keyspan USA-49WLC Firmware"
+	depends on USB_SERIAL_KEYSPAN
+	help
+	  Say Y here to include firmware for the USA-49WLC converter.
+
 config USB_SERIAL_KLSI
 	tristate "USB KL5KUSB105 (Palmconnect) Driver (EXPERIMENTAL)"
 	depends on USB_SERIAL && EXPERIMENTAL
diff -urN linux-2.5.63-bk4/drivers/usb/serial/belkin_sa.c linux-2.5.63-bk5/drivers/usb/serial/belkin_sa.c
--- linux-2.5.63-bk4/drivers/usb/serial/belkin_sa.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/belkin_sa.c	Mon Mar 31 12:18:55 2003
@@ -144,6 +144,7 @@
 
 
 struct belkin_sa_private {
+	spinlock_t		lock;
 	unsigned long		control_state;
 	unsigned char		last_lsr;
 	unsigned char		last_msr;
@@ -175,6 +176,7 @@
 	if (!priv)
 		return (-1); /* error */
 	/* set initial values for control structures */
+	spin_lock_init(&priv->lock);
 	priv->control_state = 0;
 	priv->last_lsr = 0;
 	priv->last_msr = 0;
@@ -262,6 +264,7 @@
 	struct usb_serial *serial;
 	unsigned char *data = urb->transfer_buffer;
 	int retval;
+	unsigned long flags;
 
 	switch (urb->status) {
 	case 0:
@@ -289,6 +292,7 @@
 	/* ignore data[0] and data[1] */
 
 	priv = usb_get_serial_port_data(port);
+	spin_lock_irqsave(&priv->lock, flags);
 	priv->last_msr = data[BELKIN_SA_MSR_INDEX];
 	
 	/* Record Control Line states */
@@ -336,6 +340,7 @@
 		}
 	}
 #endif
+	spin_unlock_irqrestore(&priv->lock, flags);
 exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
@@ -352,6 +357,9 @@
 	unsigned int old_iflag = 0;
 	unsigned int old_cflag = 0;
 	__u16 urb_value = 0; /* Will hold the new flags */
+	unsigned long flags;
+	unsigned long control_state;
+	int bad_flow_control;
 	
 	if ((!port->tty) || (!port->tty->termios)) {
 		dbg ("%s - no tty or termios structure", __FUNCTION__);
@@ -361,6 +369,12 @@
 	iflag = port->tty->termios->c_iflag;
 	cflag = port->tty->termios->c_cflag;
 
+	/* get a local copy of the current port settings */
+	spin_lock_irqsave(&priv->lock, flags);
+	control_state = priv->control_state;
+	bad_flow_control = priv->bad_flow_control;
+	spin_unlock_irqrestore(&priv->lock, flags);
+	
 	/* check that they really want us to change something */
 	if (old_termios) {
 		if ((cflag == old_termios->c_cflag) &&
@@ -376,7 +390,7 @@
 	if( (cflag&CBAUD) != (old_cflag&CBAUD) ) {
 		/* reassert DTR and (maybe) RTS on transition from B0 */
 		if( (old_cflag&CBAUD) == B0 ) {
-			priv->control_state |= (TIOCM_DTR|TIOCM_RTS);
+			control_state |= (TIOCM_DTR|TIOCM_RTS);
 			if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
 				err("Set DTR error");
 			/* don't set RTS if using hardware flow control */
@@ -410,7 +424,7 @@
 				err("Disable flowcontrol error");
 
 			/* Drop RTS and DTR */
-			priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
+			control_state &= ~(TIOCM_DTR | TIOCM_RTS);
 			if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
 				err("DTR LOW error");
 			if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
@@ -465,12 +479,17 @@
 		else
 			urb_value &= ~(BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS);
 
-		if (priv->bad_flow_control)
+		if (bad_flow_control)
 			urb_value &= ~(BELKIN_SA_FLOW_IRTS);
 
 		if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0)
 			err("Set flow control error");
 	}
+
+	/* save off the modified port settings */
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->control_state = control_state;
+	spin_unlock_irqrestore(&priv->lock, flags);
 } /* belkin_sa_set_termios */
 
 
@@ -488,12 +507,19 @@
 	struct usb_serial *serial = port->serial;
 	__u16 urb_value; /* Will hold the new flags */
 	struct belkin_sa_private *priv = usb_get_serial_port_data(port);
-	int  ret, mask;
+	int ret = 0;
+	int mask;
+	unsigned long control_state;
+	unsigned long flags;
 	
+	spin_lock_irqsave(&priv->lock, flags);
+	control_state = priv->control_state;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	/* Based on code from acm.c and others */
 	switch (cmd) {
 	case TIOCMGET:
-		return put_user(priv->control_state, (unsigned long *) arg);
+		return put_user(control_state, (unsigned long *) arg);
 		break;
 
 	case TIOCMSET: /* Turns on and off the lines as specified by the mask */
@@ -506,13 +532,13 @@
 			/* RTS needs set */
 			urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_RTS)) || (cmd == TIOCMBIS) ? 1 : 0;
 			if (urb_value)
-				priv->control_state |= TIOCM_RTS;
+				control_state |= TIOCM_RTS;
 			else
-				priv->control_state &= ~TIOCM_RTS;
+				control_state &= ~TIOCM_RTS;
 
 			if ((ret = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, urb_value)) < 0) {
 				err("Set RTS error %d", ret);
-				return(ret);
+				goto cmerror;
 			}
 		}
 
@@ -520,14 +546,19 @@
 			/* DTR needs set */
 			urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_DTR)) || (cmd == TIOCMBIS) ? 1 : 0;
 			if (urb_value)
-				priv->control_state |= TIOCM_DTR;
+				control_state |= TIOCM_DTR;
 			else
-				priv->control_state &= ~TIOCM_DTR;
+				control_state &= ~TIOCM_DTR;
 			if ((ret = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, urb_value)) < 0) {
 				err("Set DTR error %d", ret);
-				return(ret);
+				goto cmerror;
 			}
 		}
+cmerror:
+		spin_lock_irqsave(&priv->lock, flags);
+		priv->control_state = control_state;
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return ret;
 		break;
 					
 	case TIOCMIWAIT:
diff -urN linux-2.5.63-bk4/drivers/usb/serial/ipaq.c linux-2.5.63-bk5/drivers/usb/serial/ipaq.c
--- linux-2.5.63-bk4/drivers/usb/serial/ipaq.c	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/ipaq.c	Mon Mar 31 12:18:55 2003
@@ -107,6 +107,7 @@
 	{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) },
 	{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_0032_ID) },
 	{ USB_DEVICE(DELL_VENDOR_ID, DELL_AXIM_ID) },
+	{ USB_DEVICE(FSC_VENDOR_ID, FSC_LOOX_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_2016_ID) },
diff -urN linux-2.5.63-bk4/drivers/usb/serial/ipaq.h linux-2.5.63-bk5/drivers/usb/serial/ipaq.h
--- linux-2.5.63-bk4/drivers/usb/serial/ipaq.h	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/ipaq.h	Mon Mar 31 12:18:55 2003
@@ -33,6 +33,9 @@
 #define DELL_VENDOR_ID		0x413c
 #define DELL_AXIM_ID		0x4001
 
+#define FSC_VENDOR_ID		0x0bf8
+#define FSC_LOOX_ID		0x1001
+
 #define HP_VENDOR_ID		0x03f0
 #define HP_JORNADA_548_ID	0x1016
 #define HP_JORNADA_568_ID	0x1116
diff -urN linux-2.5.63-bk4/drivers/usb/serial/keyspan.c linux-2.5.63-bk5/drivers/usb/serial/keyspan.c
--- linux-2.5.63-bk4/drivers/usb/serial/keyspan.c	Mon Feb 24 11:05:08 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/keyspan.c	Mon Mar 31 12:18:55 2003
@@ -28,6 +28,24 @@
 
   Change History
 
+    Wed Feb 19 22:00:00 PST 2003 (Jeffrey S. Laing <keyspan@jsl.com>)
+      Merged the current (1/31/03) Keyspan code with the current (2.4.21-pre4)
+      Linux source tree.  The Linux tree lacked support for the 49WLC and
+      others.  The Keyspan patches didn't work with the current kernel.
+
+    2003jan30	LPM	add support for the 49WLC and MPR
+
+    Wed Apr 25 12:00:00 PST 2002 (Keyspan)
+      Started with Hugh Blemings' code dated Jan 17, 2002.  All adapters
+      now supported (including QI and QW).  Modified port open, port
+      close, and send setup() logic to fix various data and endpoint
+      synchronization bugs and device LED status bugs.  Changed keyspan_
+      write_room() to accurately return transmit buffer availability.
+      Changed forwardingLength from 1 to 16 for all adapters.
+
+    Fri Oct 12 16:45:00 EST 2001
+      Preliminary USA-19QI and USA-28 support (both test OK for me, YMMV)
+
     Wed Apr 25 12:00:00 PST 2002 (Keyspan)
       Started with Hugh Blemings' code dated Jan 17, 2002.  All adapters
       now supported (including QI and QW).  Modified port open, port
@@ -103,7 +121,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.1.3"
+#define DRIVER_VERSION "v1.1.4"
 #define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
 #define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
 
@@ -900,6 +918,9 @@
 		/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
 	}
 
+	// if the device is a USA49x, determine whether it is an W or WLC model
+	// and set the baud clock accordingly
+
 	keyspan_send_setup(port, 1);
 	//mdelay(100);
 	keyspan_set_termios(port, NULL);
@@ -1008,6 +1029,11 @@
 		fw_name = "USA19QI";
 		break;
 			     
+	case keyspan_mpr_pre_product_id:
+		record = &keyspan_mpr_firmware[0];
+		fw_name = "MPR";
+		break;
+
 	case keyspan_usa19qw_pre_product_id:
 		record = &keyspan_usa19qw_firmware[0];
 		fw_name = "USA19QI";
@@ -1028,6 +1054,11 @@
 		fw_name = "USA49W";
 		break;
 
+	case keyspan_usa49wlc_pre_product_id:
+		record = &keyspan_usa49wlc_firmware[0];
+		fw_name = "USA49WLC";
+		break;
+
 	default:
 		record = NULL;
 		fw_name = "Unknown";
diff -urN linux-2.5.63-bk4/drivers/usb/serial/keyspan.h linux-2.5.63-bk5/drivers/usb/serial/keyspan.h
--- linux-2.5.63-bk4/drivers/usb/serial/keyspan.h	Mon Feb 24 11:05:37 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/keyspan.h	Mon Mar 31 12:18:55 2003
@@ -136,6 +136,12 @@
 	static const struct ezusb_hex_record *keyspan_usa19qi_firmware = NULL;
 #endif
 
+#ifdef CONFIG_USB_SERIAL_KEYSPAN_MPR
+        #include "keyspan_mpr_fw.h"
+#else
+	static const struct ezusb_hex_record *keyspan_mpr_firmware = NULL;
+#endif
+
 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19QW
 	#include "keyspan_usa19qw_fw.h"
 #else
@@ -160,6 +166,12 @@
 	static const struct ezusb_hex_record *keyspan_usa49w_firmware = NULL;
 #endif
 
+#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA49WLC
+        #include "keyspan_usa49wlc_fw.h"
+#else
+	static const struct ezusb_hex_record *keyspan_usa49wlc_firmware = NULL;
+#endif
+
 /* Values used for baud rate calculation - device specific */
 #define	KEYSPAN_INVALID_BAUD_RATE		(-1)
 #define	KEYSPAN_BAUD_RATE_OK			(0)
@@ -182,6 +194,7 @@
 #define	keyspan_usa18x_pre_product_id		0x0105
 #define	keyspan_usa19_pre_product_id		0x0103
 #define	keyspan_usa19qi_pre_product_id		0x010b
+#define	keyspan_mpr_pre_product_id		0x011b
 #define	keyspan_usa19qw_pre_product_id		0x0118
 #define	keyspan_usa19w_pre_product_id		0x0106
 #define	keyspan_usa28_pre_product_id		0x0101
@@ -189,6 +202,7 @@
 #define	keyspan_usa28xa_pre_product_id		0x0114
 #define	keyspan_usa28xb_pre_product_id		0x0113
 #define	keyspan_usa49w_pre_product_id		0x0109
+#define	keyspan_usa49wlc_pre_product_id		0x011a
 
 /* Product IDs post-renumeration.  Note that the 28x and 28xb
    have the same id's post-renumeration but behave identically
@@ -196,6 +210,7 @@
 #define	keyspan_usa18x_product_id		0x0112
 #define	keyspan_usa19_product_id		0x0107
 #define	keyspan_usa19qi_product_id		0x010c
+#define	keyspan_mpr_product_id			0x011c
 #define	keyspan_usa19qw_product_id		0x0119
 #define	keyspan_usa19w_product_id		0x0108
 #define	keyspan_usa28_product_id		0x010f
@@ -203,6 +218,7 @@
 #define	keyspan_usa28xa_product_id		0x0115
 #define	keyspan_usa28xb_product_id		0x0110
 #define	keyspan_usa49w_product_id		0x010a
+#define	keyspan_usa49wlc_product_id		0x012a
 
 
 struct keyspan_device_details {
@@ -394,6 +410,22 @@
 	.baudclk		= KEYSPAN_USA49W_BAUDCLK,
 };
 
+static const struct keyspan_device_details usa49wlc_device_details = {
+	product_id:		keyspan_usa49wlc_product_id,
+	msg_format:		msg_usa49,
+	num_ports:		4,
+	indat_endp_flip:	0,
+	outdat_endp_flip:	0,
+	indat_endpoints:	{0x81, 0x82, 0x83, 0x84},
+	outdat_endpoints:	{0x01, 0x02, 0x03, 0x04},
+	inack_endpoints:	{-1, -1, -1, -1},
+	outcont_endpoints:	{-1, -1, -1, -1},
+	instat_endpoint:	0x87,
+	glocont_endpoint:	0x07,
+	calculate_baud_rate:	keyspan_usa19w_calc_baud,
+	baudclk:		KEYSPAN_USA19W_BAUDCLK,
+};
+
 static const struct keyspan_device_details *keyspan_devices[] = {
 	&usa18x_device_details,
 	&usa19_device_details,
@@ -405,6 +437,7 @@
 	&usa28xa_device_details,
 	/* 28xb not required as it renumerates as a 28x */
 	&usa49w_device_details,
+	&usa49wlc_device_details,
 	NULL,
 };
 
@@ -414,21 +447,25 @@
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_pre_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_pre_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)},
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
 	{ } /* Terminating entry */
 };
 
@@ -448,11 +485,13 @@
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_pre_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_pre_product_id) },
 	{ } /* Terminating entry */
 };
 
@@ -462,6 +501,7 @@
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_pre_product_id) },
 	{ } /* Terminating entry */
 };
 
@@ -469,11 +509,13 @@
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
 	{ } /* Terminating entry */
 };
 
 static struct usb_device_id keyspan_4port_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
 	{ } /* Terminating entry */
 };
 
diff -urN linux-2.5.63-bk4/drivers/usb/serial/keyspan_mpr_fw.h linux-2.5.63-bk5/drivers/usb/serial/keyspan_mpr_fw.h
--- linux-2.5.63-bk4/drivers/usb/serial/keyspan_mpr_fw.h	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk5/drivers/usb/serial/keyspan_mpr_fw.h	Mon Mar 31 12:18:55 2003
@@ -0,0 +1,286 @@
+/* keyspan_mpr_fw.h
+ 
+	The firmware contained herein as keyspan_mpr_fw.h is
+
+		Copyright (C) 1999-2001
+		Keyspan, A division of InnoSys Incorporated ("Keyspan")
+		
+	as an unpublished work. This notice does not imply unrestricted or
+	public access to the source code from which this firmware image is
+	derived.  Except as noted below this firmware image may not be 
+	reproduced, used, sold or transferred to any third party without 
+	Keyspan's prior written consent.  All Rights Reserved.
+
+	Permission is hereby granted for the distribution of this firmware 
+	image as part of a Linux or other Open Source operating system kernel 
+	in text or binary form as required. 
+
+	This firmware may not be modified and may only be used with  
+	Keyspan hardware.  Distribution and/or Modification of the 
+	keyspan.c driver which includes this firmware, in whole or in 
+	part, requires the inclusion of this statement."
+
+static char theFirmwareDate53[] =
+	"04/26/2002  02:47p              11,570 USA53";
+*/
+
+static const struct ezusb_hex_record keyspan_mpr_firmware[] = {
+ {0x0033,  3, { 0x02, 0x00, 0x1a}},
+ {0x001a,  4, { 0x53, 0xd8, 0xef, 0x32}},
+ {0x0003, 16, { 0x8e, 0x56, 0x8f, 0x57, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x60}},
+ {0x0013,  7, { 0x05, 0x12, 0x0f, 0xa2, 0x80, 0xee, 0x22}},
+ {0x0023,  3, { 0x02, 0x00, 0x46}},
+ {0x0046, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08}},
+ {0x0056, 16, { 0x30, 0x99, 0x0e, 0x30, 0x0b, 0x07, 0xa2, 0x0e, 0x92, 0x9b, 0x85, 0x36, 0x99, 0xc2, 0x99, 0xd2}},
+ {0x0066, 16, { 0x12, 0x20, 0x12, 0x03, 0x02, 0x02, 0xf9, 0xc2, 0x12, 0x30, 0x03, 0x19, 0x7e, 0x7e, 0x7f, 0x40}},
+ {0x0076, 16, { 0x75, 0x1a, 0x7e, 0x75, 0x1b, 0x40, 0x75, 0x17, 0x00, 0x7e, 0x7d, 0x7f, 0xc0, 0x75, 0x18, 0x7d}},
+ {0x0086, 16, { 0x75, 0x19, 0xc0, 0x80, 0x17, 0x7e, 0x7d, 0x7f, 0xc0, 0x75, 0x1a, 0x7d, 0x75, 0x1b, 0xc0, 0x75}},
+ {0x0096, 16, { 0x17, 0x01, 0x7e, 0x7e, 0x7f, 0x40, 0x75, 0x18, 0x7e, 0x75, 0x19, 0x40, 0x20, 0x0b, 0x03, 0x02}},
+ {0x00a6, 16, { 0x01, 0x84, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x3c, 0x20, 0x0c, 0x34, 0x20, 0x09, 0x31, 0x90}},
+ {0x00b6, 16, { 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x29, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b}},
+ {0x00c6, 16, { 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a}},
+ {0x00d6, 16, { 0xe5, 0x1b, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0x02, 0x02, 0xf7}},
+ {0x00e6, 16, { 0xc2, 0x0b, 0x02, 0x02, 0xf7, 0x30, 0x03, 0x11, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xa3, 0xe0, 0x54}},
+ {0x00f6, 16, { 0x02, 0xf5, 0x1d, 0xa3, 0xe0, 0xf5, 0x1c, 0x80, 0x11, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0x90, 0x7f}},
+ {0x0043,  3, { 0x02, 0x0f, 0x00}},
+ {0x0000,  3, { 0x02, 0x00, 0x26}},
+ {0x0026, 12, { 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5a, 0x02, 0x0a, 0x33}},
+ {0x0106, 64, { 0xc6, 0xe0, 0x54, 0x02, 0xf5, 0x1d, 0xa3, 0xe0, 0xf5, 0x1c, 0xe5, 0x17, 0x24, 0xff, 0x92, 0x03, 0x30,
+  0x0d, 0x0d, 0xc2, 0x0d, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0xc2, 0x0b, 0x02, 0x02, 0xf7, 0xe5,
+  0x1d, 0x60, 0x05, 0xc2, 0x0b, 0x02, 0x02, 0xf7, 0x85, 0x1c, 0x53, 0x85, 0x19, 0x82, 0x85, 0x18,
+  0x83, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x12, 0xff, 0x20, 0x0c, 0x3a, 0x20, 0x09, 0x37, 0x90}},
+ {0x0146, 64, { 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x70, 0x2f, 0x30, 0x10, 0x1c, 0x85, 0x19, 0x82, 0x85, 0x18, 0x83, 0xa3,
+  0xe0, 0x13, 0x92, 0x0e, 0x85, 0x19, 0x82, 0x85, 0x18, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x36, 0x75,
+  0x3a, 0x03, 0x02, 0x02, 0xf7, 0x75, 0x3a, 0x02, 0x85, 0x19, 0x82, 0x85, 0x18, 0x83, 0xa3, 0xe0,
+  0xf5, 0x36, 0x02, 0x02, 0xf7, 0x75, 0x3a, 0x01, 0xc2, 0x0b, 0x02, 0x02, 0xf7, 0x30, 0x03}},
+ {0x0186, 64, { 0x0e, 0x90, 0x7f, 0xc6, 0xe0, 0x54, 0x02, 0xf5, 0x1d, 0xa3, 0xe0, 0xf5, 0x1c, 0x80, 0x0c, 0x90, 0x7f,
+  0xc8, 0xe0, 0x54, 0x02, 0xf5, 0x1d, 0xa3, 0xe0, 0xf5, 0x1c, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50,
+  0x03, 0x02, 0x02, 0x68, 0xe5, 0x1d, 0x60, 0x07, 0xc2, 0x14, 0xc2, 0x05, 0x02, 0x02, 0xf7, 0x85,
+  0x1c, 0x53, 0x85, 0x1b, 0x82, 0x85, 0x1a, 0x83, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x12, 0xff}},
+ {0x01c6, 64, { 0x30, 0x0c, 0x03, 0x02, 0x02, 0x60, 0x30, 0x09, 0x03, 0x02, 0x02, 0x60, 0x90, 0x7f, 0x9b, 0xe0, 0x55,
+  0x38, 0x60, 0x03, 0x02, 0x02, 0x60, 0x30, 0x10, 0x1b, 0x85, 0x1b, 0x82, 0x85, 0x1a, 0x83, 0xa3,
+  0xe0, 0x13, 0x92, 0x9b, 0x85, 0x1b, 0x82, 0x85, 0x1a, 0x83, 0xa3, 0xa3, 0xe0, 0xf5, 0x99, 0x75,
+  0x3a, 0x03, 0x80, 0x0d, 0x85, 0x1b, 0x82, 0x85, 0x1a, 0x83, 0xa3, 0xe0, 0xf5, 0x99, 0x75}},
+ {0x0206, 64, { 0x3a, 0x02, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x40, 0x26, 0x30, 0x03, 0x07, 0x90, 0x7f, 0xc7, 0xe4, 0xf0,
+  0x80, 0x05, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xe5, 0x17, 0x24, 0xff, 0x92, 0x03, 0x20, 0x0d, 0x03,
+  0x02, 0x02, 0xf7, 0xc2, 0x0d, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0x02, 0x02, 0xf7, 0x30, 0x10,
+  0x12, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83}},
+ {0x0246, 64, { 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5,
+  0x83, 0xe0, 0xf5, 0x36, 0xd2, 0x0b, 0x02, 0x02, 0xf7, 0x75, 0x3a, 0x01, 0xc2, 0x14, 0x02, 0x02,
+  0xf7, 0x30, 0x0c, 0x03, 0x02, 0x02, 0xf5, 0x30, 0x09, 0x03, 0x02, 0x02, 0xf5, 0x90, 0x7f, 0x9b,
+  0xe0, 0x55, 0x38, 0x70, 0x79, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f}},
+ {0x0286, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b,
+  0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0xf5, 0x99, 0xe5, 0x3a, 0xc3, 0x95, 0x53,
+  0x40, 0x22, 0x30, 0x03, 0x07, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xc9, 0xe4,
+  0xf0, 0xe5, 0x17, 0x24, 0xff, 0x92, 0x03, 0x30, 0x0d, 0x36, 0xc2, 0x0d, 0x90, 0x7f, 0xbb}},
+ {0x02c6, 64, { 0x74, 0x01, 0xf0, 0x80, 0x2c, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f, 0xf5, 0x82,
+  0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x1b, 0x2f,
+  0xf5, 0x82, 0xe4, 0x35, 0x1a, 0xf5, 0x83, 0xe0, 0xf5, 0x36, 0xd2, 0x0b, 0x80, 0x02, 0xc2, 0x14,
+  0xd2, 0x01, 0x20, 0x98, 0x03, 0x02, 0x04, 0x35, 0xc2, 0x98, 0x20, 0x02, 0x03, 0x02, 0x03}},
+ {0x0306, 64, { 0xa2, 0x20, 0x15, 0x27, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5,
+  0x83, 0xe5, 0x99, 0xf0, 0x30, 0x10, 0x4d, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82,
+  0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, 0x99, 0x55, 0xe5, 0x55, 0xb5,
+  0x47, 0x04, 0xd2, 0x09, 0x80, 0x2e, 0xe5, 0x55, 0xb5, 0x46, 0x04, 0xc2, 0x09, 0x80, 0x25}},
+ {0x0346, 64, { 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x55, 0xf0,
+  0x30, 0x10, 0x11, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5,
+  0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0f, 0xe5, 0x39, 0xc3, 0x95, 0x43, 0x50, 0x03, 0x02, 0x04, 0x33,
+  0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x16, 0xe5, 0x39, 0xc3, 0x94, 0x40, 0x50, 0x03, 0x02}},
+ {0x0386, 64, { 0x04, 0x33, 0x15, 0x39, 0x15, 0x39, 0x05, 0x2b, 0x43, 0x34, 0x01, 0x02, 0x04, 0x33, 0x90, 0x7f, 0xb7,
+  0xe5, 0x39, 0xf0, 0x75, 0x39, 0x00, 0xc2, 0x02, 0x02, 0x04, 0x33, 0x20, 0x15, 0x27, 0xaf, 0x39,
+  0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30,
+  0x10, 0x4d, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5}},
+ {0x03c6, 64, { 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, 0x99, 0x55, 0xe5, 0x55, 0xb5, 0x47, 0x04, 0xd2, 0x09, 0x80,
+  0x2e, 0xe5, 0x55, 0xb5, 0x46, 0x04, 0xc2, 0x09, 0x80, 0x25, 0xaf, 0x39, 0x05, 0x39, 0x74, 0x00,
+  0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x55, 0xf0, 0x30, 0x10, 0x11, 0xaf, 0x39,
+  0x05, 0x39, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0}},
+ {0x0406, 64, { 0xd2, 0x0f, 0xe5, 0x39, 0xc3, 0x95, 0x43, 0x40, 0x24, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x12, 0xe5,
+  0x39, 0xc3, 0x94, 0x40, 0x40, 0x16, 0x15, 0x39, 0x15, 0x39, 0x05, 0x2b, 0x43, 0x34, 0x01, 0x80,
+  0x0b, 0x90, 0x7f, 0xb9, 0xe5, 0x39, 0xf0, 0x75, 0x39, 0x00, 0xd2, 0x02, 0xd2, 0x01, 0x30, 0x01,
+  0x05, 0xc2, 0x01, 0x02, 0x00, 0x56, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x82, 0xd0, 0x83, 0xd0}},
+ {0x0446, 64, { 0xe0, 0x32, 0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x54, 0xe5, 0x34, 0x60, 0x50, 0xe5, 0x31, 0x70, 0x4c,
+  0xe5, 0x34, 0x30, 0xe1, 0x0b, 0xe4, 0xf5, 0x2f, 0x75, 0x34, 0x01, 0x75, 0x31, 0x02, 0x80, 0x0e,
+  0xa2, 0x08, 0xe4, 0x33, 0xf5, 0x2f, 0xc2, 0x08, 0xe4, 0xf5, 0x34, 0x75, 0x31, 0x10, 0xe4, 0xf5,
+  0x56, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x56, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12}},
+ {0x0486, 64, { 0x0c, 0x79, 0xff, 0x74, 0x00, 0x25, 0x56, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x05,
+  0x56, 0xe5, 0x56, 0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xbd, 0x74, 0x0c, 0xf0, 0x90, 0x7f, 0xca, 0xe0,
+  0x30, 0xe1, 0x03, 0x02, 0x05, 0xd1, 0xe4, 0xf5, 0x56, 0x74, 0x40, 0x25, 0x56, 0xf5, 0x82, 0xe4,
+  0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x56, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x3b, 0xf9}},
+ {0x04c6, 64, { 0xec, 0x34, 0x00, 0xfa, 0xef, 0x12, 0x0c, 0x92, 0x05, 0x56, 0xe5, 0x56, 0xb4, 0x18, 0xdb, 0xe5, 0x3b,
+  0x60, 0x11, 0x75, 0xc9, 0x20, 0x75, 0xc8, 0x36, 0x85, 0x3c, 0xca, 0x85, 0x3d, 0xcb, 0xe4, 0x90,
+  0x7f, 0x9f, 0xf0, 0xe5, 0x3e, 0x13, 0x92, 0x10, 0x92, 0x9f, 0x85, 0x3f, 0x38, 0xe5, 0x40, 0x13,
+  0x92, 0x15, 0xe5, 0x41, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x07}},
+ {0x0506, 64, { 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x42, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0x7f,
+  0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x48, 0x60, 0x0b, 0xc2, 0x0c,
+  0xc2, 0x09, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x49, 0x60, 0x0c, 0xd2, 0x09, 0x43,
+  0x34, 0x01, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x4a, 0x60, 0x0d, 0xc2, 0xaf}},
+ {0x0546, 64, { 0xc2, 0x0b, 0xd2, 0x00, 0xe4, 0xf5, 0x53, 0xf5, 0x3a, 0xd2, 0xaf, 0xe5, 0x4b, 0x60, 0x05, 0x30, 0x15,
+  0x02, 0xd2, 0x09, 0xe5, 0x4c, 0x60, 0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f,
+  0x9e, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x4d, 0x60, 0x0a,
+  0xd2, 0x9c, 0xc2, 0x98, 0x75, 0x2c, 0x01, 0x75, 0x31, 0x1e, 0xe5, 0x4e, 0x60, 0x07, 0xc2}},
+ {0x0586, 64, { 0x9c, 0xe4, 0xf5, 0x39, 0xf5, 0x2c, 0xe5, 0x4f, 0x60, 0x03, 0xe4, 0xf5, 0x39, 0xe5, 0x50, 0x60, 0x02,
+  0xd2, 0x07, 0xe5, 0x51, 0x60, 0x0a, 0xe5, 0x4d, 0x70, 0x02, 0xf5, 0x31, 0xe5, 0x51, 0x42, 0x34,
+  0xe5, 0x52, 0x60, 0x1f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x12, 0xf0,
+  0x74, 0x32, 0xf0, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, 0xf0}},
+ {0x05c6, 64, { 0xd2, 0x03, 0xd2, 0x02, 0xd2, 0x08, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0xa2, 0x0c, 0xe4, 0x33, 0xff, 0x65,
+  0x29, 0x60, 0x05, 0x8f, 0x29, 0x43, 0x34, 0x01, 0xa2, 0x09, 0xe4, 0x33, 0xff, 0x65, 0x2a, 0x60,
+  0x05, 0x8f, 0x2a, 0x43, 0x34, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0xff, 0x54, 0x08, 0x64, 0x08, 0xf5,
+  0x57, 0x65, 0x25, 0x60, 0x06, 0x85, 0x57, 0x25, 0x43, 0x34, 0x01, 0xef, 0x54, 0x10, 0x64}},
+ {0x0606, 64, { 0x10, 0xf5, 0x57, 0x65, 0x26, 0x60, 0x06, 0x85, 0x57, 0x26, 0x43, 0x34, 0x01, 0xef, 0x54, 0x40, 0x64,
+  0x40, 0xf5, 0x57, 0x65, 0x27, 0x60, 0x06, 0x85, 0x57, 0x27, 0x43, 0x34, 0x01, 0xef, 0x54, 0x20,
+  0x64, 0x20, 0xf5, 0x57, 0x65, 0x28, 0x60, 0x06, 0x85, 0x57, 0x28, 0x43, 0x34, 0x01, 0x90, 0x7f,
+  0x9a, 0xe0, 0x54, 0x40, 0x64, 0x40, 0xf5, 0x57, 0x65, 0x2e, 0x60, 0x06, 0x85, 0x57, 0x2e}},
+ {0x0646, 64, { 0x43, 0x34, 0x01, 0x30, 0x07, 0x35, 0xc2, 0xaf, 0x30, 0x02, 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1,
+  0x27, 0xe5, 0x39, 0x60, 0x09, 0x90, 0x7f, 0xb7, 0xf0, 0xe4, 0xf5, 0x39, 0xc2, 0x02, 0xc2, 0x07,
+  0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x39, 0x60, 0x09, 0x90, 0x7f, 0xb9,
+  0xf0, 0xe4, 0xf5, 0x39, 0xd2, 0x02, 0xc2, 0x07, 0xd2, 0xaf, 0x20, 0x05, 0x3d, 0x30, 0x03}},
+ {0x0686, 64, { 0x1e, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x33, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x3a,
+  0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x53, 0xd2, 0x05, 0x75, 0x12, 0xff, 0x80, 0x1c, 0x90, 0x7f,
+  0xc8, 0xe0, 0x20, 0xe1, 0x15, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0d, 0x75, 0x3a, 0x01, 0x90,
+  0x7f, 0xc9, 0xe0, 0xf5, 0x53, 0xd2, 0x05, 0x75, 0x12, 0xff, 0x20, 0x14, 0x33, 0x20, 0x00}},
+ {0x06c6, 64, { 0x06, 0xe5, 0x3a, 0x65, 0x53, 0x70, 0x2a, 0x30, 0x05, 0x1a, 0x30, 0x03, 0x09, 0xe4, 0x90, 0x7f, 0xc7,
+  0xf0, 0xc2, 0x03, 0x80, 0x07, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0xc2, 0x05, 0xe4, 0xf5,
+  0x53, 0xf5, 0x3a, 0x30, 0x0d, 0x0a, 0xc2, 0x0d, 0xc2, 0x00, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0,
+  0x30, 0x14, 0x03, 0x02, 0x07, 0xbf, 0x20, 0x05, 0x03, 0x02, 0x07, 0xbf, 0x30, 0x0c, 0x03}},
+ {0x0706, 64, { 0x02, 0x07, 0xbf, 0x30, 0x09, 0x03, 0x02, 0x07, 0xbf, 0x90, 0x7f, 0x9b, 0xe0, 0x55, 0x38, 0x60, 0x03,
+  0x02, 0x07, 0xbf, 0x30, 0x03, 0x0c, 0x7e, 0x7e, 0x7f, 0x40, 0x75, 0x58, 0x7e, 0x75, 0x59, 0x40,
+  0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0xc0, 0x75, 0x58, 0x7d, 0x75, 0x59, 0xc0, 0x30, 0x10, 0x12, 0xaf,
+  0x3a, 0x05, 0x3a, 0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0x13}},
+ {0x0746, 64, { 0x92, 0x1a, 0xaf, 0x3a, 0x05, 0x3a, 0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0,
+  0xf5, 0x57, 0xe5, 0x3a, 0xc3, 0x95, 0x53, 0x50, 0x2a, 0x30, 0x10, 0x12, 0xaf, 0x3a, 0x05, 0x3a,
+  0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0e, 0xaf, 0x3a,
+  0x05, 0x3a, 0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 0xe0, 0xf5, 0x36}},
+ {0x0786, 64, { 0xd2, 0x0b, 0x80, 0x15, 0xc2, 0x0b, 0x30, 0x03, 0x09, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x03, 0x80,
+  0x07, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0x30, 0x10, 0x04, 0xa2, 0x1a, 0x92, 0x9b, 0xd2,
+  0x14, 0xc2, 0xaf, 0x85, 0x57, 0x99, 0x20, 0x0b, 0x0d, 0x30, 0x0d, 0x0a, 0xc2, 0x0d, 0xc2, 0x00,
+  0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0c}},
+ {0x07c6, 64, { 0xa4, 0x09, 0x1c, 0x00, 0x09, 0x89, 0x01, 0x09, 0xe6, 0x03, 0x07, 0xe3, 0x06, 0x09, 0x0d, 0x08, 0x09,
+  0x01, 0x09, 0x08, 0xe9, 0x0a, 0x08, 0xf8, 0x0b, 0x00, 0x00, 0x0a, 0x24, 0x90, 0x7f, 0xeb, 0xe0,
+  0x24, 0xfe, 0x60, 0x1c, 0x14, 0x70, 0x03, 0x02, 0x08, 0x79, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0a,
+  0x24, 0x74, 0x0d, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x87, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0a}},
+ {0x0806, 64, { 0x2b, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0xd8,
+  0x75, 0x83, 0x0d, 0xef, 0xf0, 0x75, 0x82, 0xd1, 0x75, 0x83, 0x0d, 0xf0, 0x75, 0x82, 0xca, 0x75,
+  0x83, 0x0d, 0xf0, 0x75, 0x82, 0xc3, 0x75, 0x83, 0x0d, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75,
+  0x82, 0x9e, 0x75, 0x83, 0x0d, 0xf0, 0x90, 0x7f, 0xef, 0xe0, 0xfe, 0x90, 0x7f, 0xee, 0xe0}},
+ {0x0846, 64, { 0x7c, 0x00, 0x24, 0x00, 0xf5, 0x5a, 0xec, 0x3e, 0xf5, 0x59, 0x75, 0x15, 0x0d, 0x75, 0x16, 0x99, 0x75,
+  0x82, 0x9b, 0x75, 0x83, 0x0d, 0xe0, 0x75, 0x13, 0x00, 0xf5, 0x14, 0xd3, 0xe5, 0x14, 0x95, 0x5a,
+  0xe5, 0x13, 0x95, 0x59, 0x40, 0x06, 0x85, 0x59, 0x13, 0x85, 0x5a, 0x14, 0x12, 0x0b, 0xba, 0x02,
+  0x0a, 0x2b, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x0b, 0x75, 0x56, 0xff, 0x75, 0x57, 0x0d, 0x75}},
+ {0x0886, 64, { 0x58, 0xdc, 0x80, 0x2d, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x0b, 0x75, 0x56, 0xff, 0x75, 0x57, 0x0d,
+  0x75, 0x58, 0xe0, 0x80, 0x1b, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x02, 0x0b, 0x75, 0x56, 0xff, 0x75,
+  0x57, 0x0d, 0x75, 0x58, 0xf0, 0x80, 0x09, 0x75, 0x56, 0xff, 0x75, 0x57, 0x0e, 0x75, 0x58, 0x1e,
+  0x90, 0x7f, 0xee, 0xe0, 0x75, 0x59, 0x00, 0xf5, 0x5a, 0xae, 0x57, 0xaf, 0x58, 0x8e, 0x15}},
+ {0x08c6, 64, { 0x8f, 0x16, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x13, 0xf5, 0x14, 0xd3, 0x95, 0x5a,
+  0xe5, 0x13, 0x95, 0x59, 0x40, 0x06, 0x85, 0x59, 0x13, 0x85, 0x5a, 0x14, 0x12, 0x0b, 0xba, 0x02,
+  0x0a, 0x2b, 0x90, 0x7f, 0x00, 0xe5, 0x11, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0a,
+  0x2b, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x11, 0x02, 0x0a, 0x2b, 0x12, 0x0c, 0x24, 0x90, 0x7f}},
+ {0x0906, 64, { 0xea, 0xe0, 0xf5, 0x10, 0x02, 0x0a, 0x2b, 0x90, 0x7f, 0x00, 0xe5, 0x10, 0xf0, 0x90, 0x7f, 0xb5, 0x74,
+  0x01, 0xf0, 0x02, 0x0a, 0x2b, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x27, 0x14, 0x60, 0x34,
+  0x24, 0x02, 0x60, 0x03, 0x02, 0x0a, 0x24, 0xa2, 0x16, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2,
+  0x18, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74}},
+ {0x0946, 64, { 0x02, 0xf0, 0x02, 0x0a, 0x2b, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02,
+  0xf0, 0x02, 0x0a, 0x2b, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff,
+  0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0,
+  0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0}},
+ {0x0986, 64, { 0x02, 0x0a, 0x2b, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x17, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0a,
+  0x2b, 0x90, 0x7f, 0xea, 0xe0, 0x64, 0x01, 0x60, 0x03, 0x02, 0x0a, 0x24, 0xc2, 0x16, 0x02, 0x0a,
+  0x2b, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x76, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4,
+  0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34}},
+ {0x09c6, 64, { 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f,
+  0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x45, 0x90,
+  0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x10, 0x24, 0x02, 0x70, 0x39, 0x90, 0x7f, 0xea, 0xe0, 0x64,
+  0x01, 0x70, 0x2a, 0xd2, 0x16, 0x80, 0x2d, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f}},
+ {0x0a06, 64, { 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24,
+  0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4,
+  0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xc2, 0x10, 0xe4, 0xf5,
+  0x10, 0xf5, 0x34, 0xc2, 0x09, 0xc2, 0x0c, 0xc2, 0x0b, 0xc2, 0x14, 0xc2, 0x0d, 0xc2, 0x15}},
+ {0x0a46, 64, { 0xc2, 0x11, 0xc2, 0x07, 0xc2, 0x12, 0xc2, 0x0f, 0xc2, 0x08, 0xf5, 0x35, 0xf5, 0x39, 0xf5, 0x53, 0xf5,
+  0x3a, 0xf5, 0x33, 0xf5, 0x30, 0xf5, 0x2f, 0xf5, 0x2e, 0xf5, 0x2d, 0xf5, 0x2c, 0xf5, 0x2b, 0xf5,
+  0x2a, 0xf5, 0x29, 0xf5, 0x28, 0xf5, 0x27, 0xf5, 0x26, 0xf5, 0x25, 0xf5, 0x24, 0xc2, 0x05, 0xc2,
+  0x17, 0xc2, 0x19, 0xc2, 0x16, 0xc2, 0x18, 0xc2, 0x04, 0xd2, 0x13, 0xc2, 0x06, 0xc2, 0x01}},
+ {0x0a86, 64, { 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01,
+  0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90,
+  0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae,
+  0xe0, 0x44, 0x0f, 0xf0, 0x90, 0x7f, 0xac, 0x74, 0x0e, 0xf0, 0xd2, 0xaf, 0xd2, 0xbc, 0xd2}},
+ {0x0ac6, 64, { 0x1a, 0x12, 0x0f, 0x7d, 0xc2, 0x17, 0x30, 0x04, 0x03, 0x12, 0x04, 0x48, 0x30, 0x04, 0x2a, 0x30, 0x06,
+  0x27, 0xc2, 0x06, 0xe5, 0x12, 0x60, 0x16, 0x15, 0x12, 0x90, 0x7f, 0xd8, 0xe0, 0x30, 0xe6, 0x04,
+  0x7f, 0x00, 0x80, 0x02, 0x7f, 0x20, 0x90, 0x7f, 0x96, 0xef, 0xf0, 0x80, 0x06, 0x90, 0x7f, 0x96,
+  0x74, 0x20, 0xf0, 0x12, 0x0b, 0x14, 0x80, 0xcd, 0x30, 0x17, 0x07, 0xc2, 0x17, 0x12, 0x07}},
+ {0x0b06, 64, { 0xc0, 0x80, 0xc3, 0x30, 0x19, 0xc0, 0xc2, 0x19, 0x12, 0x0e, 0xdc, 0x80, 0xb9, 0x22, 0xe5, 0x31, 0x60,
+  0x02, 0x15, 0x31, 0xe5, 0x39, 0x60, 0x55, 0x65, 0x35, 0x70, 0x4b, 0xe5, 0x33, 0xf4, 0x60, 0x02,
+  0x05, 0x33, 0xe5, 0x33, 0xc3, 0x95, 0x44, 0x40, 0x43, 0xc2, 0xaf, 0x30, 0x02, 0x1b, 0x90, 0x7f,
+  0xb8, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7f, 0xb7, 0xe5, 0x39, 0xf0, 0xc2, 0x02, 0xe4, 0xf5}},
+ {0x0b46, 64, { 0x39, 0xf5, 0x33, 0xf5, 0x35, 0x75, 0x12, 0xff, 0x80, 0x19, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x12,
+  0x90, 0x7f, 0xb9, 0xe5, 0x39, 0xf0, 0xd2, 0x02, 0xe4, 0xf5, 0x39, 0xf5, 0x33, 0xf5, 0x35, 0x75,
+  0x12, 0xff, 0xd2, 0xaf, 0x80, 0x06, 0x85, 0x39, 0x35, 0xe4, 0xf5, 0x33, 0xe5, 0x2c, 0x60, 0x30,
+  0x20, 0x0f, 0x07, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe0, 0x0f, 0xe5, 0x2d, 0x60, 0x06, 0xe4}},
+ {0x0b86, 64, { 0xf5, 0x2d, 0x43, 0x34, 0x01, 0xe4, 0xf5, 0x30, 0x80, 0x14, 0xe5, 0x30, 0xd3, 0x95, 0x45, 0x50, 0x0d,
+  0xe5, 0x30, 0xb5, 0x45, 0x06, 0x75, 0x2d, 0x01, 0x43, 0x34, 0x01, 0x05, 0x30, 0xc2, 0x0f, 0x22,
+  0x90, 0x7f, 0xd9, 0xe0, 0x30, 0xe2, 0x04, 0x7f, 0x00, 0x80, 0x02, 0x7f, 0x20, 0x90, 0x7f, 0x96,
+  0xef, 0xf0, 0x22, 0xe5, 0x14, 0x45, 0x13, 0x60, 0x57, 0xae, 0x13, 0xaf, 0x14, 0xd3, 0xef}},
+ {0x0bc6, 64, { 0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x04, 0x7e, 0x00, 0x7f, 0x40, 0xc3, 0xe5, 0x14, 0x9f, 0xf5, 0x14,
+  0xe5, 0x13, 0x9e, 0xf5, 0x13, 0xe4, 0xfd, 0xed, 0xc3, 0x9f, 0xe4, 0x9e, 0x50, 0x1f, 0x85, 0x16,
+  0x82, 0x85, 0x15, 0x83, 0xe0, 0xfc, 0x74, 0x00, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83,
+  0xec, 0xf0, 0x0d, 0x05, 0x16, 0xe5, 0x16, 0x70, 0x02, 0x05, 0x15, 0x80, 0xda, 0x90, 0x7f}},
+ {0x0c06, 64, { 0xa9, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xef, 0xf0, 0x22,
+  0x90, 0x7f, 0xac, 0xe0, 0x54, 0xfe, 0xf0, 0xe4, 0x90, 0x7f, 0xb5, 0xf0, 0x22, 0xe4, 0x90, 0x7f,
+  0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x20, 0xf0, 0x90, 0x7f,
+  0x94, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0x97, 0x74, 0x86}},
+ {0x0c46, 64, { 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x03, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x84, 0xf0, 0x90, 0x7f, 0x98, 0xf0,
+  0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x75, 0x98, 0x40,
+  0x43, 0xa8, 0x10, 0x90, 0x7f, 0xde, 0x74, 0x1f, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x0f, 0xf0, 0xd2,
+  0x04, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22}},
+ {0x0c86, 64, { 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82,
+  0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0,
+  0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74,
+  0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3}},
+ {0x0cc6, 64, { 0xa3, 0xa3, 0x80, 0xdf, 0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x93, 0xf0,
+  0x90, 0x7f, 0x9d, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x97, 0xe0, 0x44, 0x42, 0xf0, 0x90, 0x7f,
+  0x9c, 0x74, 0x10, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xbe, 0xf0, 0x30,
+  0x16, 0x04, 0x7f, 0x80, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x7f, 0x97, 0xef, 0xf0, 0xe4, 0x90}},
+ {0x0d06, 64, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0xf0, 0x90, 0x7f, 0x98, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0,
+  0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0,
+  0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0, 0x12, 0x0b, 0xba, 0xd0, 0xd0, 0xd0,
+  0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0}},
+ {0x0d46, 64, { 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4,
+  0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0,
+  0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0d86, 64, { 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0xff, 0xff, 0x40, 0xcd, 0x06, 0x1c, 0x01, 0x01, 0x00, 0x01, 0x02,
+  0x00, 0x02, 0x09, 0x02, 0x43, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x07,
+  0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00}},
+ {0x0dc6, 64, { 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05,
+  0x84, 0x02, 0x40, 0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79,
+  0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2e, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79,
+  0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x50, 0x00}},
+ {0x0e06, 64, { 0x53, 0x00, 0x48, 0x00, 0x31, 0x00, 0x31, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72,
+  0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x22, 0x03, 0x55, 0x00, 0x53, 0x00, 0x41, 0x00, 0x2d,
+  0x00, 0x35, 0x00, 0x33, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x32, 0x00, 0x61,
+  0x00, 0x70, 0x00, 0x72, 0x00, 0x32, 0x00, 0x36, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xc0, 0x83}},
+ {0x0e46, 64, { 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab,
+  0x74, 0x02, 0xf0, 0xd2, 0x06, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0,
+  0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86,
+  0x00, 0xd2, 0x17, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0}},
+ {0x0e86, 64, { 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0,
+  0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x19, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab,
+  0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32,
+  0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00}},
+ {0x0ec6, 64, { 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x02, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82,
+  0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x12, 0x0c, 0xca, 0x12, 0x0f, 0xb3, 0x90, 0x7f, 0xd6, 0xe0, 0x30,
+  0xe7, 0x12, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6,
+  0xe0, 0x54, 0xfe, 0xf0, 0x12, 0x0c, 0x24, 0x22, 0x00, 0x02, 0x0e, 0x69, 0x00, 0x02, 0x0e}},
+ {0x0f06, 64, { 0x42, 0x00, 0x02, 0x0d, 0x45, 0x00, 0x02, 0x0e, 0x90, 0x00, 0x02, 0x0f, 0x10, 0x00, 0x02, 0x0f, 0x14,
+  0x00, 0x02, 0x0d, 0x12, 0x00, 0x02, 0x0f, 0x1c, 0x00, 0x02, 0x0e, 0xb7, 0x00, 0x02, 0x0f, 0x24,
+  0x00, 0x02, 0x0f, 0x33, 0x00, 0x02, 0x0f, 0x2c, 0x00, 0x02, 0x0f, 0x58, 0xc0, 0xe0, 0xc0, 0x83,
+  0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53, 0x91, 0xef, 0x90}},
+ {0x0f46, 64, { 0x7f, 0xa9, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0,
+  0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00,
+  0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0,
+  0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44}},
+ {0x0f86, 61, { 0x08, 0xf0, 0x30, 0x1a, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, 0x03, 0x90,
+  0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90,
+  0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0,
+  0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22}},
+ {0xffff,	0,	{0x00}}
+};
+
diff -urN linux-2.5.63-bk4/drivers/usb/serial/keyspan_usa49wlc_fw.h linux-2.5.63-bk5/drivers/usb/serial/keyspan_usa49wlc_fw.h
--- linux-2.5.63-bk4/drivers/usb/serial/keyspan_usa49wlc_fw.h	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk5/drivers/usb/serial/keyspan_usa49wlc_fw.h	Mon Mar 31 12:18:55 2003
@@ -0,0 +1,476 @@
+/* keyspan_usa49w_fw.h
+
+	The firmware contained herein as keyspan_usa49w_fw.h is
+
+		Copyright (C) 1999-2003
+		Keyspan, A division of InnoSys Incorporated ("Keyspan")
+		
+	as an unpublished work. This notice does not imply unrestricted or
+	public access to the source code from which this firmware image is
+	derived.  Except as noted below this firmware image may not be 
+	reproduced, used, sold or transferred to any third party without 
+	Keyspan's prior written consent.  All Rights Reserved.
+
+	Permission is hereby granted for the distribution of this firmware 
+	image as part of a Linux or other Open Source operating system kernel 
+	in text or binary form as required. 
+
+	This firmware may not be modified and may only be used with  
+	Keyspan hardware.  Distribution and/or Modification of the 
+	keyspan.c driver which includes this firmware, in whole or in 
+	part, requires the inclusion of this statement."
+
+static char theFirmwareDate49[] =
+	"02/14/2002  02:37p              19,347 USA49";
+
+
+
+static char theFirmwareDate65[] =
+	"01/31/2003  09:34a              19,331 USA65";
+
+
+*/
+
+static const struct ezusb_hex_record keyspan_usa49wlc_firmware[] = {
+ {0x7f92,  1, { 0x01}},
+ {0x0033,  3, { 0x02, 0x18, 0xfb}},
+ {0x0036, 13, { 0xe5, 0x11, 0x04, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}},
+ {0x0046, 16, { 0xe4, 0xff, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xfe, 0xe5, 0x15}},
+ {0x0056, 16, { 0x24, 0x04, 0xfd, 0xe4, 0x35, 0x14, 0xfa, 0xa9, 0x05, 0x7b, 0x01, 0xef, 0x7c, 0x00, 0x29, 0xf9}},
+ {0x0066, 16, { 0xec, 0x3a, 0xfa, 0xee, 0x12, 0x11, 0xec, 0x0f, 0xbf, 0x22, 0xd7, 0xe5, 0x15, 0x24, 0x05, 0xf5}},
+ {0x0076, 16, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x01, 0x34, 0xe5, 0x15, 0x24, 0x09}},
+ {0x0086, 16, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x0a, 0xf5, 0x82}},
+ {0x0096, 16, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x18, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x16, 0x6b, 0xe5}},
+ {0x00a6, 16, { 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xcf, 0xf0, 0x80, 0x41}},
+ {0x00b6, 16, { 0xe5, 0x15, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x00, 0x03}},
+ {0x00c6, 16, { 0xe5, 0x15, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0xab}},
+ {0x00d6, 16, { 0x7f, 0x01, 0xe5, 0x15, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfd, 0x12}},
+ {0x00e6, 16, { 0x16, 0x6b, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x30}},
+ {0x00f6, 16, { 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0}},
+ {0x0003, 16, { 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74}},
+ {0x0013, 16, { 0xf0, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24}},
+ {0x0023, 16, { 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22}},
+ {0x0043,  3, { 0x02, 0x1b, 0x00}},
+ {0x0000,  3, { 0x02, 0x10, 0x90}},
+ {0x0106, 64, { 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf2, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24,
+  0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x32, 0xe5, 0x15, 0x24, 0x0c}},
+ {0x0146, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x3f, 0xff, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24,
+  0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24,
+  0x0d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x02, 0x4f, 0xe5}},
+ {0x0186, 64, { 0x15, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x32,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24,
+  0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfb, 0xf0, 0xe4, 0xff, 0xe5, 0x15,
+  0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x16, 0x6b, 0xe5}},
+ {0x01c6, 64, { 0x15, 0x24, 0x0e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x33,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24,
+  0x33, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x15, 0x24, 0x33,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x15, 0x24, 0x0f}},
+ {0x0206, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x2f, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x16, 0x0b, 0xe5, 0x15, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x16, 0x3b, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4}},
+ {0x0246, 64, { 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0xdb, 0xe5, 0x15, 0x24, 0x14, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x60, 0x44, 0xe5, 0x15, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0,
+  0x44, 0x01, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}},
+ {0x0286, 64, { 0x83, 0xe0, 0x54, 0xfe, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x12, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x44, 0xe5, 0x15, 0x24, 0x13, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14}},
+ {0x02c6, 64, { 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x16,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82}},
+ {0x0306, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x15, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x44, 0x40, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x54, 0xbf, 0xf0, 0xe5, 0x15, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}},
+ {0x0346, 64, { 0x83, 0xe0, 0xff, 0xe5, 0x15, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5,
+  0x15, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24,
+  0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x0f, 0xe5, 0x15,
+  0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x78}},
+ {0x0386, 64, { 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90,
+  0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60,
+  0x6b, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xbf, 0xf0,
+  0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14}},
+ {0x03c6, 64, { 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf1, 0xf0, 0x12, 0x00,
+  0x36, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x6b, 0xe5, 0x15,
+  0x24, 0x2c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x15, 0x24, 0x2b}},
+ {0x0406, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x1b,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x6b, 0xe5}},
+ {0x0446, 64, { 0x15, 0x24, 0x2b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x16, 0x42, 0x13,
+  0xe5, 0x15, 0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x70, 0x0e, 0xe5,
+  0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x2a, 0x90, 0x78, 0x41,
+  0x74, 0xf2, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}},
+ {0x0486, 64, { 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xef, 0x60, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x44, 0x40, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5}},
+ {0x04c6, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x1e,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x6b,
+  0xe5, 0x15, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5}},
+ {0x0506, 64, { 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x1f, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e,
+  0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x15,
+  0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xff, 0xf0, 0xfd, 0xe4,
+  0xff, 0x12, 0x16, 0x6b, 0xe5, 0x15, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83}},
+ {0x0546, 64, { 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x20, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60,
+  0x18, 0x90, 0x78, 0x41, 0x74, 0xf2, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x21, 0xf5, 0x82}},
+ {0x0586, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x60, 0x1f, 0xe5, 0x15, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74,
+  0x01, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0}},
+ {0x05c6, 64, { 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x23, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60,
+  0x03, 0x12, 0x18, 0x7a, 0xe5, 0x15, 0x24, 0x24, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0,
+  0x60, 0x23, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x08,
+  0xf0, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0xff, 0x42, 0x11, 0x90, 0x7f, 0x96, 0xe0, 0x4f, 0xf0}},
+ {0x0606, 64, { 0x90, 0x78, 0x41, 0xe0, 0x4f, 0xf0, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x60, 0x24, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54,
+  0xf7, 0xf0, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0xf4, 0xff, 0x52, 0x11, 0x90, 0x7f, 0x96, 0xe0, 0x5f,
+  0xf0, 0x90, 0x78, 0x41, 0xe0, 0x5f, 0xf0, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x11, 0xfe}},
+ {0x0646, 64, { 0x07, 0x99, 0x00, 0x08, 0x0d, 0x01, 0x08, 0x79, 0x03, 0x06, 0x62, 0x06, 0x07, 0x8a, 0x08, 0x07, 0x7e,
+  0x09, 0x07, 0x66, 0x0a, 0x07, 0x75, 0x0b, 0x00, 0x00, 0x08, 0xc8, 0x90, 0x7f, 0xeb, 0xe0, 0x24,
+  0xfe, 0x60, 0x1c, 0x14, 0x70, 0x03, 0x02, 0x07, 0x14, 0x24, 0x02, 0x60, 0x03, 0x02, 0x07, 0x5c,
+  0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x08, 0xcf}},
+ {0x0686, 64, { 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30,
+  0xe0, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0,
+  0x75, 0x82, 0x6d, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82,
+  0x5f, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea}},
+ {0x06c6, 64, { 0xe0, 0x30, 0xe1, 0x04, 0x7f, 0x64, 0x80, 0x02, 0x7f, 0x32, 0x75, 0x82, 0x1a, 0x75, 0x83, 0x19, 0xef,
+  0xf0, 0x90, 0x7f, 0xef, 0xe0, 0xfe, 0x90, 0x7f, 0xee, 0xe0, 0x7c, 0x00, 0x24, 0x00, 0xf5, 0x18,
+  0xec, 0x3e, 0xf5, 0x17, 0x75, 0x33, 0x19, 0x75, 0x34, 0x12, 0x75, 0x82, 0x14, 0x75, 0x83, 0x19,
+  0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, 0xd3, 0xe5, 0x28, 0x95, 0x18, 0xe5, 0x27, 0x95, 0x17}},
+ {0x0706, 64, { 0x40, 0x06, 0x85, 0x17, 0x27, 0x85, 0x18, 0x28, 0x12, 0x13, 0x0d, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xea,
+  0xe0, 0xff, 0x12, 0x14, 0x5f, 0xea, 0x49, 0x60, 0x32, 0x90, 0x7f, 0xee, 0xe0, 0x75, 0x17, 0x00,
+  0xf5, 0x18, 0xae, 0x02, 0xaf, 0x01, 0x8e, 0x33, 0x8f, 0x34, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe,
+  0xa3, 0xe0, 0x8e, 0x27, 0xf5, 0x28, 0xd3, 0x95, 0x18, 0xe5, 0x27, 0x95, 0x17, 0x40, 0x06}},
+ {0x0746, 64, { 0x85, 0x17, 0x27, 0x85, 0x18, 0x28, 0x12, 0x13, 0x0d, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xb4, 0xe0, 0x44,
+  0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90,
+  0x7f, 0x00, 0xe5, 0x25, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f,
+  0xea, 0xe0, 0xf5, 0x25, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x22, 0x12, 0x0a}},
+ {0x0786, 64, { 0xce, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0x00, 0xe5, 0x22, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02,
+  0x08, 0xcf, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70,
+  0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x06, 0xe4, 0x33, 0x4f, 0x90, 0x7f,
+  0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xcf, 0xe4}},
+ {0x07c6, 64, { 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f,
+  0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0,
+  0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0,
+  0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xb4}},
+ {0x0806, 64, { 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02,
+  0x60, 0x03, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02, 0x08,
+  0xcf, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xcf, 0x90, 0x7f, 0xea, 0xe0, 0x70,
+  0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54}},
+ {0x0846, 64, { 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f,
+  0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90,
+  0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0,
+  0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90}},
+ {0x0886, 64, { 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0,
+  0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff,
+  0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34,
+  0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0}},
+ {0x08c6, 64, { 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22,
+  0xe5, 0x12, 0x54, 0x0f, 0x70, 0x03, 0x02, 0x09, 0xc8, 0x12, 0x16, 0x9a, 0xef, 0x20, 0xe1, 0x75,
+  0x12, 0x16, 0xf8, 0xef, 0x14, 0xf5, 0x18, 0x12, 0x18, 0xc5, 0xef, 0x25, 0x18, 0xff, 0xe4, 0x33,
+  0xfe, 0xc3, 0xef, 0x94, 0x80, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x59, 0x85, 0x15, 0x82}},
+ {0x0906, 64, { 0x85, 0x14, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5,
+  0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f,
+  0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5,
+  0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe2, 0x12, 0xe5}},
+ {0x0946, 64, { 0x18, 0x60, 0x0e, 0xf5, 0x23, 0xef, 0x24, 0x01, 0xf5, 0x2d, 0xe4, 0x3e, 0xf5, 0x2c, 0x12, 0x14, 0xa0,
+  0xe4, 0xff, 0x12, 0x14, 0xd7, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x30, 0xe7, 0x5d, 0x12, 0x18, 0xc5, 0xe5, 0x15, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x48, 0xe5, 0x15, 0x24, 0x2f, 0xf5, 0x82}},
+ {0x0986, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x54, 0x7b, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x10, 0xe5, 0x15,
+  0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xf5, 0x24, 0x80, 0x03, 0x12}},
+ {0x09c6, 64, { 0x12, 0x9c, 0x12, 0x16, 0xc9, 0xef, 0x30, 0xe1, 0x03, 0x02, 0x0a, 0xcd, 0x12, 0x17, 0xc7, 0x8f, 0x18,
+  0x12, 0x18, 0xd3, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0,
+  0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0xc3,
+  0x9f, 0x50, 0x28, 0x12, 0x18, 0xa9, 0xef, 0x30, 0xe0, 0x21, 0xe5, 0x15, 0x24, 0x38, 0xf5}},
+ {0x0a06, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe7, 0x12, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x03, 0x02, 0x0a, 0xcd, 0xe5, 0x15, 0x24, 0x31, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x18, 0x70, 0x03, 0x02, 0x0a,
+  0xcd, 0xb4, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83}},
+ {0x0a46, 64, { 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff,
+  0x30, 0xe7, 0x29, 0xe5, 0x18, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x18, 0x20, 0x85, 0x18, 0x23,
+  0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0x8c, 0x2c, 0xf5, 0x2d,
+  0x12, 0x13, 0xcf, 0xe5, 0x18, 0x25, 0xe0, 0xff, 0x12, 0x15, 0x0d, 0x22, 0xe5, 0x18, 0xd3}},
+ {0x0a86, 64, { 0x94, 0x3f, 0x40, 0x03, 0x75, 0x18, 0x3f, 0x85, 0x18, 0x23, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0xe0, 0xfc,
+  0xa3, 0xe0, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3,
+  0xe0, 0xfe, 0xa3, 0xe0, 0x24, 0x01, 0xf5, 0x2d, 0xe4, 0x3e, 0xf5, 0x2c, 0x12, 0x14, 0x1d}},
+ {0x0ac6, 64, { 0xe5, 0x18, 0x04, 0xff, 0x12, 0x15, 0x0d, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74,
+  0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x78, 0x4a, 0x04, 0xf0,
+  0xf5, 0x8e, 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f,
+  0x98, 0x74, 0x2f, 0xf0, 0x90, 0x78, 0x43, 0x74, 0xf7, 0xf0, 0xe4, 0x90, 0x78, 0x41, 0xf0}},
+ {0x0b06, 64, { 0x90, 0x7f, 0xdf, 0x74, 0x9f, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0,
+  0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0,
+  0x75, 0x16, 0x01, 0x12, 0x0f, 0x28, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0,
+  0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82}},
+ {0x0b46, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0x7e, 0x7e, 0x7f, 0x40, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83,
+  0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7e, 0x7f, 0x80, 0x85, 0x15, 0x82, 0x85, 0x14,
+  0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14,
+  0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x0f}},
+ {0x0b86, 64, { 0x28, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0,
+  0x75, 0x16, 0x02, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01,
+  0xf0, 0x7e, 0x7d, 0x7f, 0xc0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74,
+  0xc0, 0xf0, 0x7e, 0x7e, 0x7f, 0x00, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74}},
+ {0x0bc6, 64, { 0x7e, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90,
+  0x7f, 0x98, 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04, 0x12, 0x0f, 0x28, 0x7e, 0x7c, 0x7f, 0x40, 0x75,
+  0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04, 0xe5, 0x15,
+  0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x02, 0xf0, 0x7e, 0x7d, 0x7f}},
+ {0x0c06, 64, { 0x40, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7d, 0x7f,
+  0x80, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x80, 0xf0,
+  0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0,
+  0x75, 0x16, 0x08, 0x12, 0x0f, 0x28, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15}},
+ {0x0c46, 64, { 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, 0x08, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x7e, 0x7c, 0x7f, 0xc0, 0x85, 0x15, 0x82, 0x85, 0x14,
+  0x83, 0x74, 0x7c, 0xf0, 0xa3, 0x74, 0xc0, 0xf0, 0x7e, 0x7d, 0x7f, 0x00, 0x85, 0x15, 0x82, 0x85,
+  0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0xc2, 0x0a, 0xc2, 0x09}},
+ {0x0c86, 64, { 0xe4, 0xf5, 0x11, 0xd2, 0x02, 0x22, 0xe5, 0x10, 0x04, 0x54, 0x03, 0xf5, 0x10, 0x14, 0x60, 0x1f, 0x14,
+  0x60, 0x31, 0x14, 0x60, 0x43, 0x24, 0x03, 0x70, 0x52, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b,
+  0x75, 0x15, 0xc0, 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0x80, 0x3d, 0x7e, 0x7c,
+  0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75}},
+ {0x0cc6, 64, { 0x16, 0x02, 0x80, 0x28, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x98,
+  0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04, 0x80, 0x13, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75,
+  0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, 0x08, 0xe5, 0x32, 0x55, 0x16, 0x70,
+  0x03, 0x02, 0x0e, 0x27, 0xe5, 0x16, 0xf4, 0x52, 0x32, 0xe5, 0x26, 0x54, 0x7f, 0xff, 0x70}},
+ {0x0d06, 64, { 0x17, 0xe5, 0x2a, 0x55, 0x16, 0x60, 0x34, 0x90, 0x7f, 0x96, 0xe0, 0xfe, 0xe5, 0x16, 0xc4, 0x54, 0xf0,
+  0xf4, 0xfd, 0xee, 0x5d, 0xf0, 0x80, 0x23, 0xbf, 0x20, 0x20, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe3, 0x11, 0xe4, 0xf5, 0x2a, 0x90, 0x7f, 0x96, 0xe0,
+  0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0xfe, 0xef, 0x4e, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5}},
+ {0x0d46, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe5, 0x15, 0x24, 0x34, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe0, 0x60, 0x03, 0x02,
+  0x0e, 0x27, 0x74, 0x0a, 0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0x01, 0xff, 0xf5, 0x18, 0xe5, 0x15,
+  0x24, 0x2c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x18}},
+ {0x0d86, 64, { 0xf0, 0xe5, 0x16, 0x42, 0x13, 0x12, 0x18, 0xe1, 0x8f, 0x18, 0xe5, 0x15, 0x24, 0x27, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x54, 0x10, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0,
+  0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x28, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0,
+  0xff, 0xe5, 0x18, 0x54, 0x80, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x16, 0x42, 0x13}},
+ {0x0dc6, 64, { 0xe5, 0x15, 0x24, 0x29, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x54, 0x20,
+  0xfe, 0x6f, 0x60, 0x15, 0xee, 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x30, 0xe4, 0x04, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x2a, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x54, 0x40, 0xfe, 0x6f, 0x60, 0x15, 0xee}},
+ {0x0e06, 64, { 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe5, 0x04, 0xe5,
+  0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0,
+  0x22, 0x30, 0x09, 0x03, 0x02, 0x0f, 0x27, 0xe5, 0x24, 0x14, 0x60, 0x2a, 0x14, 0x60, 0x41, 0x14,
+  0x60, 0x58, 0x14, 0x60, 0x6f, 0x24, 0x04, 0x60, 0x03, 0x02, 0x0e, 0xe5, 0x7e, 0x7b, 0x7f}},
+ {0x0e46, 64, { 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0x12,
+  0x12, 0x9c, 0x75, 0x24, 0x01, 0x22, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00,
+  0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x12, 0x9c, 0x75, 0x24, 0x02, 0x22,
+  0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x2b}},
+ {0x0e86, 64, { 0xf0, 0x75, 0x16, 0x04, 0x12, 0x12, 0x9c, 0x75, 0x24, 0x03, 0x22, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14,
+  0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x12, 0x9c,
+  0x75, 0x24, 0x04, 0x22, 0x30, 0x04, 0x33, 0xc2, 0x04, 0x53, 0x13, 0xdf, 0xe4, 0xf5, 0x18, 0x7e,
+  0x00, 0x7b, 0x00, 0x74, 0x2e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11, 0xa6}},
+ {0x0ec6, 64, { 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5,
+  0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0x75, 0x24, 0x05, 0x22, 0xe5, 0x36,
+  0x60, 0x3b, 0xd5, 0x36, 0x0a, 0x53, 0x13, 0xef, 0x30, 0x0a, 0x04, 0xd2, 0x09, 0xc2, 0x0a, 0xe4,
+  0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x35, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa}},
+ {0x0f06, 64, { 0x12, 0x11, 0xa6, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0,
+  0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x24,
+  0x22, 0xe4, 0xf5, 0x19, 0x7e, 0x00, 0x7b, 0x01, 0xe5, 0x15, 0x25, 0x19, 0xf9, 0xee, 0x35, 0x14,
+  0xfa, 0xe4, 0x12, 0x11, 0xec, 0x05, 0x19, 0xe5, 0x19, 0xb4, 0x3c, 0xe8, 0xe5, 0x15, 0x24}},
+ {0x0f46, 64, { 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0,
+  0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x90, 0xc0,
+  0x00, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x16, 0x6b, 0x7f, 0x10, 0xe5, 0x15, 0x24, 0x33, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0x12, 0x15, 0xdb, 0x90, 0x78, 0x41, 0x74}},
+ {0x0f86, 64, { 0xf2, 0xf0, 0x7f, 0x01, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0,
+  0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0xe5, 0x15, 0x24, 0x39,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4,
+  0xfd, 0x12, 0x16, 0x6b, 0xe4, 0xff, 0x7e, 0xa3, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4}},
+ {0x0fc6, 64, { 0x35, 0x14, 0xf5, 0x83, 0xee, 0xf0, 0xfd, 0x12, 0x16, 0x6b, 0x90, 0x78, 0x41, 0x74, 0xf1, 0xf0, 0x90,
+  0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x16, 0x6b, 0x7f, 0x01, 0x12, 0x15, 0x43,
+  0x7f, 0x03, 0x7d, 0x07, 0x12, 0x16, 0x6b, 0x22, 0x53, 0x13, 0x3f, 0x90, 0x7b, 0xf1, 0xe0, 0x30,
+  0xe3, 0x16, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x98}},
+ {0x1006, 64, { 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0x12, 0x08, 0xd7, 0x90, 0x7c, 0x31, 0xe0, 0x30, 0xe3, 0x16, 0x7e,
+  0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75,
+  0x16, 0x02, 0x12, 0x08, 0xd7, 0x90, 0x7c, 0x71, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x40,
+  0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04}},
+ {0x1046, 64, { 0x12, 0x08, 0xd7, 0x90, 0x7c, 0xb1, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c,
+  0x75, 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x08, 0xd7, 0x05,
+  0x12, 0xe5, 0x12, 0x54, 0x0f, 0xf5, 0x17, 0x70, 0x04, 0x12, 0x11, 0x1c, 0x22, 0xe5, 0x17, 0xb4,
+  0x01, 0x04, 0x12, 0x0c, 0x8c, 0x22, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x08, 0xe5, 0x13}},
+ {0x1086, 64, { 0x60, 0x04, 0x12, 0x0e, 0x28, 0x22, 0x12, 0x0c, 0x8c, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75,
+  0x81, 0x37, 0x02, 0x10, 0xd7, 0x02, 0x12, 0x24, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40,
+  0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07,
+  0x24, 0x0c, 0xc8, 0xc3, 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4}},
+ {0x10c6, 64, { 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+  0x90, 0x18, 0x45, 0xe4, 0x7e, 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09,
+  0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8,
+  0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5}},
+ {0x1106, 64, { 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf,
+  0xe9, 0xde, 0xe7, 0x80, 0xbe, 0x90, 0x7f, 0xd2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x11, 0xa5, 0xc2,
+  0x09, 0x90, 0x7b, 0x40, 0xe0, 0x14, 0x60, 0x26, 0x14, 0x60, 0x3b, 0x14, 0x60, 0x50, 0x24, 0x83,
+  0x60, 0x64, 0x24, 0x80, 0x70, 0x63, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15}},
+ {0x1146, 64, { 0xc0, 0x90, 0x7f, 0x98, 0x74, 0x2e, 0xf0, 0x75, 0x16, 0x01, 0x12, 0x00, 0x46, 0x80, 0x4b, 0x7e, 0x7c,
+  0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x2d, 0xf0, 0x75, 0x16,
+  0x02, 0x12, 0x00, 0x46, 0x80, 0x33, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40,
+  0x90, 0x7f, 0x98, 0x74, 0x2b, 0xf0, 0x75, 0x16, 0x04, 0x12, 0x00, 0x46, 0x80, 0x1b, 0x7e}},
+ {0x1186, 64, { 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x27, 0xf0, 0x75, 0x16,
+  0x08, 0x12, 0x00, 0x46, 0x80, 0x03, 0x12, 0x17, 0x51, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x22, 0xbb,
+  0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3,
+  0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5}},
+ {0x11c6, 64, { 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb,
+  0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a,
+  0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02,
+  0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70}},
+ {0x1206, 64, { 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83,
+  0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0x90, 0x7f, 0xae,
+  0xe0, 0xff, 0xd3, 0x92, 0x00, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20,
+  0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff}},
+ {0x1246, 64, { 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0x74, 0x01,
+  0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x0b, 0x12, 0x18, 0x09, 0xc2, 0x01,
+  0xe4, 0xf5, 0x2b, 0xf5, 0x31, 0xc2, 0x07, 0xc2, 0x02, 0x75, 0x29, 0x0f, 0x90, 0x7f, 0xd8, 0xe0,
+  0x65, 0x26, 0x60, 0x06, 0x75, 0x32, 0x0f, 0xe0, 0xf5, 0x26, 0x30, 0x02, 0x03, 0x12, 0x0f}},
+ {0x1286, 64, { 0xef, 0x30, 0x01, 0x07, 0xc2, 0x01, 0x12, 0x06, 0x3f, 0x80, 0xe2, 0x30, 0x08, 0xdf, 0xc2, 0x08, 0x12,
+  0x18, 0x2a, 0x80, 0xd8, 0x22, 0xe5, 0x13, 0x55, 0x16, 0x60, 0x6a, 0xe5, 0x15, 0x24, 0x3a, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x5c, 0xe5, 0x16, 0xf4, 0x52, 0x13, 0xe5, 0x15,
+  0x24, 0x26, 0xff, 0xe4, 0x35, 0x14, 0xfe, 0xe4, 0xfd, 0x0f, 0xef, 0xaa, 0x06, 0x70, 0x01}},
+ {0x12c6, 64, { 0x0e, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0xfc, 0x74, 0x80, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5,
+  0x83, 0xec, 0xf0, 0x0d, 0xbd, 0x0b, 0xe2, 0x90, 0x7f, 0xc3, 0x74, 0x0b, 0xf0, 0xe5, 0x15, 0x24,
+  0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x10, 0xf0, 0xe5, 0x15, 0x24, 0x2e, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x15, 0x24, 0x2f, 0xf5, 0x82, 0xe4}},
+ {0x1306, 64, { 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0x22, 0xe5, 0x28, 0x45, 0x27, 0x60, 0x57, 0xae, 0x27, 0xaf, 0x28,
+  0xd3, 0xef, 0x94, 0x40, 0xee, 0x94, 0x00, 0x40, 0x04, 0x7e, 0x00, 0x7f, 0x40, 0xc3, 0xe5, 0x28,
+  0x9f, 0xf5, 0x28, 0xe5, 0x27, 0x9e, 0xf5, 0x27, 0xe4, 0xfd, 0xed, 0xc3, 0x9f, 0xe4, 0x9e, 0x50,
+  0x1f, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0x74, 0x00, 0x2d, 0xf5, 0x82, 0xe4}},
+ {0x1346, 64, { 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x0d, 0x05, 0x34, 0xe5, 0x34, 0x70, 0x02, 0x05, 0x33, 0x80, 0xda,
+  0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb5,
+  0xef, 0xf0, 0x22, 0x90, 0x7f, 0xac, 0xe0, 0x54, 0xfe, 0xf0, 0xe4, 0x90, 0x7f, 0xb5, 0xf0, 0x22,
+  0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0xe4, 0x90, 0x78, 0x4a, 0xf0, 0x90, 0x7f, 0x94, 0xf0}},
+ {0x1386, 64, { 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x7f,
+  0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xff, 0xf0, 0x30, 0x00, 0x07, 0xe5, 0x29, 0x54, 0x0f, 0xff,
+  0x80, 0x02, 0x7f, 0x00, 0x90, 0x7f, 0x96, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x1f, 0xf0, 0xe4,
+  0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0xdf}},
+ {0x13c6, 64, { 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x8f, 0x19, 0x05, 0x2d, 0xe5, 0x2d, 0xae, 0x2c,
+  0x70, 0x02, 0x05, 0x2c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x19, 0xf0, 0x12, 0x18, 0xef, 0x05,
+  0x2d, 0xe5, 0x2d, 0xac, 0x2c, 0x70, 0x02, 0x05, 0x2c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0,
+  0x15, 0x23, 0xe5, 0x23, 0x60, 0x1f, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14}},
+ {0x1406, 64, { 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12, 0x18, 0xd3, 0x8f, 0x19, 0xee, 0x4f, 0xd0, 0x82,
+  0xd0, 0x83, 0xf0, 0x80, 0xb5, 0x22, 0x90, 0x78, 0x41, 0xe5, 0x11, 0xf0, 0x90, 0x78, 0x4f, 0x74,
+  0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x50, 0xf0, 0xe5, 0x2c, 0x90, 0x78, 0x51, 0xf0, 0xae, 0x2c, 0xe5,
+  0x2d, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78, 0x54, 0xe5, 0x23, 0xf0, 0x90, 0x78, 0x57, 0x74}},
+ {0x1446, 64, { 0x04, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x10, 0xf0, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0x90, 0x78, 0x55,
+  0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22, 0x8f, 0x19, 0xe4, 0xf5, 0x1a, 0x75, 0x1b, 0xff,
+  0x75, 0x1c, 0x19, 0x75, 0x1d, 0x86, 0xab, 0x1b, 0xaa, 0x1c, 0xa9, 0x1d, 0x90, 0x00, 0x01, 0x12,
+  0x11, 0xbf, 0xb4, 0x03, 0x1d, 0xaf, 0x1a, 0x05, 0x1a, 0xef, 0xb5, 0x19, 0x01, 0x22, 0x12}},
+ {0x1486, 64, { 0x11, 0xa6, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1b, 0xff, 0xf5, 0x1c, 0x89, 0x1d,
+  0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x22, 0x90, 0x78, 0x41, 0xe5, 0x11, 0xf0, 0xe5,
+  0x2c, 0x90, 0x78, 0x4f, 0xf0, 0xae, 0x2c, 0xe5, 0x2d, 0x90, 0x78, 0x50, 0xf0, 0x90, 0x78, 0x51,
+  0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78, 0x54, 0xe5, 0x23, 0xf0, 0x90}},
+ {0x14c6, 64, { 0x78, 0x57, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22,
+  0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14,
+  0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f,
+  0xc9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xcb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xcd}},
+ {0x1506, 64, { 0xef, 0xf0, 0xe5, 0x16, 0x42, 0x2a, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xb7,
+  0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f, 0xb9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xbb, 0xef, 0xf0,
+  0x80, 0x05, 0x90, 0x7f, 0xbd, 0xef, 0xf0, 0xe5, 0x16, 0x42, 0x2a, 0x22, 0xae, 0x07, 0xe4}},
+ {0x1546, 64, { 0xff, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xfd, 0x12,
+  0x16, 0x6b, 0x90, 0x78, 0x41, 0x74, 0xf1, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x15,
+  0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xfd, 0x12, 0x16, 0x6b,
+  0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86}},
+ {0x1586, 64, { 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0,
+  0x12, 0x13, 0x0d, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0,
+  0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0,
+  0x90, 0x78, 0x41, 0x74, 0xf1, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74}},
+ {0x15c6, 64, { 0xf3, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90,
+  0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0,
+  0x90, 0x78, 0x41, 0x74, 0xf2, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3,
+  0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f}},
+ {0x1606, 64, { 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0,
+  0x90, 0x78, 0x41, 0x74, 0xf4, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3,
+  0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90,
+  0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf}},
+ {0x1646, 64, { 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf6, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf3,
+  0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90,
+  0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0xf3, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41}},
+ {0x1686, 64, { 0x74, 0xf7, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0xf5, 0xf0, 0x90, 0xc0, 0x00,
+  0xed, 0xf0, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14,
+  0x60, 0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc6, 0xe0, 0xff, 0x22,
+  0x90, 0x7f, 0xc8, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xca, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcc}},
+ {0x16c6, 64, { 0xe0, 0xff, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60,
+  0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xb6, 0xe0, 0xff, 0x22, 0x90,
+  0x7f, 0xb8, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xba, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xbc, 0xe0, 0xff,
+  0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60}},
+ {0x1706, 64, { 0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xe0, 0xff, 0x22, 0x90, 0x7f,
+  0xc9, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcb, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcd, 0xe0, 0xff, 0x22,
+  0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90,
+  0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86}},
+ {0x1746, 64, { 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7b, 0x41, 0xe0, 0xf5, 0x36,
+  0x43, 0x13, 0x10, 0xa3, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0,
+  0x90, 0x7b, 0x43, 0xe0, 0xf5, 0x37, 0xa3, 0xe0, 0x54, 0xf0, 0xf5, 0x29, 0xe0, 0x60, 0x02, 0xd2,
+  0x0a, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75}},
+ {0x1786, 64, { 0x86, 0x00, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84,
+  0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0,
+  0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab,
+  0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0}},
+ {0x17c6, 64, { 0x32, 0x12, 0x18, 0xb7, 0xae, 0x07, 0x12, 0x18, 0xb7, 0xad, 0x07, 0xee, 0x6d, 0x60, 0x10, 0x12, 0x18,
+  0xb7, 0xae, 0x07, 0xee, 0x6d, 0x60, 0x07, 0x12, 0x18, 0xb7, 0xad, 0x07, 0x80, 0xec, 0xaf, 0x06,
+  0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70,
+  0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00}},
+ {0x1806, 64, { 0x00, 0x00, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x04, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x0b, 0x04,
+  0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x18, 0x60, 0x90, 0x7f, 0xd6, 0xe0, 0x54,
+  0xf7, 0xf0, 0x22, 0x12, 0x13, 0x77, 0x12, 0x17, 0xf9, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x0a,
+  0x7f, 0x05, 0x7e, 0x00, 0x12, 0x18, 0x60, 0x12, 0x18, 0x93, 0x12, 0x0a, 0xce, 0x22, 0x03}},
+ {0x1846, 64, { 0x35, 0x80, 0x00, 0x00, 0x03, 0x2e, 0x81, 0x00, 0x00, 0xc1, 0x85, 0xc1, 0x81, 0xc1, 0x08, 0xc1, 0x00,
+  0xc1, 0x06, 0x01, 0x22, 0x00, 0x01, 0x24, 0x00, 0x00, 0x8e, 0x17, 0x8f, 0x18, 0xe5, 0x18, 0x15,
+  0x18, 0xae, 0x17, 0x70, 0x02, 0x15, 0x17, 0x4e, 0x60, 0x08, 0x12, 0x17, 0xe8, 0x12, 0x17, 0xe8,
+  0x80, 0xeb, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}},
+ {0x1886, 64, { 0x04, 0xff, 0x44, 0x10, 0x90, 0x7f, 0xd7, 0xf0, 0xef, 0x44, 0x30, 0xf0, 0x22, 0x90, 0x7f, 0xd6, 0xe0,
+  0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x18, 0x60, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe,
+  0xf0, 0x22, 0xe5, 0x11, 0x24, 0x02, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22,
+  0xe5, 0x11, 0x24, 0x03, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0xe5}},
+ {0x18c6, 64, { 0x11, 0x24, 0x04, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0xe5, 0x11, 0x24, 0x05,
+  0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0xe5, 0x11, 0x24, 0x06, 0x90, 0x78,
+  0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x78, 0x41, 0xe5, 0x11, 0xf0, 0x90, 0xc0,
+  0x00, 0xe0, 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0x00, 0x12, 0x01, 0x10, 0x01, 0xff, 0xff}},
+ {0x1906, 64, { 0xff, 0x40, 0xcd, 0x06, 0x2a, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x04, 0x09, 0x02, 0x74, 0x00, 0x01,
+  0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01,
+  0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}},
+ {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05,
+  0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02,
+  0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00,
+  0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}},
+ {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61,
+  0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76,
+  0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+  0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}},
+ {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x24, 0x03, 0x4b, 0x00, 0x65,
+  0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53,
+  0x00, 0x41, 0x00, 0x2d, 0x00, 0x34, 0x00, 0x39, 0x00, 0x57, 0x00, 0x4c, 0x00, 0x43, 0x00, 0x22,
+  0x03, 0x55, 0x00, 0x53, 0x00, 0x41, 0x00, 0x2d, 0x00, 0x36, 0x00, 0x35, 0x00, 0x20, 0x00}},
+ {0x1a06, 64, { 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x6a, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x33, 0x00, 0x31,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1a46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1a86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1ac6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x17, 0x79, 0x00, 0x02, 0x1b}},
+ {0x1b06, 21, { 0x04, 0x00, 0x02, 0x17, 0x27, 0x00, 0x02, 0x17, 0xa0, 0x00, 0x02, 0x1b, 0x10, 0x00, 0x02, 0x1b, 0x14,
+  0x00, 0x02, 0x15, 0x78}},
+ {0xffff,  0, { 0x00}},
+};
+
+
diff -urN linux-2.5.63-bk4/drivers/usb/serial/kl5kusb105.c linux-2.5.63-bk5/drivers/usb/serial/kl5kusb105.c
--- linux-2.5.63-bk4/drivers/usb/serial/kl5kusb105.c	Mon Feb 24 11:05:33 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/kl5kusb105.c	Mon Mar 31 12:18:55 2003
@@ -166,7 +166,7 @@
 	unsigned long			line_state; /* modem line settings */
 	/* write pool */
 	struct urb *			write_urb_pool[NUM_URBS];
-	spinlock_t			write_urb_pool_lock;
+	spinlock_t			lock;
 	unsigned long			bytes_in;
 	unsigned long			bytes_out;
 };
@@ -284,7 +284,7 @@
 		priv->bytes_out	    = 0;
 		usb_set_serial_port_data(&serial->port[i], priv);
 
-		spin_lock_init (&priv->write_urb_pool_lock);
+		spin_lock_init (&priv->lock);
 		for (i=0; i<NUM_URBS; i++) {
 			struct urb* urb = usb_alloc_urb(0, GFP_KERNEL);
 
@@ -326,7 +326,7 @@
 			/* kill our write urb pool */
 			int j;
 			struct urb **write_urbs = priv->write_urb_pool;
-			spin_lock_irqsave(&priv->write_urb_pool_lock,flags);
+			spin_lock_irqsave(&priv->lock,flags);
 
 			for (j = 0; j < NUM_URBS; j++) {
 				if (write_urbs[j]) {
@@ -343,8 +343,7 @@
 				}
 			}
 
-			spin_unlock_irqrestore (&priv->write_urb_pool_lock,
-					       	flags);
+			spin_unlock_irqrestore (&priv->lock, flags);
 
 			kfree(priv);
 			usb_set_serial_port_data(&serial->port[i], NULL);
@@ -360,6 +359,8 @@
 	int rc;
 	int i;
 	unsigned long line_state;
+	struct klsi_105_port_settings cfg;
+	unsigned long flags;
 
 	dbg("%s port %d", __FUNCTION__, port->number);
 
@@ -374,21 +375,27 @@
 	 * Then read the modem line control and store values in
 	 * priv->line_state.
 	 */
-	priv->cfg.pktlen   = 5;
-	priv->cfg.baudrate = kl5kusb105a_sio_b9600;
-	priv->cfg.databits = kl5kusb105a_dtb_8;
-	priv->cfg.unknown1 = 0;
-	priv->cfg.unknown2 = 1;
-	klsi_105_chg_port_settings(serial, &(priv->cfg));
+	cfg.pktlen   = 5;
+	cfg.baudrate = kl5kusb105a_sio_b9600;
+	cfg.databits = kl5kusb105a_dtb_8;
+	cfg.unknown1 = 0;
+	cfg.unknown2 = 1;
+	klsi_105_chg_port_settings(serial, &cfg);
 	
 	/* set up termios structure */
+	spin_lock_irqsave (&priv->lock, flags);
 	priv->termios.c_iflag = port->tty->termios->c_iflag;
 	priv->termios.c_oflag = port->tty->termios->c_oflag;
 	priv->termios.c_cflag = port->tty->termios->c_cflag;
 	priv->termios.c_lflag = port->tty->termios->c_lflag;
 	for (i=0; i<NCCS; i++)
 		priv->termios.c_cc[i] = port->tty->termios->c_cc[i];
-
+	priv->cfg.pktlen   = cfg.pktlen;
+	priv->cfg.baudrate = cfg.baudrate;
+	priv->cfg.databits = cfg.databits;
+	priv->cfg.unknown1 = cfg.unknown1;
+	priv->cfg.unknown2 = cfg.unknown2;
+	spin_unlock_irqrestore (&priv->lock, flags);
 
 	/* READ_ON and urb submission */
 	usb_fill_bulk_urb(port->read_urb, serial->dev, 
@@ -422,7 +429,9 @@
 
 	rc = klsi_105_get_line_state(serial, &line_state);
 	if (rc >= 0) {
+		spin_lock_irqsave (&priv->lock, flags);
 		priv->line_state = line_state;
+		spin_unlock_irqrestore (&priv->lock, flags);
 		dbg("%s - read line state 0x%lx", __FUNCTION__, line_state);
 		retval = 0;
 	} else
@@ -492,7 +501,7 @@
 		unsigned long flags;
 		int i;
 		/* since the pool is per-port we might not need the spin lock !? */
-		spin_lock_irqsave (&priv->write_urb_pool_lock, flags);
+		spin_lock_irqsave (&priv->lock, flags);
 		for (i=0; i<NUM_URBS; i++) {
 			if (priv->write_urb_pool[i]->status != -EINPROGRESS) {
 				urb = priv->write_urb_pool[i];
@@ -500,7 +509,7 @@
 				break;
 			}
 		}
-		spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
+		spin_unlock_irqrestore (&priv->lock, flags);
 
 		if (urb==NULL) {
 			dbg("%s - no more free urbs", __FUNCTION__);
@@ -552,6 +561,7 @@
 		count -= size;
 	}
 exit:
+	/* lockless, but it's for debug info only... */
 	priv->bytes_out+=bytes_sent;
 
 	return bytes_sent;	/* that's how much we wrote */
@@ -588,7 +598,7 @@
 	unsigned long flags;
 	struct klsi_105_private *priv = usb_get_serial_port_data(port);
 
-	spin_lock_irqsave (&priv->write_urb_pool_lock, flags);
+	spin_lock_irqsave (&priv->lock, flags);
 
 	for (i = 0; i < NUM_URBS; ++i) {
 		if (priv->write_urb_pool[i]->status == -EINPROGRESS) {
@@ -596,7 +606,7 @@
 		}
 	}
 
-	spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
+	spin_unlock_irqrestore (&priv->lock, flags);
 
 	dbg("%s - returns %d", __FUNCTION__, chars);
 	return (chars);
@@ -609,14 +619,14 @@
 	int room = 0;
 	struct klsi_105_private *priv = usb_get_serial_port_data(port);
 
-	spin_lock_irqsave (&priv->write_urb_pool_lock, flags);
+	spin_lock_irqsave (&priv->lock, flags);
 	for (i = 0; i < NUM_URBS; ++i) {
 		if (priv->write_urb_pool[i]->status != -EINPROGRESS) {
 			room += URB_TRANSFER_BUFFER_SIZE;
 		}
 	}
 
-	spin_unlock_irqrestore (&priv->write_urb_pool_lock, flags);
+	spin_unlock_irqrestore (&priv->lock, flags);
 
 	dbg("%s - returns %d", __FUNCTION__, room);
 	return (room);
@@ -690,6 +700,8 @@
 			tty_insert_flip_char(tty, ((__u8*) data)[i], 0);
 		}
 		tty_flip_buffer_push(tty);
+
+		/* again lockless, but debug info only */
 		priv->bytes_in += bytes_sent;
 	}
 	/* Continue trying to always read  */
@@ -715,6 +727,11 @@
 	unsigned int old_iflag = old_termios->c_iflag;
 	unsigned int cflag = port->tty->termios->c_cflag;
 	unsigned int old_cflag = old_termios->c_cflag;
+	struct klsi_105_port_settings cfg;
+	unsigned long flags;
+	
+	/* lock while we are modifying the settings */
+	spin_lock_irqsave (&priv->lock, flags);
 	
 	/*
 	 * Update baud rate
@@ -838,9 +855,11 @@
 #endif
 		;
 	}
-
+	memcpy (&cfg, &priv->cfg, sizeof(cfg));
+	spin_unlock_irqrestore (&priv->lock, flags);
+	
 	/* now commit changes to device */
-	klsi_105_chg_port_settings(serial, &(priv->cfg));
+	klsi_105_chg_port_settings(serial, &cfg);
 } /* klsi_105_set_termios */
 
 
@@ -866,6 +885,7 @@
 	struct usb_serial *serial = port->serial;
 	struct klsi_105_private *priv = usb_get_serial_port_data(port);
 	int mask;
+	unsigned long flags;
 	
 	dbg("%scmd=0x%x", __FUNCTION__, cmd);
 
@@ -881,11 +901,12 @@
 			err("Reading line control failed (error = %d)", rc);
 			/* better return value? EAGAIN? */
 			return -ENOIOCTLCMD;
-		} else {
-			priv->line_state = line_state;
-			dbg("%s - read line state 0x%lx", __FUNCTION__, line_state);
 		}
-		return put_user(priv->line_state, (unsigned long *) arg); 
+		spin_lock_irqsave (&priv->lock, flags);
+		priv->line_state = line_state;
+		spin_unlock_irqrestore (&priv->lock, flags);
+		dbg("%s - read line state 0x%lx", __FUNCTION__, line_state);
+		return put_user(line_state, (unsigned long *) arg); 
 	       };
 
 	case TIOCMSET: /* Turns on and off the lines as specified by the mask */
diff -urN linux-2.5.63-bk4/drivers/usb/serial/mct_u232.c linux-2.5.63-bk5/drivers/usb/serial/mct_u232.c
--- linux-2.5.63-bk4/drivers/usb/serial/mct_u232.c	Mon Feb 24 11:05:36 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/mct_u232.c	Mon Mar 31 12:18:55 2003
@@ -171,6 +171,7 @@
 
 
 struct mct_u232_private {
+	spinlock_t lock;
 	unsigned long	     control_state; /* Modem Line Setting (TIOCM) */
 	unsigned char        last_lcr;      /* Line Control Register */
 	unsigned char	     last_lsr;      /* Line Status Register */
@@ -306,8 +307,9 @@
 	/* allocate the private data structure */
 	priv = kmalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
 	if (!priv)
-		return (-1); /* error */
+		return -ENOMEM;
 	/* set initial values for control structures */
+	spin_lock_init(&priv->lock);
 	priv->control_state = 0;
 	priv->last_lsr = 0;
 	priv->last_msr = 0;
@@ -339,6 +341,10 @@
 	struct usb_serial *serial = port->serial;
 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
 	int retval = 0;
+	unsigned long control_state;
+	unsigned long flags;
+	unsigned char last_lcr;
+	unsigned char last_msr;
 
 	dbg("%s port %d", __FUNCTION__, port->number);
 
@@ -355,20 +361,27 @@
 	 * sure if this is really necessary. But it should not harm
 	 * either.
 	 */
+	spin_lock_irqsave(&priv->lock, flags);
 	if (port->tty->termios->c_cflag & CBAUD)
 		priv->control_state = TIOCM_DTR | TIOCM_RTS;
 	else
 		priv->control_state = 0;
-	mct_u232_set_modem_ctrl(serial, priv->control_state);
 	
 	priv->last_lcr = (MCT_U232_DATA_BITS_8 | 
 			  MCT_U232_PARITY_NONE |
 			  MCT_U232_STOP_BITS_1);
-	mct_u232_set_line_ctrl(serial, priv->last_lcr);
+	control_state = priv->control_state;
+	last_lcr = priv->last_lcr;
+	spin_unlock_irqrestore(&priv->lock, flags);
+	mct_u232_set_modem_ctrl(serial, control_state);
+	mct_u232_set_line_ctrl(serial, last_lcr);
 
 	/* Read modem status and update control state */
-	mct_u232_get_modem_stat(serial, &priv->last_msr);
+	mct_u232_get_modem_stat(serial, &last_msr);
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->last_msr = last_msr;
 	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	{
 		/* Puh, that's dirty */
@@ -523,6 +536,7 @@
 	struct tty_struct *tty;
 	unsigned char *data = urb->transfer_buffer;
 	int status;
+	unsigned long flags;
 
         dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -567,6 +581,7 @@
 	 * The interrupt-in pipe signals exceptional conditions (modem line
 	 * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
 	 */
+	spin_lock_irqsave(&priv->lock, flags);
 	priv->last_msr = data[MCT_U232_MSR_INDEX];
 	
 	/* Record Control Line states */
@@ -597,6 +612,7 @@
 		}
 	}
 #endif
+	spin_unlock_irqrestore(&priv->lock, flags);
 exit:
 	status = usb_submit_urb (urb, GFP_ATOMIC);
 	if (status)
@@ -614,7 +630,16 @@
 	unsigned int old_iflag = old_termios->c_iflag;
 	unsigned int cflag = port->tty->termios->c_cflag;
 	unsigned int old_cflag = old_termios->c_cflag;
-	
+	unsigned long flags;
+	unsigned long control_state;
+	unsigned char last_lcr;
+	
+	/* get a local copy of the current port settings */
+	spin_lock_irqsave(&priv->lock, flags);
+	control_state = priv->control_state;
+	last_lcr = priv->last_lcr;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	/*
 	 * Update baud rate
 	 */
@@ -622,12 +647,12 @@
 	        /* reassert DTR and (maybe) RTS on transition from B0 */
 		if( (old_cflag & CBAUD) == B0 ) {
 			dbg("%s: baud was B0", __FUNCTION__);
-			priv->control_state |= TIOCM_DTR;
+			control_state |= TIOCM_DTR;
 			/* don't set RTS if using hardware flow control */
 			if (!(old_cflag & CRTSCTS)) {
-				priv->control_state |= TIOCM_RTS;
+				control_state |= TIOCM_RTS;
 			}
-			mct_u232_set_modem_ctrl(serial, priv->control_state);
+			mct_u232_set_modem_ctrl(serial, control_state);
 		}
 		
 		switch(cflag & CBAUD) {
@@ -659,8 +684,8 @@
 		if ((cflag & CBAUD) == B0 ) {
 			dbg("%s: baud is B0", __FUNCTION__);
 			/* Drop RTS and DTR */
-			priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
-        		mct_u232_set_modem_ctrl(serial, priv->control_state);
+			control_state &= ~(TIOCM_DTR | TIOCM_RTS);
+        		mct_u232_set_modem_ctrl(serial, control_state);
 		}
 	}
 
@@ -672,36 +697,36 @@
 	    || (cflag & CSTOPB) != (old_cflag & CSTOPB) ) {
 		
 
-		priv->last_lcr = 0;
+		last_lcr = 0;
 
 		/* set the parity */
 		if (cflag & PARENB)
-			priv->last_lcr |= (cflag & PARODD) ?
+			last_lcr |= (cflag & PARODD) ?
 				MCT_U232_PARITY_ODD : MCT_U232_PARITY_EVEN;
 		else
-			priv->last_lcr |= MCT_U232_PARITY_NONE;
+			last_lcr |= MCT_U232_PARITY_NONE;
 
 		/* set the number of data bits */
 		switch (cflag & CSIZE) {
 		case CS5:
-			priv->last_lcr |= MCT_U232_DATA_BITS_5; break;
+			last_lcr |= MCT_U232_DATA_BITS_5; break;
 		case CS6:
-			priv->last_lcr |= MCT_U232_DATA_BITS_6; break;
+			last_lcr |= MCT_U232_DATA_BITS_6; break;
 		case CS7:
-			priv->last_lcr |= MCT_U232_DATA_BITS_7; break;
+			last_lcr |= MCT_U232_DATA_BITS_7; break;
 		case CS8:
-			priv->last_lcr |= MCT_U232_DATA_BITS_8; break;
+			last_lcr |= MCT_U232_DATA_BITS_8; break;
 		default:
 			err("CSIZE was not CS5-CS8, using default of 8");
-			priv->last_lcr |= MCT_U232_DATA_BITS_8;
+			last_lcr |= MCT_U232_DATA_BITS_8;
 			break;
 		}
 
 		/* set the number of stop bits */
-		priv->last_lcr |= (cflag & CSTOPB) ?
+		last_lcr |= (cflag & CSTOPB) ?
 			MCT_U232_STOP_BITS_2 : MCT_U232_STOP_BITS_1;
 
-		mct_u232_set_line_ctrl(serial, priv->last_lcr);
+		mct_u232_set_line_ctrl(serial, last_lcr);
 	}
 	
 	/*
@@ -714,11 +739,17 @@
 		
 		/* Drop DTR/RTS if no flow control otherwise assert */
 		if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS) )
-			priv->control_state |= TIOCM_DTR | TIOCM_RTS;
+			control_state |= TIOCM_DTR | TIOCM_RTS;
 		else
-			priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
-		mct_u232_set_modem_ctrl(serial, priv->control_state);
+			control_state &= ~(TIOCM_DTR | TIOCM_RTS);
+		mct_u232_set_modem_ctrl(serial, control_state);
 	}
+
+	/* save off the modified port settings */
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->control_state = control_state;
+	priv->last_lcr = last_lcr;
+	spin_unlock_irqrestore(&priv->lock, flags);
 } /* mct_u232_set_termios */
 
 
@@ -726,10 +757,15 @@
 {
 	struct usb_serial *serial = port->serial;
 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
-	unsigned char lcr = priv->last_lcr;
+	unsigned char lcr;
+	unsigned long flags;
 
 	dbg("%sstate=%d", __FUNCTION__, break_state);
 
+	spin_lock_irqsave(&priv->lock, flags);
+	lcr = priv->last_lcr;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	if (break_state)
 		lcr |= MCT_U232_SET_BREAK;
 
@@ -743,13 +779,19 @@
 	struct usb_serial *serial = port->serial;
 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
 	int mask;
+	unsigned long control_state;
+	unsigned long flags;
 	
 	dbg("%scmd=0x%x", __FUNCTION__, cmd);
 
+	spin_lock_irqsave(&priv->lock, flags);
+	control_state = priv->control_state;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
 	/* Based on code from acm.c and others */
 	switch (cmd) {
 	case TIOCMGET:
-		return put_user(priv->control_state, (unsigned long *) arg);
+		return put_user(control_state, (unsigned long *) arg);
 		break;
 
 	case TIOCMSET: /* Turns on and off the lines as specified by the mask */
@@ -762,20 +804,24 @@
 			/* RTS needs set */
 			if( ((cmd == TIOCMSET) && (mask & TIOCM_RTS)) ||
 			    (cmd == TIOCMBIS) )
-				priv->control_state |=  TIOCM_RTS;
+				control_state |=  TIOCM_RTS;
 			else
-				priv->control_state &= ~TIOCM_RTS;
+				control_state &= ~TIOCM_RTS;
 		}
 
 		if ((cmd == TIOCMSET) || (mask & TIOCM_DTR)) {
 			/* DTR needs set */
 			if( ((cmd == TIOCMSET) && (mask & TIOCM_DTR)) ||
 			    (cmd == TIOCMBIS) )
-				priv->control_state |=  TIOCM_DTR;
+				control_state |=  TIOCM_DTR;
 			else
-				priv->control_state &= ~TIOCM_DTR;
+				control_state &= ~TIOCM_DTR;
 		}
-		mct_u232_set_modem_ctrl(serial, priv->control_state);
+		mct_u232_set_modem_ctrl(serial, control_state);
+
+		spin_lock_irqsave(&priv->lock, flags);
+		priv->control_state = control_state;
+		spin_unlock_irqrestore(&priv->lock, flags);
 		break;
 					
 	case TIOCMIWAIT:
diff -urN linux-2.5.63-bk4/drivers/usb/serial/pl2303.c linux-2.5.63-bk5/drivers/usb/serial/pl2303.c
--- linux-2.5.63-bk4/drivers/usb/serial/pl2303.c	Mon Feb 24 11:05:31 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/pl2303.c	Mon Mar 31 12:18:55 2003
@@ -148,7 +148,8 @@
 	.shutdown =		pl2303_shutdown,
 };
 
-struct pl2303_private { 
+struct pl2303_private {
+	spinlock_t lock;
 	u8 line_control;
 	u8 termios_initialized;
 };
@@ -164,6 +165,7 @@
 		if (!priv)
 			return -ENOMEM;
 		memset (priv, 0x00, sizeof (struct pl2303_private));
+		spin_lock_init(&priv->lock);
 		usb_set_serial_port_data(&serial->port[i], priv);
 	}
 	return 0;
@@ -223,18 +225,21 @@
 	int baud;
 	int i;
 
-	dbg("%s -  port %d, initialized = %d", __FUNCTION__, port->number, priv->termios_initialized);
+	dbg("%s -  port %d", __FUNCTION__, port->number);
 
 	if ((!port->tty) || (!port->tty->termios)) {
 		dbg("%s - no tty structures", __FUNCTION__);
 		return;
 	}
 
+	spin_lock(&priv->lock);
 	if (!priv->termios_initialized) {
 		*(port->tty->termios) = tty_std_termios;
 		port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 		priv->termios_initialized = 1;
 	}
+	spin_unlock(&priv->lock);
+
 	cflag = port->tty->termios->c_cflag;
 	/* check that they really want us to change something */
 	if (old_termios) {
@@ -341,11 +346,16 @@
 	dbg ("0x21:0x20:0:0  %d", i);
 
 	if (cflag && CBAUD) {
+		u8 control;
+
+		spin_lock (&priv->lock);
 		if ((cflag && CBAUD) == B0)
 			priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
 		else
 			priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
-		set_control_lines (serial->dev, priv->line_control);
+		control = priv->line_control;
+		spin_unlock (&priv->lock);
+		set_control_lines (serial->dev, control);
 	}
 	
 	buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;
@@ -444,48 +454,50 @@
 	
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
-	if (serial->dev) {
-		if (port->tty) {
-			c_cflag = port->tty->termios->c_cflag;
-			if (c_cflag & HUPCL) {
-				/* drop DTR and RTS */
-				priv = usb_get_serial_port_data(port);
-				priv->line_control = 0;
-				set_control_lines (port->serial->dev,
-						   priv->line_control);
-			}
-		}
+	/* shutdown our urbs */
+	dbg("%s - shutting down urbs", __FUNCTION__);
+	result = usb_unlink_urb (port->write_urb);
+	if (result)
+		dbg("%s - usb_unlink_urb (write_urb)"
+		    " failed with reason: %d", __FUNCTION__,
+		     result);
+
+	result = usb_unlink_urb (port->read_urb);
+	if (result)
+		dbg("%s - usb_unlink_urb (read_urb) "
+		    "failed with reason: %d", __FUNCTION__,
+		     result);
 
-		/* shutdown our urbs */
-		dbg("%s - shutting down urbs", __FUNCTION__);
-		result = usb_unlink_urb (port->write_urb);
-		if (result)
-			dbg("%s - usb_unlink_urb (write_urb)"
-			    " failed with reason: %d", __FUNCTION__,
-			     result);
-
-		result = usb_unlink_urb (port->read_urb);
-		if (result)
-			dbg("%s - usb_unlink_urb (read_urb) "
-			    "failed with reason: %d", __FUNCTION__,
-			     result);
-
-		result = usb_unlink_urb (port->interrupt_in_urb);
-		if (result)
-			dbg("%s - usb_unlink_urb (interrupt_in_urb)"
-			    " failed with reason: %d", __FUNCTION__,
-			     result);
+	result = usb_unlink_urb (port->interrupt_in_urb);
+	if (result)
+		dbg("%s - usb_unlink_urb (interrupt_in_urb)"
+		    " failed with reason: %d", __FUNCTION__,
+		     result);
+
+	if (port->tty) {
+		c_cflag = port->tty->termios->c_cflag;
+		if (c_cflag & HUPCL) {
+			/* drop DTR and RTS */
+			priv = usb_get_serial_port_data(port);
+			spin_lock (&priv->lock);
+			priv->line_control = 0;
+			spin_unlock (&priv->lock);
+			set_control_lines (port->serial->dev, 0);
+		}
 	}
+
 }
 
 static int set_modem_info (struct usb_serial_port *port, unsigned int cmd, unsigned int *value)
 {
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	unsigned int arg;
+	u8 control;
 
 	if (copy_from_user(&arg, value, sizeof(int)))
 		return -EFAULT;
 
+	spin_lock (&priv->lock);
 	switch (cmd) {
 		case TIOCMBIS:
 			if (arg & TIOCM_RTS)
@@ -509,16 +521,22 @@
 			priv->line_control |= ((arg & TIOCM_DTR) ? CONTROL_DTR : 0);
 			break;
 	}
+	control = priv->line_control;
+	spin_unlock (&priv->lock);
 
-	return set_control_lines (port->serial->dev, priv->line_control);
+	return set_control_lines (port->serial->dev, control);
 }
 
 static int get_modem_info (struct usb_serial_port *port, unsigned int *value)
 {
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
-	unsigned int mcr = priv->line_control;
+	unsigned int mcr;
 	unsigned int result;
 
+	spin_lock (&priv->lock);
+	mcr = priv->line_control;
+	spin_unlock (&priv->lock);
+
 	result = ((mcr & CONTROL_DTR)		? TIOCM_DTR : 0)
 		  | ((mcr & CONTROL_RTS)	? TIOCM_RTS : 0);
 
diff -urN linux-2.5.63-bk4/drivers/usb/serial/visor.c linux-2.5.63-bk5/drivers/usb/serial/visor.c
--- linux-2.5.63-bk4/drivers/usb/serial/visor.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk5/drivers/usb/serial/visor.c	Mon Mar 31 12:18:55 2003
@@ -2,7 +2,7 @@
  * USB HandSpring Visor, Palm m50x, and Sony Clie driver
  * (supports all of the Palm OS USB devices)
  *
- *	Copyright (C) 1999 - 2002
+ *	Copyright (C) 1999 - 2003
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -183,34 +183,34 @@
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
-		.driver_info = (unsigned int)&palm_os_3_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_3_probe },
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID),
-		.driver_info = (unsigned int)&palm_os_4_probe },
+		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ }					/* Terminating entry */
 };
 
@@ -374,27 +374,22 @@
 	if (!serial)
 		return;
 	
-	if (serial->dev) {
-		/* only send a shutdown message if the 
-		 * device is still here */
-		transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
-		if (!transfer_buffer) {
-			dev_err(&port->dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 0x12);
-		} else {
-			/* send a shutdown message to the device */
-			usb_control_msg (serial->dev,
-					 usb_rcvctrlpipe(serial->dev, 0),
-					 VISOR_CLOSE_NOTIFICATION, 0xc2,
-					 0x0000, 0x0000, 
-					 transfer_buffer, 0x12, 300);
-			kfree (transfer_buffer);
-		}
-		/* shutdown our bulk read */
-		usb_unlink_urb (port->read_urb);
-
-		if (port->interrupt_in_urb)
-			usb_unlink_urb (port->interrupt_in_urb);
+	/* shutdown our urbs */
+	usb_unlink_urb (port->read_urb);
+	if (port->interrupt_in_urb)
+		usb_unlink_urb (port->interrupt_in_urb);
+
+	/* Try to send shutdown message, if the device is gone, this will just fail. */
+	transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
+	if (transfer_buffer) {
+		usb_control_msg (serial->dev,
+				 usb_rcvctrlpipe(serial->dev, 0),
+				 VISOR_CLOSE_NOTIFICATION, 0xc2,
+				 0x0000, 0x0000, 
+				 transfer_buffer, 0x12, 300);
+		kfree (transfer_buffer);
 	}
+
 	/* Uncomment the following line if you want to see some statistics in your syslog */
 	/* dev_info (&port->dev, "Bytes In = %d  Bytes Out = %d\n", bytes_in, bytes_out); */
 }
diff -urN linux-2.5.63-bk4/drivers/usb/storage/unusual_devs.h linux-2.5.63-bk5/drivers/usb/storage/unusual_devs.h
--- linux-2.5.63-bk4/drivers/usb/storage/unusual_devs.h	Mon Feb 24 11:05:39 2003
+++ linux-2.5.63-bk5/drivers/usb/storage/unusual_devs.h	Mon Mar 31 12:18:55 2003
@@ -137,12 +137,12 @@
 		"LS-120 Camera",
 		US_SC_UFI, US_PR_CBI, NULL, 0),
 
-/* Reported by Peter Wächtler <pwaechtler@loewe-komp.de> */
-UNUSUAL_DEV(  0x04ce, 0x0002, 0x0074, 0x0074,
-		"ScanLogic",
-		"SL11R-IDE 0049SQFP-1.2 A002",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_FIX_INQUIRY ),
+/* From Yukihiro Nakai, via zaitcev@yahoo.com.
+ * This is needed for CB instead of CBI */
+UNUSUAL_DEV(  0x04da, 0x0d05, 0x0000, 0x0000,
+		"Sharp CE-CW05",
+		"CD-R/RW Drive",
+		US_SC_8070, US_PR_CB, NULL, 0),
 
 /* Most of the following entries were developed with the help of
  * Shuttle/SCM directly.
diff -urN linux-2.5.63-bk4/fs/ext3/namei.c linux-2.5.63-bk5/fs/ext3/namei.c
--- linux-2.5.63-bk4/fs/ext3/namei.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/fs/ext3/namei.c	Mon Mar 31 12:18:55 2003
@@ -533,7 +533,7 @@
 	struct dx_hash_info hinfo;
 	struct buffer_head *bh;
 	struct ext3_dir_entry_2 *de, *top;
-	static struct dx_frame frames[2], *frame;
+	struct dx_frame frames[2], *frame;
 	struct inode *dir;
 	int block, err;
 	int count = 0;
diff -urN linux-2.5.63-bk4/include/acpi/acconfig.h linux-2.5.63-bk5/include/acpi/acconfig.h
--- linux-2.5.63-bk4/include/acpi/acconfig.h	Mon Feb 24 11:05:39 2003
+++ linux-2.5.63-bk5/include/acpi/acconfig.h	Mon Mar 31 12:18:55 2003
@@ -72,7 +72,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20030122
+#define ACPI_CA_VERSION                 0x20030228
 
 /* Version of ACPI supported */
 
diff -urN linux-2.5.63-bk4/include/acpi/acdebug.h linux-2.5.63-bk5/include/acpi/acdebug.h
--- linux-2.5.63-bk4/include/acpi/acdebug.h	Mon Feb 24 11:05:10 2003
+++ linux-2.5.63-bk5/include/acpi/acdebug.h	Mon Mar 31 12:18:55 2003
@@ -177,6 +177,9 @@
 	char                            *object_arg);
 
 void
+acpi_db_display_gpes (void);
+
+void
 acpi_db_check_integrity (
 	void);
 
@@ -208,6 +211,10 @@
 	void                            *context,
 	void                            **return_value);
 
+void
+acpi_db_generate_gpe (
+	char                            *gpe_arg,
+	char                            *block_arg);
 
 /*
  * dbdisply - debug display commands
diff -urN linux-2.5.63-bk4/include/acpi/acevents.h linux-2.5.63-bk5/include/acpi/acevents.h
--- linux-2.5.63-bk4/include/acpi/acevents.h	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/include/acpi/acevents.h	Mon Mar 31 12:18:55 2003
@@ -91,14 +91,6 @@
 acpi_ev_init_global_lock_handler (
 	void);
 
-struct acpi_gpe_register_info *
-acpi_ev_get_gpe_register_info (
-	u32                             gpe_number);
-
-struct acpi_gpe_number_info *
-acpi_ev_get_gpe_number_info (
-	u32                             gpe_number);
-
 u32
 acpi_ev_get_gpe_number_index (
 	u32                             gpe_number);
@@ -117,17 +109,17 @@
  * Evgpe - GPE handling and dispatch
  */
 
-acpi_status
-acpi_ev_gpe_initialize (
-	void);
+struct acpi_gpe_event_info *
+acpi_ev_get_gpe_event_info (
+	u32                             gpe_number);
 
 acpi_status
-acpi_ev_init_gpe_control_methods (
+acpi_ev_gpe_initialize (
 	void);
 
 u32
 acpi_ev_gpe_dispatch (
-	u32                             gpe_number);
+	struct acpi_gpe_event_info      *gpe_event_info);
 
 u32
 acpi_ev_gpe_detect (
diff -urN linux-2.5.63-bk4/include/acpi/acglobal.h linux-2.5.63-bk5/include/acpi/acglobal.h
--- linux-2.5.63-bk4/include/acpi/acglobal.h	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk5/include/acpi/acglobal.h	Mon Mar 31 12:18:55 2003
@@ -234,22 +234,7 @@
 
 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 acpi_handle                         acpi_gbl_gpe_obj_handle;
-ACPI_EXTERN u32                                 acpi_gbl_gpe_register_count;
-ACPI_EXTERN u32                                 acpi_gbl_gpe_number_max;
-ACPI_EXTERN struct acpi_gpe_register_info      *acpi_gbl_gpe_register_info;
-ACPI_EXTERN struct acpi_gpe_number_info        *acpi_gbl_gpe_number_info;
-ACPI_EXTERN struct acpi_gpe_block_info          acpi_gbl_gpe_block_info[ACPI_MAX_GPE_BLOCKS];
-
-/*
- * GPE translation table
- * Indexed by the GPE number, returns a valid index into the global GPE tables.
- *
- * This table is needed because the GPE numbers supported by block 1 do not
- * have to be contiguous with the GPE numbers supported by block 0.
- */
-ACPI_EXTERN struct acpi_gpe_index_info         *acpi_gbl_gpe_number_to_index;
+ACPI_EXTERN struct acpi_gpe_block_info          *acpi_gbl_gpe_block_list_head;
 
 
 /*****************************************************************************
diff -urN linux-2.5.63-bk4/include/acpi/achware.h linux-2.5.63-bk5/include/acpi/achware.h
--- linux-2.5.63-bk4/include/acpi/achware.h	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/include/acpi/achware.h	Mon Mar 31 12:18:56 2003
@@ -115,29 +115,25 @@
 
 /* GPE support */
 
-u8
-acpi_hw_get_gpe_bit_mask (
-	u32                             gpe_number);
-
 acpi_status
 acpi_hw_enable_gpe (
-	u32                             gpe_number);
+	struct acpi_gpe_event_info      *gpe_event_info);
 
 void
 acpi_hw_enable_gpe_for_wakeup (
-	u32                             gpe_number);
+	struct acpi_gpe_event_info      *gpe_event_info);
 
 acpi_status
 acpi_hw_disable_gpe (
-	u32                             gpe_number);
+	struct acpi_gpe_event_info      *gpe_event_info);
 
 void
 acpi_hw_disable_gpe_for_wakeup (
-	u32                             gpe_number);
+	struct acpi_gpe_event_info      *gpe_event_info);
 
 acpi_status
 acpi_hw_clear_gpe (
-	u32                             gpe_number);
+	struct acpi_gpe_event_info      *gpe_event_info);
 
 acpi_status
 acpi_hw_get_gpe_status (
diff -urN linux-2.5.63-bk4/include/acpi/aclocal.h linux-2.5.63-bk5/include/acpi/aclocal.h
--- linux-2.5.63-bk4/include/acpi/aclocal.h	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk5/include/acpi/aclocal.h	Mon Mar 31 12:18:56 2003
@@ -308,25 +308,28 @@
  *
  ****************************************************************************/
 
-/* Information about each GPE register block */
+/* Information about each particular GPE level */
 
-struct acpi_gpe_block_info
+struct acpi_gpe_event_info
 {
-	struct acpi_generic_address     *block_address;
-	u16                             register_count;
-	u8                              block_base_number;
+	struct acpi_namespace_node              *method_node;   /* Method node for this GPE level */
+	acpi_gpe_handler                        handler;        /* Address of handler, if any */
+	void                                    *context;       /* Context to be passed to handler */
+	struct acpi_gpe_register_info           *register_info;
+	u8                                      type;           /* Level or Edge */
+	u8                                      bit_mask;
 };
 
 /* Information about a particular GPE register pair */
 
 struct acpi_gpe_register_info
 {
-	struct acpi_generic_address     status_address; /* Address of status reg */
-	struct acpi_generic_address     enable_address; /* Address of enable reg */
-	u8                              status;         /* Current value of status reg */
-	u8                              enable;         /* Current value of enable reg */
-	u8                              wake_enable;    /* Mask of bits to keep enabled when sleeping */
-	u8                              base_gpe_number; /* Base GPE number for this register */
+	struct acpi_generic_address             status_address; /* Address of status reg */
+	struct acpi_generic_address             enable_address; /* Address of enable reg */
+	u8                                      status;         /* Current value of status reg */
+	u8                                      enable;         /* Current value of enable reg */
+	u8                                      wake_enable;    /* Mask of bits to keep enabled when sleeping */
+	u8                                      base_gpe_number; /* Base GPE number for this register */
 };
 
 
@@ -334,23 +337,21 @@
 #define ACPI_GPE_EDGE_TRIGGERED         2
 
 
-/* Information about each particular GPE level */
+/* Information about each GPE register block */
 
-struct acpi_gpe_number_info
+struct acpi_gpe_block_info
 {
-	struct acpi_namespace_node      *method_node;   /* Method node for this GPE level */
-	acpi_gpe_handler                handler;        /* Address of handler, if any */
-	void                            *context;       /* Context to be passed to handler */
-	u8                              type;           /* Level or Edge */
-	u8                              bit_mask;
+	struct acpi_gpe_block_info              *previous;
+	struct acpi_gpe_block_info              *next;
+	struct acpi_gpe_block_info              *next_on_interrupt;
+	struct acpi_gpe_register_info           *register_info;
+	struct acpi_gpe_event_info              *event_info;
+	struct acpi_generic_address             block_address;
+	u32                                     register_count;
+	u8                                      block_base_number;
 };
 
 
-struct acpi_gpe_index_info
-{
-	u8                              number_index;
-};
-
 /* Information about each particular fixed event */
 
 struct acpi_fixed_event_handler
diff -urN linux-2.5.63-bk4/include/acpi/acpixf.h linux-2.5.63-bk5/include/acpi/acpixf.h
--- linux-2.5.63-bk4/include/acpi/acpixf.h	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk5/include/acpi/acpixf.h	Mon Mar 31 12:18:56 2003
@@ -339,6 +339,12 @@
  * Resource interfaces
  */
 
+typedef
+acpi_status (*ACPI_WALK_RESOURCE_CALLBACK) (
+	struct acpi_resource            *resource,
+	void                            *context);
+
+
 acpi_status
 acpi_get_current_resources(
 	acpi_handle                     device_handle,
@@ -350,6 +356,13 @@
 	struct acpi_buffer              *ret_buffer);
 
 acpi_status
+acpi_walk_resources (
+	acpi_handle                             device_handle,
+	char                                    *path,
+	ACPI_WALK_RESOURCE_CALLBACK     user_function,
+	void                                    *context);
+
+acpi_status
 acpi_set_current_resources (
 	acpi_handle                     device_handle,
 	struct acpi_buffer              *in_buffer);
@@ -359,6 +372,10 @@
 	acpi_handle                     bus_device_handle,
 	struct acpi_buffer              *ret_buffer);
 
+acpi_status
+acpi_resource_to_address64 (
+	struct acpi_resource            *resource,
+	struct acpi_resource_address64 *out);
 
 /*
  * Hardware (ACPI device) interfaces
@@ -399,6 +416,10 @@
 	u8                              sleep_state);
 
 acpi_status
+acpi_enter_sleep_state_s4bios (
+	void);
+
+acpi_status
 acpi_leave_sleep_state (
 	u8                              sleep_state);
 
diff -urN linux-2.5.63-bk4/include/acpi/acresrc.h linux-2.5.63-bk5/include/acpi/acresrc.h
--- linux-2.5.63-bk4/include/acpi/acresrc.h	Mon Feb 24 11:05:09 2003
+++ linux-2.5.63-bk5/include/acpi/acresrc.h	Mon Mar 31 12:18:56 2003
@@ -66,6 +66,12 @@
 	struct acpi_buffer              *ret_buffer);
 
 acpi_status
+acpi_rs_get_method_data (
+	acpi_handle                     handle,
+	char                            *path,
+	struct acpi_buffer              *ret_buffer);
+
+acpi_status
 acpi_rs_set_srs_method_data (
 	acpi_handle                     handle,
 	struct acpi_buffer              *ret_buffer);
diff -urN linux-2.5.63-bk4/include/acpi/acutils.h linux-2.5.63-bk5/include/acpi/acutils.h
--- linux-2.5.63-bk4/include/acpi/acutils.h	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk5/include/acpi/acutils.h	Mon Mar 31 12:18:56 2003
@@ -463,6 +463,8 @@
 #define METHOD_NAME__SEG        "_SEG"
 #define METHOD_NAME__BBN        "_BBN"
 #define METHOD_NAME__PRT        "_PRT"
+#define METHOD_NAME__CRS        "_CRS"
+#define METHOD_NAME__PRS        "_PRS"
 
 
 acpi_status
diff -urN linux-2.5.63-bk4/include/asm-generic/topology.h linux-2.5.63-bk5/include/asm-generic/topology.h
--- linux-2.5.63-bk4/include/asm-generic/topology.h	Mon Feb 24 11:05:07 2003
+++ linux-2.5.63-bk5/include/asm-generic/topology.h	Mon Mar 31 12:18:56 2003
@@ -47,6 +47,9 @@
 #ifndef node_to_memblk
 #define node_to_memblk(node)	(0)
 #endif
+#ifndef pcibus_to_cpumask
+#define pcibus_to_cpumask(bus)	(cpu_online_map)
+#endif
 
 /* Cross-node load balancing interval. */
 #ifndef NODE_BALANCE_RATE
diff -urN linux-2.5.63-bk4/include/asm-i386/mach-bigsmp/mach_apic.h linux-2.5.63-bk5/include/asm-i386/mach-bigsmp/mach_apic.h
--- linux-2.5.63-bk4/include/asm-i386/mach-bigsmp/mach_apic.h	Mon Mar 31 12:18:53 2003
+++ linux-2.5.63-bk5/include/asm-i386/mach-bigsmp/mach_apic.h	Mon Mar 31 12:18:56 2003
@@ -87,7 +87,8 @@
        return (int)cpu_2_logical_apicid[cpu];
  }
 
-static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
+static inline int mpc_apic_id(struct mpc_config_processor *m,
+			struct mpc_config_translation *translation_record)
 {
 	printk("Processor #%d %ld:%ld APIC version %d\n",
 	        m->mpc_apicid,
diff -urN linux-2.5.63-bk4/include/asm-i386/mach-default/mach_apic.h linux-2.5.63-bk5/include/asm-i386/mach-default/mach_apic.h
--- linux-2.5.63-bk4/include/asm-i386/mach-default/mach_apic.h	Mon Mar 31 12:18:53 2003
+++ linux-2.5.63-bk5/include/asm-i386/mach-default/mach_apic.h	Mon Mar 31 12:18:56 2003
@@ -79,7 +79,8 @@
 	return (1ul << phys_apicid);
 }
 
-static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
+static inline int mpc_apic_id(struct mpc_config_processor *m, 
+			struct mpc_config_translation *translation_record)
 {
 	printk("Processor #%d %ld:%ld APIC version %d\n",
 			m->mpc_apicid,
diff -urN linux-2.5.63-bk4/include/asm-i386/mach-numaq/mach_apic.h linux-2.5.63-bk5/include/asm-i386/mach-numaq/mach_apic.h
--- linux-2.5.63-bk4/include/asm-i386/mach-numaq/mach_apic.h	Mon Mar 31 12:18:53 2003
+++ linux-2.5.63-bk5/include/asm-i386/mach-numaq/mach_apic.h	Mon Mar 31 12:18:56 2003
@@ -73,8 +73,10 @@
 	return ( (logical_apicid&0xf) << (4*apicid_to_node(logical_apicid)) );
 }
 
-static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
+static inline int mpc_apic_id(struct mpc_config_processor *m, 
+			struct mpc_config_translation *translation_record)
 {
+	int quad = translation_record->trans_quad;
 	int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid);
 
 	printk("Processor #%d %ld:%ld APIC version %d (quad %d, apic %d)\n",
diff -urN linux-2.5.63-bk4/include/asm-i386/mach-summit/mach_apic.h linux-2.5.63-bk5/include/asm-i386/mach-summit/mach_apic.h
--- linux-2.5.63-bk4/include/asm-i386/mach-summit/mach_apic.h	Mon Mar 31 12:18:53 2003
+++ linux-2.5.63-bk5/include/asm-i386/mach-summit/mach_apic.h	Mon Mar 31 12:18:56 2003
@@ -90,7 +90,8 @@
 		return (1ul << apicid);
 }
 
-static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
+static inline int mpc_apic_id(struct mpc_config_processor *m, 
+			struct mpc_config_translation *translation_record)
 {
 	printk("Processor #%d %ld:%ld APIC version %d\n",
 			m->mpc_apicid,
diff -urN linux-2.5.63-bk4/include/asm-i386/numaq.h linux-2.5.63-bk5/include/asm-i386/numaq.h
--- linux-2.5.63-bk4/include/asm-i386/numaq.h	Mon Mar 31 12:18:53 2003
+++ linux-2.5.63-bk5/include/asm-i386/numaq.h	Mon Mar 31 12:18:56 2003
@@ -36,10 +36,11 @@
 #define MAX_ELEMENTS 256
 #define PAGES_PER_ELEMENT (16777216/256)
 
+extern int physnode_map[];
+#define pfn_to_nid(pfn)	({ physnode_map[(pfn) / PAGES_PER_ELEMENT]; })
 #define pfn_to_pgdat(pfn) NODE_DATA(pfn_to_nid(pfn))
 #define PHYSADDR_TO_NID(pa) pfn_to_nid(pa >> PAGE_SHIFT)
 #define MAX_NUMNODES		8
-extern int pfn_to_nid(unsigned long);
 extern void get_memcfg_numaq(void);
 #define get_memcfg_numa() get_memcfg_numaq()
 
diff -urN linux-2.5.63-bk4/include/asm-i386/topology.h linux-2.5.63-bk5/include/asm-i386/topology.h
--- linux-2.5.63-bk4/include/asm-i386/topology.h	Mon Feb 24 11:05:11 2003
+++ linux-2.5.63-bk5/include/asm-i386/topology.h	Mon Mar 31 12:18:56 2003
@@ -29,6 +29,8 @@
 
 #ifdef CONFIG_NUMA
 
+#include <asm/mpspec.h>
+
 /* Mappings between logical cpu number and node number */
 extern volatile unsigned long node_2_cpu_mask[];
 extern volatile int cpu_2_node[];
@@ -61,6 +63,12 @@
 /* Returns the number of the first MemBlk on Node 'node' */
 #define node_to_memblk(node) (node)
 
+/* Returns the number of the node containing PCI bus 'bus' */
+static inline unsigned long pcibus_to_cpumask(int bus)
+{
+	return node_to_cpumask(mp_bus_id_to_node[bus]);
+}
+
 /* Cross-node load balancing interval. */
 #define NODE_BALANCE_RATE 100
 
diff -urN linux-2.5.63-bk4/include/linux/suspend.h linux-2.5.63-bk5/include/linux/suspend.h
--- linux-2.5.63-bk4/include/linux/suspend.h	Mon Feb 24 11:05:13 2003
+++ linux-2.5.63-bk5/include/linux/suspend.h	Mon Mar 31 12:18:56 2003
@@ -73,6 +73,7 @@
 /* Communication between acpi and arch/i386/suspend.c */
 
 extern void do_suspend_lowlevel(int resume);
+extern void do_suspend_lowlevel_s4bios(int resume);
 
 #else
 static inline void software_suspend(void)
diff -urN linux-2.5.63-bk4/include/linux/usb.h linux-2.5.63-bk5/include/linux/usb.h
--- linux-2.5.63-bk4/include/linux/usb.h	Mon Feb 24 11:05:29 2003
+++ linux-2.5.63-bk5/include/linux/usb.h	Mon Mar 31 12:18:56 2003
@@ -960,8 +960,6 @@
 #define usb_rcvbulkpipe(dev,endpoint)	((PIPE_BULK << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
 #define usb_sndintpipe(dev,endpoint)	((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint))
 #define usb_rcvintpipe(dev,endpoint)	((PIPE_INTERRUPT << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN)
-#define usb_snddefctrl(dev)		((PIPE_CONTROL << 30))
-#define usb_rcvdefctrl(dev)		((PIPE_CONTROL << 30) | USB_DIR_IN)
 
 /* -------------------------------------------------------------------------- */
 
diff -urN linux-2.5.63-bk4/sound/oss/trident.c linux-2.5.63-bk5/sound/oss/trident.c
--- linux-2.5.63-bk4/sound/oss/trident.c	Mon Mar 31 12:18:53 2003
+++ linux-2.5.63-bk5/sound/oss/trident.c	Mon Mar 31 12:18:56 2003
@@ -3059,7 +3059,7 @@
         ncount = 10;
 	while(1) {
 		wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
-		if(!wcontrol & 0x8000)
+		if(!(wcontrol & 0x8000))
 			break;
 		if(ncount <= 0)
 			break;
