diff -Nru a/Documentation/00-INDEX b/Documentation/00-INDEX
--- a/Documentation/00-INDEX	Tue Mar  4 19:30:05 2003
+++ b/Documentation/00-INDEX	Tue Mar  4 19:30:05 2003
@@ -56,6 +56,8 @@
 	- info on Computone Intelliport II/Plus Multiport Serial Driver
 cpqarray.txt
 	- info on using Compaq's SMART2 Intelligent Disk Array Controllers.
+cpufreq/
+	- info on CPU frequency and voltage scaling
 cris/
 	- directory with info about Linux on CRIS architecture.
 devices.txt
diff -Nru a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
--- a/Documentation/DocBook/Makefile	Tue Mar  4 19:30:08 2003
+++ b/Documentation/DocBook/Makefile	Tue Mar  4 19:30:08 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 -Nru a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl
--- a/Documentation/DocBook/deviceiobook.tmpl	Tue Mar  4 19:30:08 2003
+++ b/Documentation/DocBook/deviceiobook.tmpl	Tue Mar  4 19:30:08 2003
@@ -152,7 +152,7 @@
       <para>
 	While the basic functions are defined to be synchronous with respect
 	to each other and ordered with respect to each other the busses the
-	devices sit on may themselves have asynchronocity. In paticular many
+	devices sit on may themselves have asynchronicity. In particular many
 	authors are burned by the fact that PCI bus writes are posted
 	asynchronously. A driver author must issue a read from the same
 	device to ensure that writes have occurred in the specific cases the
diff -Nru a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
--- a/Documentation/DocBook/kernel-api.tmpl	Tue Mar  4 19:30:03 2003
+++ b/Documentation/DocBook/kernel-api.tmpl	Tue Mar  4 19:30:03 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 -Nru a/Documentation/DocBook/parportbook.tmpl b/Documentation/DocBook/parportbook.tmpl
--- a/Documentation/DocBook/parportbook.tmpl	Tue Mar  4 19:30:04 2003
+++ b/Documentation/DocBook/parportbook.tmpl	Tue Mar  4 19:30:04 2003
@@ -1149,7 +1149,7 @@
    peripheral what transfer mode it would like to use, and the
    peripheral either accepts that mode or rejects it; if the mode is
    rejected, the host can try again with a different mode.  This is
-   the negotation phase.  Once the peripheral has accepted a
+   the negotiation phase.  Once the peripheral has accepted a
    particular transfer mode, data transfer can begin that mode.
   </para>
 
diff -Nru a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/DocBook/usb.tmpl	Tue Mar  4 19:30:14 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 -Nru a/Documentation/arm/XScale/IOP310/IQ80310 b/Documentation/arm/XScale/IOP310/IQ80310
--- a/Documentation/arm/XScale/IOP310/IQ80310	Tue Mar  4 19:30:13 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,295 +0,0 @@
-
-Board Overview
------------------------------
-
-The Cyclone IQ80310 board is an evaluation platform for Intel's 80200 Xscale
-CPU and 80312 Intelligent I/O chipset (collectively called IOP310 chipset).
-
-The 80312 contains dual PCI hoses (called the ATUs), a PCI-to-PCI bridge,
-three DMA channels (1 on secondary PCI, one on primary PCI ), I2C, I2O
-messaging unit, XOR unit for RAID operations, a bus performance monitoring
-unit, and a memory controller with ECC features.
-
-For more information on the board, see http://developer.intel.com/iio
-
-Port Status
------------------------------
-
-Supported:
-
-- MTD/JFFS/JFFS2
-- NFS root
-- RAMDISK root
-- 2ndary PCI slots
-- Onboard ethernet
-- Serial ports (ttyS0/S1)
-- Cache/TLB locking on 80200 CPU
-- Performance monitoring unit on 80200 CPU
-- 80200 Performance Monitoring Unit
-- Acting as a system controller on Cyclone 80303BP PCI backplane
-- DMA engines (EXPERIMENTAL)
-- 80312 Bus Performance Monitor (EXPERIMENTAL)
-- Application Accelerator Unit (XOR engine for RAID) (EXPERIMENTAL)
-- Messaging Unit (EXPERIMENTAL)
-
-TODO:
-- I2C
-
-Building the Kernel
------------------------------
-make iq80310_config
-make oldconfig
-make dep
-make zImage
-
-This will build an image setup for BOOTP/NFS root support.  To change this,
-just run make menuconfig and disable nfs root or add a "root=" option.
-
-Preparing the Hardware
------------------------------
-
-This document assumes you're using a Rev D or newer board running
-Redboot as the bootloader.
-
-The as-supplied RedBoot image appears to leave the first page of RAM
-in a corrupt state such that certain words in that page are unwritable
-and contain random data.  The value of the data, and the location within
-the first page changes with each boot, but is generally in the range
-0xa0000150 to 0xa0000fff.
-
-You can grab the source from the ECOS CVS or you can get a prebuilt image
-from:
-
-   ftp://source.mvista.com/pub/xscale/iop310/IQ80310/redboot.bin
-
-which is:
-
-    # strings redboot.bin | grep bootstrap
-    RedBoot(tm) bootstrap and debug environment, version UNKNOWN - built 14:58:21, Aug 15 2001
-
-md5sum of this version:
-
-    bcb96edbc6f8e55b16c165930b6e4439  redboot.bin
-
-You have two options to program it:
-
-1. Using the FRU program (see the instructions in the user manual).
-
-2. Using a Linux host, with MTD support built into the host kernel:
-   - ensure that the RedBoot image is not locked (issue the following
-     command under the existing RedBoot image):
-    RedBoot> fis unlock -f 0 -l 0x40000
-   - switch S3-1 and S3-2 on.
-   - reboot the host
-   - login as root
-   - identify the 80310 card:
-    # lspci
-    ...
-    00:0c.1 Memory controller: Intel Corporation 80310 IOP [IO Processor] (rev 01)
-   - in this example, bus 0, slot 0c, function 1.
-   - insert the MTD modules, and the PCI map module:
-    # insmod drivers/mtd/maps/pci.o
-   - locate the MTD device (using the bus, slot, function)
-    # cat /proc/mtd
-    dev:    size   erasesize  name
-    mtd0: 00800000 00020000 "00:0c.1"
-   - in this example, it is mtd device 0.  Yours will be different.
-     Check carefully.
-   - program the flash
-    # cat redboot.bin > /dev/mtdblock0
-   - check the kernel message log for errors (some cat commands don't
-     error on failure)   
-    # dmesg
-   - switch S3-1 and S3-2 off
-   - reboot host
-
-In any case, make sure you do an 'fis init' command once you boot with the new
-RedBoot image.
-
-
-
-Downloading Linux
------------------------------
-
-Assuming you have your development system setup to act as a bootp/dhcp
-server and running tftp:
-
-   RedBoot> load -r -b 0xa1008000 /tftpboot/zImage.xs
-   Raw file loaded 0xa1008000-0xa1094bd8
-
-If you're not using dhcp/tftp, you can use y-modem instead:
-
-   RedBoot> load -r -b 0xa1008000 -m y
-
-Note that on Rev D. of the board, tftp does not work due to intermittent
-interrupt issues, so you need to download using ymodem.
-
-Once the download is completed:
-
-   RedBoot> go 0xa1008000
-
-Root Devices
------------------------------
-
-A kernel is not useful without a root filesystem, and you have several
-choices with this board:  NFS root, RAMDISK, or JFFS/JFFS2.  For development
-purposes, it is suggested that you use NFS root for easy access to various
-tools.  Once you're ready to deploy, probably want to utilize JFFS/JFFS2 on
-the flash device.
-
-MTD on the IQ80310
------------------------------
-
-Linux on the IQ80310 supports RedBoot FIS paritioning if it is enabled.
-Out of the box, once you've done 'fis init' on RedBoot, you will get
-the following partitioning scheme:
-
-   root@192.168.0.14:~# cat /proc/mtd
-   dev:    size   erasesize  name
-   mtd0: 00040000 00020000 "RedBoot"
-   mtd1: 00040000 00020000 "RedBoot[backup]"
-   mtd2: 0075f000 00020000 "unallocated space"
-   mtd3: 00001000 00020000 "RedBoot config"
-   mtd4: 00020000 00020000 "FIS directory"
-
-To create an FIS directory, you need to use the fis command in RedBoot.
-As an example, you can burn the kernel into the flash once it's downloaded:
-
-   RedBoot> fis create -b 0xa1008000 -l 0x8CBAC -r 0xa1008000 -f 0x80000 kernel
-   ... Erase from 0x00080000-0x00120000: .....
-   ... Program from 0xa1008000-0xa1094bac at 0x00080000: .....
-   ... Unlock from 0x007e0000-0x00800000: .
-   ... Erase from 0x007e0000-0x00800000: .
-   ... Program from 0xa1fdf000-0xa1fff000 at 0x007e0000: .
-   ... Lock from 0x007e0000-0x00800000: .
-
-   RedBoot> fis list
-   Name              FLASH addr  Mem addr    Length      Entry point
-   RedBoot           0x00000000  0x00000000  0x00040000  0x00000000
-   RedBoot[backup]   0x00040000  0x00040000  0x00040000  0x00000000
-   RedBoot config    0x007DF000  0x007DF000  0x00001000  0x00000000
-   FIS directory     0x007E0000  0x007E0000  0x00020000  0x00000000
-   kernel            0x00080000  0xA1008000  0x000A0000  0x00000000
-
-This leads to the following Linux MTD setup:
-
-   mtroot@192.168.0.14:~# cat /proc/mtd
-   dev:    size   erasesize  name
-   mtd0: 00040000 00020000 "RedBoot"
-   mtd1: 00040000 00020000 "RedBoot[backup]"
-   mtd2: 000a0000 00020000 "kernel"
-   mtd3: 006bf000 00020000 "unallocated space"
-   mtd4: 00001000 00020000 "RedBoot config"
-   mtd5: 00020000 00020000 "FIS directory"
-
-Note that there is not a 1:1 mapping to the number of RedBoot paritions to
-MTD partitions as unused space also gets allocated into MTD partitions.
-
-As an aside, the -r option when creating the Kernel entry allows you to
-simply do an 'fis load kernel' to copy the image from flash into memory.
-You can then do an 'fis go 0xa1008000' to start Linux.
-
-If you choose to use static partitioning instead of the RedBoot partioning:
-
-   /dev/mtd0  0x00000000 - 0x0007ffff: Boot Monitor     (512k)
-   /dev/mtd1  0x00080000 - 0x0011ffff: Kernel Image     (640K)
-   /dev/mtd2  0x00120000 - 0x0071ffff: File System      (6M)
-   /dev/mtd3  0x00720000 - 0x00800000: RedBoot Reserved (896K)
-
-To use a JFFS1/2 root FS, you need to donwload the JFFS image using either
-tftp or ymodem, and then copy it to flash:
-
-   RedBoot> load -r -b 0xa1000000 /tftpboot/jffs.img
-   Raw file loaded 0xa1000000-0xa1600000
-   RedBoot> fis create -b 0xa1000000 -l 0x600000 -f 0x120000 jffs
-   ... Erase from 0x00120000-0x00720000: ..................................
-   ... Program from 0xa1000000-0xa1600000 at 0x00120000: ..................
-   ......................
-   ... Unlock from 0x007e0000-0x00800000: .
-   ... Erase from 0x007e0000-0x00800000: .
-   ... Program from 0xa1fdf000-0xa1fff000 at 0x007e0000: .
-   ... Lock from 0x007e0000-0x00800000: .
-   RedBoot> fis list
-   Name              FLASH addr  Mem addr    Length      Entry point
-   RedBoot           0x00000000  0x00000000  0x00040000  0x00000000
-   RedBoot[backup]   0x00040000  0x00040000  0x00040000  0x00000000
-   RedBoot config    0x007DF000  0x007DF000  0x00001000  0x00000000
-   FIS directory     0x007E0000  0x007E0000  0x00020000  0x00000000
-   kernel            0x00080000  0xA1008000  0x000A0000  0xA1008000
-   jffs              0x00120000  0x00120000  0x00600000  0x00000000
-
-This looks like this in Linux:
-
-   root@192.168.0.14:~# cat /proc/mtd
-   dev:    size   erasesize  name
-   mtd0: 00040000 00020000 "RedBoot"
-   mtd1: 00040000 00020000 "RedBoot[backup]"
-   mtd2: 000a0000 00020000 "kernel"
-   mtd3: 00600000 00020000 "jffs"
-   mtd4: 000bf000 00020000 "unallocated space"
-   mtd5: 00001000 00020000 "RedBoot config"
-   mtd6: 00020000 00020000 "FIS directory"
-
-You need to boot the kernel once and watch the boot messages to see how the
-JFFS RedBoot partition mapped into the MTD partition scheme.
-
-You can grab a pre-built JFFS image to use as a root file system at:
-
-   ftp://source.mvista.com/pub/xscale/iop310/IQ80310/jffs.img
-
-For detailed info on using MTD and creating a JFFS image go to:
-
-   http://www.linux-mtd.infradead.org.
-
-For details on using RedBoot's FIS commands, type 'fis help' or consult
-your RedBoot manual.
-
-Contributors
------------------------------
-
-Thanks to Intel Corporation for providing the hardware.
-
-John Clark <jclark@teamasa.com> - Initial discovery of RedBoot issues
-Dave Jiang <dave.jiang@intel.com> - IRQ demux fixes, AAU, DMA, MU
-Nicolas Pitre <nico@cam.org> - Initial port, cleanup, debugging
-Matt Porter <mporter@mvista.com> - PCI subsystem development, debugging
-Tim Sanders <tsanders@sanders.org> - Initial PCI code
-Mark Salter <msalter@redhat.com> - RedBoot fixes
-Deepak Saxena <dsaxena@mvista.com> - Cleanup, debug, cache lock, PMU
-
------------------------------
-Enjoy.
-
-If you have any problems please contact Deepak Saxena <dsaxena@mvista.com>
-
-A few notes from rmk
------------------------------
-
-These are notes of my initial experience getting the IQ80310 Rev D up and
-running.  In total, it has taken many hours to work out what's going on...
-The version of redboot used is:
-
- RedBoot(tm) bootstrap and debug environment, version UNKNOWN - built 14:58:21, Aug 15 2001
-
-
-1. I've had a corrupted download of the redboot.bin file from Montavista's
-   FTP site.  It would be a good idea if there were md5sums, sum or gpg
-   signatures available to ensure the integrity of the downloaded files.
-   The result of this was an apparantly 100% dead card.
-
-2. RedBoot Intel EtherExpress Pro 100 driver seems to be very unstable -
-   I've had it take out the whole of a 100mbit network for several minutes.
-   The Hub indiates ZERO activity, despite machines attempting to communicate.
-   Further to this, while tftping the kernel, the transfer will stall regularly,
-   and might even drop the link LED.
-
-3. There appears to be a bug in the Intel Documentation Pack that comes with
-   the IQ80310 board.  Serial port 1, which is the socket next to the LEDs
-   is address 0xfe810000, not 0xfe800000.
-
-   Note that RedBoot uses either serial port 1 OR serial port 2, so if you
-   have your console connected to the wrong port, you'll see redboot messages
-   but not kernel boot messages.
-
-4. Trying to use fconfig to setup a boot script fails - it hangs when trying
-   to erase the flash.
diff -Nru a/Documentation/arm/XScale/IOP3XX/IQ80310 b/Documentation/arm/XScale/IOP3XX/IQ80310
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/IOP3XX/IQ80310	Tue Mar  4 19:30:13 2003
@@ -0,0 +1,248 @@
+
+Board Overview
+-----------------------------
+
+The Cyclone IQ80310 board is an evaluation platform for Intel's 80200 Xscale
+CPU and 80312 Intelligent I/O chipset (collectively called IOP310 chipset).
+
+The 80312 contains dual PCI hoses (called the ATUs), a PCI-to-PCI bridge,
+three DMA channels (1 on secondary PCI, one on primary PCI ), I2C, I2O
+messaging unit, XOR unit for RAID operations, a bus performance monitoring
+unit, and a memory controller with ECC features.
+
+For more information on the board, see http://developer.intel.com/iio
+
+Port Status
+-----------------------------
+
+Supported:
+
+- MTD/JFFS/JFFS2
+- NFS root
+- RAMDISK root
+- 2ndary PCI slots
+- Onboard ethernet
+- Serial ports (ttyS0/S1)
+- Cache/TLB locking on 80200 CPU
+- Performance monitoring unit on 80200 CPU
+- 80200 Performance Monitoring Unit
+- Acting as a system controller on Cyclone 80303BP PCI backplane
+- DMA engines (EXPERIMENTAL)
+- 80312 Bus Performance Monitor (EXPERIMENTAL)
+- Application Accelerator Unit (XOR engine for RAID) (EXPERIMENTAL)
+- Messaging Unit (EXPERIMENTAL)
+
+TODO:
+- I2C
+
+Building the Kernel
+-----------------------------
+make iq80310_config
+make oldconfig
+make dep
+make zImage
+
+This will build an image setup for BOOTP/NFS root support.  To change this,
+just run make menuconfig and disable nfs root or add a "root=" option.
+
+Preparing the Hardware
+-----------------------------
+
+This document assumes you're using a Rev D or newer board running
+Redboot as the bootloader.  Note that the version of RedBoot provided
+with the boards has a major issue and you need to replace it with the
+latest RedBoot. You can grab the source from the ECOS CVS or you can
+get a prebuilt image and burn it in using FRU at:
+
+   ftp://source.mvista.com/pub/xscale/iq80310/redboot.bin
+
+Make sure you do an 'fis init' command once you boot with the new
+RedBoot image.
+
+
+
+Downloading Linux
+-----------------------------
+
+Assuming you have your development system setup to act as a bootp/dhcp
+server and running tftp:
+
+   RedBoot> load -r -b 0xa1008000 /tftpboot/zImage.xs
+   Raw file loaded 0xa1008000-0xa1094bd8
+
+If you're not using dhcp/tftp, you can use y-modem instead:
+
+   RedBoot> load -r -b 0xa1008000 -m y
+
+Note that on Rev D. of the board, tftp does not work due to intermittent
+interrupt issues, so you need to download using ymodem.
+
+Once the download is completed:
+
+   RedBoot> go 0xa1008000
+
+Root Devices
+-----------------------------
+
+A kernel is not useful without a root filesystem, and you have several
+choices with this board:  NFS root, RAMDISK, or JFFS/JFFS2.  For development
+purposes, it is suggested that you use NFS root for easy access to various
+tools.  Once you're ready to deploy, probably want to utilize JFFS/JFFS2 on
+the flash device.
+
+MTD on the IQ80310
+-----------------------------
+
+Linux on the IQ80310 supports RedBoot FIS paritioning if it is enabled.
+Out of the box, once you've done 'fis init' on RedBoot, you will get
+the following partitioning scheme:
+
+   root@192.168.0.14:~# cat /proc/mtd
+   dev:    size   erasesize  name
+   mtd0: 00040000 00020000 "RedBoot"
+   mtd1: 00040000 00020000 "RedBoot[backup]"
+   mtd2: 0075f000 00020000 "unallocated space"
+   mtd3: 00001000 00020000 "RedBoot config"
+   mtd4: 00020000 00020000 "FIS directory"
+
+To create an FIS directory, you need to use the fis command in RedBoot.
+As an example, you can burn the kernel into the flash once it's downloaded:
+
+   RedBoot> fis create -b 0xa1008000 -l 0x8CBAC -r 0xa1008000 -f 0x80000 kernel
+   ... Erase from 0x00080000-0x00120000: .....
+   ... Program from 0xa1008000-0xa1094bac at 0x00080000: .....
+   ... Unlock from 0x007e0000-0x00800000: .
+   ... Erase from 0x007e0000-0x00800000: .
+   ... Program from 0xa1fdf000-0xa1fff000 at 0x007e0000: .
+   ... Lock from 0x007e0000-0x00800000: .
+
+   RedBoot> fis list
+   Name              FLASH addr  Mem addr    Length      Entry point
+   RedBoot           0x00000000  0x00000000  0x00040000  0x00000000
+   RedBoot[backup]   0x00040000  0x00040000  0x00040000  0x00000000
+   RedBoot config    0x007DF000  0x007DF000  0x00001000  0x00000000
+   FIS directory     0x007E0000  0x007E0000  0x00020000  0x00000000
+   kernel            0x00080000  0xA1008000  0x000A0000  0x00000000
+
+This leads to the following Linux MTD setup:
+
+   mtroot@192.168.0.14:~# cat /proc/mtd
+   dev:    size   erasesize  name
+   mtd0: 00040000 00020000 "RedBoot"
+   mtd1: 00040000 00020000 "RedBoot[backup]"
+   mtd2: 000a0000 00020000 "kernel"
+   mtd3: 006bf000 00020000 "unallocated space"
+   mtd4: 00001000 00020000 "RedBoot config"
+   mtd5: 00020000 00020000 "FIS directory"
+
+Note that there is not a 1:1 mapping to the number of RedBoot paritions to
+MTD partitions as unused space also gets allocated into MTD partitions.
+
+As an aside, the -r option when creating the Kernel entry allows you to
+simply do an 'fis load kernel' to copy the image from flash into memory.
+You can then do an 'fis go 0xa1008000' to start Linux.
+
+If you choose to use static partitioning instead of the RedBoot partioning:
+
+   /dev/mtd0  0x00000000 - 0x0007ffff: Boot Monitor     (512k)
+   /dev/mtd1  0x00080000 - 0x0011ffff: Kernel Image     (640K)
+   /dev/mtd2  0x00120000 - 0x0071ffff: File System      (6M)
+   /dev/mtd3  0x00720000 - 0x00800000: RedBoot Reserved (896K)
+
+To use a JFFS1/2 root FS, you need to donwload the JFFS image using either
+tftp or ymodem, and then copy it to flash:
+
+   RedBoot> load -r -b 0xa1000000 /tftpboot/jffs.img
+   Raw file loaded 0xa1000000-0xa1600000
+   RedBoot> fis create -b 0xa1000000 -l 0x600000 -f 0x120000 jffs
+   ... Erase from 0x00120000-0x00720000: ..................................
+   ... Program from 0xa1000000-0xa1600000 at 0x00120000: ..................
+   ......................
+   ... Unlock from 0x007e0000-0x00800000: .
+   ... Erase from 0x007e0000-0x00800000: .
+   ... Program from 0xa1fdf000-0xa1fff000 at 0x007e0000: .
+   ... Lock from 0x007e0000-0x00800000: .
+   RedBoot> fis list
+   Name              FLASH addr  Mem addr    Length      Entry point
+   RedBoot           0x00000000  0x00000000  0x00040000  0x00000000
+   RedBoot[backup]   0x00040000  0x00040000  0x00040000  0x00000000
+   RedBoot config    0x007DF000  0x007DF000  0x00001000  0x00000000
+   FIS directory     0x007E0000  0x007E0000  0x00020000  0x00000000
+   kernel            0x00080000  0xA1008000  0x000A0000  0xA1008000
+   jffs              0x00120000  0x00120000  0x00600000  0x00000000
+
+This looks like this in Linux:
+
+   root@192.168.0.14:~# cat /proc/mtd
+   dev:    size   erasesize  name
+   mtd0: 00040000 00020000 "RedBoot"
+   mtd1: 00040000 00020000 "RedBoot[backup]"
+   mtd2: 000a0000 00020000 "kernel"
+   mtd3: 00600000 00020000 "jffs"
+   mtd4: 000bf000 00020000 "unallocated space"
+   mtd5: 00001000 00020000 "RedBoot config"
+   mtd6: 00020000 00020000 "FIS directory"
+
+You need to boot the kernel once and watch the boot messages to see how the
+JFFS RedBoot partition mapped into the MTD partition scheme.
+
+You can grab a pre-built JFFS image to use as a root file system at:
+
+   ftp://source.mvista.com/pub/xscale/iq80310/jffs.img
+
+For detailed info on using MTD and creating a JFFS image go to:
+
+   http://www.linux-mtd.infradead.org.
+
+For details on using RedBoot's FIS commands, type 'fis help' or consult
+your RedBoot manual.
+
+Contributors
+-----------------------------
+
+Thanks to Intel Corporation for providing the hardware.
+
+John Clark <jclark@teamasa.com> - Initial discovery of RedBoot issues
+Dave Jiang <dave.jiang@intel.com> - IRQ demux fixes, AAU, DMA, MU
+Nicolas Pitre <nico@cam.org> - Initial port, cleanup, debugging
+Matt Porter <mporter@mvista.com> - PCI subsystem development, debugging
+Tim Sanders <tsanders@sanders.org> - Initial PCI code
+Mark Salter <msalter@redhat.com> - RedBoot fixes
+Deepak Saxena <dsaxena@mvista.com> - Cleanup, debug, cache lock, PMU
+
+-----------------------------
+Enjoy.
+
+If you have any problems please contact Deepak Saxena <dsaxena@mvista.com>
+
+A few notes from rmk
+-----------------------------
+
+These are notes of my initial experience getting the IQ80310 Rev D up and
+running.  In total, it has taken many hours to work out what's going on...
+The version of redboot used is:
+
+ RedBoot(tm) bootstrap and debug environment, version UNKNOWN - built 14:58:21, Aug 15 2001
+
+
+1. I've had a corrupted download of the redboot.bin file from Montavista's
+   FTP site.  It would be a good idea if there were md5sums, sum or gpg
+   signatures available to ensure the integrity of the downloaded files.
+   The result of this was an apparantly 100% dead card.
+
+2. RedBoot Intel EtherExpress Pro 100 driver seems to be very unstable -
+   I've had it take out the whole of a 100mbit network for several minutes.
+   The Hub indiates ZERO activity, despite machines attempting to communicate.
+   Further to this, while tftping the kernel, the transfer will stall regularly,
+   and might even drop the link LED.
+
+3. There appears to be a bug in the Intel Documentation Pack that comes with
+   the IQ80310 board.  Serial port 1, which is the socket next to the LEDs
+   is address 0xfe810000, not 0xfe800000.
+
+   Note that RedBoot uses either serial port 1 OR serial port 2, so if you
+   have your console connected to the wrong port, you'll see redboot messages
+   but not kernel boot messages.
+
+4. Trying to use fconfig to setup a boot script fails - it hangs when trying
+   to erase the flash.
diff -Nru a/Documentation/arm/XScale/IOP3XX/IQ80321 b/Documentation/arm/XScale/IOP3XX/IQ80321
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/IOP3XX/IQ80321	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,216 @@
+
+Board Overview
+-----------------------------
+
+The Worcester IQ80321 board is an evaluation platform for Intel's 80321 Xscale
+CPU (sometimes called IOP321 chipset).
+
+The 80321 contains a single PCI hose (called the ATUs), a PCI-to-PCI bridge,
+two DMA channels, I2C, I2O messaging unit, XOR unit for RAID operations,
+a bus performance monitoring unit, and a memory controller with ECC features.
+
+For more information on the board, see http://developer.intel.com/iio
+
+Port Status
+-----------------------------
+
+Supported:
+
+- MTD/JFFS/JFFS2 root
+- NFS root
+- RAMDISK root
+- Serial port (ttyS0)
+- Cache/TLB locking on 80321 CPU
+- Performance monitoring unit on 80321 CPU
+
+TODO:
+
+- DMA engines
+- I2C
+- 80321 Bus Performance Monitor
+- Application Accelerator Unit (XOR engine for RAID)
+- I2O Messaging Unit
+- I2C unit
+- SSP
+
+Building the Kernel
+-----------------------------
+make iq80321_config
+make oldconfig
+make dep
+make zImage
+
+This will build an image setup for BOOTP/NFS root support.  To change this,
+just run make menuconfig and disable nfs root or add a "root=" option.
+
+Preparing the Hardware
+-----------------------------
+
+Make sure you do an 'fis init' command once you boot with the new
+RedBoot image.
+
+Downloading Linux
+-----------------------------
+
+Assuming you have your development system setup to act as a bootp/dhcp
+server and running tftp:
+
+NOTE: The 80321 board uses a different default memory map than the 80310.
+
+   RedBoot> load -r -b 0x01008000 -m y
+
+Once the download is completed:
+
+   RedBoot> go 0x01008000
+
+There is a version of RedBoot floating around that has DHCP support, but
+I've never been able to cleanly transfer a kernel image and have it run.
+
+Root Devices
+-----------------------------
+
+A kernel is not useful without a root filesystem, and you have several
+choices with this board:  NFS root, RAMDISK, or JFFS/JFFS2.  For development
+purposes, it is suggested that you use NFS root for easy access to various
+tools.  Once you're ready to deploy, probably want to utilize JFFS/JFFS2 on
+the flash device.
+
+MTD on the IQ80321
+-----------------------------
+
+Linux on the IQ80321 supports RedBoot FIS paritioning if it is enabled.
+Out of the box, once you've done 'fis init' on RedBoot, you will get
+the following partitioning scheme:
+
+   root@192.168.0.14:~# cat /proc/mtd
+   dev:    size   erasesize  name
+   mtd0: 00040000 00020000 "RedBoot"
+   mtd1: 00040000 00020000 "RedBoot[backup]"
+   mtd2: 0075f000 00020000 "unallocated space"
+   mtd3: 00001000 00020000 "RedBoot config"
+   mtd4: 00020000 00020000 "FIS directory"
+
+To create an FIS directory, you need to use the fis command in RedBoot.
+As an example, you can burn the kernel into the flash once it's downloaded:
+
+   RedBoot> fis create -b 0x01008000 -l 0x8CBAC -r 0x01008000 -f 0x80000 kernel
+   ... Erase from 0x00080000-0x00120000: .....
+   ... Program from 0x01008000-0x01094bac at 0x00080000: .....
+   ... Unlock from 0x007e0000-0x00800000: .
+   ... Erase from 0x007e0000-0x00800000: .
+   ... Program from 0x01fdf000-0x01fff000 at 0x007e0000: .
+   ... Lock from 0x007e0000-0x00800000: .
+
+   RedBoot> fis list
+   Name              FLASH addr  Mem addr    Length      Entry point
+   RedBoot           0x00000000  0x00000000  0x00040000  0x00000000
+   RedBoot[backup]   0x00040000  0x00040000  0x00040000  0x00000000
+   RedBoot config    0x007DF000  0x007DF000  0x00001000  0x00000000
+   FIS directory     0x007E0000  0x007E0000  0x00020000  0x00000000
+   kernel            0x00080000  0x01008000  0x000A0000  0x00000000
+
+This leads to the following Linux MTD setup:
+
+   mtroot@192.168.0.14:~# cat /proc/mtd
+   dev:    size   erasesize  name
+   mtd0: 00040000 00020000 "RedBoot"
+   mtd1: 00040000 00020000 "RedBoot[backup]"
+   mtd2: 000a0000 00020000 "kernel"
+   mtd3: 006bf000 00020000 "unallocated space"
+   mtd4: 00001000 00020000 "RedBoot config"
+   mtd5: 00020000 00020000 "FIS directory"
+
+Note that there is not a 1:1 mapping to the number of RedBoot paritions to
+MTD partitions as unused space also gets allocated into MTD partitions.
+
+As an aside, the -r option when creating the Kernel entry allows you to
+simply do an 'fis load kernel' to copy the image from flash into memory.
+You can then do an 'fis go 0x01008000' to start Linux.
+
+If you choose to use static partitioning instead of the RedBoot partioning:
+
+   /dev/mtd0  0x00000000 - 0x0007ffff: Boot Monitor     (512k)
+   /dev/mtd1  0x00080000 - 0x0011ffff: Kernel Image     (640K)
+   /dev/mtd2  0x00120000 - 0x0071ffff: File System      (6M)
+   /dev/mtd3  0x00720000 - 0x00800000: RedBoot Reserved (896K)
+
+To use a JFFS1/2 root FS, you need to donwload the JFFS image using either
+tftp or ymodem, and then copy it to flash:
+
+   RedBoot> load -r -b 0x01000000 /tftpboot/jffs.img
+   Raw file loaded 0x01000000-0x01600000
+   RedBoot> fis create -b 0x01000000 -l 0x600000 -f 0x120000 jffs
+   ... Erase from 0x00120000-0x00720000: ..................................
+   ... Program from 0x01000000-0x01600000 at 0x00120000: ..................
+   ......................
+   ... Unlock from 0x007e0000-0x00800000: .
+   ... Erase from 0x007e0000-0x00800000: .
+   ... Program from 0x01fdf000-0x01fff000 at 0x007e0000: .
+   ... Lock from 0x007e0000-0x00800000: .
+   RedBoot> fis list
+   Name              FLASH addr  Mem addr    Length      Entry point
+   RedBoot           0x00000000  0x00000000  0x00040000  0x00000000
+   RedBoot[backup]   0x00040000  0x00040000  0x00040000  0x00000000
+   RedBoot config    0x007DF000  0x007DF000  0x00001000  0x00000000
+   FIS directory     0x007E0000  0x007E0000  0x00020000  0x00000000
+   kernel            0x00080000  0x01008000  0x000A0000  0x01008000
+   jffs              0x00120000  0x00120000  0x00600000  0x00000000
+
+This looks like this in Linux:
+
+   root@192.168.0.14:~# cat /proc/mtd
+   dev:    size   erasesize  name
+   mtd0: 00040000 00020000 "RedBoot"
+   mtd1: 00040000 00020000 "RedBoot[backup]"
+   mtd2: 000a0000 00020000 "kernel"
+   mtd3: 00600000 00020000 "jffs"
+   mtd4: 000bf000 00020000 "unallocated space"
+   mtd5: 00001000 00020000 "RedBoot config"
+   mtd6: 00020000 00020000 "FIS directory"
+
+You need to boot the kernel once and watch the boot messages to see how the
+JFFS RedBoot partition mapped into the MTD partition scheme.
+
+You can grab a pre-built JFFS image to use as a root file system at:
+
+   ftp://source.mvista.com/pub/xscale/iq80310/jffs.img
+
+For detailed info on using MTD and creating a JFFS image go to:
+
+   http://www.linux-mtd.infradead.org.
+
+For details on using RedBoot's FIS commands, type 'fis help' or consult
+your RedBoot manual.
+
+BUGS and ISSUES
+-----------------------------
+
+* As shipped from Intel, pre-production boards have two issues:
+
+- The on board ethernet is disabled S8E1-2 is off. You will need to turn it on.
+
+- The PCIXCAPs are configured for a 100Mhz clock, but the clock selected is
+  actually only 66Mhz. This causes the wrong PPL multiplier to be used and the
+  board only runs at 400Mhz instead of 600Mhz. The way to observe this is to
+  use a independent clock to time a "sleep 10" command from the prompt. If it
+  takes 15 seconds instead of 10, you are running at 400Mhz.
+
+- The experimental IOP310 drivers for the AAU, DMA, etc. are not supported yet.
+
+Contributors
+-----------------------------
+The port to the IQ80321 was performed by:
+
+Rory Bolt <rorybolt@pacbell.net> - Initial port, debugging.
+
+This port was based on the IQ80310 port with the following contributors:
+
+Nicolas Pitre <nico@cam.org> - Initial port, cleanup, debugging
+Matt Porter <mporter@mvista.com> - PCI subsystem development, debugging
+Tim Sanders <tsanders@sanders.org> - Initial PCI code
+Deepak Saxena <dsaxena@mvista.com> - Cleanup, debug, cache lock, PMU
+
+The port is currently maintained by Deepak Saxena <dsaxena@mvista.com>
+
+-----------------------------
+Enjoy.
diff -Nru a/Documentation/arm/XScale/IOP3XX/aau.txt b/Documentation/arm/XScale/IOP3XX/aau.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/IOP3XX/aau.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,178 @@
+Support functions for the Intel 80310 AAU
+===========================================
+
+Dave Jiang <dave.jiang@intel.com>
+Last updated: 09/18/2001
+
+The Intel 80312 companion chip in the 80310 chipset contains an AAU. The
+AAU is capable of processing up to 8 data block sources and perform XOR
+operations on them. This unit is typically used to accelerated XOR
+operations utilized by RAID storage device drivers such as RAID 5. This
+API is designed to provide a set of functions to take adventage of the
+AAU. The AAU can also be used to transfer data blocks and used as a memory
+copier. The AAU transfer the memory faster than the operation performed by
+using CPU copy therefore it is recommended to use the AAU for memory copy.
+
+------------------
+int aau_request(u32 *aau_context, const char *device_id);
+This function allows the user the acquire the control of the the AAU. The
+function will return a context of AAU to the user and allocate
+an interrupt for the AAU. The user must pass the context as a parameter to
+various AAU API calls.
+
+int aau_queue_buffer(u32 aau_context, aau_head_t *listhead);
+This function starts the AAU operation. The user must create a SGL
+header with a SGL attached. The format is presented below. The SGL is
+built from kernel memory.
+
+/* hardware descriptor */
+typedef struct _aau_desc
+{
+    u32 NDA;                    /* next descriptor address [READONLY] */
+    u32 SAR[AAU_SAR_GROUP];     /* src addrs */
+    u32 DAR;                    /* destination addr */
+    u32 BC;                     /* byte count */
+    u32 DC;                     /* descriptor control */
+    u32 SARE[AAU_SAR_GROUP];    /* extended src addrs */
+} aau_desc_t;
+
+/* user SGL format */
+typedef struct _aau_sgl
+{
+    aau_desc_t          aau_desc;  /* AAU HW Desc */
+    u32		        status;    /* status of SGL [READONLY] */
+    struct _aau_sgl	*next;     /* pointer to next SG [READONLY] */
+    void                *dest;     /* destination addr */
+    void                *src[AAU_SAR_GROUP]; 	    /* source addr[4] */
+    void                *ext_src[AAU_SAR_GROUP];    /* ext src addr[4] */
+    u32                 total_src; /* total number of source */
+} aau_sgl_t;
+
+/* header for user SGL */
+typedef struct _aau_head
+{
+    u32		total;      /* total descriptors allocated */
+    u32         status;     /* SGL status */
+    aau_sgl_t   *list;      /* ptr to head of list */
+    aau_callback_t  callback;  /* callback func ptr */
+} aau_head_t;
+
+
+The function will call aau_start() and start the AAU after it queues
+the SGL to the processing queue. When the function will either
+a. Sleep on the wait queue aau->wait_q if no callback has been provided, or
+b. Continue and then call the provided callback function when DMA interrupt
+   has been triggered.
+
+int aau_suspend(u32 aau_context);
+Stops/Suspends the AAU operation
+
+int aau_free(u32 aau_context);
+Frees the ownership of AAU. Called when no longer need AAU service.
+
+aau_sgl_t * aau_get_buffer(u32 aau_context, int num_buf);
+This function obtains an AAU SGL for the user. User must specify the number
+of descriptors to be allocated in the chain that is returned.
+
+void aau_return_buffer(u32 aau_context, aau_sgl_t *list);
+This function returns all SGL back to the API after user is done.
+
+int aau_memcpy(void *dest, void *src, u32 size);
+This function is a short cut for user to do memory copy utilizing the AAU for
+better large block memory copy vs using the CPU. This is similar to using
+typical memcpy() call.
+
+* User is responsible for the source address(es) and the destination address.
+  The source and destination should all be cached memory.
+
+
+
+void aau_test()
+{
+	u32 aau;
+	char dev_id[] = "AAU";
+	int size = 2;
+	int err = 0;
+	aau_head_t *head;
+	aau_sgl_t *list;
+	u32 i;
+	u32 result = 0;
+	void *src, *dest;
+
+	printk("Starting AAU test\n");
+	if((err = aau_request(&aau, dev_id))<0)
+	{
+		printk("test - AAU request failed: %d\n", err);
+		return;
+	}
+	else
+	{
+		printk("test - AAU request successful\n");
+	}
+
+	head = kmalloc(sizeof(aau_head_t), GFP_KERNEL);
+	head->total = size;
+	head->status = 0;
+	head->callback = NULL;
+
+	list = aau_get_buffer(aau, size);
+	if(!list)
+	{
+		printk("Can't get buffers\n");
+		return;
+	}
+	head->list = list;
+
+	src = kmalloc(1024, GFP_KERNEL);
+	dest = kmalloc(1024, GFP_KERNEL);
+
+	while(list)
+	{
+		list->status = 0;
+		list->aau_desc->SAR[0] = (u32)src;
+		list->aau_desc->DAR = (u32)dest;
+		list->aau_desc->BC = 1024;
+
+		/* see iop310-aau.h for more DCR commands */
+		list->aau_desc->DC = AAU_DCR_WRITE | AAU_DCR_BLKCTRL_1_DF;
+		if(!list->next)
+		{
+			list->aau_desc->DC = AAU_DCR_IE;
+			break;
+		}
+		list = list->next;
+	}
+
+	printk("test- Queueing buffer for AAU operation\n");
+	err = aau_queue_buffer(aau, head);
+	if(err >= 0)
+	{
+		printk("AAU Queue Buffer is done...\n");
+	}
+	else
+	{
+		printk("AAU Queue Buffer failed...: %d\n", err);
+	}
+
+
+
+#if 1
+	printk("freeing the AAU\n");
+	aau_return_buffer(aau, head->list);
+	aau_free(aau);
+	kfree(src);
+	kfree(dest);
+	kfree((void *)head);
+#endif
+}
+
+All Disclaimers apply. Use this at your own discretion. Neither Intel nor I
+will be responsible if anything goes wrong. =)
+
+
+TODO
+____
+* Testing
+* Do zero-size AAU transfer/channel at init
+  so all we have to do is chainining
+
diff -Nru a/Documentation/arm/XScale/IOP3XX/dma.txt b/Documentation/arm/XScale/IOP3XX/dma.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/IOP3XX/dma.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,214 @@
+Support functions forthe Intel 80310 DMA channels
+==================================================
+
+Dave Jiang <dave.jiang@intel.com>
+Last updated: 09/18/2001
+
+The Intel 80310 XScale chipset provides 3 DMA channels via the 80312 I/O
+companion chip. Two of them resides on the primary PCI bus and one on the
+secondary PCI bus.
+
+The DMA API provided is not compatible with the generic interface in the
+ARM tree unfortunately due to how the 80312 DMACs work. Hopefully some time
+in the near future a software interface can be done to bridge the differences.
+The DMA API has been modeled after Nicholas Pitre's SA11x0 DMA API therefore
+they will look somewhat similar.
+
+
+80310 DMA API
+-------------
+
+int dma_request(dmach_t channel, const char *device_id);
+
+This function will attempt to allocate the channel depending on what the
+user requests:
+
+IOP310_DMA_P0: PCI Primary 1
+IOP310_DMA_P1: PCI Primary 2
+IOP310_DMA_S0: PCI Secondary 1
+/*EOF*/
+
+Once the user allocates the DMA channel it is owned until released. Although
+other users can also use the same DMA channel, but no new resources will be
+allocated. The function will return the allocated channel number if successful.
+
+int dma_queue_buffer(dmach_t channel, dma_sghead_t *listhead);
+
+The user will construct a SGL in the form of below:
+/*
+ * Scattered Gather DMA List for user
+ */
+typedef struct _dma_desc
+{
+    u32  NDAR;       /* next descriptor adress [READONLY] */
+    u32  PDAR;       /* PCI address */
+    u32  PUADR;      /* upper PCI address */
+    u32  LADR;       /* local address */
+    u32  BC;         /* byte count */
+    u32  DC;         /* descriptor control */
+} dma_desc_t;
+
+typedef struct _dma_sgl
+{
+    dma_desc_t      dma_desc;     /* DMA descriptor */
+    u32             status;       /* descriptor status [READONLY] */
+    u32	    	    data;	  /* user defined data */
+    struct _dma_sgl *next;	  /* next descriptor [READONLY] */
+} dma_sgl_t;
+
+/* dma sgl head */
+typedef struct _dma_head
+{
+    u32		    total;	/* total elements in SGL */
+    u32		    status;	/* status of sgl */
+    u32		    mode;	/* read or write mode */
+    dma_sgl_t	    *list;	/* pointer to list */
+    dma_callback_t  callback;   /* callback function */
+} dma_head_t;
+
+
+The user shall allocate user SGL elements by calling the function:
+dma_get_buffer(). This function will give the user an SGL element. The user
+is responsible for creating the SGL head however. The user is also
+responsible for allocating the memory for DMA data. The following code segment
+shows how a DMA operation can be performed:
+
+#include <asm/arch/iop310-dma.h>
+
+void dma_test(void)
+{
+	char dev_id[] = "Primary 0";
+	dma_head_t *sgl_head = NULL;
+	dma_sgl_t *sgl = NULL;
+	int err = 0;
+	int channel = -1;
+	u32 *test_ptr = 0;
+	DECLARE_WAIT_QUEUE_HEAD(wait_q);
+
+
+	*(IOP310_ATUCR) = (IOP310_ATUCR_PRIM_OUT_ENAB |
+			IOP310_ATUCR_DIR_ADDR_ENAB);
+
+	channel = dma_request(IOP310_DMA_P0, dev_id);
+
+	sgl_head = (dma_head_t *)kmalloc(sizeof(dma_head_t), GFP_KERNEL);
+	sgl_head->callback = NULL;      /* no callback created */
+	sgl_head->total = 2; /* allocating 2 DMA descriptors */
+	sgl_head->mode = (DMA_MOD_WRITE);
+	sgl_head->status = 0;
+
+	/* now we get the two descriptors */
+	sgl = dma_get_buffer(channel, 2);
+
+    	/* we set the header to point to the list we allocated */
+    	sgl_head->list = sgl;
+
+	/* allocate 1k of DMA data */
+    	sgl->data = (u32)kmalloc(1024, GFP_KERNEL);
+
+    	/* Local address is physical */
+	sgl->dma_desc.LADR = (u32)virt_to_phys(sgl->data);
+
+	/* write to arbitrary location over the PCI bus */
+    	sgl->dma_desc.PDAR = 0x00600000;
+	sgl->dma_desc.PUADR = 0;
+	sgl->dma_desc.BC = 1024;
+
+    	/* set write & invalidate PCI command */
+	sgl->dma_desc.DC = DMA_DCR_PCI_MWI;
+	sgl->status = 0;
+
+    	/* set a pattern */
+    	memset(sgl->data, 0xFF, 1024);
+
+	/* User's responsibility to keep buffers cached coherent */
+	cpu_dcache_clean(sgl->data, sgl->data + 1024);
+
+	sgl = sgl->next;
+
+	sgl->data = (u32)kmalloc(1024, GFP_KERNEL);
+	sgl->dma_desc.LADR = (u32)virt_to_phys(sgl->data);
+	sgl->dma_desc.PDAR = 0x00610000;
+	sgl->dma_desc.PUADR = 0;
+	sgl->dma_desc.BC = 1024;
+
+	/* second descriptor has interrupt flag enabled */
+	sgl->dma_desc.DC = (DMA_DCR_PCI_MWI | DMA_DCR_IE);
+
+	/* must set end of chain flag */
+	sgl->status = DMA_END_CHAIN; /* DO NOT FORGET THIS!!!! */
+
+    	memset(sgl->data, 0x0f, 1024);
+	/* User's responsibility to keep buffers cached coherent */
+	cpu_dcache_clean(sgl->data, sgl->data + 1024);
+
+    	/* queing the buffer, this function will sleep since no callback */
+    	err = dma_queue_buffer(channel, sgl_head);
+
+    	/* now we are woken from DMA complete */
+
+    	/* do data operations here */
+
+    	/* free DMA data if necessary */
+
+	/* return the descriptors */
+	dma_return_buffer(channel, sgl_head->list);
+
+	/* free the DMA */
+	dma_free(channel);
+
+	kfree((void *)sgl_head);
+}
+
+
+dma_sgl_t * dma_get_buffer(dmach_t channel, int buf_num);
+
+This call allocates DMA descriptors for the user.
+
+
+void dma_return_buffer(dmach_t channel, dma_sgl_t *list);
+
+This call returns the allocated descriptors back to the API.
+
+
+int dma_suspend(dmach_t channel);
+
+This call suspends any DMA transfer on the given channel.
+
+
+
+int dma_resume(dmach_t channel);
+
+This call resumes a DMA transfer which would have been stopped through
+dma_suspend().
+
+
+int dma_flush_all(dmach_t channel);
+
+This completely flushes all queued buffers and on-going DMA transfers on a
+given channel. This is called when DMA channel errors have occured.
+
+
+void dma_free(dmach_t channel);
+
+This clears all activities on a given DMA channel and releases it for future
+requests.
+
+
+
+Buffer Allocation
+-----------------
+It is the user's responsibility to allocate, free, and keep track of the
+allocated DMA data memory. Upon calling dma_queue_buffer() the user must
+relinquish the control of the buffers to the kernel and not change the
+state of the buffers that it has passed to the kernel. The user will regain
+the control of the buffers when it has been woken up by the bottom half of
+the DMA interrupt handler. The user can allocate cached buffers or non-cached
+via pci_alloc_consistent(). It is the user's responsibility to ensure that
+the data is cache coherent.
+
+*Reminder*
+The user is responsble to ensure the ATU is setup properly for DMA transfers.
+
+All Disclaimers apply. Use this at your own discretion. Neither Intel nor I
+will be responsible ifanything goes wrong.
diff -Nru a/Documentation/arm/XScale/IOP3XX/message.txt b/Documentation/arm/XScale/IOP3XX/message.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/IOP3XX/message.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,110 @@
+Support functions for the Intel 80310 MU
+===========================================
+
+Dave Jiang <dave.jiang@intel.com>
+Last updated: 10/11/2001
+
+The messaging unit of the IOP310 contains 4 components and is utilized for
+passing messages between the PCI agents on the primary bus and the Intel(R)
+80200 CPU. The four components are:
+Messaging Component
+Doorbell Component
+Circular Queues Component
+Index Registers Component
+
+Messaging Component:
+Contains 4 32bit registers, 2 in and 2 out. Writing to the registers assert
+interrupt on the PCI bus or to the 80200 depend on incoming or outgoing.
+
+int mu_msg_request(u32 *mu_context);
+Request the usage of Messaging Component. mu_context is written back by the
+API. The MU context is passed to other Messaging calls as a parameter.
+
+int mu_msg_set_callback(u32 mu_context, u8 reg, mu_msg_cb_t func);
+Setup the callback function for incoming messages. Callback can be setup for
+outbound 0, 1, or both outbound registers.
+
+int mu_msg_post(u32 mu_context, u32 val, u8 reg);
+Posting a message in the val parameter. The reg parameter denotes whether
+to use register 0, 1.
+
+int mu_msg_free(u32 mu_context, u8 mode);
+Free the usage of messaging component. mode can be specified soft or hard. In
+hardmode all resources are unallocated.
+
+Doorbell Component:
+The doorbell registers contains 1 inbound and 1 outbound. Depending on the bits
+being set different interrupts are asserted.
+
+int mu_db_request(u32 *mu_context);
+Request the usage of the doorbell register.
+
+int mu_db_set_callback(u32 mu_context, mu_db_cb_t func);
+Setting up the inbound callback.
+
+void mu_db_ring(u32 mu_context, u32 mask);
+Write to the outbound db register with mask.
+
+int mu_db_free(u32 mu_context);
+Free the usage of doorbell component.
+
+Circular Queues Component:
+The circular queue component has 4 circular queues. Inbound post, inbound free,
+outbound post, outbound free. These queues are used to pass messages.
+
+int mu_cq_request(u32 *mu_context, u32 q_size);
+Request the usage of the queue. See code comment header for q_size. It tells
+the API how big of queues to setup.
+
+int mu_cq_inbound_init(u32 mu_context, mfa_list_t *list, u32 size,
+                       mu_cq_cb_t func);
+Init inbound queues. The user must provide a list of free message frames to
+be put in inbound free queue and the callback function to handle the inbound
+messages.
+
+int mu_cq_enable(u32 mu_context);
+Enables the circular queues mechanism. Called once all the setup functions
+are called.
+
+u32 mu_cq_get_frame(u32 mu_context);
+Obtain the address of an outbound free frame for the user.
+
+int mu_cq_post_frame(u32 mu_context, u32 mfa);
+The user can post the frame once getting the frame and put information in the
+frame.
+
+int mu_cq_free(u32 mu_context);
+Free the usage of circular queues mechanism.
+
+Index Registers Component:
+The index register provides the mechanism to receive inbound messages.
+
+int mu_ir_request(u32 *mu_context);
+Request of Index Register component usage.
+
+int mu_ir_set_callback(u32 mu_context, mu_ir_cb_t callback);
+Setting up callback for inbound messages. The callback will receive the
+value of the register that IAR offsets to.
+
+int mu_ir_free(u32 mu_context);
+Free the usage of Index Registers component.
+
+void mu_set_irq_threshold(u32 mu_context, int thresh);
+Setup the IRQ threshold before relinquish processing in IRQ space. Default
+is set at 10 loops.
+
+
+*NOTE: Example of host driver that utilize the MU can be found in the Linux I2O
+driver. Specifically i2o_pci and some functions of i2o_core. The I2O driver
+only utilize the circular queues mechanism. The other 3 components are simple
+enough that they can be easily setup. The MU API provides no flow control for
+the messaging mechanism. Flow control of the messaging needs to be established
+by a higher layer of software on the IOP or the host driver.
+
+All Disclaimers apply. Use this at your own discretion. Neither Intel nor I
+will be responsible if anything goes wrong. =)
+
+
+TODO
+____
+
diff -Nru a/Documentation/arm/XScale/IOP3XX/pmon.txt b/Documentation/arm/XScale/IOP3XX/pmon.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/IOP3XX/pmon.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,71 @@
+
+Intel's XScale Microarchitecture 80312 companion processor provides a
+Performance Monitoring Unit (PMON) that can be utilized to provide
+information that can be useful for fine tuning of code.  This text
+file describes the API that's been developed for use by Linux kernel
+programmers.  Note that to get the most usage out of the PMON,
+I highly reccomend getting the XScale reference manual from Intel[1]
+and looking at chapter 12.
+
+To use the PMON, you must #include <asm-arm/arch-iop310/pmon.h> in your
+source file.
+
+Since there's only one PMON, only one user can currently use the PMON
+at a given time.  To claim the PMON for usage, call iop310_pmon_claim() which
+returns an identifier.  When you are done using the PMON, call
+iop310_pmon_release() with the id you were given earlier.
+
+The PMON consists of 14 registers that can be used for performance measurements.
+By combining different statistics, you can derive complex performance metrics.
+
+To start the PMON, just call iop310_pmon_start(mode).  Mode tells the PMON what
+statistics to capture and can each be one of:
+
+    IOP310_PMU_MODE0
+    Performance Monitoring Disabled
+
+    IOP310_PMU_MODE1
+    Primary PCI bus and internal agents (bridge, dma Ch0, dam Ch1, patu)
+
+    IOP310_PMU_MODE2
+    Secondary PCI bus and internal agents (bridge, dma Ch0, dam Ch1, patu)
+
+    IOP310_PMU_MODE3
+    Secondary PCI bus and internal agents (external masters 0..2 and Intel
+    80312 I/O companion chip)
+
+    IOP310_PMU_MODE4
+    Secondary PCI bus and internal agents (external masters 3..5 and Intel
+    80312 I/O companion chip)
+
+    IOP310_PMU_MODE5
+    Intel 80312 I/O companion chip internal bus, DMA Channels and Application
+    Accelerator
+
+    IOP310_PMU_MODE6
+    Intel 80312 I/O companion chip internal bus, PATU, SATU and Intel 80200
+    processor
+
+    IOP310_PMU_MODE7
+    Intel 80312 I/O companion chip internal bus, Primary PCI bus, Secondary
+    PCI bus and Secondary PCI agents (external masters 0..5 & Intel 80312 I/O
+    companion chip)
+
+To get the results back, call iop310_pmon_stop(&results) where results is
+defined as follows:
+
+typedef struct _iop310_pmon_result
+{
+	u32 timestamp;			/* Global Time Stamp Register */
+	u32 timestamp_overflow;		/* Time Stamp overflow count */
+	u32 event_count[14];		/* Programmable Event Counter
+					   Registers 1-14 */
+	u32 event_overflow[14];		/* Overflow counter for PECR1-14 */
+} iop310_pmon_res_t;
+
+
+--
+This code is still under development, so please feel free to send patches,
+questions, comments, etc to me.
+
+Deepak Saxena <dsaxena@mvista.com>
diff -Nru a/Documentation/arm/XScale/cache-lock.txt b/Documentation/arm/XScale/cache-lock.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/cache-lock.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,123 @@
+
+Intel's XScale Microarchitecture provides support for locking of data
+and instructions into the appropriate caches. This  file provides
+an overview of the API that has been developed to take advantage of this
+feature from kernel space. Note that there is NO support for user space
+cache locking.
+
+For example usage of this code, grab:
+
+	ftp://source.mvista.com/pub/xscale/cache-test.c
+
+If you have any questions, comments, patches, etc, please contact me.
+
+Deepak Saxena <dsaxena@mvista.com>
+
+API DESCRIPTION
+
+
+I. Header File
+
+   #include <asm/xscale-lock.h>
+
+II. Cache Capability Discovery
+
+   SYNOPSIS
+
+   int cache_query(u8 cache_type,
+                           struct cache_capabilities *pcache);
+
+   struct cache_capabilities
+   {
+      u32   flags;      /* Flags defining capabilities  */
+      u32   cache_size; /* Cache size in K (1024 bytes) */
+      u32   max_lock;   /* Maximum lockable region in K */
+   }
+
+   /*
+    * Flags
+    */
+
+   /*
+    * Bit 0: Cache lockability
+    * Bits 1-31: Reserved for future use
+    */
+   #define CACHE_LOCKABLE    0x00000001   /* Cache can be locked */
+
+   /*
+    * Cache Types
+    */
+   #define ICACHE            0x00
+   #define DCACHE            0x01
+
+   DESCRIPTION
+
+   This function fills out the pcache capability identifier for the
+   requested cache. cache_type is either DCACHE or ICACHE. This
+   function is not very useful at the moment as all XScale CPU's
+   have the same size Cache, but is is provided for future XScale
+   based processors that may have larger cache sizes.
+
+   RETURN VALUE
+
+   This function returns 0 if no error occurs, otherwise it returns
+   a negative, errno compatible value.
+
+      -EIO   Unknown hardware error
+
+III. Cache Locking
+
+   SYNOPSIS
+
+   int cache_lock(void *addr, u32 len, u8 cache_type, const char *desc);
+
+   DESCRIPTION
+
+   This function locks a physically contigous portion of memory starting
+   at the virtual address pointed to by addr into the cache referenced
+   by cache_type.
+
+   The address of the data/instruction that is to be locked must be
+   aligned on a cache line boundary (L1_CACHE_ALIGNEMENT).
+
+   The desc parameter is an optional (pass NULL if not used) human readable
+   descriptor of the locked memory region that is used by the cache
+   management code to build the /proc/cache_locks table.
+
+   Note that this function does not check whether the address is valid
+   or not before locking it into the cache.  That duty is up to the
+   caller.  Also, it does not check for duplicate or overlaping
+   entries.
+
+   RETURN VALUE
+
+   If the function is successful in locking the entry into cache, a
+   zero is returned.
+
+   If an error occurs, an appropriate error value is returned.
+
+      -EINVAL   The memory address provided was not cache line aligned
+      -ENOMEM   Could not allocate memory to complete operation
+      -ENOSPC   Not enough space left on cache to lock in requested region
+      -EIO      Unknown error
+
+III. Cache Unlocking
+
+   SYNOPSIS
+
+   int cache_unlock(void *addr)
+
+   DESCRIPTION
+
+   This function unlocks a portion of memory that was previously locked
+   into either the I or D cache.
+
+   RETURN VALUE
+
+   If the entry is cleanly unlocked from the cache, a 0 is returned.
+   In the case of an error, an appropriate error is returned.
+
+      -ENOENT    No entry with given address associated with this cache
+      -EIO       Unknown error
+
+
diff -Nru a/Documentation/arm/XScale/pmu.txt b/Documentation/arm/XScale/pmu.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/pmu.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,168 @@
+
+Intel's XScale Microarchitecture processors provide a Performance
+Monitoring Unit (PMU) that can be utilized to provide information
+that can be useful for fine tuning of code.  This text file describes
+the API that's been developed for use by Linux kernel programmers.
+When I have some extra time on my hand, I will extend the code to
+provide support for user mode performance monitoring (which is
+probably much more useful).  Note that to get the most usage out
+of the PMU, I highly reccomend getting the XScale reference manual
+from Intel and looking at chapter 12.
+
+To use the PMU, you must #include <asm/xscale-pmu.h> in your source file.
+
+Since there's only one PMU, only one user can currently use the PMU
+at a given time.  To claim the PMU for usage, call pmu_claim() which
+returns an identifier.  When you are done using the PMU, call
+pmu_release() with the identifier that you were given by pmu_claim.
+
+In addition, the PMU can only be used on XScale based systems that
+provide an external timer.  Systems that the PMU is currently supported
+on are:
+
+	- Cyclone IQ80310
+
+Before delving into how to use the PMU code, let's do a quick overview
+of the PMU itself.  The PMU consists of three registers that can be
+used for performance measurements.  The first is the CCNT register with
+provides the number of clock cycles elapsed since the PMU was started.
+The next two register, PMN0 and PMN1, are eace user programmable to
+provide 1 of 20 different performance statistics.  By combining different
+statistics, you can derive complex performance metrics.
+
+To start the PMU, just call pmu_start(pm0, pmn1).  pmn0 and pmn1 tell
+the PMU what statistics to capture and can each be one of:
+
+EVT_ICACHE_MISS
+	Instruction fetches requiring access to external memory
+
+EVT_ICACHE_NO_DELIVER
+	Instruction cache could not deliver an instruction.  Either an
+	ICACHE miss or an instruction TLB miss.
+
+EVT_ICACHE_DATA_STALL
+	Stall in execution due to a data dependency. This counter is
+	incremented each cycle in which the condition is present.
+
+EVT_ITLB_MISS
+	Instruction TLB miss
+
+EVT_DTLB_MISS
+	Data TLB miss
+
+EVT_BRANCH
+	A branch instruction was executed and it may or may not have
+	changed program flow
+
+EVT_BRANCH_MISS
+	A branch (B or BL instructions only) was mispredicted
+
+EVT_INSTRUCTION
+	An instruction was executed
+
+EVT_DCACHE_FULL_STALL
+	Stall because data cache buffers are full.  Incremented on every
+	cycle in which condition is present.
+
+EVT_DCACHE_FULL_STALL_CONTIG
+	Stall because data cache buffers are full.  Incremented on every
+	cycle in which condition is contigous.
+
+EVT_DCACHE_ACCESS
+	Data cache access (data fetch)
+
+EVT_DCACHE_MISS
+	Data cache miss
+
+EVT_DCACHE_WRITE_BACK
+	Data cache write back.  This counter is incremented for every
+	1/2 line (four words) that are written back.
+
+EVT_PC_CHANGED
+	Software changed the PC.  This is incremented only when the
+	software changes the PC and there is no mode change.  For example,
+	a MOV instruction that targets the PC would increment the counter.
+	An SWI would not as it triggers a mode change.
+
+EVT_BCU_REQUEST
+	The Bus Control Unit(BCU) received a request from the core
+
+EVT_BCU_FULL
+	The BCU request queue if full.  A high value for this event means
+	that the BCU is often waiting for to complete on the external bus.
+
+EVT_BCU_DRAIN
+	The BCU queues were drained due to either a Drain Write Buffer
+	command or an I/O transaction for a page that was marked as
+	uncacheable and unbufferable.
+
+EVT_BCU_ECC_NO_ELOG
+	The BCU detected an ECC error on the memory bus but noe ELOG
+	register was available to to log the errors.
+
+EVT_BCU_1_BIT_ERR
+	The BCU detected a 1-bit error while reading from the bus.
+
+EVT_RMW
+	An RMW cycle occurred due to narrow write on ECC protected memory.
+
+To get the results back, call pmu_stop(&results) where results is defined
+as a struct pmu_results:
+
+	struct pmu_results
+	{
+		u32     ccnt;	/* Clock Counter Register */
+		u32	ccnt_of; /
+		u32     pmn0;	/* Performance Counter Register 0 */
+		u32	pmn0_of;
+		u32     pmn1;	/* Performance Counter Register 1 */
+		u32	pmn1_of;
+	};
+
+Pretty simple huh?  Following are some examples of how to get some commonly
+wanted numbers out of the PMU data.  Note that since you will be dividing
+things, this isn't super useful from the kernel and you need to printk the
+data out to syslog.  See [1] for more examples.
+
+Instruction Cache Efficiency
+
+	pmu_start(EVT_INSTRUCTION, EVT_ICACHE_MISS);
+	...
+	pmu_stop(&results);
+
+	icache_miss_rage = results.pmn1 / results.pmn0;
+	cycles_per_instruction = results.ccnt / results.pmn0;
+
+Data Cache Efficiency
+
+	pmu_start(EVT_DCACHE_ACCESS, EVT_DCACHE_MISS);
+	...
+	pmu_stop(&results);
+
+	dcache_miss_rage = results.pmn1 / results.pmn0;
+
+Instruction Fetch Latency
+
+	pmu_start(EVT_ICACHE_NO_DELIVER, EVT_ICACHE_MISS);
+	...
+	pmu_stop(&results);
+
+	average_stall_waiting_for_instruction_fetch =
+		results.pmn0 / results.pmn1;
+
+	percent_stall_cycles_due_to_instruction_fetch =
+		results.pmn0 / results.ccnt;
+
+
+ToDo:
+
+- Add support for usermode PMU usage.  This might require hooking into
+  the scheduler so that we pause the PMU when the task that requested
+  statistics is scheduled out.
+
+--
+This code is still under development, so please feel free to send patches,
+questions, comments, etc to me.
+
+Deepak Saxena <dsaxena@mvista.com>
+
diff -Nru a/Documentation/arm/XScale/tlb-lock.txt b/Documentation/arm/XScale/tlb-lock.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/arm/XScale/tlb-lock.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,64 @@
+
+Intel's XScale Microarchitecture provides support for locking of TLB
+entries in both the instruction and data TLBs.  This  file provides
+an overview of the API that has been developed to take advantage of this
+feature from kernel space. Note that there is NO support for user space.
+
+In general, this feature should be used in conjunction with locking
+data or instructions into the appropriate caches.  See the file
+cache-lock.txt in this directory.
+
+If you have any questions, comments, patches, etc, please contact me.
+
+Deepak Saxena <dsaxena@mvista.com>
+
+
+API DESCRIPTION
+
+I. Header file
+
+   #include <asm/xscale-lock.h>
+
+II. Locking an entry into the TLB
+
+    SYNOPSIS
+
+    xscale_tlb_lock(u8 tlb_type, u32 addr);
+
+    /*
+     * TLB types
+     */
+    #define ITLB	0x0
+    #define DTLB	0x1
+
+    DESCRIPTION
+
+    This function locks the virtual to physical mapping for virtual
+    address addr into the requested TLB.
+
+    RETURN VALUE
+
+    If the entry is properly locked into the TLB, a 0 is returned.
+    In case of an error, an appropriate error is returned.
+
+       -ENOSPC No more entries left in the TLB
+       -EIO    Unknown error
+
+III. Unlocking an entry from a TLB
+
+     SYNOPSIS
+
+     xscale_tlb_unlock(u8 tlb_type, u32 addr);
+
+     DESCRIPTION
+
+     This function unlocks the entry for virtual address addr from the
+     specified cache.
+
+     RETURN VALUE
+
+     If the TLB entry is properly unlocked, a 0 is returned.
+     In case of an error, an appropriate error is returned.
+
+        -ENOENT  No entry for given address in specified TLB
+
diff -Nru a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
--- a/Documentation/block/biodoc.txt	Tue Mar  4 19:30:12 2003
+++ b/Documentation/block/biodoc.txt	Tue Mar  4 19:30:12 2003
@@ -1038,7 +1038,7 @@
 in fact all queues get unplugged as a side-effect.
 
 Aside:
-  This is kind of controversial territory, as its not clear if plugging is
+  This is kind of controversial territory, as it's not clear if plugging is
   always the right thing to do. Devices typically have their own queues,
   and allowing a big queue to build up in software, while letting the device be
   idle for a while may not always make sense. The trick is to handle the fine
diff -Nru a/Documentation/cpu-freq/core.txt b/Documentation/cpu-freq/core.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/cpu-freq/core.txt	Tue Mar  4 19:30:12 2003
@@ -0,0 +1,90 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+			  C P U F r e q    C o r e
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+		     David Kimdon <dwhedon@debian.org>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+Contents:
+---------
+1.  CPUFreq core and interfaces
+2.  CPUFreq notifiers
+
+1. General Information
+=======================
+
+The CPUFreq core code is located in linux/kernel/cpufreq.c. This
+cpufreq code offers a standardized interface for the CPUFreq
+architecture drivers (those pieces of code that do actual
+frequency transitions), as well as to "notifiers". These are device
+drivers or other part of the kernel that need to be informed of
+policy changes (ex. thermal modules like ACPI) or of all
+frequency changes (ex. timing code) or even need to force certain
+speed limits (like LCD drivers on ARM architecture). Additionally, the
+kernel "constant" loops_per_jiffy is updated on frequency changes
+here.
+
+
+2. CPUFreq notifiers
+====================
+
+CPUFreq notifiers conform to the standard kernel notifier interface.
+See linux/include/linux/notifier.h for details on notifiers.
+
+There are two different CPUFreq notifiers - policy notifiers and
+transition notifiers.
+
+
+2.1 CPUFreq policy notifiers
+----------------------------
+
+These are notified when a new policy is intended to be set. Each
+CPUFreq policy notifier is called three times for a policy transition:
+
+1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
+    they see a need for this - may it be thermal considerations or
+    hardware limitations.
+
+2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid
+    hardware failure.
+
+3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
+   - if two hardware drivers failed to agree on a new policy before this
+   stage, the incompatible hardware shall be shut down, and the user
+   informed of this.
+
+The phase is specified in the second argument to the notifier.
+
+The third argument, a void *pointer, points to a struct cpufreq_policy
+consisting of five values: cpu, min, max, policy and max_cpu_freq. min 
+and max are the lower and upper frequencies (in kHz) of the new
+policy, policy the new policy, cpu the number of the affected CPU or
+CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported
+CPU frequency. This value is given for informational purposes only.
+
+
+2.2 CPUFreq transition notifiers
+--------------------------------
+
+These are notified twice when the CPUfreq driver switches the CPU core
+frequency and this change has any external implications.
+
+The second argument specifies the phase - CPUFREQ_PRECHANGE or
+CPUFREQ_POSTCHANGE.
+
+The third argument is a struct cpufreq_freqs with the following
+values:
+cpu	- number of the affected CPU or CPUFREQ_ALL_CPUS
+old	- old frequency
+new	- new frequency
diff -Nru a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/cpu-freq/cpu-drivers.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,207 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+			   C P U   D r i v e r s 
+
+		       - information for developers -
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+Contents:
+---------
+1.   What To Do?
+1.1  Initialization
+1.2  Per-CPU Initialization
+1.3  verify
+1.4  target or setpolicy?
+1.5  target
+1.6  setpolicy
+2.   Frequency Table Helpers
+
+
+
+1. What To Do?
+==============
+
+So, you just got a brand-new CPU / chipset with datasheets and want to
+add cpufreq support for this CPU / chipset? Great. Here are some hints
+on what is neccessary:
+
+
+1.1 Initialization
+------------------
+
+First of all, in an __initcall level 7 or later (preferrably
+module_init() so that your driver is modularized) function check
+whether this kernel runs on the right CPU and the right chipset. If
+so, register a struct cpufreq_driver with the CPUfreq core using
+cpufreq_register_driver()
+
+What shall this struct cpufreq_driver contain? 
+
+cpufreq_driver.name -		The name of this driver.
+
+cpufreq_driver.init -		A pointer to the per-CPU initialization 
+				function.
+
+cpufreq_driver.verify -		A pointer to a "verfication" funciton.
+
+cpufreq_driver.setpolicy _or_ 
+cpufreq_driver.target -		See below on the differences.
+
+And optionally
+
+cpufreq_driver.exit -		A pointer to a per-CPU cleanup function.
+
+
+
+1.2 Per-CPU Initialization
+--------------------------
+
+Whenever a new CPU is registered with the device model, or after the
+cpufreq driver registers itself, the per-CPU initialization fucntion 
+cpufreq_driver.init is called. It takes a struct cpufreq_policy
+*policy as argument. What to do now?
+
+If necessary, activate the CPUfreq support on your CPU (unlock that
+register etc.).
+
+Then, the driver must fill in the following values:
+
+policy->cpuinfo.min_freq _and_
+policy->cpuinfo.max_freq -	the minimum and maximum frequency 
+				(in kHz) which is supported by 
+				this CPU
+policy->cpuinfo.transition_latency   the time it takes on this CPU to
+				switch between two frequencies (if
+				appropriate, else specify
+				CPUFREQ_ETERNAL)
+
+policy->cur			The current operating frequency of
+				this CPU (if appropriate)
+policy->min, 
+policy->max, 
+policy->policy and, if neccessary,
+policy->governor		must contain the "default policy" for
+				this CPU. A few moments later,
+				cpufreq_driver.verify and either
+				cpufreq_driver.setpolicy or
+				cpufreq_driver.target is called with
+				these values.
+
+For setting some of these values, the frequency table helpers might be
+helpful. See the section 2 for more information on them.
+
+
+1.3 verify
+------------
+
+When the user decides a new policy (consisting of
+"policy,governor,min,max") shall be set, this policy must be validated
+so that incompatible values can be corrected. For verifying these
+values, a frequency table helper and/or the
+cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned
+int min_freq, unsigned int max_freq) function might be helpful. See
+section 2 for details on frequency table helpers.
+
+You need to make sure that at least one valid frequency (or operating
+range) is within policy->min and policy->max. If necessary, increase
+policy->max fist, and only if this is no solution, decreas policy->min.
+
+
+1.4 target or setpolicy?
+----------------------------
+
+Most cpufreq drivers or even most cpu frequency scaling algorithms 
+only allow the CPU to be set to one frequency. For these, you use the
+->target call.
+
+Some cpufreq-capable processors switch the frequency between certain
+limits on their own. These shall use the ->setpolicy call
+
+
+1.4. target
+-------------
+
+The target call has three arguments: struct cpufreq_policy *policy,
+unsigned int target_frequency, unsigned int relation.
+
+The CPUfreq driver must set the new frequency when called here. The
+actual frequency must be determined using the following rules:
+
+- keep close to "target_freq"
+- policy->min <= new_freq <= policy->max (THIS MUST BE VALID!!!)
+- if relation==CPUFREQ_REL_L, try to select a new_freq higher than or equal
+  target_freq. ("L for lowest, but no lower than")
+- if relation==CPUFREQ_REL_H, try to select a new_freq lower than or equal
+  target_freq. ("H for highest, but no higher than")
+
+Here again the frequency table helper might assist you - see section 3
+for details.
+
+
+1.5 setpolicy
+---------------
+
+The setpolicy call only takes a struct cpufreq_policy *policy as
+argument. You need to set the lower limit of the in-processor or
+in-chipset dynamic frequency switching to policy->min, the upper limit
+to policy->max, and -if supported- select a performance-oriented
+setting when policy->policy is CPUFREQ_POLICY_PERFORMANCE, and a
+powersaving-oriented setting when CPUFREQ_POLICY_POWERSAVE. Also check
+the reference implementation in arch/i386/kernel/cpu/cpufreq/longrun.c
+
+
+
+2. Frequency Table Helpers
+==========================
+
+As most cpufreq processors only allow for being set to a few specific
+frequencies, a "frequency table" with some functions might assist in
+some work of the processor driver. Such a "frequency table" consists
+of an array of struct cpufreq_freq_table entries, with any value in
+"index" you want to use, and the corresponding frequency in
+"frequency". At the end of the table, you need to add a
+cpufreq_freq_table entry with frequency set to CPUFREQ_TABLE_END. And
+if you want to skip one entry in the table, set the frequency to 
+CPUFREQ_ENTRY_INVALID. The entries don't need to be in ascending
+order.
+
+By calling cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
+					struct cpufreq_frequency_table *table);
+the cpuinfo.min_freq and cpuinfo.max_freq values are detected, and
+policy->min and policy->max are set to the same values. This is
+helpful for the per-CPU initialization stage.
+
+int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
+                                   struct cpufreq_frequency_table *table);
+assures that at least one valid frequency is within policy->min and
+policy->max, and all other criteria are met. This is helpful for the
+->verify call.
+
+int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+                                   struct cpufreq_frequency_table *table,
+                                   unsigned int target_freq,
+                                   unsigned int relation,
+                                   unsigned int *index);
+
+is the corresponding frequency table helper for the ->target
+stage. Just pass the values to this function, and the unsigned int
+index returns the number of the frequency table entry which contains
+the frequency the CPU shall be set to. PLEASE NOTE: This is not the
+"index" which is in this cpufreq_table_entry.index, but instead
+cpufreq_table[index]. So, the new frequency is
+cpufreq_table[index].frequency, and the value you stored into the
+frequency table "index" field is
+cpufreq_table[index].index.
+
diff -Nru a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/cpu-freq/governors.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,155 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+		      C P U F r e q   G o v e r n o r s
+
+		   - information for users and developers -
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+Contents:
+---------
+1.   What is a CPUFreq Governor?
+
+2.   Governors In the Linux Kernel
+2.1  Performance
+2.2  Powersave
+2.3  Userspace
+
+3.   The Governor Interface in the CPUfreq Core
+
+
+
+1. What Is A CPUFreq Governor?
+==============================
+
+Most cpufreq drivers (in fact, all except one, longrun) or even most
+cpu frequency scaling algorithms only offer the CPU to be set to one
+frequency. In order to offer dynamic frequency scaling, the cpufreq
+core must be able to tell these drivers of a "target frequency". So
+these specific drivers will be transformed to offer a "->target"
+call instead of the existing "->setpolicy" call. For "longrun", all
+stays the same, though.
+
+How to decide what frequency within the CPUfreq policy should be used?
+That's done using "cpufreq governors". Two are already in this patch
+-- they're the already existing "powersave" and "performance" which
+set the frequency statically to the lowest or highest frequency,
+respectively. At least two more such governors will be ready for
+addition in the near future, but likely many more as there are various
+different theories and models about dynamic frequency scaling
+around. Using such a generic interface as cpufreq offers to scaling
+governors, these can be tested extensively, and the best one can be
+selected for each specific use.
+
+Basically, it's the following flow graph:
+
+CPU can be set to switch independetly	 |	   CPU can only be set
+      within specific "limits"		 |       to specific frequencies
+
+                                 "CPUfreq policy"
+		consists of frequency limits (policy->{min,max})
+  		     and CPUfreq governor to be used
+			 /		      \
+			/		       \
+		       /		       the cpufreq governor decides
+		      /			       (dynamically or statically)
+		     /			       what target_freq to set within
+		    /			       the limits of policy->{min,max}
+		   /			            \
+		  /				     \
+	Using the ->setpolicy call,		 Using the ->target call,
+	    the limits and the			  the frequency closest
+	     "policy" is set.			  to target_freq is set.
+						  It is assured that it
+						  is within policy->{min,max}
+
+
+2. Governors In the Linux Kernel
+================================
+
+2.1 Performance
+---------------
+
+The CPUfreq governor "performance" sets the CPU statically to the
+highest frequency within the borders of scaling_min_freq and
+scaling_max_freq.
+
+
+2.1 Powersave
+-------------
+
+The CPUfreq governor "powersave" sets the CPU statically to the
+lowest frequency within the borders of scaling_min_freq and
+scaling_max_freq.
+
+
+2.2 Userspace
+-------------
+
+The CPUfreq governor "userspace" allows the user, or any userspace
+program running with UID "root", to set the CPU to a specifc frequency
+by making a sysfs file "scaling_setspeed" available in the CPU-device
+directory.
+
+
+
+3. The Governor Interface in the CPUfreq Core
+=============================================
+
+A new governor must register itself with the CPUfreq core using
+"cpufreq_register_governor". The struct cpufreq_governor, which has to
+be passed to that function, must contain the following values:
+
+governor->name -	    A unique name for this governor
+governor->governor -	    The governor callback function
+governor->owner	-	    .THIS_MODULE for the governor module (if 
+			    appropriate)
+
+The governor->governor callback is called with the current (or to-be-set)
+cpufreq_policy struct for that CPU, and an unsigned int event. The
+following events are currently defined:
+
+CPUFREQ_GOV_START:   This governor shall start its duty for the CPU
+		     policy->cpu
+CPUFREQ_GOV_STOP:    This governor shall end its duty for the CPU
+		     policy->cpu
+CPUFREQ_GOV_LIMITS:  The limits for CPU policy->cpu have changed to
+		     policy->min and policy->max.
+
+If you need other "events" externally of your driver, _only_ use the
+cpufreq_governor_l(unsigned int cpu, unsigned int event) call to the
+CPUfreq core to ensure proper locking.
+
+
+The CPUfreq governor may call the CPU processor driver using one of
+these two functions:
+
+inline int cpufreq_driver_target(struct cpufreq_policy *policy,
+                                 unsigned int target_freq,
+                                 unsigned int relation);
+
+inline int cpufreq_driver_target_l(struct cpufreq_policy *policy,
+                                   unsigned int target_freq,
+                                   unsigned int relation);
+
+target_freq must be within policy->min and policy->max, of course.
+What's the difference between these two functions? When your governor
+still is in a direct code path of a call to governor->governor, the
+cpufreq_driver_sem lock is still held in the cpufreq core, and there's
+no need to lock it again (in fact, this would cause a deadlock). So
+use cpufreq_driver_target only in these cases. In all other cases (for
+example, when there's a "daemonized" function that wakes up every
+second), use cpufreq_driver_target_l to lock the cpufreq_driver_sem
+before the command is passed to the cpufreq processor driver.
+
diff -Nru a/Documentation/cpu-freq/index.txt b/Documentation/cpu-freq/index.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/cpu-freq/index.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,56 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+
+Documents in this directory:
+----------------------------
+core.txt	-	General description of the CPUFreq core and
+			of CPUFreq notifiers
+
+cpu-drivers.txt -	How to implement a new cpufreq processor driver
+
+governors.txt	-	What are cpufreq governors and how to
+			implement them?
+
+index.txt	-	File index, Mailing list and Links (this document)
+
+user-guide.txt	-	User Guide to CPUFreq
+
+
+Mailing List
+------------
+There is a CPU frequency changing CVS commit and general list where
+you can report bugs, problems or submit patches. To post a message,
+send an email to cpufreq@www.linux.org.uk, to subscribe go to
+http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
+mailing list are available to subscribers at
+http://www.linux.org.uk/mailman/private/cpufreq/.
+
+
+Links
+-----
+the FTP archives:
+* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
+
+how to access the CVS repository:
+* http://cvs.arm.linux.org.uk/
+
+the CPUFreq Mailing list:
+* http://www.linux.org.uk/mailman/listinfo/cpufreq
+
+Clock and voltage scaling for the SA-1100:
+* http://www.lart.tudelft.nl/projects/scaling
diff -Nru a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/cpu-freq/user-guide.txt	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,166 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+			     U S E R   G U I D E
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+Contents:
+---------
+1. Supported Architectures and Processors
+1.1 ARM
+1.2 x86
+1.3 sparc64
+
+2. "Policy" / "Governor"?
+2.1 Policy
+2.2 Governor
+
+3. How to change the CPU cpufreq policy and/or speed
+3.1 Preferred interface: sysfs
+3.2 Deprecated interfaces
+
+
+
+1. Supported Architectures and Processors
+=========================================
+
+1.1 ARM
+-------
+
+The following ARM processors are supported by cpufreq:
+
+ARM Integrator
+ARM-SA1100
+ARM-SA1110
+
+
+1.2 x86
+-------
+
+The following processors for the x86 architecture are supported by cpufreq:
+
+AMD Elan - SC400, SC410
+AMD mobile K6-2+
+AMD mobile K6-3+
+Cyrix Media GXm
+Intel mobile PIII [*] and Intel mobile PIII-M on certain chipsets
+Intel Pentium 4, Intel Xeon
+National Semiconductors Geode GX
+Transmeta Crusoe
+varios processors on some ACPI 2.0-compatible systems [**]
+
+[*] only certain Intel mobile PIII processors are supported. If you
+know that you own a speedstep-capable processor, pass the option
+"speedstep_coppermine=1" to the module speedstep.o
+
+[**] Only if "ACPI Processor Performance States" are available
+to the ACPI<->BIOS interface.
+
+
+1.3 sparc64
+-----------
+
+The following processors for the sparc64 architecture are supported by
+cpufreq:
+
+UltraSPARC-III
+
+
+
+2. "Policy" / "Governor" ?
+==========================
+
+Some CPU frequency scaling-capable processor switch between varios
+frequencies and operating voltages "on the fly" without any kernel or
+user involvement. This guarantuees very fast switching to a frequency
+which is high enough to serve the user's needs, but low enough to save
+power.
+
+
+2.1 Policy
+----------
+
+On these systems, all you can do is select the lower and upper
+frequency limit as well as whether you want more aggressive
+power-saving or more instantly avaialble processing power.
+
+
+2.2 Governor
+------------
+
+On all other cpufreq implementations, these boundaries still need to
+be set. Then, a "governor" must be selected. Such a "governor" decides
+what speed the processor shall run within the boundaries. One such
+"governor" is the "userspace" governor. This one allows the user - or
+a yet-to-implement userspace program - to decide what specific speed
+the processor shall run at.
+
+
+3. How to change the CPU cpufreq policy and/or speed
+====================================================
+
+3.1 Preferred Interface: sysfs
+------------------------------
+
+The preferred interface is located in the sysfs filesystem. If you
+mounted it at /sys, the cpufreq interface is located in the 
+cpu-device directory (e.g. /sys/devices/sys/cpu0/ for the first
+CPU).
+
+cpuinfo_min_freq :		this file shows the minimum operating
+				frequency the processor can run at(in kHz) 
+cpuinfo_max_freq :		this file shows the maximum operating
+				frequency the processor can run at(in kHz) 
+scaling_driver :		this file shows what cpufreq driver is
+				used to set the frequency on this CPU
+
+available_scaling_governors :	this file shows the CPUfreq governors
+				available in this kernel. You can see the
+				currently activated governor in
+
+scaling_governor,		and by "echoing" the name of another
+				governor you can change it. Please note
+				that some governors won't load - they only
+				work on some specific architectures or
+				processors.
+scaling_min_freq and 
+scaling_max_freq		show the current "policy limits" (in
+				kHz). By echoing new values into these
+				files, you can change these limits.
+
+
+If you have selected the "userspace" governor which allows you to
+set the CPU operating frequency to a specific value, you can read out
+the current frequency in
+
+scaling_setspeed.		By "echoing" a new frequency into this
+				you can change the speed of the CPU,
+				but only within the limits of
+				scaling_min_freq and scaling_max_freq.
+				
+
+3.2 Deprecated Interfaces
+-------------------------
+
+Depending on your kernel configuration, you might find the following 
+cpufreq-related files:
+/proc/cpufreq
+/proc/sys/cpu/*/speed
+/proc/sys/cpu/*/speed-min
+/proc/sys/cpu/*/speed-max
+
+These are files for deprecated interfaces to cpufreq, which offer far
+less functionality. Because of this, these interfaces aren't described
+here.
+
diff -Nru a/Documentation/cpufreq b/Documentation/cpufreq
--- a/Documentation/cpufreq	Tue Mar  4 19:30:12 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,364 +0,0 @@
-     CPU frequency and voltage scaling code in the Linux(TM) kernel
-
-
-		         L i n u x    C P U F r e q
-
-
-
-
-		    Dominik Brodowski  <linux@brodo.de>
-		     David Kimdon <dwhedon@debian.org>
-
-
-
-   Clock scaling allows you to change the clock speed of the CPUs on the
-    fly. This is a nice method to save battery power, because the lower
-            the clock speed, the less power the CPU consumes.
-
-
-
-Contents:
----------
-1.  Supported architectures
-2.  User interface
-2.1   /proc/cpufreq interface  [2.6]
-2.2.  /proc/sys/cpu/ interface [2.4]
-3.  CPUFreq core and interfaces
-3.1   General information
-3.2   CPUFreq notifiers
-3.3   CPUFreq architecture drivers
-4.  Mailing list and Links
-
-
-
-1. Supported architectures
-==========================
-
-ARM:
-    ARM Integrator, SA 1100, SA1110
---------------------------------
-    This driver will be ported to new CPUFreq core soon, so
-    far it will not work.
-
-
-AMD Elan:
-    SC400, SC410
---------------------------------
-    You need to specify the highest allowed CPU frequency as 
-    a module parameter ("max_freq") or as boot parameter 
-    ("elanfreq="). Else the available speed range will be 
-    limited to the speed at which the CPU runs while this
-    module is loaded.
-
-
-VIA Cyrix Longhaul:
-    VIA Samuel/CyrixIII, VIA Cyrix Samuel/C3, 
-    VIA Cyrix Ezra, VIA Cyrix Ezra-T
---------------------------------
-    If you do not want to scale the Front Side Bus or voltage,
-    pass the module parameter "dont_scale_fsb 1" or
-    "dont_scale_voltage 1". Additionally, it is advised that
-    you pass the current Front Side Bus speed (in MHz) to 
-    this module as module parameter "current_fsb", e.g. 
-    "current_fsb 133" for a Front Side Bus speed of 133 MHz.
-
-
-Intel SpeedStep:
-    certain mobile Intel Pentium III (Coppermine), and all mobile
-    Intel Pentium III-M (Tualatin) and mobile Intel Pentium 4 P4-Ms.
---------------------------------
-    Unfortunately only modern Intel ICH2-M and ICH3-M chipsets are 
-    supported.
-
-
-P4 CPU Clock Modulation:
-    Intel Pentium 4 Xeon processors
----------------------------------
-    Note that you can only switch the speed of two logical CPUs at
-    once - but each phyiscal CPU may have different throttling levels.
-
-
-PowerNow! K6:
-    mobile AMD K6-2+ / mobile K6-3+:
---------------------------------
-    No known issues.
-
-
-Transmeta Crusoe Longrun:
-    Transmeta Crusoe processors:
---------------------------------
-    It is recommended to use the 2.6. /proc/cpufreq interface when
-    using this driver
-
-
-
-2. User Interface
-=================
-
-2.1   /proc/cpufreq interface [2.6]
-***********************************
-
-Starting in the patches for kernel 2.5.33, CPUFreq uses a "policy"
-interface /proc/cpufreq.
-
-When you "cat" this file, you'll find something like:
-
---
-          minimum CPU frequency  -  maximum CPU frequency  -  policy
-CPU  0       1200000 ( 75%)      -     1600000 (100%)      -  performance
---
-
-This means the current policy allows this CPU to be run anywhere
-between 1.2 GHz (the value is in kHz) and 1.6 GHz with an eye towards
-performance.
-
-To change the policy, "echo" the desired new policy into
-/proc/cpufreq. Use one of the following formats:
-
-cpu_nr:min_freq:max_freq:policy
-cpu_nr%min_freq%max_freq%policy
-min_freq:max_freq:policy
-min_freq%max_freq%policy
-
-with cpu_nr being the CPU which shall be affected, min_freq and
-max_freq the lower and upper limit of the CPU core frequency in kHz,
-and policy either "performance" or "powersave".
-A few examples:
-
-root@notebook:#echo -n "0:0:0:powersave" > /proc/cpufreq
-     sets the CPU #0 to the lowest supported frequency.
-
-root@notebook:#echo -n "1%100%100%performance" > /proc/cpufreq
-     sets the CPU #1 to the highest supported frequency.
-
-root@notebook:#echo -n "1000000:2000000:performance" > /proc/cpufreq
-     to set the frequency of all CPUs between 1 GHz and 2 GHz and to
-     the policy "performance".
-
-Please note that the values you "echo" into /proc/cpufreq are
-validated first, and may be limited by hardware or thermal
-considerations. Because of this, a read from /proc/cpufreq might 
-differ from what was written into it.
-
-
-When you read /proc/cpufreq for the first time after a CPUFreq driver
-has been initialized, you'll see the "default policy" for this
-driver. If this does not suit your needs, you can pass a boot
-parameter to the cpufreq core. Use the following syntax for this:
-   "cpufreq=min_freq:max_freq:policy", i.e. you may not chose a
-specific CPU and you need to specify the limits in kHz and not in
-per cent.
-
-
-2.2   /proc/cpufreq interface [2.4]
-***********************************
-
-Previsiously (and still available as a config option), CPUFreq used 
-a "sysctl" interface which is located in 
-	/proc/sys/cpu/0/
-	/proc/sys/cpu/1/ ...	(SMP only)
-
-In these directories, you will find three files of importance for
-CPUFreq: speed-max, speed-min and speed: 
-
-speed		    shows the current CPU frequency in kHz, 
-speed-min	    the minimum supported CPU frequency, and
-speed-max	    the maximum supported CPU frequency.
-
-
-To change the CPU frequency, "echo" the desired CPU frequency (in kHz)
-to speed. For example, to set the CPU speed to the lowest/highest
-allowed frequency do:
-
-root@notebook:# cat /proc/sys/cpu/0/speed-min > /proc/sys/cpu/0/speed
-root@notebook:# cat /proc/sys/cpu/0/speed-max > /proc/sys/cpu/0/speed
-
-
-
-3.  CPUFreq core and interfaces
-===============================
-
-3.1   General information
-*************************
-
-The CPUFreq core code is located in linux/kernel/cpufreq.c. This
-cpufreq code offers a standardized interface for the CPUFreq
-architecture drivers (those pieces of code that do actual
-frequency transitions), as well as to "notifiers". These are device
-drivers or other part of the kernel that need to be informed of
-policy changes (like thermal modules like ACPI) or of all
-frequency changes (like timing code) or even need to force certain
-speed limits (like LCD drivers on ARM architecture). Additionally, the
-kernel "constant" loops_per_jiffy is updated on frequency changes
-here.
-
-
-3.2   CPUFreq notifiers
-***********************
-
-CPUFreq notifiers conform to the standard kernel notifier interface.
-See linux/include/linux/notifier.h for details on notifiers.
-
-There are two different CPUFreq notifiers - policy notifiers and
-transition notifiers.
-
-
-3.2.1 CPUFreq policy notifiers
-******************************
-
-These are notified when a new policy is intended to be set. Each
-CPUFreq policy notifier is called three times for a policy transition:
-
-1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
-    they see a need for this - may it be thermal considerations or
-    hardware limitations.
-
-2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid
-    hardware failure.
-
-3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
-   - if two hardware drivers failed to agree on a new policy before this
-   stage, the incompatible hardware shall be shut down, and the user
-   informed of this.
-
-The phase is specified in the second argument to the notifier.
-
-The third argument, a void *pointer, points to a struct cpufreq_policy
-consisting of five values: cpu, min, max, policy and max_cpu_freq. Min 
-and max are the lower and upper frequencies (in kHz) of the new
-policy, policy the new policy, cpu the number of the affected CPU or
-CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported
-CPU frequency. This value is given for informational purposes only.
-
-
-3.2.2 CPUFreq transition notifiers
-**********************************
-
-These are notified twice when the CPUfreq driver switches the CPU core
-frequency and this change has any external implications.
-
-The second argument specifies the phase - CPUFREQ_PRECHANGE or
-CPUFREQ_POSTCHANGE.
-
-The third argument is a struct cpufreq_freqs with the following
-values:
-cpu	- number of the affected CPU or CPUFREQ_ALL_CPUS
-old	- old frequency
-new	- new frequency
-
-
-3.3   CPUFreq architecture drivers
-**********************************
-
-CPUFreq architecture drivers are the pieces of kernel code that
-actually perform CPU frequency transitions. These need to be
-initialized separately (separate initcalls), and may be
-modularized. They interact with the CPUFreq core in the following way:
-
-cpufreq_register()
-------------------
-cpufreq_register registers an arch driver to the CPUFreq core. Please
-note that only one arch driver may be registered at any time. -EBUSY
-is returned when an arch driver is already registered. The argument to
-cpufreq_register, struct cpufreq_driver *driver, is described later.
-
-cpufreq_unregister()
---------------------
-cpufreq_unregister unregisters an arch driver, e.g. on module
-unloading. Please note that there is no check done that this is called
-from the driver which actually registered itself to the core, so
-please only call this function when you are sure the arch driver got
-registered correctly before.
-
-cpufreq_notify_transition()
----------------------------
-On "dumb" hardware where only fixed frequency can be set, the driver
-must call cpufreq_notify_transition() once before, and once after the
-actual transition.
-
-struct cpufreq_driver
----------------------
-On initialization, the arch driver is supposed to pass a pointer
-to a struct cpufreq_driver *cpufreq_driver consisting of the following
-entries:
-
-cpufreq_verify_t verify: This is a pointer to a function with the
-	following definition:
-	int verify_function (struct cpufreq_policy *policy).
-	This function must verify the new policy is within the limits
-	supported by the CPU, and at least one supported CPU is within
-	this range. It may be useful to use cpufreq.h /
-	cpufreq_verify_within_limits for this. If this is called with
-        CPUFREQ_ALL_CPUS, and there is no common subset of frequencies
-        for all CPUs, exit with an error.
-
-cpufreq_setpolicy_t setpolicy: This is a pointer to a function with
-	the following definition:
-	int setpolicy_function (struct cpufreq_policy *policy).
-	This function must set the CPU to the new policy. If it is a
-	"dumb" CPU which only allows fixed frequencies to be set, it
-	shall set it to the lowest within the limit for
-	CPUFREQ_POLICY_POWERSAVE, and to the highest for
-	CPUFREQ_POLICY_PERFORMANCE. Once CONFIG_CPU_FREQ_DYNAMIC is
-	implemented, it can use a dynamic method to adjust the speed
-	between the lower and upper limit.
-
-struct cpufreq_policy   *policy: This is an array of NR_CPUS struct
-	cpufreq_policies, containing the current policies set for these
-	CPUs. Note that policy[cpu].max_cpu_freq must contain the
-	absolute maximum CPU frequency supported by the specified cpu.
-
-In case the driver is expected to run with the 2.4.-style API
-(/proc/sys/cpu/.../), two more values must be passed
-#ifdef CONFIG_CPU_FREQ_24_API
-	unsigned int            cpu_min_freq[NR_CPUS];
-	unsigned int            cpu_cur_freq[NR_CPUS];
-#endif
-	with cpu_min_freq[cpu] being the minimum CPU frequency
-	supported by the CPU; and the entries in cpu_cur_freq
-	reflecting the current speed of the appropriate CPU.
-
-Some Requirements to CPUFreq architecture drivers
--------------------------------------------------
-* Only call cpufreq_register() when the ability to switch CPU
-  frequencies is _verified_ or can't be missing. Also, all
-  other initialization must be done beofre this call, as
-  cpfureq_register calls the driver's verify and setpolicy code for
-  each CPU.
-* cpufreq_unregister() may only be called if cpufreq_register() has
-  been successfully(!) called before.
-* kfree() the struct cpufreq_driver only after the call to 
-  cpufreq_unregister(), unless cpufreq_register() failed.
-
-
-
-4. Mailing list and Links
-*************************
-
-
-Mailing List
-------------
-There is a CPU frequency changing CVS commit and general list where
-you can report bugs, problems or submit patches. To post a message,
-send an email to cpufreq@www.linux.org.uk, to subscribe go to
-http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
-mailing list are available to subscribers at
-http://www.linux.org.uk/mailman/private/cpufreq/.
-
-
-Links
------
-the FTP archives:
-* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
-
-how to access the CVS repository:
-* http://cvs.arm.linux.org.uk/
-
-the CPUFreq Mailing list:
-* http://www.linux.org.uk/mailman/listinfo/cpufreq
-
-Clock and voltage scaling for the SA-1100:
-* http://www.lart.tudelft.nl/projects/scaling
-
-CPUFreq project homepage
-* http://www.brodo.de/cpufreq/
diff -Nru a/Documentation/fb/sstfb.txt b/Documentation/fb/sstfb.txt
--- a/Documentation/fb/sstfb.txt	Tue Mar  4 19:30:05 2003
+++ b/Documentation/fb/sstfb.txt	Tue Mar  4 19:30:05 2003
@@ -138,7 +138,7 @@
 	- The driver is not your_favorite_toy-safe. this includes SMP...
           [Actually from inspection it seems to be safe - Alan]
 	- when using XFree86 FBdev (X over fbdev) you may see strange color
-	patterns at the border of your windows (the pixels loose the lowest
+	patterns at the border of your windows (the pixels lose the lowest
 	byte -> basicaly the blue component nd some of the green) . I'm unable
 	to reproduce this with XFree86-3.3, but one of the testers has this
 	problem with XFree86-4. apparently recent Xfree86-4.x solve this
diff -Nru a/Documentation/filesystems/hpfs.txt b/Documentation/filesystems/hpfs.txt
--- a/Documentation/filesystems/hpfs.txt	Tue Mar  4 19:30:07 2003
+++ b/Documentation/filesystems/hpfs.txt	Tue Mar  4 19:30:07 2003
@@ -109,7 +109,7 @@
 Once I booted English OS/2 working in cp 850 and I created a file on my 852
 partition. It marked file name codepage as 850 - good. But when I again booted
 Czech OS/2, the file was completely inaccessible under any name. It seems that
-OS/2 uppercases the search pattern with it's system code page (852) and file
+OS/2 uppercases the search pattern with its system code page (852) and file
 name it's comparing to with its code page (850). These could never match. Is it
 really what IBM developers wanted? But problems continued. When I created in
 Czech OS/2 another file in that directory, that file was inaccessible too. OS/2
diff -Nru a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
--- a/Documentation/filesystems/vfs.txt	Tue Mar  4 19:30:11 2003
+++ b/Documentation/filesystems/vfs.txt	Tue Mar  4 19:30:11 2003
@@ -439,7 +439,7 @@
 
   d_release: called when a dentry is really deallocated
 
-  d_iput: called when a dentry looses its inode (just prior to its
+  d_iput: called when a dentry loses its inode (just prior to its
 	being deallocated). The default when this is NULL is that the
 	VFS calls iput(). If you define this method, you must call
 	iput() yourself
diff -Nru a/Documentation/input/joystick-api.txt b/Documentation/input/joystick-api.txt
--- a/Documentation/input/joystick-api.txt	Tue Mar  4 19:30:08 2003
+++ b/Documentation/input/joystick-api.txt	Tue Mar  4 19:30:08 2003
@@ -168,7 +168,7 @@
 and too many events to store in the queue get generated. Note that
 high system load may contribute to space those reads even more.
 
-If time between reads is enough to fill the queue and loose an event,
+If time between reads is enough to fill the queue and lose an event,
 the driver will switch to startup mode and next time you read it,
 synthetic events (JS_EVENT_INIT) will be generated to inform you of
 the actual state of the joystick.
diff -Nru a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
--- a/Documentation/ioctl-number.txt	Tue Mar  4 19:30:13 2003
+++ b/Documentation/ioctl-number.txt	Tue Mar  4 19:30:13 2003
@@ -72,6 +72,7 @@
 		linux/blkpg.h
 0x20	all	drivers/cdrom/cm206.h
 0x22	all	scsi/sg.h
+'#'	00-3F	IEEE 1394 Subsystem	Block for the entire subsystem
 '1'	00-1F	<linux/timepps.h>	PPS kit from Ulrich Windl
 					<ftp://ftp.de.kernel.org/pub/linux/daemons/ntp/PPS/>
 '6'	00-10	<asm-i386/processor.h>	Intel IA32 microcode update driver
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	Tue Mar  4 19:30:14 2003
+++ b/Documentation/kernel-parameters.txt	Tue Mar  4 19:30:14 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 -Nru a/Documentation/networking/decnet.txt b/Documentation/networking/decnet.txt
--- a/Documentation/networking/decnet.txt	Tue Mar  4 19:30:04 2003
+++ b/Documentation/networking/decnet.txt	Tue Mar  4 19:30:04 2003
@@ -42,7 +42,7 @@
 3) Command line options
 
 You can set a DECnet address on the kernel command line for compatibility
-with the 2.4 configuration procedure, but in general its not needed any more.
+with the 2.4 configuration procedure, but in general it's not needed any more.
 If you do st a DECnet address on the command line, it has only one purpose
 which is that its added to the addresses on the loopback device.
 
diff -Nru a/Documentation/networking/ifenslave.c b/Documentation/networking/ifenslave.c
--- a/Documentation/networking/ifenslave.c	Tue Mar  4 19:30:05 2003
+++ b/Documentation/networking/ifenslave.c	Tue Mar  4 19:30:05 2003
@@ -299,7 +299,7 @@
 		else {  /* attach a slave interface to the master */
 			/* two possibilities :
 			   - if hwaddr_notset, do nothing.  The bond will assign the
-			     hwaddr from it's first slave.
+			     hwaddr from its first slave.
 			   - if !hwaddr_notset, assign the master's hwaddr to each slave
 			*/
 
diff -Nru a/Documentation/networking/netdevices.txt b/Documentation/networking/netdevices.txt
--- a/Documentation/networking/netdevices.txt	Tue Mar  4 19:30:05 2003
+++ b/Documentation/networking/netdevices.txt	Tue Mar  4 19:30:05 2003
@@ -18,7 +18,8 @@
 dev->stop:
 	Synchronization: rtnl_lock() semaphore.
 	Context: process
-	Notes: netif_running() is guaranteed false when this is called
+	Note1: netif_running() is guaranteed false
+	Note2: dev->poll() is guaranteed to be stopped
 
 dev->do_ioctl:
 	Synchronization: rtnl_lock() semaphore.
@@ -31,10 +32,12 @@
 dev->hard_start_xmit:
 	Synchronization: dev->xmit_lock spinlock.
 	Context: BHs disabled
+	Notes: netif_queue_stopped() is guaranteed false
 
 dev->tx_timeout:
 	Synchronization: dev->xmit_lock spinlock.
 	Context: BHs disabled
+	Notes: netif_queue_stopped() is guaranteed true
 
 dev->set_multicast_list:
 	Synchronization: dev->xmit_lock spinlock.
diff -Nru a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt
--- a/Documentation/networking/sk98lin.txt	Tue Mar  4 19:30:11 2003
+++ b/Documentation/networking/sk98lin.txt	Tue Mar  4 19:30:11 2003
@@ -187,7 +187,7 @@
   this port is not "Sense". If autonegotiation is "On", all
   three values are possible. If it is "Off", only "Full" and
   "Half" are allowed.
-  It is usefull if your link partner does not support all
+  It is useful if your link partner does not support all
   possible combinations.
 
 - Flow Control
diff -Nru a/Documentation/s390/TAPE b/Documentation/s390/TAPE
--- a/Documentation/s390/TAPE	Tue Mar  4 19:30:13 2003
+++ b/Documentation/s390/TAPE	Tue Mar  4 19:30:13 2003
@@ -91,7 +91,7 @@
 
 TODO List 
 
-   - Driver has to be stabelized still
+   - Driver has to be stabilized still
 
 BUGS 
 
diff -Nru a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt
--- a/Documentation/s390/s390dbf.txt	Tue Mar  4 19:30:11 2003
+++ b/Documentation/s390/s390dbf.txt	Tue Mar  4 19:30:11 2003
@@ -14,7 +14,7 @@
 If the system still runs but only a subcomponent which uses dbf failes,
 it is possible to look at the debug logs on a live system via the Linux proc
 filesystem.
-The debug feature may also very usefull for kernel and driver development.
+The debug feature may also very useful for kernel and driver development.
 
 Design:
 -------
diff -Nru a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt
--- a/Documentation/scsi/ibmmca.txt	Tue Mar  4 19:30:11 2003
+++ b/Documentation/scsi/ibmmca.txt	Tue Mar  4 19:30:11 2003
@@ -254,7 +254,7 @@
    device to be existant, but it has no ldn assigned, it gets a ldn out of 7 
    to 14. The numbers are assigned in cyclic order. Therefore it takes 8 
    dynamical reassignments on the SCSI-devices, until a certain device 
-   looses its ldn again. This assures, that dynamical remapping is avoided 
+   loses its ldn again. This assures, that dynamical remapping is avoided 
    during intense I/O between up to 15 SCSI-devices (means pun,lun 
    combinations). A further advantage of this method is, that people who
    build their kernel without probing on all luns will get what they expect,
diff -Nru a/Documentation/sound/oss/Wavefront b/Documentation/sound/oss/Wavefront
--- a/Documentation/sound/oss/Wavefront	Tue Mar  4 19:30:04 2003
+++ b/Documentation/sound/oss/Wavefront	Tue Mar  4 19:30:04 2003
@@ -81,7 +81,7 @@
 2) Why does line XXX of the code look like this .... ?
 **********************************************************************
 
-Either because its not finished yet, or because you're a better coder
+Either because it's not finished yet, or because you're a better coder
 than I am, or because you don't understand some aspect of how the card
 or the code works. 
 
diff -Nru a/Documentation/sx.txt b/Documentation/sx.txt
--- a/Documentation/sx.txt	Tue Mar  4 19:30:08 2003
+++ b/Documentation/sx.txt	Tue Mar  4 19:30:08 2003
@@ -265,7 +265,7 @@
 	  -- Done (Ugly: not the way I want it. Copied from serial.c).
 
         - write buffer isn't flushed at close.
-	  -- Done. I still seem to loose a few chars at close. 
+	  -- Done. I still seem to lose a few chars at close. 
 	     Sorry. I think that this is a firmware issue. (-> Specialix)
 
 	- drain hardware before  changing termios
diff -Nru a/Documentation/video4linux/bttv/Sound-FAQ b/Documentation/video4linux/bttv/Sound-FAQ
--- a/Documentation/video4linux/bttv/Sound-FAQ	Tue Mar  4 19:30:14 2003
+++ b/Documentation/video4linux/bttv/Sound-FAQ	Tue Mar  4 19:30:14 2003
@@ -120,7 +120,7 @@
 video_inputs    - # of video inputs the card has
 audio_inputs    - historical cruft, not used any more.
 tuner           - which input is the tuner
-svhs            - which input is svhs (all others are labled composite)
+svhs            - which input is svhs (all others are labeled composite)
 muxsel          - video mux, input->registervalue mapping
 pll             - same as pll= insmod option
 tuner_type      - same as tuner= insmod option
diff -Nru a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt
--- a/Documentation/vm/hugetlbpage.txt	Tue Mar  4 19:30:04 2003
+++ b/Documentation/vm/hugetlbpage.txt	Tue Mar  4 19:30:04 2003
@@ -1,4 +1,3 @@
-2002  Rohit Seth <rohit.seth@intel.com>
 
 The intent of this file is to give a brief summary of hugetlbpage support in
 the Linux kernel.  This support is built on top of multiple page size support
@@ -11,75 +10,194 @@
 now as bigger and bigger physical memories (several GBs) are more readily
 available.
 
-The current support is provided in kernel using the following two system calls:
+Users can use the huge page support in Linux kernel by either using the mmap
+system call or standard SYSv shared memory system calls (shmget, shmat).
 
-1) sys_alloc_hugepages(int key, unsigned long addr, size_t len, int prot, int flag)
+First the Linux kernel needs to be built with CONFIG_HUGETLB_PAGE (present
+under Processor types and feature)  and CONFIG_HUGETLBFS (present under file
+system option on config menu) config options.
 
-2) sys_free_hugepages(unsigned long addr)
+The kernel built with hugepage support should show the number of configured
+hugepages in the system by running the "cat /proc/meminfo" command.  
 
-Arguments to these system calls are defined as follows:
-
-key: If a user application wants to share hugepages with other
-      processes then this input argument needs to be greater than 0. 
-      Different applications can use the same key to map the same physical
-      memory (mapped by hugeTLBs) in their address space.  When a process
-      forks, then children share the same physical memory with their parent.
-
-      For the cases when an application wishes to keep the huge
-      pages private, the key value of 0 is defined.  In this case
-      kernel allocates hugetlb pages to the process that are not
-      shareable across different processes.  These segments are marked
-      private for the process.  These segments are not copied to
-      children's address space on forks - the child will have no
-      mapping for these virtual addresses.
-
-      The key manangement (and assignment) part is left to user
-      applications.
-
-addr: This is an address hint.  The kernel will perform a sanity check
-      on this address (alignment etc.) before using it.  It is possible that
-      kernel will allocates a different address (on success).
-
-len:  Length of the required segment.  Applications are expected to give
-      HPAGE_SIZE aligned length.  (Else EINVAL is returned.)
-
-prot: The prot parameter specifies the desired memory protection on the
-      requested hugepages.  The possible values are PROT_EXEC, PROT_READ,
-      PROT_WRITE.
-
-flag: This parameter can only take the value IPC_CREAT for the cases
-      when "key" value greater than zero (shared hugepage cases).  It is
-      ignored for values of "key" that are <= 0.
-
-      This parameter indicates that the kernel should create a new huge
-      page segment (corresponding to "key"), if none already exists.  If this
-      flag is not set, then sys_allochugepages() will return ENOENT if there
-      is no segment associated with corresponding "key".
-
-In case of success, sys_alloc_hugepages() return the allocated virtual address.
-
-sys_free_hugepages() frees the hugetlb resources from the calling process's
-address space.  The input argument "addr" specifies the segment that needs to
-be freed.  It is important to note that for the shared hugepage cases, the
-underlying hugepages are freed onlyafter all the users of those pages have
-either freed those hugepages or have exited.
-
-/proc/sys/vm_nr_hugepages indicates the current number of configured hugetlb
-pages in the kernel.  Super user privileges are required for modification of
-this value.  The allocation of hugetlb pages is possible only if there are
-enough physically contiguous free pages in system OR if there are enough
-hugetlb pages free that can be transfered back to regular memory pool.
-
-/proc/meminfo also gives the information about the total number of hugetlb
+/proc/meminfo also provides information about the total number of hugetlb
 pages configured in the kernel.  It also displays information about the
 number of free hugetlb pages at any time.  It also displays information about
-the configured hugepage size - this is needed for generting the proper
+the configured hugepage size - this is needed for generating the proper
 alignment and size of the arguments to the above system calls.
 
-Pages that are used as hugetlb pages are marked reserved inside the kernel. 
-This allows hugetlb pages to be always locked in memory.  The user either
-needs to be super user to use these pages or one of supplementary group
-should include root.  In future there will be support to check RLIMIT_MLOCK
-for limited (number of hugetlb pages) usage to unprivileged applications.
+The output of "cat /proc/meminfo" will have output like:
 
-If the kernel does not support hugepages these system calls will return ENOSYS.
+.....
+HugePages_Total: xxx
+HugePages_Free:  yyy
+Hugepagesize:    zzz KB
+
+/proc/filesystems should also show a filesystem of type "hugetlbfs" configured
+in the kernel.
+
+/proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
+pages in the kernel.  Super user can dynamically request more (or free some
+pre-configured) hugepages. 
+The allocation( or deallocation) of hugetlb pages is posible only if there are
+enough physically contiguous free pages in system (freeing of hugepages is
+possible only if there are enough hugetlb pages free that can be transfered 
+back to regular memory pool).
+
+Pages that are used as hugetlb pages are reserved inside the kernel and can
+not be used for other purposes. 
+
+Once the kernel with Hugetlb page support is built and running, a user can
+use either the mmap system call or shared memory system calls to start using
+the huge pages.  It is required that the system administrator preallocate
+enough memory for huge page purposes.  
+
+Use the following command to dynamically allocate/deallocate hugepages:
+
+	echo 20 > /proc/sys/vm/nr_hugepages
+
+This command will try to configure 20 hugepages in the system.  The success
+or failure of allocation depends on the amount of physically contiguous
+memory that is preset in system at this time.  System administrators may want
+to put this command in one of the local rc init file.  This will enable the
+kernel to request huge pages early in the boot process (when the possibility
+of getting physical contiguous pages is still very high).
+
+If the user applications are going to request hugepages using mmap system
+call, then it is required that system administrator mount a file system of
+type hugetlbfs:
+
+	mount none /mnt/huge -t hugetlbfs
+
+This commands mounts a (psuedo) filesystem of type hugetlbfs on the directory
+/mnt/huge.  Any files created on /mnt/huge uses hugepages.  An example is
+given at the end of this document.
+
+read and write system calls are not supported on files that reside on hugetlb
+file systems.
+
+Also, it is important to note that no such mount command is required if the
+applications are going to use only shmat/shmget system calls.  It is possible
+for same or different applications to use any combination of mmaps and shm*
+calls.  Though the mount of filesystem will be required for using mmaps.
+
+/* Example of using hugepage in user application using Sys V shared memory
+ * system calls.  In this example, app is requesting memory of size 256MB that
+ * is backed by huge pages.  Application uses the flag SHM_HUGETLB in shmget
+ * system call to informt the kernel that it is requesting hugepages.  For
+ * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
+ * That means the addresses starting with 0x800000....will need to be
+ * specified.
+ */
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+extern int errno;
+#define SHM_HUGETLB 04000
+#define LPAGE_SIZE      (256UL*1024UL*1024UL)
+#define         dprintf(x)  printf(x)
+#define ADDR (0x8000000000000000UL)
+main()
+{
+        int shmid;
+        int     i, j, k;
+        volatile        char    *shmaddr;
+
+        if ((shmid =shmget(2, LPAGE_SIZE, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W ))
+< 0) {
+                perror("Failure:");
+                exit(1);
+        }
+        printf("shmid: 0x%x\n", shmid);
+        shmaddr = shmat(shmid, (void *)ADDR, SHM_RND) ;
+        if (errno != 0) {
+                perror("Shared Memory Attach Failure:");
+                exit(2);
+        }
+        printf("shmaddr: %p\n", shmaddr);
+
+        dprintf("Starting the writes:\n");
+        for (i=0;i<LPAGE_SIZE;i++) {
+                shmaddr[i] = (char) (i);
+                if (!(i%(1024*1024))) dprintf(".");
+        }
+        dprintf("\n");
+        dprintf("Starting the Check...");
+        for (i=0; i<LPAGE_SIZE;i++)
+                if (shmaddr[i] != (char)i)
+                        printf("\nIndex %d mismatched.");
+        dprintf("Done.\n");
+        if (shmdt((const void *)shmaddr) != 0) {
+                perror("Detached Failure:");
+                exit (3);
+        }
+}
+*******************************************************************
+*******************************************************************
+
+
+/* Example of using hugepage in user application using mmap 
+ * system call.  Before running this application, make sure that
+ * administrator has mounted the hugetlbfs (on some directory like /mnt) using
+ * the command mount -t hugetlbfs nodev /mnt
+ * In this example, app is requesting memory of size 256MB that
+ * is backed by huge pages.  Application uses the flag SHM_HUGETLB in shmget
+ * system call to informt the kernel that it is requesting hugepages.  For
+ * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
+ * That means the addresses starting with 0x800000....will need to be
+ * specified.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define FILE_NAME "/mnt/hugepagefile"
+#define LENGTH (256*1024*1024)
+#define PROTECTION (PROT_READ | PROT_WRITE)
+#define FLAGS   MAP_SHARED |MAP_FIXED
+#define ADDRESS (char *)(0x60000000UL + 0x8000000000000000UL)
+
+extern errno;
+
+check_bytes(char *addr)
+{
+        printf("First hex is %x\n", *((unsigned int *)addr));
+}
+
+write_bytes(char *addr)
+{
+        int i;
+        for (i=0;i<LENGTH;i++)
+                *(addr+i)=(char)i;
+}
+read_bytes(char *addr)
+{
+        int i;
+        check_bytes(addr);
+        for (i=0;i<LENGTH;i++)
+                if (*(addr+i)!=(char)i) {
+                        printf("Mismatch at %d\n", i);
+                        break;
+                }
+}
+main()
+{
+        unsigned long addr = 0;
+        int fd ;
+
+        fd = open(FILE_NAME, O_CREAT|O_RDWR, 0755);
+        if (fd < 0) {
+                perror("Open failed");
+                exit(errno);
+        }
+        addr = (unsigned long)mmap(ADDRESS, LENGTH, PROTECTION, FLAGS, fd, 0);
+        if (errno != 0)
+                perror("mmap failed");
+        printf("Returned address is %p\n", addr);
+        check_bytes((char*)addr);
+        write_bytes((char*)addr);
+        read_bytes((char *)addr);
+}
diff -Nru a/Documentation/vm/locking b/Documentation/vm/locking
--- a/Documentation/vm/locking	Tue Mar  4 19:30:05 2003
+++ b/Documentation/vm/locking	Tue Mar  4 19:30:05 2003
@@ -80,7 +80,7 @@
 mm start up ... this is a loose form of stability on mm_users. For
 example, it is used in copy_mm to protect against a racing tlb_gather_mmu
 single address space optimization, so that the zap_page_range (from
-vmtruncate) does not loose sending ipi's to cloned threads that might 
+vmtruncate) does not lose sending ipi's to cloned threads that might 
 be spawned underneath it and go to user mode to drag in pte's into tlbs.
 
 swap_list_lock/swap_device_lock
diff -Nru a/Documentation/vm/overcommit-accounting b/Documentation/vm/overcommit-accounting
--- a/Documentation/vm/overcommit-accounting	Tue Mar  4 19:30:05 2003
+++ b/Documentation/vm/overcommit-accounting	Tue Mar  4 19:30:05 2003
@@ -26,7 +26,7 @@
 The C language stack growth does an implicit mremap. If you want absolute
 guarantees and run close to the edge you MUST mmap your stack for the 
 largest size you think you will need. For typical stack usage is does
-not matter much but its a corner case if you really really care
+not matter much but it's a corner case if you really really care
 
 In mode 2 the MAP_NORESERVE flag is ignored. 
 
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Tue Mar  4 19:30:10 2003
+++ b/MAINTAINERS	Tue Mar  4 19:30:10 2003
@@ -1791,10 +1791,10 @@
 S:	Maintained
 
 TRIDENT 4DWAVE/SIS 7018 PCI AUDIO CORE
-P:	Ollie Lho  
-M:	ollie@sis.com.tw
+P:	Muli Ben-Yehuda
+M:	mulix@mulix.org
 L:	linux-kernel@vger.kernel.org
-S:	Supported
+S:	Maintained
 
 TMS380 TOKEN-RING NETWORK DRIVER
 P:	Adam Fritzler
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Tue Mar  4 19:30:04 2003
+++ b/Makefile	Tue Mar  4 19:30:04 2003
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 63
+SUBLEVEL = 64
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -159,7 +159,7 @@
 OBJCOPY		= $(CROSS_COMPILE)objcopy
 OBJDUMP		= $(CROSS_COMPILE)objdump
 AWK		= awk
-GENKSYMS	= /sbin/genksyms
+GENKSYMS	= scripts/genksyms/genksyms
 DEPMOD		= /sbin/depmod
 KALLSYMS	= scripts/kallsyms
 PERL		= perl
@@ -190,11 +190,12 @@
 
 # The temporary file to save gcc -MD generated dependencies must not
 # contain a comma
+comma := ,
 depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
 
 noconfig_targets := xconfig menuconfig config oldconfig randconfig \
 		    defconfig allyesconfig allnoconfig allmodconfig \
-		    clean mrproper distclean \
+		    clean mrproper distclean rpm \
 		    help tags TAGS cscope sgmldocs psdocs pdfdocs htmldocs \
 		    checkconfig checkhelp checkincludes
 
@@ -319,36 +320,31 @@
 endef
 
 #	set -e makes the rule exit immediately on error
-#	Final awk script makes sure per-cpu vars are in per-cpu section, as
-#	old gcc (eg egcs 2.92.11) ignores section attribute if uninitialized.
 
 define rule_vmlinux__
-	set -e
-	$(if $(filter .tmp_kallsyms%,$^),,
-	  echo '  Generating build number'
-	  . $(src)/scripts/mkversion > .tmp_version
-	  mv -f .tmp_version .version
-	  $(Q)$(MAKE) $(build)=init
+	set -e;								\
+	$(if $(filter .tmp_kallsyms%,$^),,				\
+	  echo '  GEN     .version';					\
+	  . $(srctree)/scripts/mkversion > .tmp_version;		\
+	  mv -f .tmp_version .version;					\
+	  $(MAKE) $(build)=init;					\
 	)
-	$(call cmd,vmlinux__)
+	$(call cmd,vmlinux__);						\
 	echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
 endef
 
-define rule_vmlinux_no_percpu
-	$(rule_vmlinux__)
-	$(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
-endef
-
 ifdef CONFIG_SMP
+#	Final awk script makes sure per-cpu vars are in per-cpu section, as
+#	old gcc (eg egcs 2.92.11) ignores section attribute if uninitialized.
+
+check_per_cpu =	$(AWK) -f $(srctree)/scripts/per-cpu-check.awk < System.map
+endif
+
 define rule_vmlinux
-	$(rule_vmlinux_no_percpu)
-	$(AWK) -f $(srctree)/scripts/per-cpu-check.awk < System.map
-endef
-else
-define rule_vmlinux
-	$(rule_vmlinux_no_percpu)
+	$(rule_vmlinux__)
+	$(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
+	$(check_per_cpu)
 endef
-endif
 
 LDFLAGS_vmlinux += -T arch/$(ARCH)/vmlinux.lds.s
 
@@ -377,7 +373,7 @@
 	$(call cmd,kallsyms)
 
 .tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE
-	$(call if_changed_rule,vmlinux__)
+	+$(call if_changed_rule,vmlinux__)
 
 .tmp_vmlinux2: $(vmlinux-objs) .tmp_kallsyms1.o arch/$(ARCH)/vmlinux.lds.s FORCE
 	$(call if_changed_rule,vmlinux__)
@@ -457,14 +453,14 @@
 # 	Split autoconf.h into include/linux/config/*
 
 include/config/MARKER: scripts/split-include include/linux/autoconf.h
-	@echo '  SPLIT  include/linux/autoconf.h -> include/config/*'
+	@echo '  SPLIT   include/linux/autoconf.h -> include/config/*'
 	@scripts/split-include include/linux/autoconf.h include/config
 	@touch $@
 
 # 	if .config is newer than include/linux/autoconf.h, someone tinkered
 # 	with it and forgot to run make oldconfig
 
-include/linux/autoconf.h: .config
+include/linux/autoconf.h: .config scripts/fixdep
 	$(Q)$(MAKE) $(build)=scripts/kconfig scripts/kconfig/conf
 	./scripts/kconfig/conf -s arch/$(ARCH)/Kconfig
 
@@ -481,7 +477,7 @@
 	  echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \
 	  exit 1; \
 	fi;
-	@echo -n '  Generating $@'
+	@echo -n '  GEN     $@'
 	@(echo \#define UTS_RELEASE \"$(KERNELRELEASE)\"; \
 	  echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)`; \
 	 echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))'; \
@@ -506,7 +502,7 @@
 #	Build modules
 
 .PHONY: modules
-modules: $(SUBDIRS) $(if $(CONFIG_MODVERSIONS),vmlinux)
+modules: $(SUBDIRS) $(if $(KBUILD_BUILTIN),vmlinux)
 	@echo '  Building modules, stage 2.';
 	$(Q)$(MAKE) -rR -f scripts/Makefile.modpost
 
@@ -571,33 +567,6 @@
 	 echo "#endif" )
 endef
 
-# RPM target
-# ---------------------------------------------------------------------------
-
-#	If you do a make spec before packing the tarball you can rpm -ta it
-
-spec:
-	. scripts/mkspec >kernel.spec
-
-#	Build a tar ball, generate an rpm from it and pack the result
-#	There arw two bits of magic here
-#	1) The use of /. to avoid tar packing just the symlink
-#	2) Removing the .dep files as they have source paths in them that
-#	   will become invalid
-
-rpm:	clean spec
-	find . $(RCS_FIND_IGNORE) \
-		\( -size 0 -o -name .depend -o -name .hdepend\) \
-		-type f -print | xargs rm -f
-	set -e; \
-	cd $(TOPDIR)/.. ; \
-	ln -sf $(TOPDIR) $(KERNELPATH) ; \
-	tar -cvz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
-	rm $(KERNELPATH) ; \
-	cd $(TOPDIR) ; \
-	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > .version ; \
-	rpm -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
-	rm $(TOPDIR)/../$(KERNELPATH).tar.gz
 
 else # ifdef include_config
 
@@ -630,7 +599,7 @@
 # ---------------------------------------------------------------------------
 
 .PHONY: oldconfig xconfig menuconfig config \
-	make_with_config
+	make_with_config rpm
 
 scripts/kconfig/conf scripts/kconfig/mconf scripts/kconfig/qconf: scripts/fixdep FORCE
 	$(Q)$(MAKE) $(build)=scripts/kconfig $@
@@ -763,6 +732,36 @@
 tags: FORCE
 	$(call cmd,tags)
 
+# RPM target
+# ---------------------------------------------------------------------------
+
+#	If you do a make spec before packing the tarball you can rpm -ta it
+
+spec:
+	. $(srctree)/scripts/mkspec >kernel.spec
+
+#	Build a tar ball, generate an rpm from it and pack the result
+#	There are two bits of magic here
+#	1) The use of /. to avoid tar packing just the symlink
+#	2) Removing the .dep files as they have source paths in them that
+#	   will become invalid
+
+rpm:	clean spec
+	find . $(RCS_FIND_IGNORE) \
+		\( -size 0 -o -name .depend -o -name .hdepend \) \
+		-type f -print | xargs rm -f
+	set -e; \
+	cd $(TOPDIR)/.. ; \
+	ln -sf $(TOPDIR) $(KERNELPATH) ; \
+	tar -cvz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
+	rm $(KERNELPATH) ; \
+	cd $(TOPDIR) ; \
+	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > .version ; \
+	RPM=`which rpmbuild`; \
+	if [ -z "$$RPM" ]; then RPM=rpm; fi; \
+	$$RPM -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
+	rm $(TOPDIR)/../$(KERNELPATH).tar.gz
+
 # Brief documentation of the typical targets used
 # ---------------------------------------------------------------------------
 
@@ -782,7 +781,6 @@
 	@echo  ''
 	@echo  'Other generic targets:'
 	@echo  '  all		- Build all targets marked with [*]'
-	@echo  '  dep           - Create module version information'
 	@echo  '* vmlinux	- Build the bare kernel'
 	@echo  '* modules	- Build all modules'
 	@echo  '  dir/file.[ois]- Build specified target only'
@@ -802,7 +800,7 @@
 
 # Documentation targets
 # ---------------------------------------------------------------------------
-sgmldocs psdocs pdfdocs htmldocs: scripts
+sgmldocs psdocs pdfdocs htmldocs: scripts/docproc FORCE
 	$(Q)$(MAKE) $(build)=Documentation/DocBook $@
 
 # Scripts to check various things for consistency
@@ -812,11 +810,6 @@
 	find * $(RCS_FIND_IGNORE) \
 		-name '*.[hcS]' -type f -print | sort \
 		| xargs $(PERL) -w scripts/checkconfig.pl
-
-checkhelp:
-	find * $(RCS_FIND_IGNORE) \
-		-name [cC]onfig.in -print | sort \
-		| xargs $(PERL) -w scripts/checkhelp.pl
 
 checkincludes:
 	find * $(RCS_FIND_IGNORE) \
diff -Nru a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c
--- a/arch/alpha/boot/tools/objstrip.c	Tue Mar  4 19:30:14 2003
+++ b/arch/alpha/boot/tools/objstrip.c	Tue Mar  4 19:30:14 2003
@@ -7,7 +7,7 @@
  */
 /*
  * Converts an ECOFF or ELF object file into a bootable file.  The
- * object file must be a OMAGIC file (i.e., data and bss follow immediatly
+ * object file must be a OMAGIC file (i.e., data and bss follow immediately
  * behind the text).  See DEC "Assembly Language Programmer's Guide"
  * documentation for details.  The SRM boot process is documented in
  * the Alpha AXP Architecture Reference Manual, Second Edition by
diff -Nru a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
--- a/arch/alpha/kernel/entry.S	Tue Mar  4 19:30:03 2003
+++ b/arch/alpha/kernel/entry.S	Tue Mar  4 19:30:03 2003
@@ -591,7 +591,6 @@
  */
 
 	.globl	ret_from_fork
-#if CONFIG_SMP || CONFIG_PREEMPT
 	.align	4
 	.ent	ret_from_fork
 ret_from_fork:
@@ -599,9 +598,6 @@
 	mov	$17, $16
 	jmp	$31, schedule_tail
 .end ret_from_fork
-#else
-ret_from_fork = ret_from_sys_call
-#endif
 
 /*
  * kernel_thread(fn, arg, clone_flags)
diff -Nru a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
--- a/arch/alpha/kernel/pci-noop.c	Tue Mar  4 19:30:08 2003
+++ b/arch/alpha/kernel/pci-noop.c	Tue Mar  4 19:30:08 2003
@@ -48,7 +48,6 @@
 sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn)
 {
 	struct pci_controller *hose;
-	struct pci_dev *dev;
 
 	/* from hose or from bus.devfn */
 	if (which & IOBASE_FROM_HOSE) {
@@ -106,6 +105,7 @@
 void *
 pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
 {
+	return NULL;
 }
 void
 pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
@@ -116,6 +116,7 @@
 pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size,
 	       int direction)
 {
+	return (dma_addr_t) 0;
 }
 void
 pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c	Tue Mar  4 19:30:04 2003
+++ b/arch/alpha/kernel/pci.c	Tue Mar  4 19:30:04 2003
@@ -63,17 +63,6 @@
 }
 
 static void __init
-quirk_ali_ide_ports(struct pci_dev *dev)
-{
-	if (dev->resource[0].end == 0xffff)
-		dev->resource[0].end = dev->resource[0].start + 7;
-	if (dev->resource[2].end == 0xffff)
-		dev->resource[2].end = dev->resource[2].start + 7;
-	if (dev->resource[3].end == 0xffff)
-		dev->resource[3].end = dev->resource[3].start + 7;
-}
-
-static void __init
 quirk_cypress(struct pci_dev *dev)
 {
 	/* The Notorious Cy82C693 chip.  */
@@ -121,8 +110,6 @@
 struct pci_fixup pcibios_fixups[] __initdata = {
 	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378,
 	  quirk_isa_bridge },
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229,
-	  quirk_ali_ide_ports },
 	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693,
 	  quirk_cypress },
 	{ PCI_FIXUP_FINAL,  PCI_ANY_ID,	PCI_ANY_ID,
diff -Nru a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
--- a/arch/alpha/kernel/pci_iommu.c	Tue Mar  4 19:30:14 2003
+++ b/arch/alpha/kernel/pci_iommu.c	Tue Mar  4 19:30:14 2003
@@ -318,7 +318,7 @@
 /* Unmap a single streaming mode DMA translation.  The DMA_ADDR and
    SIZE must match what was provided for in a previous pci_map_single
    call.  All other usages are undefined.  After this call, reads by
-   the cpu to the buffer are guarenteed to see whatever the device
+   the cpu to the buffer are guaranteed to see whatever the device
    wrote there.  */
 
 void
diff -Nru a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
--- a/arch/alpha/kernel/process.c	Tue Mar  4 19:30:13 2003
+++ b/arch/alpha/kernel/process.c	Tue Mar  4 19:30:13 2003
@@ -155,10 +155,7 @@
 	struct halt_info args;
 	args.mode = mode;
 	args.restart_cmd = restart_cmd;
-#ifdef CONFIG_SMP
-	smp_call_function(common_shutdown_1, &args, 1, 0);
-#endif
-	common_shutdown_1(&args);
+	on_each_cpu(common_shutdown_1, &args, 1, 0);
 }
 
 void
diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
--- a/arch/alpha/kernel/smp.c	Tue Mar  4 19:30:05 2003
+++ b/arch/alpha/kernel/smp.c	Tue Mar  4 19:30:05 2003
@@ -899,10 +899,8 @@
 smp_imb(void)
 {
 	/* Must wait other processors to flush their icache before continue. */
-	if (smp_call_function(ipi_imb, NULL, 1, 1))
+	if (on_each_cpu(ipi_imb, NULL, 1, 1))
 		printk(KERN_CRIT "smp_imb: timed out\n");
-
-	imb();
 }
 
 static void
@@ -916,11 +914,9 @@
 {
 	/* Although we don't have any data to pass, we do want to
 	   synchronize with the other processors.  */
-	if (smp_call_function(ipi_flush_tlb_all, NULL, 1, 1)) {
+	if (on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1)) {
 		printk(KERN_CRIT "flush_tlb_all: timed out\n");
 	}
-
-	tbia();
 }
 
 #define asn_locked() (cpu_data[smp_processor_id()].asn_lock)
@@ -938,6 +934,8 @@
 void
 flush_tlb_mm(struct mm_struct *mm)
 {
+	preempt_disable();
+
 	if (mm == current->active_mm) {
 		flush_tlb_current(mm);
 		if (atomic_read(&mm->mm_users) <= 1) {
@@ -948,6 +946,7 @@
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
 			}
+			preempt_enable();
 			return;
 		}
 	}
@@ -955,6 +954,8 @@
 	if (smp_call_function(ipi_flush_tlb_mm, mm, 1, 1)) {
 		printk(KERN_CRIT "flush_tlb_mm: timed out\n");
 	}
+
+	preempt_enable();
 }
 
 struct flush_tlb_page_struct {
@@ -981,6 +982,8 @@
 	struct flush_tlb_page_struct data;
 	struct mm_struct *mm = vma->vm_mm;
 
+	preempt_disable();
+
 	if (mm == current->active_mm) {
 		flush_tlb_current_page(mm, vma, addr);
 		if (atomic_read(&mm->mm_users) <= 1) {
@@ -991,6 +994,7 @@
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
 			}
+			preempt_enable();
 			return;
 		}
 	}
@@ -1002,6 +1006,8 @@
 	if (smp_call_function(ipi_flush_tlb_page, &data, 1, 1)) {
 		printk(KERN_CRIT "flush_tlb_page: timed out\n");
 	}
+
+	preempt_enable();
 }
 
 void
@@ -1030,6 +1036,8 @@
 	if ((vma->vm_flags & VM_EXEC) == 0)
 		return;
 
+	preempt_disable();
+
 	if (mm == current->active_mm) {
 		__load_new_mm_context(mm);
 		if (atomic_read(&mm->mm_users) <= 1) {
@@ -1040,6 +1048,7 @@
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
 			}
+			preempt_enable();
 			return;
 		}
 	}
@@ -1047,6 +1056,8 @@
 	if (smp_call_function(ipi_flush_icache_page, mm, 1, 1)) {
 		printk(KERN_CRIT "flush_icache_page: timed out\n");
 	}
+
+	preempt_enable();
 }
 
 #ifdef CONFIG_DEBUG_SPINLOCK
diff -Nru a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
--- a/arch/alpha/kernel/sys_marvel.c	Tue Mar  4 19:30:12 2003
+++ b/arch/alpha/kernel/sys_marvel.c	Tue Mar  4 19:30:12 2003
@@ -440,7 +440,7 @@
 		return;
 
 	/* 
-	 * There is a local IO7 - redirect all of it's interrupts here.
+	 * There is a local IO7 - redirect all of its interrupts here.
 	 */
 	printk("Redirecting IO7 interrupts to local CPU at PE %u\n", cpuid);
 
diff -Nru a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
--- a/arch/alpha/kernel/time.c	Tue Mar  4 19:30:09 2003
+++ b/arch/alpha/kernel/time.c	Tue Mar  4 19:30:09 2003
@@ -50,7 +50,7 @@
 #include "proto.h"
 #include "irq_impl.h"
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 extern unsigned long wall_jiffies;	/* kernel/timer.c */
 
diff -Nru a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
--- a/arch/alpha/kernel/traps.c	Tue Mar  4 19:30:13 2003
+++ b/arch/alpha/kernel/traps.c	Tue Mar  4 19:30:13 2003
@@ -411,7 +411,7 @@
 }
 
 /* There is an ifdef in the PALcode in MILO that enables a 
-   "kernel debugging entry point" as an unpriviledged call_pal.
+   "kernel debugging entry point" as an unprivileged call_pal.
 
    We don't want to have anything to do with it, but unfortunately
    several versions of MILO included in distributions have it enabled,
diff -Nru a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c
--- a/arch/alpha/lib/checksum.c	Tue Mar  4 19:30:09 2003
+++ b/arch/alpha/lib/checksum.c	Tue Mar  4 19:30:09 2003
@@ -63,7 +63,7 @@
 		  ((unsigned long) ntohs(len) << 16) +
 		  ((unsigned long) proto << 8));
 
-	/* Fold down to 32-bits so we don't loose in the typedef-less 
+	/* Fold down to 32-bits so we don't lose in the typedef-less 
 	   network stack.  */
 	/* 64 to 33 */
 	result = (result & 0xffffffff) + (result >> 32);
diff -Nru a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
--- a/arch/arm/common/sa1111.c	Tue Mar  4 19:30:13 2003
+++ b/arch/arm/common/sa1111.c	Tue Mar  4 19:30:13 2003
@@ -418,6 +418,7 @@
 
 	spin_lock_irqsave(&sachip->lock, flags);
 
+#if CONFIG_ARCH_SA1100
 	/*
 	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
 	 * (SA-1110 Developer's Manual, section 9.1.2.1)
@@ -425,6 +426,11 @@
 	GAFR |= GPIO_32_768kHz;
 	GPDR |= GPIO_32_768kHz;
 	TUCR = TUCR_3_6864MHz;
+#elif CONFIG_ARCH_PXA
+	pxa_gpio_mode(GPIO11_3_6MHz_MD);
+#else
+#error missing clock setup
+#endif
 
 	/*
 	 * Turn VCO on, and disable PLL Bypass.
@@ -461,6 +467,8 @@
 	spin_unlock_irqrestore(&sachip->lock, flags);
 }
 
+#ifdef CONFIG_ARCH_SA1100
+
 /*
  * Configure the SA1111 shared memory controller.
  */
@@ -476,6 +484,8 @@
 	sa1111_writel(smcr, sachip->base + SA1111_SMCR);
 }
 
+#endif
+
 static void
 sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned int offset)
 {
@@ -569,6 +579,7 @@
 	 */
 	sa1111_wake(sachip);
 
+#ifdef CONFIG_ARCH_SA1100
 	/*
 	 * The SDRAM configuration of the SA1110 and the SA1111 must
 	 * match.  This is very important to ensure that SA1111 accesses
@@ -592,6 +603,7 @@
 	 * Enable the SA1110 memory bus request and grant signals.
 	 */
 	sa1110_mb_enable();
+#endif
 
 	/*
 	 * The interrupt controller must be initialised before any
diff -Nru a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
--- a/arch/arm/kernel/entry-armo.S	Tue Mar  4 19:30:05 2003
+++ b/arch/arm/kernel/entry-armo.S	Tue Mar  4 19:30:05 2003
@@ -426,7 +426,7 @@
 		mov	r2, #0
 		tst	r4, #1 << 20		@ Check to see if it is a write instruction
 		orreq	r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction
-		mov	r1, r4, lsr #22		@ Now branch to the relevent processing routine
+		mov	r1, r4, lsr #22		@ Now branch to the relevant processing routine
 		and	r1, r1, #15 << 2
 		add	pc, pc, r1
 		movs	pc, lr
diff -Nru a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
--- a/arch/arm/kernel/entry-armv.S	Tue Mar  4 19:30:05 2003
+++ b/arch/arm/kernel/entry-armv.S	Tue Mar  4 19:30:05 2003
@@ -1026,7 +1026,7 @@
 		mrs	lr, spsr
 		str	lr, [r13, #4]			@ save spsr_IRQ
 		@
-		@ now branch to the relevent MODE handling routine
+		@ now branch to the relevant MODE handling routine
 		@
 		mov	r13, #PSR_I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
@@ -1067,7 +1067,7 @@
 		mrs	lr, spsr
 		str	lr, [r13, #4]
 		@
-		@ now branch to the relevent MODE handling routine
+		@ now branch to the relevant MODE handling routine
 		@
 		mov	r13, #PSR_I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
@@ -1109,7 +1109,7 @@
 		mrs	lr, spsr
 		str	lr, [r13, #4]			@ save spsr_ABT
 		@
-		@ now branch to the relevent MODE handling routine
+		@ now branch to the relevant MODE handling routine
 		@
 		mov	r13, #PSR_I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
@@ -1150,7 +1150,7 @@
 		mrs	lr, spsr
 		str	lr, [r13, #4]			@ save spsr_UND
 		@
-		@ now branch to the relevent MODE handling routine
+		@ now branch to the relevant MODE handling routine
 		@
 		mov	r13, #PSR_I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
diff -Nru a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
--- a/arch/arm/kernel/head.S	Tue Mar  4 19:30:03 2003
+++ b/arch/arm/kernel/head.S	Tue Mar  4 19:30:03 2003
@@ -37,7 +37,7 @@
 	.globl	swapper_pg_dir
 	.equ	swapper_pg_dir, TEXTADDR - 0x4000
 
-	.macro	pgtbl, reg, rambase
+	.macro	pgtbl, reg
 	adr	\reg, stext
 	sub	\reg, \reg, #0x4000
 	.endm
@@ -47,7 +47,7 @@
  * can convert the page table base address to the base address of the section
  * containing both.
  */
-	.macro	krnladr, rd, pgtable, rambase
+	.macro	krnladr, rd, pgtable
 	bic	\rd, \pgtable, #0x000ff000
 	.endm
 
@@ -164,7 +164,7 @@
  * r8 = page table flags
  */
 __create_page_tables:
-	pgtbl	r4, r5				@ page table address
+	pgtbl	r4				@ page table address
 
 	/*
 	 * Clear the 16K level 1 swapper page table
@@ -184,7 +184,7 @@
 	 * cater for the MMU enable.  This identity mapping
 	 * will be removed by paging_init()
 	 */
-	krnladr	r2, r4, r5			@ start of kernel
+	krnladr	r2, r4				@ start of kernel
 	add	r3, r8, r2			@ flags + kernel base
 	str	r3, [r4, r2, lsr #18]		@ identity mapping
 
diff -Nru a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
--- a/arch/arm/kernel/ptrace.c	Tue Mar  4 19:30:04 2003
+++ b/arch/arm/kernel/ptrace.c	Tue Mar  4 19:30:04 2003
@@ -435,7 +435,7 @@
 		 * be receiving a prefetch abort shortly.
 		 *
 		 * If we don't set this breakpoint here, then we can
-		 * loose control of the thread during single stepping.
+		 * lose control of the thread during single stepping.
 		 */
 		if (!alt || predicate(insn) != PREDICATE_ALWAYS)
 			add_breakpoint(child, dbg, pc + 4);
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c	Tue Mar  4 19:30:11 2003
+++ b/arch/arm/kernel/time.c	Tue Mar  4 19:30:11 2003
@@ -32,7 +32,7 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 extern unsigned long wall_jiffies;
 
diff -Nru a/arch/arm/mach-iop310/iop310-pci.c b/arch/arm/mach-iop310/iop310-pci.c
--- a/arch/arm/mach-iop310/iop310-pci.c	Tue Mar  4 19:30:07 2003
+++ b/arch/arm/mach-iop310/iop310-pci.c	Tue Mar  4 19:30:07 2003
@@ -296,7 +296,7 @@
  *  within 3 instructions."
  *
  * This does not appear to be the case.  With 8 NOPs after the load, we
- * see the imprecise abort occuring on the STM of iop310_sec_pci_status()
+ * see the imprecise abort occurring on the STM of iop310_sec_pci_status()
  * which is about 10 instructions away.
  *
  * Always trust reality!
diff -Nru a/arch/arm/mach-iop310/mm.c b/arch/arm/mach-iop310/mm.c
--- a/arch/arm/mach-iop310/mm.c	Tue Mar  4 19:30:05 2003
+++ b/arch/arm/mach-iop310/mm.c	Tue Mar  4 19:30:05 2003
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-iop310/mm.c
  *
- * Low level memory intialization for IOP310 based systems
+ * Low level memory initialization for IOP310 based systems
  *
  * Author: Nicolas Pitre <npitre@mvista.com>
  *
diff -Nru a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
--- a/arch/arm/mach-pxa/Makefile	Tue Mar  4 19:30:09 2003
+++ b/arch/arm/mach-pxa/Makefile	Tue Mar  4 19:30:09 2003
@@ -4,18 +4,17 @@
 
 # Common support (must be linked before board specific support)
 obj-y += generic.o irq.o dma.o
-obj-$(CONFIG_SA1111) += sa1111.o
 
 # Specific board support
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
 
 # Support for blinky lights
-leds-y := leds.o
-leds-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
-leds-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
+led-y := leds.o
+led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
+led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
 
-obj-$(CONFIG_LEDS) += $(leds-y)
+obj-$(CONFIG_LEDS) += $(led-y)
 
 # Misc features
 obj-$(CONFIG_PM) += pm.o sleep.o
diff -Nru a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
--- a/arch/arm/mach-pxa/generic.c	Tue Mar  4 19:30:05 2003
+++ b/arch/arm/mach-pxa/generic.c	Tue Mar  4 19:30:05 2003
@@ -38,7 +38,7 @@
 static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
 
 /* Memory Frequency to Run Mode Frequency Multiplier (M) */
-static unsigned char M_clk_mult[4] = { 0, 1, 2, 0 };
+static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
 
 /* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
 /* Note: we store the value N * 2 here. */
@@ -47,11 +47,12 @@
 /* Crystal clock */
 #define BASE_CLK	3686400
 
-
 /*
- * Display what we were booted with.
+ * Get the clock frequency as reflected by CCCR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
  */
-static int __init pxa_display_clocks(void)
+unsigned int get_clk_frequency_khz(int info)
 {
 	unsigned long cccr, turbo;
 	unsigned int l, L, m, M, n2, N;
@@ -67,20 +68,24 @@
 	M = m * L;
 	N = n2 * M / 2;
 
-	L += 5000;
-	printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n",
-		L / 1000000, (L % 1000000) / 10000, l );
-	M += 5000;
-	printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
-		M / 1000000, (M % 1000000) / 10000, m );
-	N += 5000;
-	printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
-		N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5,
-		(turbo & 1) ? "" : "in" );
+	if(info)
+	{
+		L += 5000;
+		printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n",
+			L / 1000000, (L % 1000000) / 10000, l );
+		M += 5000;
+		printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
+			M / 1000000, (M % 1000000) / 10000, m );
+		N += 5000;
+		printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
+			N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5,
+			(turbo & 1) ? "" : "in" );
+	}
 
-	return 0;
+	return (turbo & 1) ? (N/1000) : (M/1000);
 }
 
+EXPORT_SYMBOL(get_clk_frequency_khz);
 
 /*
  * Return the current lclk requency in units of 10kHz
@@ -132,5 +137,5 @@
 void __init pxa_map_io(void)
 {
 	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
-	pxa_display_clocks();
+	get_clk_frequency_khz(1);
 }
diff -Nru a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
--- a/arch/arm/mach-pxa/irq.c	Tue Mar  4 19:30:13 2003
+++ b/arch/arm/mach-pxa/irq.c	Tue Mar  4 19:30:13 2003
@@ -86,7 +86,7 @@
 }
 
 /*
- * GPIO IRQs must be acknoledged.  This is for GPIO 0 and 1.
+ * GPIO IRQs must be acknowledged.  This is for GPIO 0 and 1.
  */
 
 static void pxa_ack_low_gpio(unsigned int irq)
@@ -241,10 +241,4 @@
 	/* Install handler for GPIO 2-80 edge detect interrupts */
 	set_irq_chip(IRQ_GPIO_2_80, &pxa_internal_chip);
 	set_irq_chained_handler(IRQ_GPIO_2_80, pxa_gpio_demux_handler);
-
-	/*
-	 * We generally don't want the LCD IRQ being
-	 * enabled as soon as we request it.
-	 */
-	set_irq_flags(IRQ_LCD, IRQF_VALID | IRQF_NOAUTOEN);
 }
diff -Nru a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c
--- a/arch/arm/mach-pxa/leds.c	Tue Mar  4 19:30:14 2003
+++ b/arch/arm/mach-pxa/leds.c	Tue Mar  4 19:30:14 2003
@@ -27,4 +27,4 @@
 	return 0;
 }
 
-__initcall(pxa_leds_init);
+core_initcall(pxa_leds_init);
diff -Nru a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
--- a/arch/arm/mach-pxa/lubbock.c	Tue Mar  4 19:30:07 2003
+++ b/arch/arm/mach-pxa/lubbock.c	Tue Mar  4 19:30:07 2003
@@ -13,6 +13,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/device.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
@@ -31,7 +32,6 @@
 #include <asm/hardware/sa1111.h>
 
 #include "generic.h"
-#include "sa1111.h"
 
 static void lubbock_ack_irq(unsigned int irq)
 {
@@ -106,24 +106,16 @@
 
 static int __init lubbock_init(void)
 {
-	int ret;
-
-	ret = sa1111_probe(LUBBOCK_SA1111_BASE);
-	if (ret)
-		return ret;
-	sa1111_wake();
-	sa1111_init_irq(LUBBOCK_SA1111_IRQ);
-	return 0;
+	return sa1111_init(0x10000000, LUBBOCK_SA1111_IRQ);
 }
 
-__initcall(lubbock_init);
+subsys_initcall(lubbock_init);
 
 static struct map_desc lubbock_io_desc[] __initdata = {
  /* virtual     physical    length      type */
   { 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE }, /* CPLD */
   { 0xf1000000, 0x0c000000, 0x00100000, MT_DEVICE }, /* LAN91C96 IO */
   { 0xf1100000, 0x0e000000, 0x00100000, MT_DEVICE }, /* LAN91C96 Attr */
-  { 0xf4000000, 0x10000000, 0x00400000, MT_DEVICE }  /* SA1111 */
 };
 
 static void __init lubbock_map_io(void)
diff -Nru a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
--- a/arch/arm/mach-sa1100/irq.c	Tue Mar  4 19:30:14 2003
+++ b/arch/arm/mach-sa1100/irq.c	Tue Mar  4 19:30:14 2003
@@ -68,7 +68,7 @@
 }
 
 /*
- * GPIO IRQs must be acknoledged.  This is for IRQs from 0 to 10.
+ * GPIO IRQs must be acknowledged.  This is for IRQs from 0 to 10.
  */
 static void sa1100_low_gpio_ack(unsigned int irq)
 {
diff -Nru a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
--- a/arch/arm/mm/proc-arm6_7.S	Tue Mar  4 19:30:12 2003
+++ b/arch/arm/mm/proc-arm6_7.S	Tue Mar  4 19:30:12 2003
@@ -97,7 +97,7 @@
 		tst	r4, r4, lsr #21			@ C = bit 20
 		sbc	r1, r1, r1			@ r1 = C - 1
 		and	r2, r4, #15 << 24
-		add	pc, pc, r2, lsr #22		@ Now branch to the relevent processing routine
+		add	pc, pc, r2, lsr #22		@ Now branch to the relevant processing routine
 		movs	pc, lr
 
 		b	Ldata_unknown
diff -Nru a/arch/cris/boot/rescue/head.S b/arch/cris/boot/rescue/head.S
--- a/arch/cris/boot/rescue/head.S	Tue Mar  4 19:30:12 2003
+++ b/arch/cris/boot/rescue/head.S	Tue Mar  4 19:30:12 2003
@@ -130,7 +130,7 @@
 
 	;; first put a jump test to give a possibility of upgrading the rescue code
 	;; without erasing/reflashing the sector. we put a longword of -1 here and if
-	;; its not -1, we jump using the value as jump target. since we can always
+	;; it is not -1, we jump using the value as jump target. since we can always
 	;; change 1's to 0's without erasing the sector, it is possible to add new
 	;; code after this and altering the jumptarget in an upgrade.
 
diff -Nru a/arch/cris/drivers/eeprom.c b/arch/cris/drivers/eeprom.c
--- a/arch/cris/drivers/eeprom.c	Tue Mar  4 19:30:07 2003
+++ b/arch/cris/drivers/eeprom.c	Tue Mar  4 19:30:07 2003
@@ -815,7 +815,7 @@
       i2c_outbyte( eeprom.select_cmd | 1 );
     }
 
-    if(i2c_getack());
+    if(i2c_getack())
     {
       break;
     }
diff -Nru a/arch/cris/drivers/ethernet.c b/arch/cris/drivers/ethernet.c
--- a/arch/cris/drivers/ethernet.c	Tue Mar  4 19:30:08 2003
+++ b/arch/cris/drivers/ethernet.c	Tue Mar  4 19:30:08 2003
@@ -236,7 +236,7 @@
 /* Network speed indication. */
 static struct timer_list speed_timer = TIMER_INITIALIZER(NULL, 0, 0);
 static struct timer_list clear_led_timer = TIMER_INITIALIZER(NULL, 0, 0);
-static int current_speed; /* Speed read from tranceiver */
+static int current_speed; /* Speed read from transceiver */
 static int current_speed_selection; /* Speed selected by user */
 static int led_next_time;
 static int led_active;
@@ -276,7 +276,7 @@
 static void e100_send_mdio_cmd(unsigned short cmd, int write_cmd);
 static void e100_send_mdio_bit(unsigned char bit);
 static unsigned char e100_receive_mdio_bit(void);
-static void e100_reset_tranceiver(void);
+static void e100_reset_transceiver(void);
 
 static void e100_clear_network_leds(unsigned long dummy);
 static void e100_set_network_leds(int active);
@@ -786,7 +786,7 @@
 }
 
 static void 
-e100_reset_tranceiver(void)
+e100_reset_transceiver(void)
 {
 	unsigned short cmd;
 	unsigned short data;
@@ -826,9 +826,9 @@
 	RESET_DMA(NETWORK_TX_DMA_NBR);
 	WAIT_DMA(NETWORK_TX_DMA_NBR);
 	
-	/* Reset the tranceiver. */
+	/* Reset the transceiver. */
 	
-	e100_reset_tranceiver();
+	e100_reset_transceiver();
 	
 	/* and get rid of the packet that never got an interrupt */
 	
diff -Nru a/arch/cris/drivers/lpslave/e100lpslavenet.c b/arch/cris/drivers/lpslave/e100lpslavenet.c
--- a/arch/cris/drivers/lpslave/e100lpslavenet.c	Tue Mar  4 19:30:07 2003
+++ b/arch/cris/drivers/lpslave/e100lpslavenet.c	Tue Mar  4 19:30:07 2003
@@ -129,7 +129,7 @@
 static void e100_hardware_send_packet(unsigned long hostcmd, char *buf, int length);
 static void update_rx_stats(struct net_device_stats *);
 static void update_tx_stats(struct net_device_stats *);
-static void e100_reset_tranceiver(void);
+static void e100_reset_transceiver(void);
 
 static void boot_slave(unsigned char *code);
 
@@ -528,7 +528,7 @@
 }
 
 static void 
-e100_reset_tranceiver(void)
+e100_reset_transceiver(void)
 {
   /* To do: Reboot and setup slave Etrax */
 }
@@ -554,9 +554,9 @@
 	RESET_DMA(4);
 	WAIT_DMA(4);
 	
-	/* Reset the tranceiver. */
+	/* Reset the transceiver. */
 	
-	e100_reset_tranceiver();
+	e100_reset_transceiver();
 	
 	/* and get rid of the packet that never got an interrupt */
 	
diff -Nru a/arch/cris/drivers/serial.c b/arch/cris/drivers/serial.c
--- a/arch/cris/drivers/serial.c	Tue Mar  4 19:30:11 2003
+++ b/arch/cris/drivers/serial.c	Tue Mar  4 19:30:11 2003
@@ -132,7 +132,7 @@
  *   Items worth noticing:
  *
  *      No Etrax100 port 1 workarounds (does only compile on 2.4 anyway now)
- *      RS485 is not ported (why cant it be done in userspace as on x86 ?)
+ *      RS485 is not ported (why can't it be done in userspace as on x86 ?)
  *      Statistics done through async_icount - if any more stats are needed,
  *      that's the place to put them or in an arch-dep version of it.
  *      timeout_interrupt and the other fast timeout stuff not ported yet
@@ -1766,7 +1766,7 @@
 
 B= Break character (0x00) with framing error.
 E= Error byte with parity error received after B characters.
-F= "Faked" valid byte received immediatly after B characters.
+F= "Faked" valid byte received immediately after B characters.
 V= Valid byte
 
 1.
@@ -2802,7 +2802,7 @@
 	info->tx_ctrl |= (0x80 | 0x40); /* Set bit 7 (txd) and 6 (tr_enable) */
 	info->port[REG_TR_CTRL] = info->tx_ctrl;
 
-	/* the DMA gets awfully confused if we toggle the tranceiver like this 
+	/* the DMA gets awfully confused if we toggle the transceiver like this 
 	 * so we need to reset it 
 	 */
 	*info->ocmdadr = 4;
diff -Nru a/arch/cris/kernel/kgdb.c b/arch/cris/kernel/kgdb.c
--- a/arch/cris/kernel/kgdb.c	Tue Mar  4 19:30:13 2003
+++ b/arch/cris/kernel/kgdb.c	Tue Mar  4 19:30:13 2003
@@ -152,7 +152,7 @@
  *    (IPL too high, disabled, ...)
  *
  *  - The gdb stub is currently not reentrant, i.e. errors that happen therein
- *    (e.g. accesing invalid memory) may not be caught correctly. This could
+ *    (e.g. accessing invalid memory) may not be caught correctly. This could
  *    be removed in future by introducing a stack of struct registers.
  *
  */
@@ -1486,7 +1486,7 @@
   move.d   $r0,[reg+0x62]   ; Save the return address in BRP
   move     $usp,[reg+0x66]  ; USP
 
-;; get the serial character (from debugport.c) and check if its a ctrl-c
+;; get the serial character (from debugport.c) and check if it is a ctrl-c
 
   jsr getDebugChar
   cmp.b 3, $r10
diff -Nru a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
--- a/arch/cris/kernel/process.c	Tue Mar  4 19:30:10 2003
+++ b/arch/cris/kernel/process.c	Tue Mar  4 19:30:10 2003
@@ -154,7 +154,7 @@
 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
 	cause_of_death = 0xbedead;
 #else
-	/* Since we dont plan to keep on reseting the watchdog,
+	/* Since we don't plan to keep on reseting the watchdog,
 	   the key can be arbitrary hence three */
 	*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
 		IO_STATE(R_WATCHDOG, enable, start);
@@ -226,7 +226,7 @@
 
 	swstack = ((struct switch_stack *)childregs) - 1;
 
-	swstack->r9 = 0; /* parameter to ret_from_sys_call, 0 == dont restart the syscall */
+	swstack->r9 = 0; /* parameter to ret_from_sys_call, 0 == don't restart the syscall */
 
 	/* we want to return into ret_from_sys_call after the _resume */
 
diff -Nru a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
--- a/arch/cris/kernel/setup.c	Tue Mar  4 19:30:13 2003
+++ b/arch/cris/kernel/setup.c	Tue Mar  4 19:30:13 2003
@@ -164,7 +164,7 @@
 
 	paging_init();
 
-	/* We dont use a command line yet, so just re-initialize it without
+	/* We don't use a command line yet, so just re-initialize it without
 	   saving anything that might be there.  */
 
 	*cmdline_p = command_line;
diff -Nru a/arch/cris/kernel/signal.c b/arch/cris/kernel/signal.c
--- a/arch/cris/kernel/signal.c	Tue Mar  4 19:30:04 2003
+++ b/arch/cris/kernel/signal.c	Tue Mar  4 19:30:04 2003
@@ -494,7 +494,7 @@
 			case -ERESTARTNOHAND:
 				/* ERESTARTNOHAND means that the syscall should only be
 				   restarted if there was no handler for the signal, and since
-				   we only get here if there is a handler, we dont restart */
+				   we only get here if there is a handler, we don't restart */
 				regs->r10 = -EINTR;
 				break;
 
diff -Nru a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
--- a/arch/cris/kernel/time.c	Tue Mar  4 19:30:09 2003
+++ b/arch/cris/kernel/time.c	Tue Mar  4 19:30:09 2003
@@ -45,7 +45,7 @@
 
 #include <asm/svinto.h>
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static int have_rtc;  /* used to remember if we have an RTC or not */
 
diff -Nru a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
--- a/arch/cris/mm/fault.c	Tue Mar  4 19:30:13 2003
+++ b/arch/cris/mm/fault.c	Tue Mar  4 19:30:13 2003
@@ -170,7 +170,7 @@
 
 	if (miss) {
 		/* see if the pte exists at all
-		 * refer through current_pgd, dont use mm->pgd
+		 * refer through current_pgd, don't use mm->pgd
 		 */
 
 		pmd = (pmd_t *)(current_pgd + pgd_index(address));
diff -Nru a/arch/cris/mm/tlb.c b/arch/cris/mm/tlb.c
--- a/arch/cris/mm/tlb.c	Tue Mar  4 19:30:04 2003
+++ b/arch/cris/mm/tlb.c	Tue Mar  4 19:30:04 2003
@@ -58,7 +58,7 @@
 	int i;
 	unsigned long flags;
 
-	/* the vpn of i & 0xf is so we dont write similar TLB entries
+	/* the vpn of i & 0xf is so we don't write similar TLB entries
 	 * in the same 4-way entry group. details.. 
 	 */
 
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/Kconfig	Tue Mar  4 19:30:04 2003
@@ -19,8 +19,13 @@
 	default y
 
 config SWAP
-	bool
+	bool "Support for paging of anonymous memory"
 	default y
+	help
+	  This option allows you to choose whether you want to have support
+	  for socalled swap devices or swap files in your kernel that are
+	  used to provide more virtual memory than the actual RAM present
+	  in your computer.  If unusre say Y.
 
 config SBUS
 	bool
@@ -75,6 +80,11 @@
 
 	  If you don't have one of these computers, you should say N here.
 
+config ACPI_SRAT
+	bool
+	default y
+	depends on NUMA && X86_SUMMIT
+
 config X86_BIGSMP
 	bool "Support for other sub-arch SMP systems with more than 8 CPUs"
 	help
@@ -337,11 +347,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
@@ -483,7 +488,7 @@
 # Common NUMA Features
 config NUMA
 	bool "Numa Memory Allocation Support"
-	depends on X86_NUMAQ
+	depends on (HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT && ACPI && !ACPI_HT_ONLY)))
 
 config DISCONTIGMEM
 	bool
@@ -495,6 +500,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---
@@ -750,6 +760,13 @@
 config HAVE_DEC_LOCK
 	bool
 	depends on (SMP || PREEMPT) && X86_CMPXCHG
+	default y
+
+# turning this on wastes a bunch of space.
+# Summit needs it only when NUMA is on
+config BOOT_IOREMAP
+	bool
+	depends on (X86_SUMMIT && NUMA)
 	default y
 
 endmenu
diff -Nru a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
--- a/arch/i386/boot/bootsect.S	Tue Mar  4 19:30:09 2003
+++ b/arch/i386/boot/bootsect.S	Tue Mar  4 19:30:09 2003
@@ -405,7 +405,7 @@
 	ret
 
 sectors:	.word 0
-disksizes:	.byte 36, 18, 15, 9
+disksizes:	.byte 36, 21, 18, 15, 9
 msg1:		.byte 13, 10
 		.ascii "Loading"
 
diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
--- a/arch/i386/kernel/Makefile	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/Makefile	Tue Mar  4 19:30:05 2003
@@ -28,6 +28,7 @@
 obj-$(CONFIG_EDD)             	+= edd.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-y				+= sysenter.o
+obj-$(CONFIG_ACPI_SRAT) 	+= srat.o
 
 EXTRA_AFLAGS   := -traditional
 
diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
--- a/arch/i386/kernel/acpi/boot.c	Tue Mar  4 19:30:13 2003
+++ b/arch/i386/kernel/acpi/boot.c	Tue Mar  4 19:30:13 2003
@@ -24,6 +24,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/config.h>
 #include <linux/acpi.h>
 #include <asm/pgalloc.h>
 #include <asm/apic.h>
diff -Nru a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
--- a/arch/i386/kernel/acpi/sleep.c	Tue Mar  4 19:30:08 2003
+++ b/arch/i386/kernel/acpi/sleep.c	Tue Mar  4 19:30:08 2003
@@ -2,6 +2,7 @@
  * sleep.c - x86-specific ACPI sleep support.
  *
  *  Copyright (C) 2001-2003 Patrick Mochel
+ *  Copyright (C) 2001-2003 Pavel Machek <pavel@suse.cz>
  */
 
 #include <linux/acpi.h>
@@ -34,10 +35,8 @@
  */
 int acpi_save_state_mem (void)
 {
-#if CONFIG_X86_PAE
-	panic("S3 and PAE do not like each other for now.");
-	return 1;
-#endif
+	if (!acpi_wakeup_address)
+		return 1;
 	init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
 	memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
 	acpi_copy_wakeup_routine(acpi_wakeup_address);
@@ -65,17 +64,24 @@
 /**
  * acpi_reserve_bootmem - do _very_ early ACPI initialisation
  *
- * We allocate a page in low memory for the wakeup
+ * We allocate a page from the first 1MB of memory for the wakeup
  * routine for when we come back from a sleep state. The
- * runtime allocator allows specification of <16M pages, but not
- * <1M pages.
+ * runtime allocator allows specification of <16MB pages, but not
+ * <1MB pages.
  */
 void __init acpi_reserve_bootmem(void)
 {
+	if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) {
+		printk(KERN_ERR "ACPI: Wakeup code way too big, S3 disabled.\n");
+		return;
+	}
+#if CONFIG_X86_PAE
+	printk(KERN_ERR "ACPI: S3 and PAE do not like each other for now, S3 disabled.\n");
+	return;
+#endif
 	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
-	if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
-		printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
-	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
+	if (!acpi_wakeup_address)
+		printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
 }
 
 static int __init acpi_sleep_setup(char *str)
diff -Nru a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
--- a/arch/i386/kernel/acpi/wakeup.S	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/acpi/wakeup.S	Tue Mar  4 19:30:05 2003
@@ -44,6 +44,9 @@
 	testl	$1, video_flags - wakeup_code
 	jz	1f
 	lcall   $0xc000,$3
+	movw	%cs, %ax
+	movw	%ax, %ds					# Bios might have played with that
+	movw	%ax, %ss
 1:
 
 	testl	$2, video_flags - wakeup_code
@@ -314,6 +317,31 @@
 	movl saved_context_edi, %edi
 	call restore_processor_state
 	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
diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c	Tue Mar  4 19:30:14 2003
+++ b/arch/i386/kernel/apic.c	Tue Mar  4 19:30:14 2003
@@ -665,7 +665,6 @@
 	}
 	set_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
 	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-	boot_cpu_physical_apicid = 0;
 	if (nmi_watchdog != NMI_NONE)
 		nmi_watchdog = NMI_LOCAL_APIC;
 
@@ -1154,8 +1153,7 @@
 
 	connect_bsp_APIC();
 
-	phys_cpu_present_map = 1;
-	apic_write_around(APIC_ID, boot_cpu_physical_apicid);
+	phys_cpu_present_map = 1 << boot_cpu_physical_apicid;
 
 	apic_pm_init2();
 
diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/kernel/apm.c	Tue Mar  4 19:30:04 2003
@@ -1096,7 +1096,7 @@
  *	@blank: on/off
  *
  *	Attempt to blank the console, firstly by blanking just video device
- *	zero, and if that fails (some BIOSes dont support it) then it blanks
+ *	zero, and if that fails (some BIOSes don't support it) then it blanks
  *	all video devices. Typically the BIOS will do laptop backlight and
  *	monitor powerdown for us.
  */
diff -Nru a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
--- a/arch/i386/kernel/cpu/amd.c	Tue Mar  4 19:30:14 2003
+++ b/arch/i386/kernel/cpu/amd.c	Tue Mar  4 19:30:14 2003
@@ -151,11 +151,10 @@
 		case 6: /* An Athlon/Duron */
  
 			/* Bit 15 of Athlon specific MSR 15, needs to be 0
- 			 * to enable SSE on Palomino/Morgan CPU's.
-			 * If the BIOS didn't enable it already, enable it
-			 * here.
+ 			 * to enable SSE on Palomino/Morgan/Barton CPU's.
+			 * If the BIOS didn't enable it already, enable it here.
 			 */
-			if (c->x86_model == 6 || c->x86_model == 7) {
+			if (c->x86_model >= 6 && c->x86_model <= 10) {
 				if (!cpu_has(c, X86_FEATURE_XMM)) {
 					printk(KERN_INFO "Enabling disabled K7/SSE Support.\n");
 					rdmsr(MSR_K7_HWCR, l, h);
diff -Nru a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c
--- a/arch/i386/kernel/cpu/centaur.c	Tue Mar  4 19:30:10 2003
+++ b/arch/i386/kernel/cpu/centaur.c	Tue Mar  4 19:30:10 2003
@@ -412,8 +412,9 @@
 		size >>= 8;
 
 	/* VIA also screwed up Nehemiah stepping 1, and made
-	   it return '65KB' instead of '64KB' */
-	if ((c->x86==6) && (c->x86_model==9) && (c->x86_mask==1))
+	   it return '65KB' instead of '64KB'
+	   - Note, it seems this may only be in engineering samples. */
+	if ((c->x86==6) && (c->x86_model==9) && (c->x86_mask==1) && (size==65))
 		size -=1;
 
 	return size;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig	Tue Mar  4 19:30:05 2003
@@ -18,20 +18,6 @@
 
 source "drivers/cpufreq/Kconfig"
 
-config CPU_FREQ_24_API
-	bool "/proc/sys/cpu/ interface (2.4. / OLD)"
-	depends on CPU_FREQ
-	help
-	  This enables the /proc/sys/cpu/ sysctl interface for controlling
-	  CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. 2.5
-	  uses a sysfs interface instead. Please note that some drivers do 
-	  not work well with the 2.4. /proc/sys/cpu sysctl interface,
-	  so if in doubt, say N here.
-
-	  For details, take a look at linux/Documentation/cpufreq. 
-
-	  If in doubt, say N.
-
 config CPU_FREQ_TABLE
        tristate "CPU frequency table helpers"
        depends on CPU_FREQ
@@ -56,6 +42,16 @@
 
 	  If in doubt, say N.
 
+config X86_ACPI_CPUFREQ_PROC_INTF
+        bool "/proc/acpi/processor/../performance interface (deprecated)"
+	depends on X86_ACPI_CPUFREQ && PROC_FS
+	help
+	  This enables the deprecated /proc/acpi/processor/../performance 
+	  interface. While it is helpful for debugging, the generic,
+	  cross-architecture cpufreq interfaces should be used.
+
+	  If in doubt, say N.
+
 config ELAN_CPUFREQ
 	tristate "AMD Elan"
 	depends on CPU_FREQ_TABLE && MELAN
@@ -139,7 +135,7 @@
 
 config X86_LONGHAUL
 	tristate "VIA Cyrix III Longhaul"
-	depends on CPU_FREQ
+	depends on CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for VIA Samuel/CyrixIII, 
 	  VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/kernel/cpu/cpufreq/acpi.c	Tue Mar  4 19:30:04 2003
@@ -1,5 +1,5 @@
 /*
- * acpi_processor_perf.c - ACPI Processor P-States Driver ($Revision: 71 $)
+ * acpi_processor_perf.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -50,23 +50,12 @@
 MODULE_LICENSE("GPL");
 
 
-/* Performance Management */
-
 static struct acpi_processor_performance	*performance;
-static struct cpufreq_driver			acpi_cpufreq_driver;
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
-	.open 		= acpi_processor_perf_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
 
 
 static int 
 acpi_processor_get_performance_control (
-	struct acpi_processor	*pr)
+	struct acpi_processor_performance *perf)
 {
 	int			result = 0;
 	acpi_status		status = 0;
@@ -77,7 +66,7 @@
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
 
-	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
+	status = acpi_evaluate_object(perf->pr->handle, "_PCT", NULL, &buffer);
 	if(ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
 		return_VALUE(-ENODEV);
@@ -116,7 +105,7 @@
 		goto end;
 	}
 
-	pr->performance->control_register = (u16) reg->address;
+	perf->control_register = (u16) reg->address;
 
 	/*
 	 * status_register
@@ -143,12 +132,12 @@
 		goto end;
 	}
 
-	pr->performance->status_register = (u16) reg->address;
+	perf->status_register = (u16) reg->address;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"control_register[0x%04x] status_register[0x%04x]\n",
-		pr->performance->control_register,
-		pr->performance->status_register));
+		perf->control_register,
+		perf->status_register));
 
 end:
 	acpi_os_free(buffer.pointer);
@@ -159,7 +148,7 @@
 
 static int 
 acpi_processor_get_performance_states (
-	struct acpi_processor*	pr)
+	struct acpi_processor_performance *	perf)
 {
 	int			result = 0;
 	acpi_status		status = AE_OK;
@@ -171,7 +160,7 @@
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
 
-	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
+	status = acpi_evaluate_object(perf->pr->handle, "_PSS", NULL, &buffer);
 	if(ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
 		return_VALUE(-ENODEV);
@@ -188,20 +177,20 @@
 		pss->package.count));
 
 	if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) {
-		pr->performance->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE;
+		perf->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE;
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"Limiting number of states to max (%d)\n", 
 			ACPI_PROCESSOR_MAX_PERFORMANCE));
 	}
 	else
-		pr->performance->state_count = pss->package.count;
+		perf->state_count = pss->package.count;
 
-	if (pr->performance->state_count > 1)
-		pr->flags.performance = 1;
+	if (perf->state_count > 1)
+		perf->pr->flags.performance = 1;
 
-	for (i = 0; i < pr->performance->state_count; i++) {
+	for (i = 0; i < perf->state_count; i++) {
 
-		struct acpi_processor_px *px = &(pr->performance->states[i]);
+		struct acpi_processor_px *px = &(perf->states[i]);
 
 		state.length = sizeof(struct acpi_processor_px);
 		state.pointer = px;
@@ -236,7 +225,7 @@
 
 static int
 acpi_processor_set_performance (
-	struct acpi_processor	*pr,
+	struct acpi_processor_performance	*perf,
 	int			state)
 {
 	u16			port = 0;
@@ -246,38 +235,38 @@
 
 	ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
 
-	if (!pr)
+	if (!perf || !perf->pr)
 		return_VALUE(-EINVAL);
 
-	if (!pr->flags.performance)
+	if (!perf->pr->flags.performance)
 		return_VALUE(-ENODEV);
 
-	if (state >= pr->performance->state_count) {
+	if (state >= perf->state_count) {
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
 			"Invalid target state (P%d)\n", state));
 		return_VALUE(-ENODEV);
 	}
 
-	if (state < pr->performance_platform_limit) {
+	if (state < perf->pr->performance_platform_limit) {
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
 			"Platform limit (P%d) overrides target state (P%d)\n",
-			pr->performance->platform_limit, state));
+			perf->pr->performance_platform_limit, state));
 		return_VALUE(-ENODEV);
 	}
 
-	if (state == pr->performance->state) {
+	if (state == perf->state) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"Already at target state (P%d)\n", state));
 		return_VALUE(0);
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n",
-		pr->performance->state, state));
+		perf->state, state));
 
 	/* cpufreq frequency struct */
-	cpufreq_freqs.cpu = pr->id;
-	cpufreq_freqs.old = pr->performance->states[pr->performance->state].core_frequency;
-	cpufreq_freqs.new = pr->performance->states[state].core_frequency;
+	cpufreq_freqs.cpu = perf->pr->id;
+	cpufreq_freqs.old = perf->states[perf->state].core_frequency;
+	cpufreq_freqs.new = perf->states[state].core_frequency;
 
 	/* notify cpufreq */
 	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
@@ -287,8 +276,8 @@
 	 * control_register.
 	 */
 
-	port = pr->performance->control_register;
-	value = (u16) pr->performance->states[state].control;
+	port = perf->control_register;
+	value = (u16) perf->states[state].control;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"Writing 0x%02x to port 0x%04x\n", value, port));
@@ -302,15 +291,15 @@
 	 * giving up.
 	 */
 
-	port = pr->performance->status_register;
+	port = perf->status_register;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"Looking for 0x%02x from port 0x%04x\n",
-		(u8) pr->performance->states[state].status, port));
+		(u8) perf->states[state].status, port));
 
 	for (i=0; i<100; i++) {
 		value = inb(port);
-		if (value == (u8) pr->performance->states[state].status)
+		if (value == (u8) perf->states[state].status)
 			break;
 		udelay(10);
 	}
@@ -318,7 +307,7 @@
 	/* notify cpufreq */
 	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
 
-	if (value != pr->performance->states[state].status) {
+	if (value != perf->states[state].status) {
 		unsigned int tmp = cpufreq_freqs.new;
 		cpufreq_freqs.new = cpufreq_freqs.old;
 		cpufreq_freqs.old = tmp;
@@ -332,11 +321,23 @@
 		"Transition successful after %d microseconds\n",
 		i * 10));
 
-	pr->performance->state = state;
+	perf->state = state;
 
 	return_VALUE(0);
 }
 
+
+#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
+/* /proc/acpi/processor/../performance interface (DEPRECATED) */
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_processor_perf_fops = {
+	.open 		= acpi_processor_perf_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
 {
 	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
@@ -347,7 +348,7 @@
 	if (!pr)
 		goto end;
 
-	if (!pr->flags.performance) {
+	if (!pr->flags.performance || !pr->performance) {
 		seq_puts(seq, "<not supported>\n");
 		goto end;
 	}
@@ -379,8 +380,8 @@
 acpi_processor_write_performance (
         struct file		*file,
         const char		*buffer,
-        unsigned long		count,
-        void			*data)
+        size_t			count,
+        loff_t			*data)
 {
 	int			result = 0;
 	struct acpi_processor	*pr = (struct acpi_processor *) data;
@@ -411,24 +412,78 @@
 	return_VALUE(count);
 }
 
+static void
+acpi_cpufreq_add_file (
+	struct acpi_processor *pr)
+{
+	struct proc_dir_entry	*entry = NULL;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	/* add file 'performance' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_PERFORMANCE));
+	else {
+		entry->proc_fops = &acpi_processor_perf_fops;
+		entry->proc_fops->write = acpi_processor_write_performance;
+		entry->data = acpi_driver_data(device);
+	}
+	return_VOID;
+}
+
+static void
+acpi_cpufreq_remove_file (
+	struct acpi_processor *pr)
+{
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	/* remove file 'performance' */
+	remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  acpi_device_dir(device));
+
+	return_VOID;
+}
+
+#else
+static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
+static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
+#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
+
 
 static int
-acpi_cpufreq_setpolicy (
-	struct cpufreq_policy   *policy)
+acpi_cpufreq_target (
+	struct cpufreq_policy   *policy,
+	unsigned int target_freq,
+	unsigned int relation)
 {
-	struct acpi_processor *pr = performance[policy->cpu].pr;
+	struct acpi_processor_performance *perf = &performance[policy->cpu];
 	unsigned int next_state = 0;
 	unsigned int result = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
 
-	result = cpufreq_frequency_table_setpolicy(policy, 
-			&performance[policy->cpu].freq_table[pr->limit.state.px],
+	result = cpufreq_frequency_table_target(policy, 
+			&perf->freq_table[perf->pr->limit.state.px],
+			target_freq,
+			relation,
 			&next_state);
 	if (result)
 		return_VALUE(result);
 
-	result = acpi_processor_set_performance (pr, next_state);
+	result = acpi_processor_set_performance (perf, next_state);
 
 	return_VALUE(result);
 }
@@ -439,18 +494,17 @@
 	struct cpufreq_policy   *policy)
 {
 	unsigned int result = 0;
-	unsigned int cpu = policy->cpu;
-	struct acpi_processor *pr = performance[policy->cpu].pr;
+	struct acpi_processor_performance *perf = &performance[policy->cpu];
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
 
 	result = cpufreq_frequency_table_verify(policy, 
-			&performance[cpu].freq_table[pr->limit.state.px]);
+			&perf->freq_table[perf->pr->limit.state.px]);
 
 	cpufreq_verify_within_limits(
 		policy, 
-		performance[cpu].states[performance[cpu].state_count - 1].core_frequency * 1000,
-		performance[cpu].states[pr->limit.state.px].core_frequency * 1000);
+		perf->states[perf->state_count - 1].core_frequency * 1000,
+		perf->states[perf->pr->limit.state.px].core_frequency * 1000);
 
 	return_VALUE(result);
 }
@@ -458,7 +512,7 @@
 
 static int
 acpi_processor_get_performance_info (
-	struct acpi_processor	*pr)
+	struct acpi_processor_performance	*perf)
 {
 	int			result = 0;
 	acpi_status		status = AE_OK;
@@ -466,31 +520,32 @@
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
 
-	if (!pr)
+	if (!perf || !perf->pr || !perf->pr->handle)
 		return_VALUE(-EINVAL);
 
-	status = acpi_get_handle(pr->handle, "_PCT", &handle);
+	status = acpi_get_handle(perf->pr->handle, "_PCT", &handle);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"ACPI-based processor performance control unavailable\n"));
 		return_VALUE(-ENODEV);
 	}
 
-	result = acpi_processor_get_performance_control(pr);
+	result = acpi_processor_get_performance_control(perf);
 	if (result)
 		return_VALUE(result);
 
-	result = acpi_processor_get_performance_states(pr);
+	result = acpi_processor_get_performance_states(perf);
 	if (result)
 		return_VALUE(result);
 
-	result = acpi_processor_get_platform_limit(pr);
+	result = acpi_processor_get_platform_limit(perf->pr);
 	if (result)
 		return_VALUE(result);
 
 	return_VALUE(0);
 }
 
+
 static int
 acpi_cpufreq_cpu_init (
 	struct cpufreq_policy   *policy)
@@ -498,22 +553,18 @@
 	unsigned int		i;
 	unsigned int		cpu = policy->cpu;
 	struct acpi_processor  *pr = NULL;
+	struct acpi_processor_performance *perf = &performance[policy->cpu];
 	unsigned int		result = 0;
-	struct proc_dir_entry	*entry = NULL;
-	struct acpi_device	*device = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init");
 
-	acpi_processor_register_performance(&performance[cpu], &pr, cpu);
+	acpi_processor_register_performance(perf, &pr, cpu);
 
 	pr = performance[cpu].pr;
 	if (!pr)
 		return_VALUE(-ENODEV);
 
-	if (acpi_bus_get_device(pr->handle, &device))
-		return_VALUE(-ENODEV);
-
-	result = acpi_processor_get_performance_info(performance[cpu].pr);
+	result = acpi_processor_get_performance_info(perf);
 	if (result)
 		return_VALUE(-ENODEV);
 
@@ -523,52 +574,62 @@
 
 	/* detect transition latency */
 	policy->cpuinfo.transition_latency = 0;
-	for (i=0;i<performance[cpu].state_count;i++) {
-		if (performance[cpu].states[i].transition_latency > policy->cpuinfo.transition_latency)
-			policy->cpuinfo.transition_latency = performance[cpu].states[i].transition_latency;
+	for (i=0;i<perf->state_count;i++) {
+		if (perf->states[i].transition_latency > policy->cpuinfo.transition_latency)
+			policy->cpuinfo.transition_latency = perf->states[i].transition_latency;
 	}
 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cur = perf->states[pr->limit.state.px].core_frequency * 1000;
 
 	/* table init */
-	for (i=0; i<=performance[cpu].state_count; i++)
+	for (i=0; i<=perf->state_count; i++)
 	{
-		performance[cpu].freq_table[i].index = i;
-		if (i<performance[cpu].state_count)
-			performance[cpu].freq_table[i].frequency = performance[cpu].states[i].core_frequency * 1000;
+		perf->freq_table[i].index = i;
+		if (i<perf->state_count)
+			perf->freq_table[i].frequency = perf->states[i].core_frequency * 1000;
 		else
-			performance[cpu].freq_table[i].frequency = CPUFREQ_TABLE_END;
+			perf->freq_table[i].frequency = CPUFREQ_TABLE_END;
 	}
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	acpi_cpufreq_driver.cpu_cur_freq[policy->cpu] = performance[cpu].states[pr->limit.state.px].core_frequency * 1000;
-#endif
+	result = cpufreq_frequency_table_cpuinfo(policy, &perf->freq_table[0]);
 
-	result = cpufreq_frequency_table_cpuinfo(policy, &performance[cpu].freq_table[0]);
-
-	/* add file 'performance' [R/W] */
-	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
-		  S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_PROCESSOR_FILE_PERFORMANCE));
-	else {
-		entry->proc_fops = &acpi_processor_perf_fops;
-		entry->write_proc = acpi_processor_write_performance;
-		entry->data = acpi_driver_data(device);
-	}
+	acpi_cpufreq_add_file(pr);
 
 	return_VALUE(result);
 }
 
 
+static int
+acpi_cpufreq_cpu_exit (
+	struct cpufreq_policy   *policy)
+{
+	struct acpi_processor  *pr = performance[policy->cpu].pr;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_exit");
+
+	acpi_cpufreq_remove_file(pr);
+
+	return_VALUE(0);
+}
+
+
+static struct cpufreq_driver acpi_cpufreq_driver = {
+	.verify 	= acpi_cpufreq_verify,
+	.target 	= acpi_cpufreq_target,
+	.init		= acpi_cpufreq_cpu_init,
+	.exit		= acpi_cpufreq_cpu_exit,
+	.name		= "acpi-cpufreq",
+};
+
+
 static int __init
 acpi_cpufreq_init (void)
 {
 	int                     result = 0;
 	int                     current_state = 0;
 	int                     i = 0;
-	struct acpi_processor   *pr;
+	struct acpi_processor   *pr = NULL;
+	struct acpi_processor_performance *perf = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_init");
 
@@ -579,10 +640,9 @@
 	performance = kmalloc(NR_CPUS * sizeof(struct acpi_processor_performance), GFP_KERNEL);
 	if (!performance)
 		return_VALUE(-ENOMEM);
-
 	memset(performance, 0, NR_CPUS * sizeof(struct acpi_processor_performance));
 
-	/* register struct acpi_performance performance */
+	/* register struct acpi_processor_performance performance */
 	for (i=0; i<NR_CPUS; i++) {
 		if (cpu_online(i))
 			acpi_processor_register_performance(&performance[i], &pr, i);
@@ -591,11 +651,13 @@
 	/* initialize  */
 	for (i=0; i<NR_CPUS; i++) {
 		if (cpu_online(i) && performance[i].pr)
-			result = acpi_processor_get_performance_info(performance[i].pr);
+			result = acpi_processor_get_performance_info(&performance[i]);
 	}
 
 	/* test it on one CPU */
 	for (i=0; i<NR_CPUS; i++) {
+		if (cpu_online(i))
+			continue;
 		pr = performance[i].pr;
 		if (pr && pr->flags.performance)
 			goto found_capable_cpu;
@@ -604,10 +666,11 @@
 	goto err;
 
  found_capable_cpu:
-	current_state = pr->performance->state;
+	perf = pr->performance;
+	current_state = perf->state;
 
 	if (current_state == pr->limit.state.px) {
-		result = acpi_processor_set_performance(pr, (pr->performance->state_count - 1));
+		result = acpi_processor_set_performance(perf, (perf->state_count - 1));
 		if (result) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
 			result = -ENODEV;
@@ -615,7 +678,7 @@
 		}
 	}
 
-	result = acpi_processor_set_performance(pr, pr->limit.state.px);
+	result = acpi_processor_set_performance(perf, pr->limit.state.px);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
 		result = -ENODEV;
@@ -623,7 +686,7 @@
 	}
 	
 	if (current_state != 0) {
-		result = acpi_processor_set_performance(pr, current_state);
+		result = acpi_processor_set_performance(perf, current_state);
 		if (result) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
 			result = -ENODEV;
@@ -639,7 +702,7 @@
 
 	/* error handling */
  err:
-	/* unregister struct acpi_performance performance */
+	/* unregister struct acpi_processor_performance performance */
 	for (i=0; i<NR_CPUS; i++) {
 		if (performance[i].pr) {
 			performance[i].pr->flags.performance = 0;
@@ -647,9 +710,7 @@
 			performance[i].pr = NULL;
 		}
 	}
-
 	kfree(performance);
-
 	return_VALUE(result);
 }
 
@@ -668,7 +729,7 @@
 
 	 cpufreq_unregister_driver(&acpi_cpufreq_driver);
 
-	/* unregister struct acpi_performance performance */
+	/* unregister struct acpi_processor_performance performance */
 	for (i=0; i<NR_CPUS; i++) {
 		if (performance[i].pr) {
 			performance[i].pr->flags.performance = 0;
@@ -681,15 +742,6 @@
 
 	return_VOID;
 }
-
-static struct cpufreq_driver acpi_cpufreq_driver = {
-	.verify 	= acpi_cpufreq_verify,
-	.setpolicy	= acpi_cpufreq_setpolicy,
-	.init		= acpi_cpufreq_cpu_init,
-	.exit		= NULL,
-	.policy		= NULL,
-	.name		= "acpi-cpufreq",
-};
 
 
 late_initcall(acpi_cpufreq_init);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c
--- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c	Tue Mar  4 19:30:07 2003
+++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c	Tue Mar  4 19:30:07 2003
@@ -31,15 +31,9 @@
 #define REG_CSCIR 0x22 		/* Chip Setup and Control Index Register    */
 #define REG_CSCDR 0x23		/* Chip Setup and Control Data  Register    */
 
-static struct cpufreq_driver *elanfreq_driver;
-
 /* Module parameter */
 static int max_freq;
 
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
-MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
-
 struct s_elan_multiplier {
 	int clock;		/* frequency in kHz                         */
 	int val40h;		/* PMU Force Mode register                  */
@@ -127,11 +121,6 @@
 
 	struct cpufreq_freqs    freqs;
 
-	if (!elanfreq_driver) {
-		printk(KERN_ERR "cpufreq: initialization problem or invalid target frequency\n");
-		return;
-	}
-
 	freqs.old = elanfreq_get_cpu_frequency();
 	freqs.new = elan_multiplier[state].clock;
 	freqs.cpu = 0; /* elanfreq.c is UP only driver */
@@ -187,11 +176,13 @@
 	return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]);
 }
 
-static int elanfreq_setpolicy (struct cpufreq_policy *policy)
+static int elanfreq_target (struct cpufreq_policy *policy, 
+			    unsigned int target_freq, 
+			    unsigned int relation)
 {
 	unsigned int    newstate = 0;
 
-	if (cpufreq_frequency_table_setpolicy(policy, &elanfreq_table[0], &newstate))
+	if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate))
 		return -EINVAL;
 
 	elanfreq_set_cpu_state(newstate);
@@ -204,6 +195,35 @@
  *	Module init and exit code
  */
 
+static int elanfreq_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = cpu_data;
+	unsigned int i;
+
+	/* capability check */
+	if ((c->x86_vendor != X86_VENDOR_AMD) ||
+	    (c->x86 != 4) || (c->x86_model!=10))
+		return -ENODEV;
+
+	/* max freq */
+	if (!max_freq)
+		max_freq = elanfreq_get_cpu_frequency();
+
+	/* table init */
+ 	for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+		if (elanfreq_table[i].frequency > max_freq)
+			elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+	}
+
+	/* cpuinfo and default policy values */
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = elanfreq_get_cpu_frequency();
+
+	return cpufreq_frequency_table_cpuinfo(policy, &elanfreq_table[0]);;
+}
+
+
 #ifndef MODULE
 /**
  * elanfreq_setup - elanfreq command line parameter parsing
@@ -224,11 +244,18 @@
 __setup("elanfreq=", elanfreq_setup);
 #endif
 
+
+static struct cpufreq_driver elanfreq_driver = {
+	.verify 	= elanfreq_verify,
+	.target 	= elanfreq_target,
+	.init		= elanfreq_cpu_init,
+	.name		= "elanfreq",
+};
+
+
 static int __init elanfreq_init(void) 
 {	
 	struct cpuinfo_x86 *c = cpu_data;
-	struct cpufreq_driver *driver;
-	int ret, i;
 
 	/* Test if we have the right hardware */
 	if ((c->x86_vendor != X86_VENDOR_AMD) ||
@@ -238,63 +265,22 @@
                 return -ENODEV;
 	}
 	
-	driver = kmalloc(sizeof(struct cpufreq_driver) +
-			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (!driver)
-		return -ENOMEM;
-	memset(driver, 0, sizeof(struct cpufreq_driver) +
-			NR_CPUS * sizeof(struct cpufreq_policy));
-
-	driver->policy = (struct cpufreq_policy *) (driver + 1);
-
-	if (!max_freq)
-		max_freq = elanfreq_get_cpu_frequency();
-
-	/* table init */
- 	for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if (elanfreq_table[i].frequency > max_freq)
-			elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
-	}
-
-#ifdef CONFIG_CPU_FREQ_24_API
-	driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency();
-#endif
-
-	driver->verify        = &elanfreq_verify;
-	driver->setpolicy     = &elanfreq_setpolicy;
-	strncpy(driver->name, "elanfreq", CPUFREQ_NAME_LEN);
-
-	driver->policy[0].cpu    = 0;
-	ret = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &elanfreq_table[0]);
-	if (ret) {
-		kfree(driver);
-		return ret;
-	}
-	driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
-	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-
-	elanfreq_driver = driver;
-
-	ret = cpufreq_register(driver);
-	if (ret) {
-		elanfreq_driver = NULL;
-		kfree(driver);
-	}
-
-	return ret;
+	return cpufreq_register_driver(&elanfreq_driver);
 }
 
 
 static void __exit elanfreq_exit(void) 
 {
-	if (elanfreq_driver) {
-		cpufreq_unregister();
-		kfree(elanfreq_driver);
-	}
+	cpufreq_unregister_driver(&elanfreq_driver);
 }
 
-module_init(elanfreq_init);
-module_exit(elanfreq_exit);
 
 MODULE_PARM (max_freq, "i");
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
+MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
+
+module_init(elanfreq_init);
+module_exit(elanfreq_exit);
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Tue Mar  4 19:30:08 2003
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Tue Mar  4 19:30:08 2003
@@ -116,7 +116,6 @@
 	struct pci_dev *cs55x0;
 };
 
-static struct cpufreq_driver *gx_driver;
 static struct gxfreq_params *gx_params;
 static int stock_freq;
 
@@ -345,7 +344,7 @@
 	unsigned int tmp_freq = 0;
 	u8 tmp1, tmp2;
 
-        if (!gx_driver || !stock_freq || !policy)
+        if (!stock_freq || !policy)
                 return -EINVAL;
 
 	policy->cpu = 0;
@@ -375,33 +374,71 @@
 }
 
 /*
- *      cpufreq_gx_setpolicy:  
+ *      cpufreq_gx_target:  
  *
  */
-static int cpufreq_gx_setpolicy(struct cpufreq_policy *policy)
+static int cpufreq_gx_target(struct cpufreq_policy *policy,
+			     unsigned int target_freq,
+			     unsigned int relation)
 {
+	u8 tmp1, tmp2;
+	unsigned int tmp_freq;
 
-        if (!gx_driver || !stock_freq || !policy)
+        if (!stock_freq || !policy)
                 return -EINVAL;
 
 	policy->cpu = 0;
 
-	if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-		/* here we need to make sure that we don't set the
-		 * frequency below policy->min (see comment in
-		 * cpufreq_gx_verify() - guarantee of processing 
-		 * capacity.
-		 */
-		u8 tmp1, tmp2;
-		unsigned int tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2);
-		while (tmp_freq < policy->min) {
-			tmp_freq += stock_freq / max_duration;
-			tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
-		}
-		gx_set_cpuspeed(tmp_freq);
+	tmp_freq = gx_validate_speed(target_freq, &tmp1, &tmp2);
+	while (tmp_freq < policy->min) {
+		tmp_freq += stock_freq / max_duration;
+		tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
+	}
+	while (tmp_freq > policy->max) {
+		tmp_freq -= stock_freq / max_duration;
+		tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
+	}
+
+	gx_set_cpuspeed(tmp_freq);
+
+	return 0;
+}
+
+static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
+{
+	int maxfreq, curfreq;
+
+	if (!policy || policy->cpu != 0)
+		return -ENODEV;
+
+	/* determine maximum frequency */
+	if (pci_busclk) {
+		maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
+	} else if (cpu_khz) {
+		maxfreq = cpu_khz;
 	} else {
-		gx_set_cpuspeed(policy->max);
+		maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
 	}
+	stock_freq = maxfreq;
+	curfreq = gx_get_cpuspeed();
+
+	dprintk("cpu max frequency is %d.\n", maxfreq);
+	dprintk("cpu current frequency is %dkHz.\n",curfreq);
+
+	/* setup basic struct for cpufreq API */
+	policy->cpu = 0;
+
+	if (max_duration < POLICY_MIN_DIV)
+		policy->min = maxfreq / max_duration;
+	else
+		policy->min = maxfreq / POLICY_MIN_DIV;
+	policy->max = maxfreq;
+	policy->cur = curfreq;
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.min_freq = maxfreq / max_duration;
+	policy->cpuinfo.max_freq = maxfreq;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+
 	return 0;
 }
 
@@ -409,11 +446,16 @@
  * cpufreq_gx_init:
  *   MediaGX/Geode GX initilize cpufreq driver
  */
+static struct cpufreq_driver gx_suspmod_driver = {
+	.verify		= cpufreq_gx_verify,
+	.target		= cpufreq_gx_target,
+	.init		= cpufreq_gx_cpu_init,
+	.name		= "gx-suspmod",
+};
 
 static int __init cpufreq_gx_init(void)
 {
-	int maxfreq,ret,curfreq;
- 	struct cpufreq_driver *driver;
+	int ret;
 	struct gxfreq_params *params;
 	struct pci_dev *gx_pci;
 	u32 class_rev;
@@ -428,21 +470,13 @@
 
 	dprintk("geode suspend modulation available.\n");
 
-	driver = kmalloc(sizeof(struct cpufreq_driver) + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (driver == NULL) 
-		return -ENOMEM;
-	memset(driver, 0, sizeof(struct cpufreq_driver) +
-			NR_CPUS * sizeof(struct cpufreq_policy));
-
 	params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL);
-	if (params == NULL) {
-		kfree(driver);
+	if (params == NULL)
 		return -ENOMEM;
-	}
 	memset(params, 0, sizeof(struct gxfreq_params));
 
-	driver->policy = (struct cpufreq_policy *)(driver + 1);
 	params->cs55x0 = gx_pci;
+	gx_params = params;
 
 	/* keep cs55x0 configurations */
 	pci_read_config_byte(params->cs55x0, PCI_SUSCFG, &(params->pci_suscfg));
@@ -453,45 +487,7 @@
         pci_read_config_dword(params->cs55x0, PCI_CLASS_REVISION, &class_rev);
 	params->pci_rev = class_rev && 0xff;
 
-	gx_params = params;
-
-	/* determine maximum frequency */
-	if (pci_busclk) {
-		maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
-	} else if (cpu_khz) {
-		maxfreq = cpu_khz;
-	} else {
-		maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
-	}
-	stock_freq = maxfreq;
-	curfreq = gx_get_cpuspeed();
-
-	dprintk("cpu max frequency is %d.\n", maxfreq);
-	dprintk("cpu current frequency is %dkHz.\n",curfreq);
-
-	/* setup basic struct for cpufreq API */
-#ifdef CONFIG_CPU_FREQ_24_API
-	driver->cpu_cur_freq[0] = curfreq;
-#endif
-	driver->policy[0].cpu = 0;
-
-	if (max_duration < POLICY_MIN_DIV)
-		driver->policy[0].min = maxfreq / max_duration;
-	else
-		driver->policy[0].min = maxfreq / POLICY_MIN_DIV;
-	driver->policy[0].max = maxfreq;
-	driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
-	driver->policy[0].cpuinfo.min_freq = maxfreq / max_duration;
-	driver->policy[0].cpuinfo.max_freq = maxfreq;
-	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-	driver->verify = &cpufreq_gx_verify;
-	driver->setpolicy = &cpufreq_gx_setpolicy;
-	strncpy(driver->name, "gx-suspmod", CPUFREQ_NAME_LEN);
-
-	gx_driver = driver;
-
-	if ((ret = cpufreq_register(driver))) { 
-		kfree(driver);
+	if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { 
 		kfree(params);
 		return ret;                   /* register error! */
 	}
@@ -501,13 +497,8 @@
 
 static void __exit cpufreq_gx_exit(void)
 {
-	if (gx_driver) {
-		/* disable throttling */
-		gx_set_cpuspeed(stock_freq);
-		cpufreq_unregister();
-		kfree(gx_driver);
-		kfree(gx_params);
-	}
+	cpufreq_unregister_driver(&gx_suspmod_driver);
+	kfree(gx_params);
 }
 
 MODULE_AUTHOR ("Hiroshi Miura <miura@da-cha.org>");
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c	Tue Mar  4 19:30:04 2003
@@ -1,5 +1,5 @@
 /*
- *  $Id: longhaul.c,v 1.77 2002/10/31 21:17:40 db Exp $
+ *  $Id: longhaul.c,v 1.87 2003/02/22 10:23:46 db Exp $
  *
  *  (C) 2001  Dave Jones. <davej@suse.de>
  *  (C) 2002  Padraig Brady. <padraig@antefacto.com>
@@ -48,6 +48,7 @@
 
 
 /* Module parameters */
+static int prefer_slow_fsb;
 static int dont_scale_voltage;
 static int dont_scale_fsb;
 static int current_fsb;
@@ -237,7 +238,6 @@
 /* fsb values to favour high fsb speed (for e.g. if lowering CPU 
    freq because of heat, but want to maintain highest performance possible) */
 static unsigned int perf_fsb_table[] = { 133, 100, 66, -1 };
-static unsigned int *fsb_search_table;
 
 /* Voltage scales. Div by 1000 to get actual voltage. */
 static int __initdata vrm85scales[32] = {
@@ -260,7 +260,7 @@
 static int voltage_table[32];
 static int highest_speed, lowest_speed; /* kHz */
 static int longhaul; /* version. */
-static struct cpufreq_driver *longhaul_driver;
+static struct cpufreq_frequency_table *longhaul_table;
 
 
 static int longhaul_get_cpu_fsb (void)
@@ -428,7 +428,7 @@
 }
 
 
-static void __init longhaul_get_ranges (void)
+static int __init longhaul_get_ranges (void)
 {
 	unsigned long lo, hi, invalue;
 	unsigned int minmult=0, maxmult=0, minfsb=0, maxfsb=0;
@@ -436,6 +436,9 @@
 		50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
 		-1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
 	unsigned int fsb_table[4] = { 133, 100, -1, 66 };
+	unsigned int fsbcount = 1;
+	unsigned int i, j, k = 0;
+	static unsigned int *fsb_search_table;
 
 	switch (longhaul) {
 	case 1:
@@ -472,6 +475,11 @@
 
 			dprintk (KERN_INFO "longhaul: Min FSB=%d Max FSB=%d\n",
 				minfsb, maxfsb);
+			fsbcount = 0;
+			for (i=0;i<4;i++) {
+				if((fsb_table[i] >= minfsb) && (fsb_table[i] <= maxfsb))
+					fsbcount++;
+			}
 		} else {
 			minfsb = maxfsb = current_fsb;
 		}
@@ -480,11 +488,37 @@
 
 	highest_speed = maxmult * maxfsb * 100;
 	lowest_speed = minmult * minfsb * 100;
-
 	dprintk (KERN_INFO "longhaul: MinMult(x10)=%d MaxMult(x10)=%d\n",
-		minmult, maxmult);
+		 minmult, maxmult);
 	dprintk (KERN_INFO "longhaul: Lowestspeed=%d Highestspeed=%d\n",
-		lowest_speed, highest_speed);
+		 lowest_speed, highest_speed);
+
+	longhaul_table = kmalloc((numscales * fsbcount + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
+	if(!longhaul_table)
+		return -ENOMEM;
+
+	if (prefer_slow_fsb) 
+		fsb_search_table = perf_fsb_table;   // yep, this is right: the last entry is preferred by cpufreq_frequency_table_* ...
+	else
+		fsb_search_table = power_fsb_table;
+
+	for (i=0; (i<4); i++) {
+		if ((fsb_search_table[i] > maxfsb) || (fsb_search_table[i] < minfsb) || (fsb_search_table[i] == -1))
+			continue;
+		for (j=0; (j<numscales); j++) {
+			if ((clock_ratio[j] > maxmult) || (clock_ratio[j] < minmult) || (clock_ratio[j] == -1))
+				continue;
+			longhaul_table[k].frequency= clock_ratio[j] * fsb_search_table[i] * 100;
+			longhaul_table[k].index	= (j << 8) | (i);
+			k++;
+		}
+	}
+	
+	longhaul_table[k].frequency = CPUFREQ_TABLE_END;
+	if (!k)
+		return -EINVAL;
+	
+	return 0;
 }
 
 
@@ -523,182 +557,34 @@
 }
 
 
-static inline unsigned int longhaul_statecount_fsb(struct cpufreq_policy *policy, unsigned int fsb) {
-	unsigned int i, count = 0;
-
-	for(i=0; i<numscales; i++) {
-		if ((clock_ratio[i] != -1) &&
-		    ((clock_ratio[i] * fsb * 100) <= policy->max) &&
-		    ((clock_ratio[i] * fsb * 100) >= policy->min))
-			count++;
-	}
-
-	return count;
-}
-
-
 static int longhaul_verify(struct cpufreq_policy *policy)
 {
-	unsigned int    number_states = 0;
-	unsigned int    i;
-	unsigned int    fsb_index = 0;
-	unsigned int    tmpfreq = 0;
-	unsigned int    newmax = -1;
-
-	if (!policy || !longhaul_driver)
-		return -EINVAL;
-
-	policy->cpu = 0;
-	cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
-
-	if (can_scale_fsb==1) {
-		for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++)
-			number_states += longhaul_statecount_fsb(policy, fsb_search_table[fsb_index]);
-	} else
-		number_states = longhaul_statecount_fsb(policy, current_fsb);
-
-	if (number_states)
-		return 0;
-
-	/* get frequency closest above current policy->max */
-	if (can_scale_fsb==1) {
-		for (fsb_index=0; fsb_search_table[fsb_index] != -1; fsb_index++)
-			for(i=0; i<numscales; i++) {
-				if (clock_ratio[i] == -1)
-					continue;
-
-				tmpfreq = clock_ratio[i] * fsb_search_table[fsb_index];
-				if ((tmpfreq > policy->max) &&
-				    (tmpfreq < newmax))
-					newmax = tmpfreq;
-			}
-	} else {
-		for(i=0; i<numscales; i++) {
-			if (clock_ratio[i] == -1)
-				continue;
-
-			tmpfreq = clock_ratio[i] * current_fsb;
-			if ((tmpfreq > policy->max) &&
-			    (tmpfreq < newmax))
-				newmax = tmpfreq;
-			}
-	}
-
-	policy->max = newmax;
-
-	cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
-
-	return 0;
-}
-
-
-static int longhaul_get_best_freq_for_fsb(struct cpufreq_policy *policy, 
-					  unsigned int min_mult, 
-					  unsigned int max_mult, 
-					  unsigned int fsb, 
-					  unsigned int *new_mult)
-{
-	unsigned int optimal = 0;
-	unsigned int found_optimal = 0;
-	unsigned int i;
-
-	switch(policy->policy) {
-	case CPUFREQ_POLICY_POWERSAVE:
-		optimal = max_mult;
-		break;
-	case CPUFREQ_POLICY_PERFORMANCE:
-		optimal = min_mult;
-	}
-
-	for(i=0; i<numscales; i++) {
-		unsigned int freq = fsb * clock_ratio[i] * 100;
-		if ((freq > policy->max) ||
-		    (freq < policy->min))
-			continue;
-		switch(policy->policy) {
-		case CPUFREQ_POLICY_POWERSAVE:
-			if (clock_ratio[i] < clock_ratio[optimal]) {
-				found_optimal = 1;
-				optimal = i;
-			}
-			break;
-		case CPUFREQ_POLICY_PERFORMANCE:
-			if (clock_ratio[i] > clock_ratio[optimal]) {
-				found_optimal = 1;
-				optimal = i;
-			}
-			break;
-		}
-	}
-		
-	if (found_optimal) {
-		*new_mult = optimal;
-		return 1;
-	}
-	return 0;
+	return cpufreq_frequency_table_verify(policy, longhaul_table);
 }
 
 
-static int longhaul_setpolicy (struct cpufreq_policy *policy)
+static int longhaul_target (struct cpufreq_policy *policy,
+			    unsigned int target_freq,
+			    unsigned int relation)
 {
-	unsigned int    i;
-	unsigned int    fsb_index = 0;
-	unsigned int    new_fsb = 0;
-	unsigned int    new_clock_ratio = 0;
-	unsigned int    min_mult = 0;
-	unsigned int    max_mult = 0;
-
+	unsigned int    table_index = 0;
+ 	unsigned int    new_fsb = 0;
+ 	unsigned int    new_clock_ratio = 0;
 
-	if (!longhaul_driver)
+	if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
 		return -EINVAL;
 
-	if (policy->policy==CPUFREQ_POLICY_PERFORMANCE)
-		fsb_search_table = perf_fsb_table;
-	else
-		fsb_search_table = power_fsb_table;
-
-	for(i=0;i<numscales;i++) {
-		if (clock_ratio[max_mult] < clock_ratio[i])
-				max_mult = i;
-		else if (clock_ratio[min_mult] > clock_ratio[i])
-				min_mult = i;
-	}
-
-	if (can_scale_fsb==1) {
-		unsigned int found = 0;
-		for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++)
-		{
-			if (longhaul_get_best_freq_for_fsb(policy, 
-			              min_mult, max_mult, 
-				      fsb_search_table[fsb_index], 
-				      &new_clock_ratio)) {
-				new_fsb = fsb_search_table[fsb_index];
-				break;
-			}
-		}
-		if (!found)
-			return -EINVAL;
-	} else {
-		new_fsb = current_fsb;
-		if (!longhaul_get_best_freq_for_fsb(policy, min_mult, 
-			     max_mult, new_fsb, &new_clock_ratio))
-			return -EINVAL;
-	}
-
+	new_clock_ratio = longhaul_table[table_index].index & 0xFF;
+	new_fsb = power_fsb_table[(longhaul_table[table_index].index & 0xFF00) >> 8];
+ 
 	longhaul_setstate(new_clock_ratio, new_fsb);
 
 	return 0;
 }
 
-
-static int __init longhaul_init (void)
+static int longhaul_cpu_init (struct cpufreq_policy *policy)
 {
 	struct cpuinfo_x86 *c = cpu_data;
-	unsigned int currentspeed;
-	static int currentmult;
-	unsigned long lo, hi;
-	int ret;
-	struct cpufreq_driver *driver;
 
 	if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) )
 		return -ENODEV;
@@ -733,21 +619,12 @@
 		memcpy (eblcr_table, c5m_eblcr, sizeof(c5m_eblcr));
 		break;
 
-	default:
-		printk (KERN_INFO "longhaul: Unknown VIA CPU. Contact davej@suse.de\n");
-		return -ENODEV;
 	}
 
 	printk (KERN_INFO "longhaul: VIA CPU detected. Longhaul version %d supported\n", longhaul);
 
-	current_fsb = longhaul_get_cpu_fsb();
-	currentmult = longhaul_get_cpu_mult();
-	currentspeed = currentmult * current_fsb * 100;
-
-	dprintk (KERN_INFO "longhaul: CPU currently at %dMHz (%d x %d.%d)\n",
-		(currentspeed/1000), current_fsb, currentmult/10, currentmult%10);
-
 	if (longhaul==2 || longhaul==3) {
+		unsigned long lo, hi;
 		rdmsr (MSR_VIA_LONGHAUL, lo, hi);
 		if ((lo & (1<<0)) && (dont_scale_voltage==0))
 			longhaul_setup_voltagescaling (lo, hi);
@@ -756,57 +633,53 @@
 			can_scale_fsb = 1;
 	}
 
-	longhaul_get_ranges();
-
-	driver = kmalloc(sizeof(struct cpufreq_driver) + 
-			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (!driver)
+	if (longhaul_get_ranges())
 		return -ENOMEM;
-	memset(driver, 0, sizeof(struct cpufreq_driver) +
-			NR_CPUS * sizeof(struct cpufreq_policy));
 
-	driver->policy = (struct cpufreq_policy *) (driver + 1);
+ 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ 	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	driver->cpu_cur_freq[0] = currentspeed;
-#endif
+        policy->cur = (unsigned int) (longhaul_get_cpu_fsb() * longhaul_get_cpu_mult() * 100);
+
+	return cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
+}
+
+static struct cpufreq_driver longhaul_driver = {
+	.verify 	= longhaul_verify,
+	.target 	= longhaul_target,
+	.init		= longhaul_cpu_init,
+	.name		= "longhaul",
+};
 
-	driver->verify    = &longhaul_verify;
-	driver->setpolicy = &longhaul_setpolicy;
+static int __init longhaul_init (void)
+{
+	struct cpuinfo_x86 *c = cpu_data;
 
-	strncpy(driver->name, "longhaul", CPUFREQ_NAME_LEN);
+	if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) )
+		return -ENODEV;
 
-	driver->policy[0].cpu = 0;
-	driver->policy[0].min = (unsigned int) lowest_speed;
-	driver->policy[0].max = (unsigned int) highest_speed;
-	driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
-	driver->policy[0].cpuinfo.min_freq = (unsigned int) lowest_speed;
-	driver->policy[0].cpuinfo.max_freq = (unsigned int) highest_speed;
-	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-
-	longhaul_driver = driver;
-
-	ret = cpufreq_register(driver);
-	if (ret) {
-		longhaul_driver = NULL;
-		kfree(driver);
+	switch (c->x86_model) {
+	case 6 ... 7:
+		return cpufreq_register_driver(&longhaul_driver);
+	case 8:
+		return -ENODEV;
+	default:
+		printk (KERN_INFO "longhaul: Unknown VIA CPU. Contact davej@suse.de\n");
 	}
 
-	return ret;
+	return -ENODEV;
 }
 
-
 static void __exit longhaul_exit (void)
 {
-	if (longhaul_driver) {
-		cpufreq_unregister();
-		kfree(longhaul_driver);
-	}
+	cpufreq_unregister_driver(&longhaul_driver);
+	kfree(longhaul_table);
 }
 
 MODULE_PARM (dont_scale_fsb, "i");
 MODULE_PARM (dont_scale_voltage, "i");
 MODULE_PARM (current_fsb, "i");
+MODULE_PARM (prefer_slow_fsb, "i");
 
 MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
 MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c
--- a/arch/i386/kernel/cpu/cpufreq/longrun.c	Tue Mar  4 19:30:11 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longrun.c	Tue Mar  4 19:30:11 2003
@@ -1,5 +1,5 @@
 /*
- *  $Id: longrun.c,v 1.22 2003/02/10 17:31:50 db Exp $
+ *  $Id: longrun.c,v 1.25 2003/02/28 16:03:50 db Exp $
  *
  * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
  *
@@ -133,7 +133,7 @@
  * longrun_determine_freqs - determines the lowest and highest possible core frequency
  *
  * Determines the lowest and highest possible core frequencies on this CPU.
- * This is neccessary to calculate the performance percentage according to
+ * This is necessary to calculate the performance percentage according to
  * TMTA rules:
  * performance_pctg = (target_freq - low_freq)/(high_freq - low_freq)
  */
@@ -244,10 +244,6 @@
 	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 	longrun_get_policy(policy);
 	
-#ifdef CONFIG_CPU_FREQ_24_API
-	longrun_driver.cpu_cur_freq[policy->cpu] = longrun_low_freq; /* dummy value */
-#endif
-
 	return 0;
 }
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Tue Mar  4 19:30:13 2003
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Tue Mar  4 19:30:13 2003
@@ -49,8 +49,6 @@
 static int has_N44_O17_errata[NR_CPUS];
 static int stock_freq;
 
-static struct cpufreq_driver p4clockmod_driver;
-
 
 static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
 {
@@ -220,9 +218,7 @@
 	/* cpuinfo and default policy values */
 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = 1000;
-#ifdef CONFIG_CPU_FREQ_24_API
-	p4clockmod_driver.cpu_cur_freq[policy->cpu] = stock_freq;
-#endif
+	policy->cur = stock_freq;
 
 	return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]);
 }
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Tue Mar  4 19:30:04 2003
@@ -1,9 +1,9 @@
 /*
- *  $Id: powernow-k6.c,v 1.36 2002/10/31 21:17:40 db Exp $
+ *  $Id: powernow-k6.c,v 1.48 2003/02/22 10:23:46 db Exp $
  *  This file was part of Powertweak Linux (http://powertweak.sf.net)
  *  and is shared with the Linux Kernel module.
  *
- *  (C) 2000-2002  Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
+ *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
  *
  *  Licensed under the terms of the GNU GPL License version 2.
  *
@@ -25,7 +25,6 @@
 #define POWERNOW_IOPORT 0xfff0         /* it doesn't matter where, as long
 					  as it is unused */
 
-static struct cpufreq_driver		*powernow_driver;
 static unsigned int                     busfreq;   /* FSB, in 10 kHz */
 static unsigned int                     max_multiplier;
 
@@ -77,8 +76,8 @@
 	unsigned long           msrval;
 	struct cpufreq_freqs    freqs;
 
-	if (!powernow_driver) {
-		printk(KERN_ERR "cpufreq: initialization problem or invalid target frequency\n");
+	if (clock_ratio[best_i].index > max_multiplier) {
+		printk(KERN_ERR "cpufreq: invalid target frequency\n");
 		return;
 	}
 
@@ -126,11 +125,13 @@
  *
  * sets a new CPUFreq policy
  */
-static int powernow_k6_setpolicy (struct cpufreq_policy *policy)
+static int powernow_k6_target (struct cpufreq_policy *policy,
+			       unsigned int target_freq,
+			       unsigned int relation)
 {
 	unsigned int    newstate = 0;
 
-	if (cpufreq_frequency_table_setpolicy(policy, &clock_ratio[0], &newstate))
+	if (cpufreq_frequency_table_target(policy, &clock_ratio[0], target_freq, relation, &newstate))
 		return -EINVAL;
 
 	powernow_k6_set_state(newstate);
@@ -139,6 +140,59 @@
 }
 
 
+static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = cpu_data;
+	unsigned int i;
+
+	/* capability check */
+	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
+	    ((c->x86_model != 12) && (c->x86_model != 13)))
+		return -ENODEV;
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	/* get frequencies */
+	max_multiplier = powernow_k6_get_cpu_multiplier();
+	busfreq = cpu_khz / max_multiplier;
+
+	/* table init */
+ 	for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
+		if (clock_ratio[i].index > max_multiplier)
+			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
+		else
+			clock_ratio[i].frequency = busfreq * clock_ratio[i].index;
+	}
+
+	/* cpuinfo and default policy values */
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = busfreq * max_multiplier;
+
+	return cpufreq_frequency_table_cpuinfo(policy, &clock_ratio[0]);
+}
+
+
+static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
+{
+	unsigned int i;
+	for (i=0; i<8; i++) {
+		if (i==max_multiplier)
+			powernow_k6_set_state(i);
+	}
+	return 0;
+}
+
+
+static struct cpufreq_driver powernow_k6_driver = {
+	.verify 	= powernow_k6_verify,
+	.target 	= powernow_k6_target,
+	.init		= powernow_k6_cpu_init,
+	.exit		= powernow_k6_cpu_exit,
+	.name		= "powernow-k6",
+};
+
+
 /**
  * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
  *
@@ -149,68 +203,22 @@
 static int __init powernow_k6_init(void)
 {	
 	struct cpuinfo_x86      *c = cpu_data;
-	struct cpufreq_driver   *driver;
-	unsigned int            result;
-	unsigned int            i;
 
 	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
 		((c->x86_model != 12) && (c->x86_model != 13)))
 		return -ENODEV;
 
-	max_multiplier = powernow_k6_get_cpu_multiplier();
-	busfreq = cpu_khz / max_multiplier;
-
 	if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
 		printk("cpufreq: PowerNow IOPORT region already used.\n");
 		return -EIO;
 	}
 
-	/* initialization of main "cpufreq" code*/
-	driver = kmalloc(sizeof(struct cpufreq_driver) +
-			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (!driver) {
+	if (cpufreq_register_driver(&powernow_k6_driver)) {
 		release_region (POWERNOW_IOPORT, 16);
-		return -ENOMEM;
-	}
-	memset(driver, 0, sizeof(struct cpufreq_driver) +
-			NR_CPUS * sizeof(struct cpufreq_policy));
-	driver->policy = (struct cpufreq_policy *) (driver + 1);
-
-	/* table init */
- 	for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if (clock_ratio[i].index > max_multiplier)
-			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
-		else
-			clock_ratio[i].frequency = busfreq * clock_ratio[i].index;
-	}
-
-	driver->verify        = &powernow_k6_verify;
-	driver->setpolicy     = &powernow_k6_setpolicy;
-	strncpy(driver->name, "powernow-k6", CPUFREQ_NAME_LEN);
-
-	/* cpuinfo and default policy values */
-	driver->policy[0].cpu    = 0;
-	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-	driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
-#ifdef CONFIG_CPU_FREQ_24_API
-	driver->cpu_cur_freq[0]  = busfreq * max_multiplier;
-#endif
-	result = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &clock_ratio[0]);
-	if (result) {
-		kfree(driver);
-		return result;
-	}
-
-	powernow_driver = driver;
-
-	result = cpufreq_register(driver);
-	if (result) {
-		release_region (POWERNOW_IOPORT, 16);
-		powernow_driver = NULL;
-		kfree(driver);
+		return -EINVAL;
 	}
 
-	return result;
+	return 0;
 }
 
 
@@ -221,20 +229,14 @@
  */
 static void __exit powernow_k6_exit(void)
 {
-	unsigned int i;
-
-	if (powernow_driver) {
-		for (i=0;i<8;i++)
-			if (clock_ratio[i].index == max_multiplier)
-				powernow_k6_set_state(i);		
-		cpufreq_unregister();
-		kfree(powernow_driver);
-	}
+	cpufreq_unregister_driver(&powernow_k6_driver);
+	release_region (POWERNOW_IOPORT, 16);
 }
 
 
 MODULE_AUTHOR ("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@suse.de>, Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION ("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
 MODULE_LICENSE ("GPL");
+
 module_init(powernow_k6_init);
 module_exit(powernow_k6_exit);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	Tue Mar  4 19:30:04 2003
@@ -1,5 +1,5 @@
 /*
- *  $Id: powernow-k7.c,v 1.31 2003/02/12 21:16:35 davej Exp $
+ *  $Id: powernow-k7.c,v 1.34 2003/02/22 10:23:46 db Exp $
  *
  *  (C) 2003 Dave Jones <davej@suse.de>
  *
@@ -72,8 +72,6 @@
     150, 225, 160, 165, 170, 180, -1, -1,
 };
 
-static struct cpufreq_driver powernow_driver;
-
 static struct cpufreq_frequency_table *powernow_table;
 
 static unsigned int can_scale_bus;
@@ -369,13 +367,18 @@
 
 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = latency;
-#ifdef CONFIG_CPU_FREQ_24_API
-	powernow_driver.cpu_cur_freq[policy->cpu] = maximum_speed;
-#endif
+	policy->cur = maximum_speed;
 
 	return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
 }
 
+static struct cpufreq_driver powernow_driver = {
+	.verify 	= powernow_verify,
+	.target 	= powernow_target,
+	.init		= powernow_cpu_init,
+	.name		= "powernow-k7",
+};
+
 static int __init powernow_init (void)
 {
 	if (check_powernow()==0)
@@ -390,14 +393,6 @@
 	if (powernow_table)
 		kfree(powernow_table);
 }
-
-static struct cpufreq_driver powernow_driver = {
-	.verify 	= powernow_verify,
-	.target 	= powernow_target,
-	.init		= powernow_cpu_init,
-	.name		= "powernow-k7",
-};
-
 
 MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
 MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep.c b/arch/i386/kernel/cpu/cpufreq/speedstep.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep.c	Tue Mar  4 19:30:03 2003
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep.c	Tue Mar  4 19:30:03 2003
@@ -1,5 +1,5 @@
 /*
- *  $Id: speedstep.c,v 1.68 2003/01/20 17:31:47 db Exp $
+ *  $Id: speedstep.c,v 1.70 2003/02/22 10:23:46 db Exp $
  *
  * (C) 2001  Dave Jones, Arjan van de ven.
  * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
@@ -30,8 +30,6 @@
 #include <asm/msr.h>
 
 
-static struct cpufreq_driver		speedstep_driver;
-
 /* speedstep_chipset:
  *   It is necessary to know which chipset is used. As accesses to 
  * this device occur at various places in this module, we need a 
@@ -629,9 +627,7 @@
 	policy->policy = (speed == speedstep_low_freq) ? 
 		CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-#ifdef CONFIG_CPU_FREQ_24_API
-	speedstep_driver.cpu_cur_freq[policy->cpu] = speed;
-#endif
+	policy->cur = speed;
 
 	return cpufreq_frequency_table_cpuinfo(policy, &speedstep_freqs[0]);
 }
@@ -686,7 +682,7 @@
 		return -ENODEV;
 	}
 
-	dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.68 $\n");
+	dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.70 $\n");
 
 	/* activate speedstep support */
 	if (speedstep_activate())
diff -Nru a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
--- a/arch/i386/kernel/cpu/cyrix.c	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/cpu/cyrix.c	Tue Mar  4 19:30:05 2003
@@ -49,7 +49,7 @@
  * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in
  * order to identify the Cyrix CPU model after we're out of setup.c
  *
- * Actually since bugs.h doesnt even reference this perhaps someone should
+ * Actually since bugs.h doesn't even reference this perhaps someone should
  * fix the documentation ???
  */
 static unsigned char Cx86_dir0_msb __initdata = 0;
@@ -77,7 +77,7 @@
  * BIOSes for compatibility with DOS games.  This makes the udelay loop
  * work correctly, and improves performance.
  *
- * FIXME: our newer udelay uses the tsc. We dont need to frob with SLOP
+ * FIXME: our newer udelay uses the tsc. We don't need to frob with SLOP
  */
 
 extern void calibrate_delay(void) __init;
diff -Nru a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
--- a/arch/i386/kernel/cpu/intel.c	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/cpu/intel.c	Tue Mar  4 19:30:05 2003
@@ -151,7 +151,7 @@
 #ifdef CONFIG_X86_F00F_BUG
 	/*
 	 * All current models of Pentium and Pentium with MMX technology CPUs
-	 * have the F0 0F bug, which lets nonpriviledged users lock up the system.
+	 * have the F0 0F bug, which lets nonprivileged users lock up the system.
 	 * Note that the workaround only should be initialized once...
 	 */
 	c->f00f_bug = 0;
diff -Nru a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c
--- a/arch/i386/kernel/cpu/mcheck/non-fatal.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c	Tue Mar  4 19:30:04 2003
@@ -33,7 +33,7 @@
 		rdmsr (MSR_IA32_MC0_STATUS+i*4, low, high);
 
 		if (high & (1<<31)) {
-			printk (KERN_EMERG "MCE: The hardware reports a non fatal, correctable incident occured on CPU %d.\n",
+			printk (KERN_EMERG "MCE: The hardware reports a non fatal, correctable incident occurred on CPU %d.\n",
 				smp_processor_id());
 			printk (KERN_EMERG "Bank %d: %08x%08x\n", i, high, low);
 
diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c	Tue Mar  4 19:30:07 2003
+++ b/arch/i386/kernel/dmi_scan.c	Tue Mar  4 19:30:07 2003
@@ -440,7 +440,7 @@
 {
 	printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n");
 	printk(KERN_INFO " *** Many BIOSes matching this signature have incorrect IRQ routing tables.\n");
-	printk(KERN_INFO " *** If you see IRQ problems, in paticular SCSI resets and hangs at boot\n");
+	printk(KERN_INFO " *** If you see IRQ problems, in particular SCSI resets and hangs at boot\n");
 	printk(KERN_INFO " *** contact your hardware vendor and ask about updates.\n");
 	printk(KERN_INFO " *** Building an SMP kernel may evade the bug some of the time.\n");
 #ifdef CONFIG_X86_IO_APIC
@@ -455,7 +455,7 @@
 
 static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
 {
-	printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, contact pavel@ucw.cz\n");
+	printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n");
 	return 0;
 }
 
@@ -470,6 +470,23 @@
 	return 0;
 }
 
+#ifdef CONFIG_ACPI_SLEEP
+static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
+{
+	/* See acpi_wakeup.S */
+	extern long acpi_video_flags;
+	acpi_video_flags |= 2;
+	return 0;
+}
+
+static __init int reset_videobios_after_s3(struct dmi_blacklist *d)
+{
+	extern long acpi_video_flags;
+	acpi_video_flags |= 1;
+	return 0;
+}
+#endif
+
 /*
  * Some Bioses enable the PS/2 mouse (touchpad) at resume, even if it was
  * disabled before the suspend. Linux used to get terribly confused by that.
@@ -743,6 +760,12 @@
 			MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
 			NO_MATCH, NO_MATCH, NO_MATCH
 			} },
+#ifdef CONFIG_ACPI_SLEEP
+	{ reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
+			MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
+			NO_MATCH, NO_MATCH, NO_MATCH
+			} },
+#endif
 
 	{ print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", {
 			MATCH(DMI_SYS_VENDOR, "IBM"),
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/entry.S	Tue Mar  4 19:30:05 2003
@@ -228,7 +228,6 @@
 #define SYSENTER_RETURN 0xffffe010
 
 	# sysenter call handler stub
-	ALIGN
 ENTRY(sysenter_entry)
 	sti
 	pushl $(__USER_DS)
@@ -271,7 +270,6 @@
 
 
 	# system call handler stub
-	ALIGN
 ENTRY(system_call)
 	pushl %eax			# save orig_eax
 	SAVE_ALL
diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c	Tue Mar  4 19:30:14 2003
+++ b/arch/i386/kernel/i386_ksyms.c	Tue Mar  4 19:30:14 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 -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/io_apic.c	Tue Mar  4 19:30:05 2003
@@ -46,7 +46,7 @@
 
 /*
  *	Is the SiS APIC rmw bug present ?
- *	-1 = dont know, 0 = no, 1 = yes
+ *	-1 = don't know, 0 = no, 1 = yes
  */
 int sis_apic_bug = -1;
 
@@ -223,7 +223,7 @@
 
 extern unsigned long irq_affinity [NR_IRQS];
 int __cacheline_aligned pending_irq_balance_apicid [NR_IRQS];
-static int irqbalance_disabled __initdata = 0;
+static int irqbalance_disabled = NO_BALANCE_IRQ;
 static int physical_balance = 0;
 
 struct irq_cpu_info {
@@ -492,7 +492,7 @@
 	unsigned long allowed_mask;
 	unsigned int new_cpu;
 		
-	if (no_balance_irq)
+	if (irqbalance_disabled)
 		return;
 
 	allowed_mask = cpu_online_map & irq_affinity[irq];
@@ -1376,8 +1376,7 @@
 
 void print_all_local_APICs (void)
 {
-	smp_call_function(print_local_APIC, NULL, 1, 1);
-	print_local_APIC(NULL);
+	on_each_cpu(print_local_APIC, NULL, 1, 1);
 }
 
 void /*__init*/ print_PIC(void)
@@ -1843,8 +1842,7 @@
 	 */ 
 	printk(KERN_INFO "activating NMI Watchdog ...");
 
-	smp_call_function(enable_NMI_through_LVT0, NULL, 1, 1);
-	enable_NMI_through_LVT0(NULL);
+	on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1);
 
 	printk(" done.\n");
 }
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/kernel/irq.c	Tue Mar  4 19:30:04 2003
@@ -87,7 +87,7 @@
 {
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves, it doesnt deserve
+ * each architecture has to answer this themselves, it doesn't deserve
  * a generic callback i think.
  */
 #if CONFIG_X86
diff -Nru a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
--- a/arch/i386/kernel/ldt.c	Tue Mar  4 19:30:11 2003
+++ b/arch/i386/kernel/ldt.c	Tue Mar  4 19:30:11 2003
@@ -55,12 +55,14 @@
 	wmb();
 
 	if (reload) {
-		load_LDT(pc);
 #ifdef CONFIG_SMP
 		preempt_disable();
+		load_LDT(pc);
 		if (current->mm->cpu_vm_mask != (1 << smp_processor_id()))
 			smp_call_function(flush_ldt, 0, 1, 1);
 		preempt_enable();
+#else
+		load_LDT(pc);
 #endif
 	}
 	if (oldsize) {
diff -Nru a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
--- a/arch/i386/kernel/microcode.c	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/microcode.c	Tue Mar  4 19:30:05 2003
@@ -183,11 +183,10 @@
 	int i, error = 0, err;
 	struct microcode *m;
 
-	if (smp_call_function(do_update_one, NULL, 1, 1) != 0) {
+	if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) {
 		printk(KERN_ERR "microcode: IPI timeout, giving up\n");
 		return -EIO;
 	}
-	do_update_one(NULL);
 
 	for (i=0; i<NR_CPUS; i++) {
 		err = update_req[i].err;
diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/kernel/mpparse.c	Tue Mar  4 19:30:05 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");
@@ -631,7 +631,7 @@
 	else if (acpi_lapic)
 		printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
 
-	printk("KERN_INFO Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
+	printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
 	if (mpf->mpf_feature2 & (1<<7)) {
 		printk(KERN_INFO "    IMCR and PIC compatibility mode.\n");
 		pic_mode = 1;
diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c	Tue Mar  4 19:30:09 2003
+++ b/arch/i386/kernel/nmi.c	Tue Mar  4 19:30:09 2003
@@ -325,7 +325,7 @@
  * as these watchdog NMI IRQs are generated on every CPU, we only
  * have to check the current processor.
  *
- * since NMIs dont listen to _any_ locks, we have to be extremely
+ * since NMIs don't listen to _any_ locks, we have to be extremely
  * careful not to rely on unsafe variables. The printk might lock
  * up though, so we have to break up any console locks first ...
  * [when there will be more tty-related locks, break them up
diff -Nru a/arch/i386/kernel/numaq.c b/arch/i386/kernel/numaq.c
--- a/arch/i386/kernel/numaq.c	Tue Mar  4 19:30:11 2003
+++ b/arch/i386/kernel/numaq.c	Tue Mar  4 19:30:11 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 -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	Tue Mar  4 19:30:08 2003
+++ b/arch/i386/kernel/setup.c	Tue Mar  4 19:30:08 2003
@@ -14,6 +14,9 @@
  * Moved CPU detection code to cpu/${cpu}.c
  *    Patrick Mochel <mochel@osdl.org>, March 2002
  *
+ *  Provisions for empty E820 memory regions (reported by certain BIOSes).
+ *  Alex Achenbach <xela@slit.de>, December 2002.
+ *
  */
 
 /*
@@ -279,7 +282,7 @@
 	int chgidx, still_changing;
 	int overlap_entries;
 	int new_bios_entry;
-	int old_nr, new_nr;
+	int old_nr, new_nr, chg_nr;
 	int i;
 
 	/*
@@ -333,20 +336,24 @@
 	for (i=0; i < 2*old_nr; i++)
 		change_point[i] = &change_point_list[i];
 
-	/* record all known change-points (starting and ending addresses) */
+	/* record all known change-points (starting and ending addresses),
+	   omitting those that are for empty memory regions */
 	chgidx = 0;
 	for (i=0; i < old_nr; i++)	{
-		change_point[chgidx]->addr = biosmap[i].addr;
-		change_point[chgidx++]->pbios = &biosmap[i];
-		change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
-		change_point[chgidx++]->pbios = &biosmap[i];
+		if (biosmap[i].size != 0) {
+			change_point[chgidx]->addr = biosmap[i].addr;
+			change_point[chgidx++]->pbios = &biosmap[i];
+			change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
+			change_point[chgidx++]->pbios = &biosmap[i];
+		}
 	}
+	chg_nr = chgidx;    	/* true number of change-points */
 
 	/* sort change-point list by memory addresses (low -> high) */
 	still_changing = 1;
 	while (still_changing)	{
 		still_changing = 0;
-		for (i=1; i < 2*old_nr; i++)  {
+		for (i=1; i < chg_nr; i++)  {
 			/* if <current_addr> > <last_addr>, swap */
 			/* or, if current=<start_addr> & last=<end_addr>, swap */
 			if ((change_point[i]->addr < change_point[i-1]->addr) ||
@@ -369,7 +376,7 @@
 	last_type = 0;		 /* start with undefined memory type */
 	last_addr = 0;		 /* start with 0 as last starting address */
 	/* loop through change-points, determining affect on the new bios map */
-	for (chgidx=0; chgidx < 2*old_nr; chgidx++)
+	for (chgidx=0; chgidx < chg_nr; chgidx++)
 	{
 		/* keep track of all overlapping bios entries */
 		if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
@@ -545,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;
@@ -818,7 +831,7 @@
 		request_resource(&iomem_resource, res);
 		if (e820.map[i].type == E820_RAM) {
 			/*
-			 *  We dont't know which RAM region contains kernel data,
+			 *  We don't know which RAM region contains kernel data,
 			 *  so we try it repeatedly and let the resource manager
 			 *  test it.
 			 */
diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
--- a/arch/i386/kernel/smp.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/kernel/smp.c	Tue Mar  4 19:30:04 2003
@@ -436,7 +436,7 @@
 	preempt_enable();
 }
 
-static inline void do_flush_tlb_all_local(void)
+static void do_flush_tlb_all(void* info)
 {
 	unsigned long cpu = smp_processor_id();
 
@@ -445,18 +445,9 @@
 		leave_mm(cpu);
 }
 
-static void flush_tlb_all_ipi(void* info)
-{
-	do_flush_tlb_all_local();
-}
-
 void flush_tlb_all(void)
 {
-	preempt_disable();
-	smp_call_function (flush_tlb_all_ipi,0,1,1);
-
-	do_flush_tlb_all_local();
-	preempt_enable();
+	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
 }
 
 /*
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Tue Mar  4 19:30:08 2003
+++ b/arch/i386/kernel/smpboot.c	Tue Mar  4 19:30:08 2003
@@ -170,7 +170,7 @@
 /*
  * TSC synchronization.
  *
- * We first check wether all CPUs have their TSC's synchronized,
+ * We first check whether all CPUs have their TSC's synchronized,
  * then we print a warning if not, and always resync.
  */
 
@@ -956,7 +956,7 @@
 	smp_tune_scheduling();
 
 	/*
-	 * If we couldnt find an SMP configuration at boot time,
+	 * If we couldn't find an SMP configuration at boot time,
 	 * get out of here now!
 	 */
 	if (!smp_found_config) {
diff -Nru a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/srat.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,448 @@
+/*
+ * Some of the code in this file has been gleaned from the 64 bit 
+ * discontigmem support code base.
+ *
+ * Copyright (C) 2002, IBM Corp.
+ *
+ * All rights reserved.          
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to Pat Gaughen <gone@us.ibm.com>
+ */
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/acpi.h>
+#include <asm/srat.h>
+
+/*
+ * proximity macros and definitions
+ */
+#define NODE_ARRAY_INDEX(x)	((x) / 8)	/* 8 bits/char */
+#define NODE_ARRAY_OFFSET(x)	((x) % 8)	/* 8 bits/char */
+#define BMAP_SET(bmap, bit)	((bmap)[NODE_ARRAY_INDEX(bit)] |= 1 << NODE_ARRAY_OFFSET(bit))
+#define BMAP_TEST(bmap, bit)	((bmap)[NODE_ARRAY_INDEX(bit)] & (1 << NODE_ARRAY_OFFSET(bit)))
+#define MAX_PXM_DOMAINS		256	/* 1 byte and no promises about values */
+/* bitmap length; _PXM is at most 255 */
+#define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) 
+static u8 pxm_bitmap[PXM_BITMAP_LEN];	/* bitmap of proximity domains */
+
+#define MAX_CHUNKS_PER_NODE	4
+#define MAXCHUNKS		(MAX_CHUNKS_PER_NODE * MAX_NUMNODES)
+struct node_memory_chunk_s {
+	unsigned long	start_pfn;
+	unsigned long	end_pfn;
+	u8	pxm;		// proximity domain of node
+	u8	nid;		// which cnode contains this chunk?
+	u8	bank;		// which mem bank on this node
+};
+static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
+
+static int num_memory_chunks;		/* total number of memory chunks */
+static int zholes_size_init;
+static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES];
+
+unsigned long node_start_pfn[MAX_NUMNODES];
+unsigned long node_end_pfn[MAX_NUMNODES];
+
+extern void * boot_ioremap(unsigned long, unsigned long);
+
+/* Identify CPU proximity domains */
+static void __init parse_cpu_affinity_structure(char *p)
+{
+	struct acpi_table_processor_affinity *cpu_affinity = 
+				(struct acpi_table_processor_affinity *) p;
+
+	if (!cpu_affinity->flags.enabled)
+		return;		/* empty entry */
+
+	/* mark this node as "seen" in node bitmap */
+	BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain);
+
+	printk("CPU 0x%02X in proximity domain 0x%02X\n",
+		cpu_affinity->apic_id, cpu_affinity->proximity_domain);
+}
+
+/*
+ * Identify memory proximity domains and hot-remove capabilities.
+ * Fill node memory chunk list structure.
+ */
+static void __init parse_memory_affinity_structure (char *sratp)
+{
+	unsigned long long paddr, size;
+	unsigned long start_pfn, end_pfn; 
+	u8 pxm;
+	struct node_memory_chunk_s *p, *q, *pend;
+	struct acpi_table_memory_affinity *memory_affinity =
+			(struct acpi_table_memory_affinity *) sratp;
+
+	if (!memory_affinity->flags.enabled)
+		return;		/* empty entry */
+
+	/* mark this node as "seen" in node bitmap */
+	BMAP_SET(pxm_bitmap, memory_affinity->proximity_domain);
+
+	/* calculate info for memory chunk structure */
+	paddr = memory_affinity->base_addr_hi;
+	paddr = (paddr << 32) | memory_affinity->base_addr_lo;
+	size = memory_affinity->length_hi;
+	size = (size << 32) | memory_affinity->length_lo;
+	
+	start_pfn = paddr >> PAGE_SHIFT;
+	end_pfn = (paddr + size) >> PAGE_SHIFT;
+	
+	pxm = memory_affinity->proximity_domain;
+
+	if (num_memory_chunks >= MAXCHUNKS) {
+		printk("Too many mem chunks in SRAT. Ignoring %lld MBytes at %llx\n",
+			size/(1024*1024), paddr);
+		return;
+	}
+
+	/* Insertion sort based on base address */
+	pend = &node_memory_chunk[num_memory_chunks];
+	for (p = &node_memory_chunk[0]; p < pend; p++) {
+		if (start_pfn < p->start_pfn)
+			break;
+	}
+	if (p < pend) {
+		for (q = pend; q >= p; q--)
+			*(q + 1) = *q;
+	}
+	p->start_pfn = start_pfn;
+	p->end_pfn = end_pfn;
+	p->pxm = pxm;
+
+	num_memory_chunks++;
+
+	printk("Memory range 0x%lX to 0x%lX (type 0x%X) in proximity domain 0x%02X %s\n",
+		start_pfn, end_pfn,
+		memory_affinity->memory_type,
+		memory_affinity->proximity_domain,
+		(memory_affinity->flags.hot_pluggable ?
+		 "enabled and removable" : "enabled" ) );
+}
+
+#if MAX_NR_ZONES != 3
+#error "MAX_NR_ZONES != 3, chunk_to_zone requires review"
+#endif
+/* Take a chunk of pages from page frame cstart to cend and count the number
+ * of pages in each zone, returned via zones[].
+ */
+static __init void chunk_to_zones(unsigned long cstart, unsigned long cend, 
+		unsigned long *zones)
+{
+	unsigned long max_dma;
+	extern unsigned long max_low_pfn;
+
+	int z;
+	unsigned long rend;
+
+	/* FIXME: MAX_DMA_ADDRESS and max_low_pfn are trying to provide
+	 * similarly scoped information and should be handled in a consistant
+	 * manner.
+	 */
+	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+
+	/* Split the hole into the zones in which it falls.  Repeatedly
+	 * take the segment in which the remaining hole starts, round it
+	 * to the end of that zone.
+	 */
+	memset(zones, 0, MAX_NR_ZONES * sizeof(long));
+	while (cstart < cend) {
+		if (cstart < max_dma) {
+			z = ZONE_DMA;
+			rend = (cend < max_dma)? cend : max_dma;
+
+		} else if (cstart < max_low_pfn) {
+			z = ZONE_NORMAL;
+			rend = (cend < max_low_pfn)? cend : max_low_pfn;
+
+		} else {
+			z = ZONE_HIGHMEM;
+			rend = cend;
+		}
+		zones[z] += rend - cstart;
+		cstart = rend;
+	}
+}
+
+/*
+ * physnode_map keeps track of the physical memory layout of the
+ * numaq nodes on a 256Mb break (each element of the array will
+ * represent 256Mb of memory and will be marked by the node id.  so,
+ * if the first gig is on node 0, and the second gig is on node 1
+ * physnode_map will contain:
+ * physnode_map[0-3] = 0;
+ * physnode_map[4-7] = 1;
+ * physnode_map[8- ] = -1;
+ */
+int pfnnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1};
+EXPORT_SYMBOL(pfnnode_map);
+
+static void __init initialize_pfnnode_map(void)
+{
+	unsigned long topofchunk, cur = 0;
+	int i;
+	
+	for (i = 0; i < num_memory_chunks; i++) {
+		cur = node_memory_chunk[i].start_pfn;
+		topofchunk = node_memory_chunk[i].end_pfn;
+		while (cur < topofchunk) {
+			pfnnode_map[PFN_TO_ELEMENT(cur)] = node_memory_chunk[i].nid;
+			cur ++;
+		}
+	}
+}
+
+/* Parse the ACPI Static Resource Affinity Table */
+static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
+{
+	u8 *start, *end, *p;
+	int i, j, nid;
+	u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */
+	u8 nid_to_pxm_map[MAX_NUMNODES];/* logical node ID to _PXM map */
+
+	start = (u8 *)(&(sratp->reserved) + 1);	/* skip header */
+	p = start;
+	end = (u8 *)sratp + sratp->header.length;
+
+	memset(pxm_bitmap, 0, sizeof(pxm_bitmap));	/* init proximity domain bitmap */
+	memset(node_memory_chunk, 0, sizeof(node_memory_chunk));
+	memset(zholes_size, 0, sizeof(zholes_size));
+
+	/* -1 in these maps means not available */
+	memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map));
+	memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map));
+
+	num_memory_chunks = 0;
+	while (p < end) {
+		switch (*p) {
+		case ACPI_SRAT_PROCESSOR_AFFINITY:
+			parse_cpu_affinity_structure(p);
+			break;
+		case ACPI_SRAT_MEMORY_AFFINITY:
+			parse_memory_affinity_structure(p);
+			break;
+		default:
+			printk("ACPI 2.0 SRAT: unknown entry skipped: type=0x%02X, len=%d\n", p[0], p[1]);
+			break;
+		}
+		p += p[1];
+		if (p[1] == 0) {
+			printk("acpi20_parse_srat: Entry length value is zero;"
+				" can't parse any further!\n");
+			break;
+		}
+	}
+
+	/* Calculate total number of nodes in system from PXM bitmap and create
+	 * a set of sequential node IDs starting at zero.  (ACPI doesn't seem
+	 * to specify the range of _PXM values.)
+	 */
+	numnodes = 0;		/* init total nodes in system */
+	for (i = 0; i < MAX_PXM_DOMAINS; i++) {
+		if (BMAP_TEST(pxm_bitmap, i)) {
+			pxm_to_nid_map[i] = numnodes;
+			nid_to_pxm_map[numnodes] = i;
+			node_set_online(numnodes);
+			++numnodes;
+		}
+	}
+
+	if (numnodes == 0)
+		BUG();
+
+	/* set cnode id in memory chunk structure */
+	for (i = 0; i < num_memory_chunks; i++)
+		node_memory_chunk[i].nid = pxm_to_nid_map[node_memory_chunk[i].pxm];
+
+	initialize_pfnnode_map();
+	
+	printk("pxm bitmap: ");
+	for (i = 0; i < sizeof(pxm_bitmap); i++) {
+		printk("%02X ", pxm_bitmap[i]);
+	}
+	printk("\n");
+	printk("Number of logical nodes in system = %d\n", numnodes);
+	printk("Number of memory chunks in system = %d\n", num_memory_chunks);
+
+	for (j = 0; j < num_memory_chunks; j++){
+		printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
+		       j, node_memory_chunk[j].nid,
+		       node_memory_chunk[j].start_pfn,
+		       node_memory_chunk[j].end_pfn);
+	}
+ 
+	/*calculate node_start_pfn/node_end_pfn arrays*/
+	for (nid = 0; nid < numnodes; nid++) {
+		int been_here_before = 0;
+
+		for (j = 0; j < num_memory_chunks; j++){
+			if (node_memory_chunk[j].nid == nid) {
+				if (been_here_before == 0) {
+					node_start_pfn[nid] = node_memory_chunk[j].start_pfn;
+					node_end_pfn[nid] = node_memory_chunk[j].end_pfn;
+					been_here_before = 1;
+				} else { /* We've found another chunk of memory for the node */
+					if (node_start_pfn[nid] < node_memory_chunk[j].start_pfn) {
+						node_end_pfn[nid] = node_memory_chunk[j].end_pfn;
+					}
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+void __init get_memcfg_from_srat(void)
+{
+	struct acpi_table_header *header = NULL;
+	struct acpi_table_rsdp *rsdp = NULL;
+	struct acpi_table_rsdt *rsdt = NULL;
+	struct acpi_pointer *rsdp_address = NULL;
+	struct acpi_table_rsdt saved_rsdt;
+	int tables = 0;
+	int i = 0;
+
+	acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, rsdp_address);
+
+	if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
+		printk("%s: assigning address to rsdp\n", __FUNCTION__);
+		rsdp = (struct acpi_table_rsdp *)rsdp_address->pointer.physical;
+	} else {
+		printk("%s: rsdp_address is not a physical pointer\n", __FUNCTION__);
+		return;
+	}
+	if (!rsdp) {
+		printk("%s: Didn't find ACPI root!\n", __FUNCTION__);
+		return;
+	}
+
+	printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
+		rsdp->oem_id);
+
+	if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
+		printk(KERN_WARNING "%s: RSDP table signature incorrect\n", __FUNCTION__);
+		return;
+	}
+
+	rsdt = (struct acpi_table_rsdt *)
+	    boot_ioremap(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt));
+
+	if (!rsdt) {
+		printk(KERN_WARNING
+		       "%s: ACPI: Invalid root system description tables (RSDT)\n",
+		       __FUNCTION__);
+		return;
+	}
+
+	header = & rsdt->header;
+
+	if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
+		printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
+		return;
+	}
+
+	/* 
+	 * The number of tables is computed by taking the 
+	 * size of all entries (header size minus total 
+	 * size of RSDT) divided by the size of each entry
+	 * (4-byte table pointers).
+	 */
+	tables = (header->length - sizeof(struct acpi_table_header)) / 4;
+
+	memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
+
+	if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
+		printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n",
+		       saved_rsdt.header.length);
+		return;
+	}
+
+printk("Begin table scan....\n");
+
+	for (i = 0; i < tables; i++) {
+		/* Map in header, then map in full table length. */
+		header = (struct acpi_table_header *)
+			boot_ioremap(saved_rsdt.entry[i], sizeof(struct acpi_table_header));
+		if (!header)
+			break;
+		header = (struct acpi_table_header *)
+			boot_ioremap(saved_rsdt.entry[i], header->length);
+		if (!header)
+			break;
+
+		if (strncmp((char *) &header->signature, "SRAT", 4))
+			continue;
+		acpi20_parse_srat((struct acpi_table_srat *)header);
+		/* we've found the srat table. don't need to look at any more tables */
+		break;
+	}
+}
+
+/* For each node run the memory list to determine whether there are
+ * any memory holes.  For each hole determine which ZONE they fall
+ * into.
+ *
+ * NOTE#1: this requires knowledge of the zone boundries and so
+ * _cannot_ be performed before those are calculated in setup_memory.
+ * 
+ * NOTE#2: we rely on the fact that the memory chunks are ordered by
+ * start pfn number during setup.
+ */
+static void __init get_zholes_init(void)
+{
+	int nid;
+	int c;
+	int first;
+	unsigned long end = 0;
+
+	for (nid = 0; nid < numnodes; nid++) {
+		first = 1;
+		for (c = 0; c < num_memory_chunks; c++){
+			if (node_memory_chunk[c].nid == nid) {
+				if (first) {
+					end = node_memory_chunk[c].end_pfn;
+					first = 0;
+
+				} else {
+					/* Record any gap between this chunk
+					 * and the previous chunk on this node
+					 * against the zones it spans.
+					 */
+					chunk_to_zones(end,
+						node_memory_chunk[c].start_pfn,
+						&zholes_size[nid * MAX_NR_ZONES]);
+				}
+			}
+		}
+	}
+}
+
+unsigned long * __init get_zholes_size(int nid)
+{
+	if (!zholes_size_init) {
+		zholes_size_init++;
+		get_zholes_init();
+	}
+	if((nid >= numnodes) | (nid >= MAX_NUMNODES))
+		printk("%s: nid = %d is invalid. numnodes = %d",
+		       __FUNCTION__, nid, numnodes);
+	return &zholes_size[nid * MAX_NR_ZONES];
+}
diff -Nru a/arch/i386/kernel/suspend.c b/arch/i386/kernel/suspend.c
--- a/arch/i386/kernel/suspend.c	Tue Mar  4 19:30:12 2003
+++ b/arch/i386/kernel/suspend.c	Tue Mar  4 19:30:12 2003
@@ -113,7 +113,7 @@
 	int cpu = smp_processor_id();
 	struct tss_struct * t = init_tss + cpu;
 
-	set_tss_desc(cpu,t);	/* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
+	set_tss_desc(cpu,t);	/* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
         cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
 
 	load_TR_desc();				/* This does ltr */
diff -Nru a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c
--- a/arch/i386/kernel/sysenter.c	Tue Mar  4 19:30:14 2003
+++ b/arch/i386/kernel/sysenter.c	Tue Mar  4 19:30:14 2003
@@ -95,8 +95,7 @@
 		return 0;
 
 	memcpy((void *) page, sysent, sizeof(sysent));
-	enable_sep_cpu(NULL);
-	smp_call_function(enable_sep_cpu, NULL, 1, 1);
+	on_each_cpu(enable_sep_cpu, NULL, 1, 1);
 	return 0;
 }
 
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c	Tue Mar  4 19:30:08 2003
+++ b/arch/i386/kernel/time.c	Tue Mar  4 19:30:08 2003
@@ -66,7 +66,7 @@
 
 #include "do_timer.h"
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 unsigned long cpu_khz;	/* Detected as we calibrate the TSC */
 
diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
--- a/arch/i386/kernel/timers/timer_tsc.c	Tue Mar  4 19:30:11 2003
+++ b/arch/i386/kernel/timers/timer_tsc.c	Tue Mar  4 19:30:11 2003
@@ -264,7 +264,7 @@
  	 *	the ident/bugs checks so we must run this hook as it
  	 *	may turn off the TSC flag.
  	 *
- 	 *	NOTE: this doesnt yet handle SMP 486 machines where only
+ 	 *	NOTE: this doesn't yet handle SMP 486 machines where only
  	 *	some CPU's have a TSC. Thats never worked and nobody has
  	 *	moaned if you have the only one in the world - you fix it!
  	 */
@@ -299,6 +299,7 @@
 	return -ENODEV;
 }
 
+#ifndef CONFIG_X86_TSC
 /* disable flag for tsc.  Takes effect by clearing the TSC cpu flag
  * in cpu/common.c */
 static int __init tsc_setup(char *str)
@@ -306,7 +307,14 @@
 	tsc_disable = 1;
 	return 1;
 }
-
+#else
+static int __init tsc_setup(char *str)
+{
+	printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
+				"cannot disable TSC.\n");
+	return 1;
+}
+#endif
 __setup("notsc", tsc_setup);
 
 
diff -Nru a/arch/i386/lib/mmx.c b/arch/i386/lib/mmx.c
--- a/arch/i386/lib/mmx.c	Tue Mar  4 19:30:09 2003
+++ b/arch/i386/lib/mmx.c	Tue Mar  4 19:30:09 2003
@@ -15,7 +15,7 @@
  *		(reported so on K6-III)
  *	We should use a better code neutral filler for the short jump
  *		leal ebx. [ebx] is apparently best for K6-2, but Cyrix ??
- *	We also want to clobber the filler register so we dont get any
+ *	We also want to clobber the filler register so we don't get any
  *		register forwarding stalls on the filler. 
  *
  *	Add *user handling. Checksums are not a win with MMX on any CPU
diff -Nru a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
--- a/arch/i386/mach-visws/visws_apic.c	Tue Mar  4 19:30:04 2003
+++ b/arch/i386/mach-visws/visws_apic.c	Tue Mar  4 19:30:04 2003
@@ -190,7 +190,7 @@
  * the 'master' interrupt source: CO_IRQ_8259.
  *
  * When the 8259 interrupts its handler figures out which of these
- * devices is interrupting and dispatches to it's handler.
+ * devices is interrupting and dispatches to its handler.
  *
  * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/
  * enable_irq gets the right irq. This 'master' irq is never directly
diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
--- a/arch/i386/mach-voyager/voyager_smp.c	Tue Mar  4 19:30:07 2003
+++ b/arch/i386/mach-voyager/voyager_smp.c	Tue Mar  4 19:30:07 2003
@@ -1209,8 +1209,8 @@
 		smp_call_function_interrupt();
 }
 
-static inline void
-do_flush_tlb_all_local(void)
+static void
+do_flush_tlb_all(void* info)
 {
 	unsigned long cpu = smp_processor_id();
 
@@ -1220,19 +1220,11 @@
 }
 
 
-static void
-flush_tlb_all_function(void* info)
-{
-	do_flush_tlb_all_local();
-}
-
 /* flush the TLB of every active CPU in the system */
 void
 flush_tlb_all(void)
 {
-	smp_call_function (flush_tlb_all_function, 0, 1, 1);
-
-	do_flush_tlb_all_local();
+	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
 }
 
 /* used to set up the trampoline for other CPUs when the memory manager
@@ -1453,7 +1445,7 @@
 }
 
 /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per
- * processor to recieve CPI */
+ * processor to receive CPI */
 static void
 send_CPI(__u32 cpuset, __u8 cpi)
 {
@@ -1481,7 +1473,7 @@
 		outb((__u8)cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]);
 }
 
-/* Acknowlege receipt of CPI in the QIC, clear in QIC hardware and
+/* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and
  * set the cache line to shared by reading it.
  *
  * DON'T make this inline otherwise the cache line read will be
diff -Nru a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile
--- a/arch/i386/mm/Makefile	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/mm/Makefile	Tue Mar  4 19:30:05 2003
@@ -2,8 +2,9 @@
 # Makefile for the linux i386-specific parts of the memory manager.
 #
 
-obj-y	:= init.o pgtable.o fault.o ioremap.o extable.o pageattr.o
+obj-y	:= init.o pgtable.o fault.o ioremap.o extable.o pageattr.o 
 
 obj-$(CONFIG_DISCONTIGMEM)	+= discontig.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_HIGHMEM) += highmem.o
+obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
diff -Nru a/arch/i386/mm/boot_ioremap.c b/arch/i386/mm/boot_ioremap.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/mm/boot_ioremap.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,94 @@
+/*
+ * arch/i386/mm/boot_ioremap.c
+ * 
+ * Re-map functions for early boot-time before paging_init() when the 
+ * boot-time pagetables are still in use
+ *
+ * Written by Dave Hansen <haveblue@us.ibm.com>
+ */
+
+
+/*
+ * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
+ * keeps that from happenning.  If anyone has a better way, I'm listening.
+ *
+ * boot_pte_t is defined only if this all works correctly
+ */
+
+#include <linux/config.h>
+#undef CONFIG_X86_PAE
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <linux/init.h>
+#include <linux/stddef.h>
+
+/* 
+ * I'm cheating here.  It is known that the two boot PTE pages are 
+ * allocated next to each other.  I'm pretending that they're just
+ * one big array. 
+ */
+
+#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
+#define boot_pte_index(address) \
+	     (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
+
+static inline boot_pte_t* boot_vaddr_to_pte(void *address)
+{
+	boot_pte_t* boot_pg = (boot_pte_t*)pg0;
+	return &boot_pg[boot_pte_index((unsigned long)address)];
+}
+
+/*
+ * This is only for a caller who is clever enough to page-align
+ * phys_addr and virtual_source, and who also has a preference
+ * about which virtual address from which to steal ptes
+ */
+static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
+		    void* virtual_source)
+{
+	boot_pte_t* pte;
+	int i;
+
+	pte = boot_vaddr_to_pte(virtual_source);
+	for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
+		set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
+	}
+}
+
+/* the virtual space we're going to remap comes from this array */
+#define BOOT_IOREMAP_PAGES 4
+#define BOOT_IOREMAP_SIZE (BOOT_IOREMAP_PAGES*PAGE_SIZE)
+__initdata char boot_ioremap_space[BOOT_IOREMAP_SIZE] 
+		__attribute__ ((aligned (PAGE_SIZE)));
+
+/*
+ * This only applies to things which need to ioremap before paging_init()
+ * bt_ioremap() and plain ioremap() are both useless at this point.
+ * 
+ * When used, we're still using the boot-time pagetables, which only
+ * have 2 PTE pages mapping the first 8MB
+ *
+ * There is no unmap.  The boot-time PTE pages aren't used after boot.
+ * If you really want the space back, just remap it yourself.
+ * boot_ioremap(&ioremap_space-PAGE_OFFSET, BOOT_IOREMAP_SIZE)
+ */
+__init void* boot_ioremap(unsigned long phys_addr, unsigned long size)
+{
+	unsigned long last_addr, offset;
+	unsigned int nrpages;
+	
+	last_addr = phys_addr + size - 1;
+
+	/* page align the requested address */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(last_addr) - phys_addr;
+	
+	nrpages = size >> PAGE_SHIFT;
+	if (nrpages > BOOT_IOREMAP_PAGES)
+		return NULL;
+	
+	__boot_ioremap(phys_addr, nrpages, boot_ioremap_space);
+
+	return &boot_ioremap_space[offset];
+}
diff -Nru a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
--- a/arch/i386/mm/discontig.c	Tue Mar  4 19:30:09 2003
+++ b/arch/i386/mm/discontig.c	Tue Mar  4 19:30:09 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,8 +276,21 @@
 {
 	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;
 		unsigned int max_dma;
 
 		unsigned long low = max_low_pfn;
@@ -307,18 +314,24 @@
 #endif
 			}
 		}
+		zholes_size = get_zholes_size(nid);
 		/*
 		 * We let the lmem_map for node 0 be allocated from the
 		 * 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, 0);
-		else
+		if (!nid)
 			free_area_init_node(nid, NODE_DATA(nid), 0, 
-				zones_size, start, 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 -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
--- a/arch/i386/mm/hugetlbpage.c	Tue Mar  4 19:30:13 2003
+++ b/arch/i386/mm/hugetlbpage.c	Tue Mar  4 19:30:13 2003
@@ -29,6 +29,8 @@
 static LIST_HEAD(htlbpage_freelist);
 static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
 
+void free_huge_page(struct page *page);
+
 static struct page *alloc_hugetlb_page(void)
 {
 	int i;
@@ -45,7 +47,7 @@
 	htlbpagemem--;
 	spin_unlock(&htlbpage_lock);
 	set_page_count(page, 1);
-	page->lru.prev = (void *)huge_page_release;
+	page->lru.prev = (void *)free_huge_page;
 	for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
 		clear_highpage(&page[i]);
 	return page;
diff -Nru a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
--- a/arch/i386/mm/ioremap.c	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/mm/ioremap.c	Tue Mar  4 19:30:05 2003
@@ -205,6 +205,7 @@
 			iounmap(p); 
 			p = NULL;
 		}
+		global_flush_tlb();
 	} 
 
 	return p;					
@@ -226,6 +227,7 @@
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
 				 p->size >> PAGE_SHIFT,
 				 PAGE_KERNEL); 				 
+		global_flush_tlb();
 	} 
 	kfree(p); 
 }
diff -Nru a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c
--- a/arch/i386/mm/pageattr.c	Tue Mar  4 19:30:08 2003
+++ b/arch/i386/mm/pageattr.c	Tue Mar  4 19:30:08 2003
@@ -130,11 +130,8 @@
 } 
 
 static inline void flush_map(void)
-{	
-#ifdef CONFIG_SMP 
-	smp_call_function(flush_kernel_map, NULL, 1, 1);
-#endif	
-	flush_kernel_map(NULL);
+{
+	on_each_cpu(flush_kernel_map, NULL, 1, 1);
 }
 
 struct deferred_page { 
diff -Nru a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
--- a/arch/i386/mm/pgtable.c	Tue Mar  4 19:30:14 2003
+++ b/arch/i386/mm/pgtable.c	Tue Mar  4 19:30:14 2003
@@ -11,6 +11,7 @@
 #include <linux/smp.h>
 #include <linux/highmem.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c	Tue Mar  4 19:30:13 2003
+++ b/arch/i386/oprofile/nmi_int.c	Tue Mar  4 19:30:13 2003
@@ -95,8 +95,7 @@
 	 * without actually triggering any NMIs as this will
 	 * break the core code horrifically.
 	 */
-	smp_call_function(nmi_cpu_setup, NULL, 0, 1);
-	nmi_cpu_setup(0);
+	on_each_cpu(nmi_cpu_setup, NULL, 0, 1);
 	set_nmi_callback(nmi_callback);
 	oprofile_pmdev = set_nmi_pm_callback(oprofile_pm_callback);
 	return 0;
@@ -148,8 +147,7 @@
 {
 	unset_nmi_pm_callback(oprofile_pmdev);
 	unset_nmi_callback();
-	smp_call_function(nmi_cpu_shutdown, NULL, 0, 1);
-	nmi_cpu_shutdown(0);
+	on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
 }
 
  
@@ -162,8 +160,7 @@
 
 static int nmi_start(void)
 {
-	smp_call_function(nmi_cpu_start, NULL, 0, 1);
-	nmi_cpu_start(0);
+	on_each_cpu(nmi_cpu_start, NULL, 0, 1);
 	return 0;
 }
  
@@ -177,8 +174,7 @@
  
 static void nmi_stop(void)
 {
-	smp_call_function(nmi_cpu_stop, NULL, 0, 1);
-	nmi_cpu_stop(0);
+	on_each_cpu(nmi_cpu_stop, NULL, 0, 1);
 }
 
 
diff -Nru a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c
--- a/arch/i386/pci/numa.c	Tue Mar  4 19:30:05 2003
+++ b/arch/i386/pci/numa.c	Tue Mar  4 19:30:05 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 -Nru a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c
--- a/arch/i386/pci/visws.c	Tue Mar  4 19:30:12 2003
+++ b/arch/i386/pci/visws.c	Tue Mar  4 19:30:12 2003
@@ -52,7 +52,7 @@
 
 	pin--;
 
-	/* Nothing usefull at PIIX4 pin 1 */
+	/* Nothing useful at PIIX4 pin 1 */
 	if (bus == pci_bus0 && slot == 4 && pin == 0)
 		return -1;
 
diff -Nru a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
--- a/arch/ia64/ia32/ia32_signal.c	Tue Mar  4 19:30:04 2003
+++ b/arch/ia64/ia32/ia32_signal.c	Tue Mar  4 19:30:04 2003
@@ -338,7 +338,7 @@
 	/*
 	 * Updating fsr, fcr, fir, fdr.
 	 * Just a bit more complicated than save.
-	 * - Need to make sure that we dont write any value other than the
+	 * - Need to make sure that we don't write any value other than the
 	 *   specific fpstate info
 	 * - Need to make sure that the untouched part of frs, fdr, fir, fcr
 	 *   should remain same while writing.
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ia64/kernel/irq.c	Tue Mar  4 19:30:13 2003
@@ -104,7 +104,7 @@
 {
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves, it doesnt deserve
+ * each architecture has to answer this themselves, it doesn't deserve
  * a generic callback i think.
  */
 #if CONFIG_X86
diff -Nru a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
--- a/arch/ia64/kernel/minstate.h	Tue Mar  4 19:30:13 2003
+++ b/arch/ia64/kernel/minstate.h	Tue Mar  4 19:30:13 2003
@@ -26,7 +26,7 @@
  */
 
 /*
- * For ivt.s we want to access the stack virtually so we dont have to disable translation
+ * For ivt.s we want to access the stack virtually so we don't have to disable translation
  * on interrupts.
  */
 #define MINSTATE_START_SAVE_MIN_VIRT								\
@@ -52,7 +52,7 @@
 
 /*
  * For mca_asm.S we want to access the stack physically since the state is saved before we
- * go virtual and dont want to destroy the iip or ipsr.
+ * go virtual and don't want to destroy the iip or ipsr.
  */
 #define MINSTATE_START_SAVE_MIN_PHYS								\
 (pKStk) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE;				\
diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ia64/kernel/perfmon.c	Tue Mar  4 19:30:13 2003
@@ -718,7 +718,7 @@
 
 /*
  * counts the number of PMDS to save per entry.
- * This code is generic enough to accomodate more than 64 PMDS when they become available
+ * This code is generic enough to accommodate more than 64 PMDS when they become available
  */
 static unsigned long
 pfm_smpl_entry_size(unsigned long *which, unsigned long size)
diff -Nru a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
--- a/arch/ia64/kernel/smp.c	Tue Mar  4 19:30:14 2003
+++ b/arch/ia64/kernel/smp.c	Tue Mar  4 19:30:14 2003
@@ -206,18 +206,18 @@
 void
 smp_flush_tlb_all (void)
 {
-	smp_call_function((void (*)(void *))local_flush_tlb_all, 0, 1, 1);
-	local_flush_tlb_all();
+	on_each_cpu((void (*)(void *))local_flush_tlb_all, 0, 1, 1);
 }
 
 void
 smp_flush_tlb_mm (struct mm_struct *mm)
 {
-	local_finish_flush_tlb_mm(mm);
-
 	/* this happens for the common case of a single-threaded fork():  */
 	if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
+	{
+		local_finish_flush_tlb_mm(mm);
 		return;
+	}
 
 	/*
 	 * We could optimize this further by using mm->cpu_vm_mask to track which CPUs
@@ -226,7 +226,7 @@
 	 * anyhow, and once a CPU is interrupted, the cost of local_flush_tlb_all() is
 	 * rather trivial.
 	 */
-	smp_call_function((void (*)(void *))local_finish_flush_tlb_mm, mm, 1, 1);
+	on_each_cpu((void (*)(void *))local_finish_flush_tlb_mm, mm, 1, 1);
 }
 
 /*
diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
--- a/arch/ia64/kernel/time.c	Tue Mar  4 19:30:05 2003
+++ b/arch/ia64/kernel/time.c	Tue Mar  4 19:30:05 2003
@@ -27,7 +27,7 @@
 extern unsigned long wall_jiffies;
 extern unsigned long last_time_offset;
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 #ifdef CONFIG_IA64_DEBUG_IRQ
 
diff -Nru a/arch/ia64/lib/checksum.c b/arch/ia64/lib/checksum.c
--- a/arch/ia64/lib/checksum.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ia64/lib/checksum.c	Tue Mar  4 19:30:13 2003
@@ -50,7 +50,7 @@
 		  ((unsigned long) ntohs(len) << 16) +
 		  ((unsigned long) proto << 8));
 
-	/* Fold down to 32-bits so we don't loose in the typedef-less network stack.  */
+	/* Fold down to 32-bits so we don't lose in the typedef-less network stack.  */
 	/* 64 to 33 */
 	result = (result & 0xffffffff) + (result >> 32);
 	/* 33 to 32 */
diff -Nru a/arch/ia64/lib/do_csum.S b/arch/ia64/lib/do_csum.S
--- a/arch/ia64/lib/do_csum.S	Tue Mar  4 19:30:04 2003
+++ b/arch/ia64/lib/do_csum.S	Tue Mar  4 19:30:04 2003
@@ -41,7 +41,7 @@
 //	into one 8 byte word. In this case we have only one entry in the pipeline.
 //
 //	We use a (LOAD_LATENCY+2)-stage pipeline in the loop to account for
-//	possible load latency and also to accomodate for head and tail.
+//	possible load latency and also to accommodate for head and tail.
 //
 //	The end of the function deals with folding the checksum from 64bits
 //	down to 16bits taking care of the carry.
diff -Nru a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c
--- a/arch/ia64/lib/swiotlb.c	Tue Mar  4 19:30:11 2003
+++ b/arch/ia64/lib/swiotlb.c	Tue Mar  4 19:30:11 2003
@@ -359,7 +359,7 @@
  * was provided for in a previous swiotlb_map_single call.  All other usages are
  * undefined.
  *
- * After this call, reads by the cpu to the buffer are guarenteed to see whatever the
+ * After this call, reads by the cpu to the buffer are guaranteed to see whatever the
  * device wrote there.
  */
 void
diff -Nru a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
--- a/arch/ia64/mm/discontig.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ia64/mm/discontig.c	Tue Mar  4 19:30:13 2003
@@ -241,7 +241,7 @@
  *	- build the nodedir for the node. This contains pointers to
  *	  the per-bank mem_map entries.
  *	- fix the page struct "virtual" pointers. These are bank specific
- *	  values that the paging system doesnt understand.
+ *	  values that the paging system doesn't understand.
  *	- replicate the nodedir structure to other nodes	
  */ 
 
diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
--- a/arch/ia64/mm/hugetlbpage.c	Tue Mar  4 19:30:09 2003
+++ b/arch/ia64/mm/hugetlbpage.c	Tue Mar  4 19:30:09 2003
@@ -26,6 +26,8 @@
 static LIST_HEAD(htlbpage_freelist);
 static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
 
+void free_huge_page(struct page *page);
+
 static struct page *alloc_hugetlb_page(void)
 {
 	int i;
@@ -42,6 +44,7 @@
 	htlbpagemem--;
 	spin_unlock(&htlbpage_lock);
 	set_page_count(page, 1);
+	page->lru.prev = (void *)free_huge_page;
 	for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
 		clear_highpage(&page[i]);
 	return page;
diff -Nru a/arch/ia64/sn/fakeprom/fpmem.c b/arch/ia64/sn/fakeprom/fpmem.c
--- a/arch/ia64/sn/fakeprom/fpmem.c	Tue Mar  4 19:30:07 2003
+++ b/arch/ia64/sn/fakeprom/fpmem.c	Tue Mar  4 19:30:07 2003
@@ -218,7 +218,7 @@
 				}
 
                                 /*
-                                 * Check for the node 0 hole. Since banks cant
+                                 * Check for the node 0 hole. Since banks can't
                                  * span the hole, we only need to check if the end of
                                  * the range is the end of the hole.
                                  */
@@ -226,7 +226,7 @@
                                         numbytes -= NODE0_HOLE_SIZE;
                                 /*
                                  * UGLY hack - we must skip overr the kernel and
-                                 * PROM runtime services but we dont exactly where it is.
+                                 * PROM runtime services but we don't exactly where it is.
                                  * So lets just reserve:
 				 *	node 0
 				 *		0-1MB for PAL
diff -Nru a/arch/ia64/sn/fakeprom/fw-emu.c b/arch/ia64/sn/fakeprom/fw-emu.c
--- a/arch/ia64/sn/fakeprom/fw-emu.c	Tue Mar  4 19:30:12 2003
+++ b/arch/ia64/sn/fakeprom/fw-emu.c	Tue Mar  4 19:30:12 2003
@@ -757,7 +757,7 @@
 	sal_systab->checksum = -checksum;
 
 	/* If the checksum is correct, the kernel tries to use the
-	 * table. We dont build enough table & the kernel aborts.
+	 * table. We don't build enough table & the kernel aborts.
 	 * Note that the PROM hasd thhhe same problem!!
 	 */
 
diff -Nru a/arch/ia64/sn/io/hcl.c b/arch/ia64/sn/io/hcl.c
--- a/arch/ia64/sn/io/hcl.c	Tue Mar  4 19:30:12 2003
+++ b/arch/ia64/sn/io/hcl.c	Tue Mar  4 19:30:12 2003
@@ -467,7 +467,7 @@
 		/*
 		 * We need to clean up!
 		 */
-		printk(KERN_WARNING "HCL: Unable to set the connect point to it's parent 0x%p\n",
+		printk(KERN_WARNING "HCL: Unable to set the connect point to its parent 0x%p\n",
 			(void *)new_devfs_handle);
 	}
 
diff -Nru a/arch/ia64/sn/io/l1.c b/arch/ia64/sn/io/l1.c
--- a/arch/ia64/sn/io/l1.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ia64/sn/io/l1.c	Tue Mar  4 19:30:13 2003
@@ -2602,7 +2602,7 @@
 {
     sc_cq_t *q;         /* receive queue */
     int before_wrap,    /* packet may be split into two different       */
-        after_wrap;     /*   pieces to acommodate queue wraparound      */
+        after_wrap;     /*   pieces to accommodate queue wraparound      */
 
     /* pull message off the receive queue */
     q = subch->iqp;
diff -Nru a/arch/ia64/sn/io/sn1/pcibr.c b/arch/ia64/sn/io/sn1/pcibr.c
--- a/arch/ia64/sn/io/sn1/pcibr.c	Tue Mar  4 19:30:11 2003
+++ b/arch/ia64/sn/io/sn1/pcibr.c	Tue Mar  4 19:30:11 2003
@@ -2647,7 +2647,7 @@
 	/*
 	 * The Adaptec 1160 FC Controller WAR #767995:
 	 * The part incorrectly ignores the upper 32 bits of a 64 bit
-	 * address when decoding references to it's registers so to
+	 * address when decoding references to its registers so to
 	 * keep it from responding to a bus cycle that it shouldn't
 	 * we only use I/O space to get at it's registers.  Don't
 	 * enable memory space accesses on that PCI device.
@@ -5113,7 +5113,7 @@
 
     /* Bridge Hardware Bug WAR #484930:
      * Bridge can't handle updating External ATEs
-     * while DMA is occuring that uses External ATEs,
+     * while DMA is occurring that uses External ATEs,
      * even if the particular ATEs involved are disjoint.
      */
 
@@ -6844,7 +6844,7 @@
  *
  * This is the pcibr interrupt "wrapper" function that is called,
  * in interrupt context, to initiate the interrupt handler(s) registered
- * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
+ * (via pcibr_intr_alloc/connect) for the occurring interrupt. Non-threaded 
  * handlers will be called directly, and threaded handlers will have their 
  * thread woken up.
  */
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	Tue Mar  4 19:30:04 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	Tue Mar  4 19:30:04 2003
@@ -362,7 +362,7 @@
 
     /* Bridge Hardware Bug WAR #484930:
      * Bridge can't handle updating External ATEs
-     * while DMA is occuring that uses External ATEs,
+     * while DMA is occurring that uses External ATEs,
      * even if the particular ATEs involved are disjoint.
      */
 
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	Tue Mar  4 19:30:14 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	Tue Mar  4 19:30:14 2003
@@ -849,7 +849,7 @@
      * will set the c_slot (which is suppose to represent the external
      * slot (i.e the slot number silk screened on the back of the I/O
      * brick)).  So for PIC we need to adjust this "internal slot" num
-     * passed into us, into it's external representation.  See comment
+     * passed into us, into its external representation.  See comment
      * for the PCIBR_DEVICE_TO_SLOT macro for more information.
      */
     NEW(pcibr_info);
@@ -1527,7 +1527,7 @@
 	/* enable parity checking on PICs internal RAM */
 	pic_ctrl_reg |= PIC_CTRL_PAR_EN_RESP;
 	pic_ctrl_reg |= PIC_CTRL_PAR_EN_ATE;
-	/* PIC BRINGUP WAR (PV# 862253): dont enable write request
+	/* PIC BRINGUP WAR (PV# 862253): don't enable write request
 	 * parity checking.
 	 */
 	if (!PCIBR_WAR_ENABLED(PV862253, pcibr_soft)) {
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	Tue Mar  4 19:30:04 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	Tue Mar  4 19:30:04 2003
@@ -1806,7 +1806,7 @@
 	 *
 	 * CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges
 	 *      a group of interrupts. If while handling this error,
-	 *      some other error has occured, that would be
+	 *      some other error has occurred, that would be
 	 *      implicitly cleared by this write.
 	 *      Need a way to ensure we don't inadvertently clear some
 	 *      other errors.
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	Tue Mar  4 19:30:12 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	Tue Mar  4 19:30:12 2003
@@ -842,7 +842,7 @@
  *
  * This is the pcibr interrupt "wrapper" function that is called,
  * in interrupt context, to initiate the interrupt handler(s) registered
- * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
+ * (via pcibr_intr_alloc/connect) for the occurring interrupt. Non-threaded 
  * handlers will be called directly, and threaded handlers will have their 
  * thread woken up.
  */
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	Tue Mar  4 19:30:08 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	Tue Mar  4 19:30:08 2003
@@ -803,7 +803,7 @@
 	 * 'min_gnt' and attempt to calculate a latency time. 
 	 *
 	 * NOTE: For now if the device is on the 'real time' arbitration
-	 * ring we dont set the latency timer.  
+	 * ring we don't set the latency timer.  
 	 *
 	 * WAR: SGI's IOC3 and RAD devices target abort if you write a 
 	 * single byte into their config space.  So don't set the Latency
@@ -852,7 +852,7 @@
 	}
 
 	/* Get the PCI-X capability if running in PCI-X mode.  If the func
-	 * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
+	 * doesn't have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
 	 * pcibr_info struct so the device driver for that function is not
 	 * called.
 	 */
@@ -1449,7 +1449,7 @@
 	/*
 	 * The Adaptec 1160 FC Controller WAR #767995:
 	 * The part incorrectly ignores the upper 32 bits of a 64 bit
-	 * address when decoding references to it's registers so to
+	 * address when decoding references to its registers so to
 	 * keep it from responding to a bus cycle that it shouldn't
 	 * we only use I/O space to get at it's registers.  Don't
 	 * enable memory space accesses on that PCI device.
diff -Nru a/arch/ia64/sn/kernel/llsc4.c b/arch/ia64/sn/kernel/llsc4.c
--- a/arch/ia64/sn/kernel/llsc4.c	Tue Mar  4 19:30:12 2003
+++ b/arch/ia64/sn/kernel/llsc4.c	Tue Mar  4 19:30:12 2003
@@ -301,7 +301,7 @@
 		 */
 		linei = randn(linecount, &seed);
 		sharei = randn(2, &seed);
-		slinei = (linei + (linecount/2))%linecount;		/* I dont like this - fix later */
+		slinei = (linei + (linecount/2))%linecount;		/* I don't like this - fix later */
 
 		linep = (dataline_t *)blocks[linei];
 		slinep = (dataline_t *)blocks[slinei];
diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
--- a/arch/ia64/sn/kernel/setup.c	Tue Mar  4 19:30:05 2003
+++ b/arch/ia64/sn/kernel/setup.c	Tue Mar  4 19:30:05 2003
@@ -153,7 +153,7 @@
 /**
  * early_sn_setup - early setup routine for SN platforms
  *
- * Sets up an intial console to aid debugging.  Intended primarily
+ * Sets up an initial console to aid debugging.  Intended primarily
  * for bringup, it's only called if %BRINGUP and %CONFIG_IA64_EARLY_PRINTK
  * are turned on.  See start_kernel() in init/main.c.
  */
@@ -172,7 +172,7 @@
 
 	/*
 	 * Parse enough of the SAL tables to locate the SAL entry point. Since, console
-	 * IO on SN2 is done via SAL calls, early_printk wont work without this.
+	 * IO on SN2 is done via SAL calls, early_printk won't work without this.
 	 *
 	 * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c.
 	 * Any changes to those file may have to be made hereas well.
diff -Nru a/arch/ia64/sn/kernel/sn1/sn1_smp.c b/arch/ia64/sn/kernel/sn1/sn1_smp.c
--- a/arch/ia64/sn/kernel/sn1/sn1_smp.c	Tue Mar  4 19:30:07 2003
+++ b/arch/ia64/sn/kernel/sn1/sn1_smp.c	Tue Mar  4 19:30:07 2003
@@ -100,7 +100,7 @@
 
 /*
  * The following table/struct is for remembering PTC coherency domains. It
- * is also used to translate sapicid into cpuids. We dont want to start 
+ * is also used to translate sapicid into cpuids. We don't want to start 
  * cpus unless we know their cache domain.
  */
 #ifdef PTC_NOTYET
diff -Nru a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c	Tue Mar  4 19:30:13 2003
@@ -395,7 +395,7 @@
 	mycnode = local_nodeid;
 
 	/* 
-	 * For now, we dont want to spin uninterruptibly waiting
+	 * For now, we don't want to spin uninterruptibly waiting
 	 * for the lock. Makes hangs hard to debug.
 	 */
 	local_irq_save(flags);
@@ -506,7 +506,7 @@
 	pio_phys_write_mmr(p, val);
 
 #ifndef CONFIG_SHUB_1_0_SPECIFIC
-	/* doesnt work on shub 1.0 */
+	/* doesn't work on shub 1.0 */
 	wait_piowc();
 #endif
 }
diff -Nru a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S
--- a/arch/m68k/ifpsp060/src/fpsp.S	Tue Mar  4 19:30:14 2003
+++ b/arch/m68k/ifpsp060/src/fpsp.S	Tue Mar  4 19:30:14 2003
@@ -2201,7 +2201,7 @@
 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
 
-# now, we copy the default result to it's proper location
+# now, we copy the default result to its proper location
 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
@@ -2241,7 +2241,7 @@
 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
 
-# now, we copy the default result to it's proper location
+# now, we copy the default result to its proper location
 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
@@ -2281,7 +2281,7 @@
 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
 
-# now, we copy the default result to it's proper location
+# now, we copy the default result to its proper location
 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
diff -Nru a/arch/m68k/ifpsp060/src/isp.S b/arch/m68k/ifpsp060/src/isp.S
--- a/arch/m68k/ifpsp060/src/isp.S	Tue Mar  4 19:30:05 2003
+++ b/arch/m68k/ifpsp060/src/isp.S	Tue Mar  4 19:30:05 2003
@@ -843,7 +843,7 @@
 	bra.l		_real_access		
 
 # if the addressing mode was (an)+ or -(an), the address register must
-# be restored to it's pre-exception value before entering _real_access.
+# be restored to its pre-exception value before entering _real_access.
 isp_restore:
 	cmpi.b		SPCOND_FLG(%a6),&restore_flg # do we need a restore?
 	bne.b		isp_restore_done	# no
diff -Nru a/arch/m68k/ifpsp060/src/pfpsp.S b/arch/m68k/ifpsp060/src/pfpsp.S
--- a/arch/m68k/ifpsp060/src/pfpsp.S	Tue Mar  4 19:30:04 2003
+++ b/arch/m68k/ifpsp060/src/pfpsp.S	Tue Mar  4 19:30:04 2003
@@ -2200,7 +2200,7 @@
 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
 
-# now, we copy the default result to it's proper location
+# now, we copy the default result to its proper location
 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
@@ -2240,7 +2240,7 @@
 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
 
-# now, we copy the default result to it's proper location
+# now, we copy the default result to its proper location
 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
@@ -2280,7 +2280,7 @@
 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
 
-# now, we copy the default result to it's proper location
+# now, we copy the default result to its proper location
 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
diff -Nru a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
--- a/arch/m68k/kernel/head.S	Tue Mar  4 19:30:14 2003
+++ b/arch/m68k/kernel/head.S	Tue Mar  4 19:30:14 2003
@@ -3127,7 +3127,7 @@
 	moveb	%d0,M162_SCC_CTRL_A
 	jra	3f
 5:
-	/* 166/167/177; its a CD2401 */
+	/* 166/167/177; it's a CD2401 */
 	moveb	#0,M167_CYCAR
 	moveb	M167_CYIER,%d2
 	moveb	#0x02,M167_CYIER
diff -Nru a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
--- a/arch/m68k/kernel/time.c	Tue Mar  4 19:30:05 2003
+++ b/arch/m68k/kernel/time.c	Tue Mar  4 19:30:05 2003
@@ -26,7 +26,7 @@
 #include <linux/timex.h>
 #include <linux/profile.h>
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static inline int set_rtc_mmss(unsigned long nowtime)
 {
diff -Nru a/arch/m68k/math-emu/fp_util.S b/arch/m68k/math-emu/fp_util.S
--- a/arch/m68k/math-emu/fp_util.S	Tue Mar  4 19:30:14 2003
+++ b/arch/m68k/math-emu/fp_util.S	Tue Mar  4 19:30:14 2003
@@ -49,7 +49,7 @@
  * is currently at that time unused, be careful if you want change
  * something here. %d0 and %d1 is always usable, sometimes %d2 (or
  * only the lower half) most function have to return the %a0
- * unmodified, so that the caller can immediatly reuse it.
+ * unmodified, so that the caller can immediately reuse it.
  */
 
 	.globl	fp_ill, fp_end
diff -Nru a/arch/m68k/q40/README b/arch/m68k/q40/README
--- a/arch/m68k/q40/README	Tue Mar  4 19:30:03 2003
+++ b/arch/m68k/q40/README	Tue Mar  4 19:30:03 2003
@@ -16,7 +16,7 @@
 particular device drivers.
 
 The floppy imposes a very high interrupt load on the CPU, approx 30K/s.
-When something blocks interrupts (HD) it will loose some of them, so far 
+When something blocks interrupts (HD) it will lose some of them, so far 
 this is not known to have caused any data loss. On highly loaded systems
 it can make the floppy very slow or practically stop. Other Q40 OS' simply 
 poll the floppy for this reason - something that can't be done in Linux.
diff -Nru a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
--- a/arch/m68k/sun3/config.c	Tue Mar  4 19:30:11 2003
+++ b/arch/m68k/sun3/config.c	Tue Mar  4 19:30:11 2003
@@ -119,7 +119,7 @@
 {
 	unsigned long start_page;
 
-	/* align start/end to page boundries */
+	/* align start/end to page boundaries */
 	memory_start = ((memory_start + (PAGE_SIZE-1)) & PAGE_MASK);
 	memory_end = memory_end & PAGE_MASK;
 		
diff -Nru a/arch/m68knommu/kernel/ints.c b/arch/m68knommu/kernel/ints.c
--- a/arch/m68knommu/kernel/ints.c	Tue Mar  4 19:30:05 2003
+++ b/arch/m68knommu/kernel/ints.c	Tue Mar  4 19:30:05 2003
@@ -214,7 +214,7 @@
 /*
  * Do we need these probe functions on the m68k?
  *
- *  ... may be usefull with ISA devices
+ *  ... may be useful with ISA devices
  */
 unsigned long probe_irq_on (void)
 {
diff -Nru a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
--- a/arch/m68knommu/kernel/syscalltable.S	Tue Mar  4 19:30:03 2003
+++ b/arch/m68knommu/kernel/syscalltable.S	Tue Mar  4 19:30:03 2003
@@ -14,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/sys.h>
 #include <linux/linkage.h>
+#include <asm/unistd.h>
 
 .text
 ALIGN
diff -Nru a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
--- a/arch/m68knommu/kernel/time.c	Tue Mar  4 19:30:11 2003
+++ b/arch/m68knommu/kernel/time.c	Tue Mar  4 19:30:11 2003
@@ -26,7 +26,7 @@
 
 #define	TICK_SIZE (tick_nsec / 1000)
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static inline int set_rtc_mmss(unsigned long nowtime)
 {
diff -Nru a/arch/m68knommu/platform/5307/entry.S b/arch/m68knommu/platform/5307/entry.S
--- a/arch/m68knommu/platform/5307/entry.S	Tue Mar  4 19:30:14 2003
+++ b/arch/m68knommu/platform/5307/entry.S	Tue Mar  4 19:30:14 2003
@@ -27,6 +27,7 @@
 #include <linux/config.h>
 #include <linux/sys.h>
 #include <linux/linkage.h>
+#include <asm/unistd.h>
 #include <asm/thread_info.h>
 #include <asm/errno.h>
 #include <asm/setup.h>
diff -Nru a/arch/m68knommu/platform/5307/vectors.c b/arch/m68knommu/platform/5307/vectors.c
--- a/arch/m68knommu/platform/5307/vectors.c	Tue Mar  4 19:30:13 2003
+++ b/arch/m68knommu/platform/5307/vectors.c	Tue Mar  4 19:30:13 2003
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
+#include <linux/unistd.h>
 #include <asm/irq.h>
 #include <asm/dma.h>
 #include <asm/traps.h>
diff -Nru a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
--- a/arch/m68knommu/platform/68360/ints.c	Tue Mar  4 19:30:03 2003
+++ b/arch/m68knommu/platform/68360/ints.c	Tue Mar  4 19:30:03 2003
@@ -291,7 +291,7 @@
 
 	/* unsigned long pend = *(volatile unsigned long *)pquicc->intr_cipr; */
 
-	/* Bugger all that wierdness. For the moment, I seem to know where I came from;
+	/* Bugger all that weirdness. For the moment, I seem to know where I came from;
 	 * vec is passed from a specific ISR, so I'll use it. */
 
 	if (int_irq_list[irq] && int_irq_list[irq]->handler) {
diff -Nru a/arch/mips/au1000/common/serial.c b/arch/mips/au1000/common/serial.c
--- a/arch/mips/au1000/common/serial.c	Tue Mar  4 19:30:05 2003
+++ b/arch/mips/au1000/common/serial.c	Tue Mar  4 19:30:05 2003
@@ -2703,7 +2703,7 @@
  *	port exists and is in use an error is returned. If the port
  *	is not currently in the table it is added.
  *
- *	The port is then probed and if neccessary the IRQ is autodetected
+ *	The port is then probed and if necessary the IRQ is autodetected
  *	If this fails an error is returned.
  *
  *	On success the port is ready to use and the line number is returned.
diff -Nru a/arch/mips/baget/wbflush.c b/arch/mips/baget/wbflush.c
--- a/arch/mips/baget/wbflush.c	Tue Mar  4 19:30:11 2003
+++ b/arch/mips/baget/wbflush.c	Tue Mar  4 19:30:11 2003
@@ -17,7 +17,7 @@
 }
 
 /*
- * Baget/MIPS doesnt need to write back the WB.
+ * Baget/MIPS doesn't need to write back the WB.
  */
 static void wbflush_baget(void)
 {
diff -Nru a/arch/mips/ddb5xxx/common/pci.c b/arch/mips/ddb5xxx/common/pci.c
--- a/arch/mips/ddb5xxx/common/pci.c	Tue Mar  4 19:30:14 2003
+++ b/arch/mips/ddb5xxx/common/pci.c	Tue Mar  4 19:30:14 2003
@@ -20,7 +20,7 @@
  * Strategies:
  *
  * . We rely on pci_auto.c file to assign PCI resources (MEM and IO)
- *   TODO: this shold be optional for some machines where they do have
+ *   TODO: this should be optional for some machines where they do have
  *   a real "pcibios" that does resource assignment.
  *
  * . We then use pci_scan_bus() to "discover" all the resources for
diff -Nru a/arch/mips/dec/boot/decstation.c b/arch/mips/dec/boot/decstation.c
--- a/arch/mips/dec/boot/decstation.c	Tue Mar  4 19:30:09 2003
+++ b/arch/mips/dec/boot/decstation.c	Tue Mar  4 19:30:09 2003
@@ -70,7 +70,7 @@
 
 #ifdef RELOC
 	/*
-	 * Now copy kernel image to it's destination.
+	 * Now copy kernel image to its destination.
 	 */
 	len = ((unsigned long) (&_end) - k_start);
 	memcpy((void *)k_start, &_ftext, len);
diff -Nru a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
--- a/arch/mips/kernel/irq.c	Tue Mar  4 19:30:04 2003
+++ b/arch/mips/kernel/irq.c	Tue Mar  4 19:30:04 2003
@@ -44,7 +44,7 @@
 {
 	/*
 	 * 'what should we do if we get a hw irq event on an illegal vector'.
-	 * each architecture has to answer this themselves, it doesnt deserve
+	 * each architecture has to answer this themselves, it doesn't deserve
 	 * a generic callback i think.
 	 */
 	printk("unexpected interrupt %d\n", irq);
diff -Nru a/arch/mips/kernel/pci.c b/arch/mips/kernel/pci.c
--- a/arch/mips/kernel/pci.c	Tue Mar  4 19:30:11 2003
+++ b/arch/mips/kernel/pci.c	Tue Mar  4 19:30:11 2003
@@ -19,7 +19,7 @@
  * Strategies:
  *
  * . We rely on pci_auto.c file to assign PCI resources (MEM and IO)
- *   TODO: this shold be optional for some machines where they do have
+ *   TODO: this should be optional for some machines where they do have
  *   a real "pcibios" that does resource assignment.
  *
  * . We then use pci_scan_bus() to "discover" all the resources for
diff -Nru a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
--- a/arch/mips/kernel/process.c	Tue Mar  4 19:30:08 2003
+++ b/arch/mips/kernel/process.c	Tue Mar  4 19:30:08 2003
@@ -112,7 +112,7 @@
 	p->thread.reg31 = (unsigned long) ret_from_fork;
 
 	/*
-	 * New tasks loose permission to use the fpu. This accelerates context
+	 * New tasks lose permission to use the fpu. This accelerates context
 	 * switching for most programs since they don't use the fpu.
 	 */
 	p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
diff -Nru a/arch/mips/kernel/r2300_misc.S b/arch/mips/kernel/r2300_misc.S
--- a/arch/mips/kernel/r2300_misc.S	Tue Mar  4 19:30:12 2003
+++ b/arch/mips/kernel/r2300_misc.S	Tue Mar  4 19:30:12 2003
@@ -76,7 +76,7 @@
 	/* Check is PTE is present, if not then jump to LABEL.
 	 * PTR points to the page table where this PTE is located,
 	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
+	 * with its original value.
 	 */
 #define PTE_PRESENT(pte, ptr, label) \
 	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
diff -Nru a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
--- a/arch/mips/kernel/r2300_switch.S	Tue Mar  4 19:30:13 2003
+++ b/arch/mips/kernel/r2300_switch.S	Tue Mar  4 19:30:13 2003
@@ -80,7 +80,7 @@
 	beqz	a0, 2f				# Save floating point state
 	 nor	t3, zero, t3
 	.set	reorder
-	lw	t1, ST_OFF(a0)			# last thread looses fpu
+	lw	t1, ST_OFF(a0)			# last thread loses fpu
 	and	t1, t3
 	sw	t1, ST_OFF(a0)
 	FPU_SAVE_SINGLE(a0, t1)			# clobbers t1
@@ -108,7 +108,7 @@
 
 /*
  * Load the FPU with signalling NANS.  This bit pattern we're using has
- * the property that no matter wether considered as single or as double
+ * the property that no matter whether considered as single or as double
  * precission represents signaling NANS.
  *
  * We initialize fcr31 to rounding to nearest, no exceptions.
diff -Nru a/arch/mips/kernel/r4k_misc.S b/arch/mips/kernel/r4k_misc.S
--- a/arch/mips/kernel/r4k_misc.S	Tue Mar  4 19:30:05 2003
+++ b/arch/mips/kernel/r4k_misc.S	Tue Mar  4 19:30:05 2003
@@ -93,7 +93,7 @@
 	/* Check is PTE is present, if not then jump to LABEL.
 	 * PTR points to the page table where this PTE is located,
 	 * when the macro is done executing PTE will be restored
-	 * with it's original value.
+	 * with its original value.
 	 */
 #define PTE_PRESENT(pte, ptr, label) \
 	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
diff -Nru a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
--- a/arch/mips/kernel/r4k_switch.S	Tue Mar  4 19:30:13 2003
+++ b/arch/mips/kernel/r4k_switch.S	Tue Mar  4 19:30:13 2003
@@ -85,7 +85,7 @@
 	beqz	a0, 2f				# Save floating point state
 	 nor	t3, zero, t3
 
-	lw	t1, ST_OFF(a0)			# last thread looses fpu
+	lw	t1, ST_OFF(a0)			# last thread loses fpu
 	and	t1, t3
 	sw	t1, ST_OFF(a0)
 
diff -Nru a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
--- a/arch/mips/kernel/setup.c	Tue Mar  4 19:30:05 2003
+++ b/arch/mips/kernel/setup.c	Tue Mar  4 19:30:05 2003
@@ -775,7 +775,7 @@
 		request_resource(&iomem_resource, res);
 
 		/*
-		 *  We dont't know which RAM region contains kernel data,
+		 *  We don't know which RAM region contains kernel data,
 		 *  so we try it repeatedly and let the resource manager
 		 *  test it.
 		 */
diff -Nru a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
--- a/arch/mips/kernel/time.c	Tue Mar  4 19:30:08 2003
+++ b/arch/mips/kernel/time.c	Tue Mar  4 19:30:08 2003
@@ -32,7 +32,7 @@
 #define USECS_PER_JIFFY (1000000/HZ)
 #define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 /*
  * forward reference
diff -Nru a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
--- a/arch/mips/kernel/traps.c	Tue Mar  4 19:30:08 2003
+++ b/arch/mips/kernel/traps.c	Tue Mar  4 19:30:08 2003
@@ -793,7 +793,7 @@
 	/* Some firmware leaves the BEV flag set, clear it.  */
 	clear_cp0_status(ST0_BEV);
 
-	/* Copy the generic exception handler code to it's final destination. */
+	/* Copy the generic exception handler code to its final destination. */
 	memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
 	memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
 	memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
@@ -805,7 +805,7 @@
 		set_except_vector(i, handle_reserved);
 
 	/* 
-	 * Copy the EJTAG debug exception vector handler code to it's final 
+	 * Copy the EJTAG debug exception vector handler code to its final 
 	 * destination.
 	 */
 	memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
diff -Nru a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c
--- a/arch/mips/math-emu/dp_add.c	Tue Mar  4 19:30:05 2003
+++ b/arch/mips/math-emu/dp_add.c	Tue Mar  4 19:30:05 2003
@@ -73,7 +73,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -92,7 +92,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c
--- a/arch/mips/math-emu/dp_div.c	Tue Mar  4 19:30:04 2003
+++ b/arch/mips/math-emu/dp_div.c	Tue Mar  4 19:30:04 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Infinity handeling 
+		/* Infinity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -89,7 +89,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return ieee754dp_inf(xs ^ ys);
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c
--- a/arch/mips/math-emu/dp_mul.c	Tue Mar  4 19:30:08 2003
+++ b/arch/mips/math-emu/dp_mul.c	Tue Mar  4 19:30:08 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Infinity handeling */
+		/* Infinity handling */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
diff -Nru a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
--- a/arch/mips/math-emu/dp_sub.c	Tue Mar  4 19:30:11 2003
+++ b/arch/mips/math-emu/dp_sub.c	Tue Mar  4 19:30:11 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -91,7 +91,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
--- a/arch/mips/math-emu/ieee754.c	Tue Mar  4 19:30:04 2003
+++ b/arch/mips/math-emu/ieee754.c	Tue Mar  4 19:30:04 2003
@@ -3,7 +3,7 @@
  *
  * BUGS
  * not much dp done
- * doesnt generate IEEE754_INEXACT
+ * doesn't generate IEEE754_INEXACT
  *
  */
 /*
diff -Nru a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
--- a/arch/mips/math-emu/ieee754dp.c	Tue Mar  4 19:30:11 2003
+++ b/arch/mips/math-emu/ieee754dp.c	Tue Mar  4 19:30:11 2003
@@ -99,14 +99,14 @@
 }
 
 
-/* generate a normal/denormal number with over,under handeling
+/* generate a normal/denormal number with over,under handling
  * sn is sign
  * xe is an unbiased exponent
  * xm is 3bit extended precision value.
  */
 ieee754dp ieee754dp_format(int sn, int xe, unsigned long long xm)
 {
-	assert(xm);		/* we dont gen exact zeros (probably should) */
+	assert(xm);		/* we don't gen exact zeros (probably should) */
 
 	assert((xm >> (DP_MBITS + 1 + 3)) == 0);	/* no execess */
 	assert(xm & (DP_HIDDEN_BIT << 3));
diff -Nru a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
--- a/arch/mips/math-emu/ieee754sp.c	Tue Mar  4 19:30:06 2003
+++ b/arch/mips/math-emu/ieee754sp.c	Tue Mar  4 19:30:06 2003
@@ -100,14 +100,14 @@
 }
 
 
-/* generate a normal/denormal number with over,under handeling
+/* generate a normal/denormal number with over,under handling
  * sn is sign
  * xe is an unbiased exponent
  * xm is 3bit extended precision value.
  */
 ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
 {
-	assert(xm);		/* we dont gen exact zeros (probably should) */
+	assert(xm);		/* we don't gen exact zeros (probably should) */
 
 	assert((xm >> (SP_MBITS + 1 + 3)) == 0);	/* no execess */
 	assert(xm & (SP_HIDDEN_BIT << 3));
diff -Nru a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c
--- a/arch/mips/math-emu/sp_add.c	Tue Mar  4 19:30:12 2003
+++ b/arch/mips/math-emu/sp_add.c	Tue Mar  4 19:30:12 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -91,7 +91,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c
--- a/arch/mips/math-emu/sp_div.c	Tue Mar  4 19:30:12 2003
+++ b/arch/mips/math-emu/sp_div.c	Tue Mar  4 19:30:12 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Infinity handeling 
+		/* Infinity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -89,7 +89,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return ieee754sp_inf(xs ^ ys);
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c
--- a/arch/mips/math-emu/sp_fdp.c	Tue Mar  4 19:30:08 2003
+++ b/arch/mips/math-emu/sp_fdp.c	Tue Mar  4 19:30:08 2003
@@ -49,7 +49,7 @@
 	case IEEE754_CLASS_ZERO:
 		return ieee754sp_zero(xs);
 	case IEEE754_CLASS_DNORM:
-		/* cant possibly be sp representable */
+		/* can't possibly be sp representable */
 		SETCX(IEEE754_UNDERFLOW);
 		return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
 	case IEEE754_CLASS_NORM:
diff -Nru a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c
--- a/arch/mips/math-emu/sp_mul.c	Tue Mar  4 19:30:10 2003
+++ b/arch/mips/math-emu/sp_mul.c	Tue Mar  4 19:30:10 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Infinity handeling */
+		/* Infinity handling */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
diff -Nru a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c
--- a/arch/mips/math-emu/sp_sub.c	Tue Mar  4 19:30:07 2003
+++ b/arch/mips/math-emu/sp_sub.c	Tue Mar  4 19:30:07 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -91,7 +91,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c
--- a/arch/mips/mips-boards/generic/pci.c	Tue Mar  4 19:30:07 2003
+++ b/arch/mips/mips-boards/generic/pci.c	Tue Mar  4 19:30:07 2003
@@ -81,7 +81,7 @@
 
 	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT))
 	{
-	        /* Error occured */
+	        /* Error occurred */
 
 	        /* Clear bits */
 	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
diff -Nru a/arch/mips64/kernel/process.c b/arch/mips64/kernel/process.c
--- a/arch/mips64/kernel/process.c	Tue Mar  4 19:30:05 2003
+++ b/arch/mips64/kernel/process.c	Tue Mar  4 19:30:05 2003
@@ -105,7 +105,7 @@
 	p->thread.reg31 = (unsigned long) ret_from_fork;
 
 	/*
-	 * New tasks loose permission to use the fpu. This accelerates context
+	 * New tasks lose permission to use the fpu. This accelerates context
 	 * switching for most programs since they don't use the fpu.
 	 */
 	p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) &
diff -Nru a/arch/mips64/kernel/r4k_switch.S b/arch/mips64/kernel/r4k_switch.S
--- a/arch/mips64/kernel/r4k_switch.S	Tue Mar  4 19:30:04 2003
+++ b/arch/mips64/kernel/r4k_switch.S	Tue Mar  4 19:30:04 2003
@@ -79,7 +79,7 @@
 	beqz	a0, 2f				# Save floating point state
 	 nor	t3, zero, t3
 
-	ld	t1, ST_OFF(a0)			# last thread looses fpu
+	ld	t1, ST_OFF(a0)			# last thread loses fpu
 	and	t1, t3
 	sd	t1, ST_OFF(a0)
 	sll	t2, t1, 5
diff -Nru a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c
--- a/arch/mips64/kernel/smp.c	Tue Mar  4 19:30:11 2003
+++ b/arch/mips64/kernel/smp.c	Tue Mar  4 19:30:11 2003
@@ -195,8 +195,7 @@
 
 void flush_tlb_all(void)
 {
-	smp_call_function(flush_tlb_all_ipi, 0, 1, 1);
-	_flush_tlb_all();
+	on_each_cpu(flush_tlb_all_ipi, 0, 1, 1);
 }
 
 static void flush_tlb_mm_ipi(void *mm)
@@ -219,6 +218,8 @@
 
 void flush_tlb_mm(struct mm_struct *mm)
 {
+	preempt_disable();
+
 	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
 		smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1);
 	} else {
@@ -228,6 +229,8 @@
 				CPU_CONTEXT(i, mm) = 0;
 	}
 	_flush_tlb_mm(mm);
+
+	preempt_enable();
 }
 
 struct flush_tlb_data {
@@ -246,6 +249,8 @@
 
 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
+	preempt_disable();
+
 	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
 		struct flush_tlb_data fd;
 
@@ -260,6 +265,8 @@
 				CPU_CONTEXT(i, mm) = 0;
 	}
 	_flush_tlb_range(mm, start, end);
+
+	preempt_enable();
 }
 
 static void flush_tlb_page_ipi(void *info)
@@ -271,6 +278,8 @@
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
+	preempt_disable();
+
 	if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) {
 		struct flush_tlb_data fd;
 
@@ -284,5 +293,7 @@
 				CPU_CONTEXT(i, vma->vm_mm) = 0;
 	}
 	_flush_tlb_page(vma, page);
+
+	preempt_enable();
 }
 
diff -Nru a/arch/mips64/kernel/traps.c b/arch/mips64/kernel/traps.c
--- a/arch/mips64/kernel/traps.c	Tue Mar  4 19:30:11 2003
+++ b/arch/mips64/kernel/traps.c	Tue Mar  4 19:30:11 2003
@@ -497,7 +497,7 @@
 	/* Some firmware leaves the BEV flag set, clear it.  */
 	set_cp0_status(ST0_BEV, 0);
 
-	/* Copy the generic exception handler code to it's final destination. */
+	/* Copy the generic exception handler code to its final destination. */
 	memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
 	memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
 
diff -Nru a/arch/mips64/math-emu/dp_add.c b/arch/mips64/math-emu/dp_add.c
--- a/arch/mips64/math-emu/dp_add.c	Tue Mar  4 19:30:14 2003
+++ b/arch/mips64/math-emu/dp_add.c	Tue Mar  4 19:30:14 2003
@@ -73,7 +73,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -92,7 +92,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips64/math-emu/dp_div.c b/arch/mips64/math-emu/dp_div.c
--- a/arch/mips64/math-emu/dp_div.c	Tue Mar  4 19:30:03 2003
+++ b/arch/mips64/math-emu/dp_div.c	Tue Mar  4 19:30:03 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Infinity handeling 
+		/* Infinity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -89,7 +89,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return ieee754dp_inf(xs ^ ys);
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips64/math-emu/dp_mul.c b/arch/mips64/math-emu/dp_mul.c
--- a/arch/mips64/math-emu/dp_mul.c	Tue Mar  4 19:30:14 2003
+++ b/arch/mips64/math-emu/dp_mul.c	Tue Mar  4 19:30:14 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Infinity handeling */
+		/* Infinity handling */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
diff -Nru a/arch/mips64/math-emu/dp_sub.c b/arch/mips64/math-emu/dp_sub.c
--- a/arch/mips64/math-emu/dp_sub.c	Tue Mar  4 19:30:08 2003
+++ b/arch/mips64/math-emu/dp_sub.c	Tue Mar  4 19:30:08 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -91,7 +91,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips64/math-emu/ieee754dp.c b/arch/mips64/math-emu/ieee754dp.c
--- a/arch/mips64/math-emu/ieee754dp.c	Tue Mar  4 19:30:13 2003
+++ b/arch/mips64/math-emu/ieee754dp.c	Tue Mar  4 19:30:13 2003
@@ -99,14 +99,14 @@
 }
 
 
-/* generate a normal/denormal number with over,under handeling
+/* generate a normal/denormal number with over,under handling
  * sn is sign
  * xe is an unbiased exponent
  * xm is 3bit extended precision value.
  */
 ieee754dp ieee754dp_format(int sn, int xe, unsigned long long xm)
 {
-	assert(xm);		/* we dont gen exact zeros (probably should) */
+	assert(xm);		/* we don't gen exact zeros (probably should) */
 
 	assert((xm >> (DP_MBITS + 1 + 3)) == 0);	/* no execess */
 	assert(xm & (DP_HIDDEN_BIT << 3));
diff -Nru a/arch/mips64/math-emu/ieee754sp.c b/arch/mips64/math-emu/ieee754sp.c
--- a/arch/mips64/math-emu/ieee754sp.c	Tue Mar  4 19:30:10 2003
+++ b/arch/mips64/math-emu/ieee754sp.c	Tue Mar  4 19:30:10 2003
@@ -100,14 +100,14 @@
 }
 
 
-/* generate a normal/denormal number with over,under handeling
+/* generate a normal/denormal number with over,under handling
  * sn is sign
  * xe is an unbiased exponent
  * xm is 3bit extended precision value.
  */
 ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
 {
-	assert(xm);		/* we dont gen exact zeros (probably should) */
+	assert(xm);		/* we don't gen exact zeros (probably should) */
 
 	assert((xm >> (SP_MBITS + 1 + 3)) == 0);	/* no execess */
 	assert(xm & (SP_HIDDEN_BIT << 3));
diff -Nru a/arch/mips64/math-emu/sp_add.c b/arch/mips64/math-emu/sp_add.c
--- a/arch/mips64/math-emu/sp_add.c	Tue Mar  4 19:30:05 2003
+++ b/arch/mips64/math-emu/sp_add.c	Tue Mar  4 19:30:05 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -91,7 +91,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips64/math-emu/sp_div.c b/arch/mips64/math-emu/sp_div.c
--- a/arch/mips64/math-emu/sp_div.c	Tue Mar  4 19:30:14 2003
+++ b/arch/mips64/math-emu/sp_div.c	Tue Mar  4 19:30:14 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Infinity handeling 
+		/* Infinity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -89,7 +89,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return ieee754sp_inf(xs ^ ys);
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips64/math-emu/sp_fdp.c b/arch/mips64/math-emu/sp_fdp.c
--- a/arch/mips64/math-emu/sp_fdp.c	Tue Mar  4 19:30:13 2003
+++ b/arch/mips64/math-emu/sp_fdp.c	Tue Mar  4 19:30:13 2003
@@ -49,7 +49,7 @@
 	case IEEE754_CLASS_ZERO:
 		return ieee754sp_zero(xs);
 	case IEEE754_CLASS_DNORM:
-		/* cant possibly be sp representable */
+		/* can't possibly be sp representable */
 		SETCX(IEEE754_UNDERFLOW);
 		return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
 	case IEEE754_CLASS_NORM:
diff -Nru a/arch/mips64/math-emu/sp_mul.c b/arch/mips64/math-emu/sp_mul.c
--- a/arch/mips64/math-emu/sp_mul.c	Tue Mar  4 19:30:05 2003
+++ b/arch/mips64/math-emu/sp_mul.c	Tue Mar  4 19:30:05 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Infinity handeling */
+		/* Infinity handling */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
diff -Nru a/arch/mips64/math-emu/sp_sub.c b/arch/mips64/math-emu/sp_sub.c
--- a/arch/mips64/math-emu/sp_sub.c	Tue Mar  4 19:30:08 2003
+++ b/arch/mips64/math-emu/sp_sub.c	Tue Mar  4 19:30:08 2003
@@ -72,7 +72,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -91,7 +91,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -Nru a/arch/mips64/mips-boards/generic/pci.c b/arch/mips64/mips-boards/generic/pci.c
--- a/arch/mips64/mips-boards/generic/pci.c	Tue Mar  4 19:30:04 2003
+++ b/arch/mips64/mips-boards/generic/pci.c	Tue Mar  4 19:30:04 2003
@@ -87,7 +87,7 @@
 
 	if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT))
 	{
-	        /* Error occured */
+	        /* Error occurred */
 
 	        /* Clear bits */
 	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
diff -Nru a/arch/mips64/sgi-ip27/ip27-nmi.c b/arch/mips64/sgi-ip27/ip27-nmi.c
--- a/arch/mips64/sgi-ip27/ip27-nmi.c	Tue Mar  4 19:30:03 2003
+++ b/arch/mips64/sgi-ip27/ip27-nmi.c	Tue Mar  4 19:30:03 2003
@@ -127,7 +127,7 @@
 	 * This is for 2 reasons:
 	 *	- sometimes a MMSC fail to NMI all cpus.
 	 *	- on 512p SN0 system, the MMSC will only send NMIs to
-	 *	  half the cpus. Unfortunately, we dont know which cpus may be
+	 *	  half the cpus. Unfortunately, we don't know which cpus may be
 	 *	  NMIed - it depends on how the site chooses to configure.
 	 * 
 	 * Note: it has been measure that it takes the MMSC up to 2.3 secs to
diff -Nru a/arch/mips64/sgi-ip27/ip27-pci-dma.c b/arch/mips64/sgi-ip27/ip27-pci-dma.c
--- a/arch/mips64/sgi-ip27/ip27-pci-dma.c	Tue Mar  4 19:30:11 2003
+++ b/arch/mips64/sgi-ip27/ip27-pci-dma.c	Tue Mar  4 19:30:11 2003
@@ -74,7 +74,7 @@
  * must match what was provided for in a previous pci_map_single call.  All
  * other usages are undefined.
  *
- * After this call, reads by the cpu to the buffer are guarenteed to see
+ * After this call, reads by the cpu to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
 void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
diff -Nru a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
--- a/arch/parisc/kernel/cache.c	Tue Mar  4 19:30:08 2003
+++ b/arch/parisc/kernel/cache.c	Tue Mar  4 19:30:08 2003
@@ -39,8 +39,7 @@
 void
 flush_data_cache(void)
 {
-	smp_call_function((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
-	flush_data_cache_local();
+	on_each_cpu((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
 }
 #endif
 
diff -Nru a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
--- a/arch/parisc/kernel/irq.c	Tue Mar  4 19:30:07 2003
+++ b/arch/parisc/kernel/irq.c	Tue Mar  4 19:30:07 2003
@@ -61,20 +61,17 @@
 
 static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
 
-#ifdef CONFIG_SMP
 static void cpu_set_eiem(void *info)
 {
 	set_eiem((unsigned long) info);
 }
-#endif
 
 static inline void disable_cpu_irq(void *unused, int irq)
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
 	cpu_eiem &= ~eirr_bit;
-	set_eiem(cpu_eiem);
-        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
 static void enable_cpu_irq(void *unused, int irq)
@@ -83,8 +80,7 @@
 
 	mtctl(eirr_bit, 23);	/* clear EIRR bit before unmasking */
 	cpu_eiem |= eirr_bit;
-        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
-	set_eiem(cpu_eiem);
+        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
 /* mask and disable are the same at the CPU level
@@ -100,8 +96,7 @@
 	** handle *any* unmasked pending interrupts.
 	** ie We don't need to check for pending interrupts here.
 	*/
-        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
-	set_eiem(cpu_eiem);
+        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
 /*
@@ -349,7 +344,7 @@
 
 
 /*
-** The alloc process needs to accept a parameter to accomodate limitations
+** The alloc process needs to accept a parameter to accommodate limitations
 ** of the HW/SW which use these bits:
 ** Legacy PA I/O (GSC/NIO): 5 bits (architected EIM register)
 ** V-class (EPIC):          6 bits
diff -Nru a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
--- a/arch/parisc/kernel/perf.c	Tue Mar  4 19:30:07 2003
+++ b/arch/parisc/kernel/perf.c	Tue Mar  4 19:30:07 2003
@@ -255,7 +255,7 @@
 }
 
 /*
- * Open the device and initialize all of it's memory.  The device is only 
+ * Open the device and initialize all of its memory.  The device is only 
  * opened once, but can be "queried" by multiple processes that know its
  * file descriptor.
  */
diff -Nru a/arch/parisc/kernel/perf_images.h b/arch/parisc/kernel/perf_images.h
--- a/arch/parisc/kernel/perf_images.h	Tue Mar  4 19:30:04 2003
+++ b/arch/parisc/kernel/perf_images.h	Tue Mar  4 19:30:04 2003
@@ -1556,7 +1556,7 @@
  * IRTN_AV fires twice for every I-cache miss returning from RIB to the IFU.
  * It will not fire if a second I-cache miss is issued from the IFU to RIB
  * before the first returns.  Therefore, if the IRTN_AV count is much less
- * than 2x the ICORE_AV count, many speculative I-cache misses are occuring
+ * than 2x the ICORE_AV count, many speculative I-cache misses are occurring
  * which are "discovered" to be incorrect fairly quickly.
  * The ratio of I-cache miss transactions on Runway to the ICORE_AV count is
  * a measure of the effectiveness of instruction prefetching.  This ratio
diff -Nru a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
--- a/arch/parisc/kernel/ptrace.c	Tue Mar  4 19:30:04 2003
+++ b/arch/parisc/kernel/ptrace.c	Tue Mar  4 19:30:04 2003
@@ -242,7 +242,7 @@
 			 *
 			 * Allow writing to Nullify, Divide-step-correction,
 			 * and carry/borrow bits.
-			 * BEWARE, if you set N, and then single step, it wont
+			 * BEWARE, if you set N, and then single step, it won't
 			 * stop on the nullified instruction.
 			 */
 			DBG(("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
diff -Nru a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
--- a/arch/parisc/kernel/smp.c	Tue Mar  4 19:30:14 2003
+++ b/arch/parisc/kernel/smp.c	Tue Mar  4 19:30:14 2003
@@ -401,7 +401,7 @@
 __setup("maxcpus=", maxcpus);
 
 /*
- * Flush all other CPU's tlb and then mine.  Do this with smp_call_function()
+ * Flush all other CPU's tlb and then mine.  Do this with on_each_cpu()
  * as we want to ensure all TLB's flushed before proceeding.
  */
 
@@ -410,8 +410,7 @@
 void
 smp_flush_tlb_all(void)
 {
-	smp_call_function((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
-	flush_tlb_all_local();
+	on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
 }
 
 
diff -Nru a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
--- a/arch/parisc/kernel/time.c	Tue Mar  4 19:30:07 2003
+++ b/arch/parisc/kernel/time.c	Tue Mar  4 19:30:07 2003
@@ -32,7 +32,7 @@
 
 #include <linux/timex.h>
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 /* xtime and wall_jiffies keep wall-clock time */
 extern unsigned long wall_jiffies;
diff -Nru a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
--- a/arch/parisc/mm/init.c	Tue Mar  4 19:30:08 2003
+++ b/arch/parisc/mm/init.c	Tue Mar  4 19:30:08 2003
@@ -974,8 +974,7 @@
 	    do_recycle++;
 	}
 	spin_unlock(&sid_lock);
-	smp_call_function((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
-	flush_tlb_all_local();
+	on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
 	if (do_recycle) {
 	    spin_lock(&sid_lock);
 	    recycle_sids(recycle_ndirty,recycle_dirty_array);
diff -Nru a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
--- a/arch/ppc/4xx_io/serial_sicc.c	Tue Mar  4 19:30:03 2003
+++ b/arch/ppc/4xx_io/serial_sicc.c	Tue Mar  4 19:30:03 2003
@@ -139,7 +139,7 @@
 #define _LSR_RX_ERR    (_LSR_LB_BREAK | _LSR_FE_MASK | _LSR_OE_MASK | \
 			 _LSR_PE_MASK )
 
-/* serial port reciever command register */
+/* serial port receiver command register */
 
 #define _RCR_ER_MASK   0x80           /* enable receiver mask */
 #define _RCR_DME_MASK  0x60           /* dma mode */
diff -Nru a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
--- a/arch/ppc/8xx_io/cs4218_tdm.c	Tue Mar  4 19:30:04 2003
+++ b/arch/ppc/8xx_io/cs4218_tdm.c	Tue Mar  4 19:30:04 2003
@@ -2495,7 +2495,7 @@
 	cp->cp_simode &= ~0x00000fff;
 
 	/* Enable common receive/transmit clock pins, use IDL format.
-	 * Sync on falling edge, transmit rising clock, recieve falling
+	 * Sync on falling edge, transmit rising clock, receive falling
 	 * clock, delay 1 bit on both Tx and Rx.  Common Tx/Rx clocks and
 	 * sync.
 	 * Connect SMC2 to TSA.
diff -Nru a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S
--- a/arch/ppc/kernel/l2cr.S	Tue Mar  4 19:30:09 2003
+++ b/arch/ppc/kernel/l2cr.S	Tue Mar  4 19:30:09 2003
@@ -136,7 +136,7 @@
 	 /**** Might be a good idea to set L2DO here - to prevent instructions
 	       from getting into the cache.  But since we invalidate
 	       the next time we enable the cache it doesn't really matter.
-	       Don't do this unless you accomodate all processor variations.
+	       Don't do this unless you accommodate all processor variations.
 	       The bit moved on the 7450.....
 	  ****/
 
diff -Nru a/arch/ppc/kernel/temp.c b/arch/ppc/kernel/temp.c
--- a/arch/ppc/kernel/temp.c	Tue Mar  4 19:30:09 2003
+++ b/arch/ppc/kernel/temp.c	Tue Mar  4 19:30:09 2003
@@ -194,10 +194,7 @@
 
 	/* schedule ourselves to be run again */
 	mod_timer(&tau_timer, jiffies + shrink_timer) ;
-#ifdef CONFIG_SMP
-	smp_call_function(tau_timeout, NULL, 1, 0);
-#endif
-	tau_timeout(NULL);
+	on_each_cpu(tau_timeout, NULL, 1, 0);
 }
 
 /*
@@ -239,10 +236,7 @@
 	tau_timer.expires = jiffies + shrink_timer;
 	add_timer(&tau_timer);
 	
-#ifdef CONFIG_SMP
-	smp_call_function(TAU_init_smp, NULL, 1, 0);
-#endif
-	TAU_init_smp(NULL);
+	on_each_cpu(TAU_init_smp, NULL, 1, 0);
 	
 	printk("Thermal assist unit ");
 #ifdef CONFIG_TAU_INT
diff -Nru a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
--- a/arch/ppc/kernel/time.c	Tue Mar  4 19:30:12 2003
+++ b/arch/ppc/kernel/time.c	Tue Mar  4 19:30:12 2003
@@ -68,7 +68,7 @@
 #include <asm/time.h>
 
 /* XXX false sharing with below? */
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 unsigned long disarm_decr[NR_CPUS];
 
diff -Nru a/arch/ppc/mm/mem_pieces.c b/arch/ppc/mm/mem_pieces.c
--- a/arch/ppc/mm/mem_pieces.c	Tue Mar  4 19:30:04 2003
+++ b/arch/ppc/mm/mem_pieces.c	Tue Mar  4 19:30:04 2003
@@ -1,6 +1,6 @@
 /*
  *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
- *      Changes to accomodate Power Macintoshes.
+ *      Changes to accommodate Power Macintoshes.
  *    Cort Dougan <cort@cs.nmt.edu>
  *      Rewrites.
  *    Grant Erickson <grant@lcse.umn.edu>
diff -Nru a/arch/ppc/mm/mem_pieces.h b/arch/ppc/mm/mem_pieces.h
--- a/arch/ppc/mm/mem_pieces.h	Tue Mar  4 19:30:03 2003
+++ b/arch/ppc/mm/mem_pieces.h	Tue Mar  4 19:30:03 2003
@@ -1,6 +1,6 @@
 /*
  *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
- *      Changes to accomodate Power Macintoshes.
+ *      Changes to accommodate Power Macintoshes.
  *    Cort Dougan <cort@cs.nmt.edu>
  *      Rewrites.
  *    Grant Erickson <grant@lcse.umn.edu>
diff -Nru a/arch/ppc/platforms/4xx/ibmstbx25.h b/arch/ppc/platforms/4xx/ibmstbx25.h
--- a/arch/ppc/platforms/4xx/ibmstbx25.h	Tue Mar  4 19:30:07 2003
+++ b/arch/ppc/platforms/4xx/ibmstbx25.h	Tue Mar  4 19:30:07 2003
@@ -164,7 +164,7 @@
 #define IBM_CPM_CPU	0x10000000	/* PPC405B3 clock control */
 #define IBM_CPM_AUD	0x08000000	/* Audio Decoder */
 #define IBM_CPM_EBIU	0x04000000	/* External Bus Interface Unit */
-#define IBM_CPM_IRR	0x02000000	/* Infrared reciever */
+#define IBM_CPM_IRR	0x02000000	/* Infrared receiver */
 #define IBM_CPM_DMA	0x01000000	/* DMA controller */
 #define IBM_CPM_UART2	0x00200000	/* Serial Control Port */
 #define IBM_CPM_UART1	0x00100000	/* Serial 1 / Infrared */
diff -Nru a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
--- a/arch/ppc/platforms/pmac_feature.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ppc/platforms/pmac_feature.c	Tue Mar  4 19:30:13 2003
@@ -50,7 +50,7 @@
 
 /*
  * We use a single global lock to protect accesses. Each driver has
- * to take care of it's own locking
+ * to take care of its own locking
  */
 static spinlock_t feature_lock  __pmacdata = SPIN_LOCK_UNLOCKED;
 
diff -Nru a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
--- a/arch/ppc/syslib/mpc10x_common.c	Tue Mar  4 19:30:05 2003
+++ b/arch/ppc/syslib/mpc10x_common.c	Tue Mar  4 19:30:05 2003
@@ -109,7 +109,7 @@
 			return -1;
 	}
 
-	/* Make sure its a supported bridge */
+	/* Make sure it's a supported bridge */
 	early_read_config_dword(hose,
 			        0,
 			        PCI_DEVFN(0,0),
diff -Nru a/arch/ppc64/boot/addRamDisk.c b/arch/ppc64/boot/addRamDisk.c
--- a/arch/ppc64/boot/addRamDisk.c	Tue Mar  4 19:30:09 2003
+++ b/arch/ppc64/boot/addRamDisk.c	Tue Mar  4 19:30:09 2003
@@ -154,7 +154,7 @@
   
 	/* Process the Sysmap file to determine where _end is */
 	sysmapPages = sysmapLen / 4096;
-	/* read the whole file line by line, expect that it doesnt fail */
+	/* read the whole file line by line, expect that it doesn't fail */
 	while ( fgets(inbuf, 4096, sysmap) )  ;
 	/* search for _end in the last page of the system map */
 	ptr_end = strstr(inbuf, " _end");
diff -Nru a/arch/ppc64/boot/addSystemMap.c b/arch/ppc64/boot/addSystemMap.c
--- a/arch/ppc64/boot/addSystemMap.c	Tue Mar  4 19:30:08 2003
+++ b/arch/ppc64/boot/addSystemMap.c	Tue Mar  4 19:30:08 2003
@@ -146,7 +146,7 @@
   /* Process the Sysmap file to determine the true end of the kernel */
 	sysmapPages = sysmapLen / 4096;
 	printf("System map pages to copy = %ld\n", sysmapPages);
-	/* read the whole file line by line, expect that it doesnt fail */
+	/* read the whole file line by line, expect that it doesn't fail */
 	while ( fgets(inbuf, 4096, sysmap) )  ;
 	/* search for _end in the last page of the system map */
 	ptr_end = strstr(inbuf, " _end");
diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
--- a/arch/ppc64/kernel/head.S	Tue Mar  4 19:30:09 2003
+++ b/arch/ppc64/kernel/head.S	Tue Mar  4 19:30:09 2003
@@ -109,7 +109,7 @@
 	.llong  0x0
 
 	/* Secondary processors write this value with their cpu # */
-	/* after they enter the spin loop immediatly below.       */
+	/* after they enter the spin loop immediately below.       */
 	.globl  __secondary_hold_acknowledge
 __secondary_hold_acknowledge:
 	.llong  0x0
diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
--- a/arch/ppc64/kernel/ioctl32.c	Tue Mar  4 19:30:14 2003
+++ b/arch/ppc64/kernel/ioctl32.c	Tue Mar  4 19:30:14 2003
@@ -3315,7 +3315,7 @@
  *
  *	But how to keep track of these kernel buffers?  We'd need to either
  *	keep track of them in some table _or_ know about usbdevicefs internals
- *	(ie. the exact layout of it's file private, which is actually defined
+ *	(ie. the exact layout of its file private, which is actually defined
  *	in linux/usbdevice_fs.h, the layout of the async queues are private to
  *	devio.c)
  *
diff -Nru a/arch/ppc64/kernel/lmb.c b/arch/ppc64/kernel/lmb.c
--- a/arch/ppc64/kernel/lmb.c	Tue Mar  4 19:30:09 2003
+++ b/arch/ppc64/kernel/lmb.c	Tue Mar  4 19:30:09 2003
@@ -73,7 +73,7 @@
 	_lmb->reserved.cnt = 1;
 }
 
-/* This is only used here, it doesnt deserve to be in bitops.h */
+/* This is only used here, it doesn't deserve to be in bitops.h */
 static __inline__ long cnt_trailing_zeros(unsigned long mask)
 {
         long cnt;
diff -Nru a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c
--- a/arch/ppc64/kernel/pSeries_lpar.c	Tue Mar  4 19:30:14 2003
+++ b/arch/ppc64/kernel/pSeries_lpar.c	Tue Mar  4 19:30:14 2003
@@ -461,7 +461,7 @@
 		return -1;
 
 	/*
-	 * Since we try and ioremap PHBs we dont own, the pte insert
+	 * Since we try and ioremap PHBs we don't own, the pte insert
 	 * will fail. However we must catch the failure in hash_page
 	 * or we will loop forever, so return -2 in this case.
 	 */
@@ -485,7 +485,7 @@
 
 	for (i = 0; i < HPTES_PER_GROUP; i++) {
 
-		/* dont remove a bolted entry */
+		/* don't remove a bolted entry */
 		lpar_rc = plpar_pte_remove(H_ANDCOND, hpte_group + slot_offset,
 					   (0x1UL << 4), &dummy1, &dummy2);
 
diff -Nru a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
--- a/arch/ppc64/kernel/pci_dn.c	Tue Mar  4 19:30:14 2003
+++ b/arch/ppc64/kernel/pci_dn.c	Tue Mar  4 19:30:14 2003
@@ -150,7 +150,7 @@
 }
 
 /* This is the "slow" path for looking up a device_node from a
- * pci_dev.  It will hunt for the device under it's parent's
+ * pci_dev.  It will hunt for the device under its parent's
  * phb and then update sysdata for a future fastpath.
  *
  * It may also do fixups on the actual device since this happens
diff -Nru a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c
--- a/arch/ppc64/kernel/ras.c	Tue Mar  4 19:30:05 2003
+++ b/arch/ppc64/kernel/ras.c	Tue Mar  4 19:30:05 2003
@@ -94,7 +94,7 @@
 /*
  * Handle power subsystem events (EPOW).
  *
- * Presently we just log the event has occured.  This should be fixed
+ * Presently we just log the event has occurred.  This should be fixed
  * to examine the type of power failure and take appropriate action where
  * the time horizon permits something useful to be done.
  */
diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
--- a/arch/ppc64/kernel/smp.c	Tue Mar  4 19:30:12 2003
+++ b/arch/ppc64/kernel/smp.c	Tue Mar  4 19:30:12 2003
@@ -51,7 +51,7 @@
 int smp_threads_ready = 0;
 unsigned long cache_decay_ticks;
 
-/* initialised so it doesnt end up in bss */
+/* initialised so it doesn't end up in bss */
 unsigned long cpu_online_map = 0;
 
 static struct smp_ops_t *smp_ops;
diff -Nru a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
--- a/arch/ppc64/kernel/time.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ppc64/kernel/time.c	Tue Mar  4 19:30:13 2003
@@ -65,7 +65,7 @@
 
 void smp_local_timer_interrupt(struct pt_regs *);
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
diff -Nru a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c
--- a/arch/ppc64/xmon/xmon.c	Tue Mar  4 19:30:13 2003
+++ b/arch/ppc64/xmon/xmon.c	Tue Mar  4 19:30:13 2003
@@ -2072,7 +2072,7 @@
 	int instr;
 	int num_parms;
 
-	/* dont look for traceback table in userspace */
+	/* don't look for traceback table in userspace */
 	if (codeaddr < PAGE_OFFSET)
 		return 0;
 
diff -Nru a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
--- a/arch/s390/kernel/smp.c	Tue Mar  4 19:30:03 2003
+++ b/arch/s390/kernel/smp.c	Tue Mar  4 19:30:03 2003
@@ -228,8 +228,7 @@
 void machine_restart_smp(char * __unused) 
 {
 	cpu_restart_map = cpu_online_map;
-        smp_call_function(do_machine_restart, NULL, 0, 0);
-	do_machine_restart(NULL);
+        on_each_cpu(do_machine_restart, NULL, 0, 0);
 }
 
 static void do_machine_halt(void * __unused)
@@ -247,8 +246,7 @@
 
 void machine_halt_smp(void)
 {
-        smp_call_function(do_machine_halt, NULL, 0, 0);
-	do_machine_halt(NULL);
+        on_each_cpu(do_machine_halt, NULL, 0, 0);
 }
 
 static void do_machine_power_off(void * __unused)
@@ -266,8 +264,7 @@
 
 void machine_power_off_smp(void)
 {
-        smp_call_function(do_machine_power_off, NULL, 0, 0);
-	do_machine_power_off(NULL);
+        on_each_cpu(do_machine_power_off, NULL, 0, 0);
 }
 
 /*
@@ -339,8 +336,7 @@
 
 void smp_ptlb_all(void)
 {
-        smp_call_function(smp_ptlb_callback, NULL, 0, 1);
-	local_flush_tlb();
+        on_each_cpu(smp_ptlb_callback, NULL, 0, 1);
 }
 
 /*
@@ -400,8 +396,10 @@
 	parms.end_ctl = cr;
 	parms.orvals[cr] = 1 << bit;
 	parms.andvals[cr] = 0xFFFFFFFF;
+	preempt_disable();
 	smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         __ctl_set_bit(cr, bit);
+	preempt_enable();
 }
 
 /*
@@ -414,8 +412,10 @@
 	parms.end_ctl = cr;
 	parms.orvals[cr] = 0x00000000;
 	parms.andvals[cr] = ~(1 << bit);
+	preempt_disable();
 	smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         __ctl_clear_bit(cr, bit);
+	preempt_enable();
 }
 
 /*
diff -Nru a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
--- a/arch/s390/kernel/time.c	Tue Mar  4 19:30:03 2003
+++ b/arch/s390/kernel/time.c	Tue Mar  4 19:30:03 2003
@@ -46,7 +46,7 @@
 
 #define TICK_SIZE tick
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static ext_int_info_t ext_int_info_timer;
 static uint64_t xtime_cc;
diff -Nru a/arch/s390x/kernel/exec32.c b/arch/s390x/kernel/exec32.c
--- a/arch/s390x/kernel/exec32.c	Tue Mar  4 19:30:03 2003
+++ b/arch/s390x/kernel/exec32.c	Tue Mar  4 19:30:03 2003
@@ -4,7 +4,7 @@
  * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  * Author(s): Gerhard Tonn (ton@de.ibm.com)
  *
- * Seperated from binfmt_elf32.c to reduce exports for module enablement.
+ * Separated from binfmt_elf32.c to reduce exports for module enablement.
  *
  */
 
diff -Nru a/arch/s390x/kernel/smp.c b/arch/s390x/kernel/smp.c
--- a/arch/s390x/kernel/smp.c	Tue Mar  4 19:30:09 2003
+++ b/arch/s390x/kernel/smp.c	Tue Mar  4 19:30:09 2003
@@ -227,8 +227,7 @@
 void machine_restart_smp(char * __unused) 
 {
 	cpu_restart_map = cpu_online_map;
-        smp_call_function(do_machine_restart, NULL, 0, 0);
-	do_machine_restart(NULL);
+        on_each_cpu(do_machine_restart, NULL, 0, 0);
 }
 
 static void do_machine_halt(void * __unused)
@@ -246,8 +245,7 @@
 
 void machine_halt_smp(void)
 {
-        smp_call_function(do_machine_halt, NULL, 0, 0);
-	do_machine_halt(NULL);
+        on_each_cpu(do_machine_halt, NULL, 0, 0);
 }
 
 static void do_machine_power_off(void * __unused)
@@ -265,8 +263,7 @@
 
 void machine_power_off_smp(void)
 {
-        smp_call_function(do_machine_power_off, NULL, 0, 0);
-	do_machine_power_off(NULL);
+        on_each_cpu(do_machine_power_off, NULL, 0, 0);
 }
 
 /*
@@ -383,8 +380,10 @@
 	parms.end_ctl = cr;
 	parms.orvals[cr] = 1 << bit;
 	parms.andvals[cr] = -1L;
+	preempt_disable();
 	smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         __ctl_set_bit(cr, bit);
+	preempt_enable();
 }
 
 /*
@@ -397,8 +396,10 @@
 	parms.end_ctl = cr;
 	parms.orvals[cr] = 0;
 	parms.andvals[cr] = ~(1L << bit);
+	preempt_disable();
 	smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         __ctl_clear_bit(cr, bit);
+	preempt_enable();
 }
 
 
diff -Nru a/arch/s390x/kernel/time.c b/arch/s390x/kernel/time.c
--- a/arch/s390x/kernel/time.c	Tue Mar  4 19:30:13 2003
+++ b/arch/s390x/kernel/time.c	Tue Mar  4 19:30:13 2003
@@ -45,7 +45,7 @@
 
 #define TICK_SIZE tick
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static ext_int_info_t ext_int_info_timer;
 static uint64_t xtime_cc;
diff -Nru a/arch/sh/kernel/fpu.c b/arch/sh/kernel/fpu.c
--- a/arch/sh/kernel/fpu.c	Tue Mar  4 19:30:09 2003
+++ b/arch/sh/kernel/fpu.c	Tue Mar  4 19:30:09 2003
@@ -118,7 +118,7 @@
 
 /*
  * Load the FPU with signalling NANS.  This bit pattern we're using
- * has the property that no matter wether considered as single or as
+ * has the property that no matter whether considered as single or as
  * double precission represents signaling NANS.  
  */
 
diff -Nru a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
--- a/arch/sh/kernel/irq.c	Tue Mar  4 19:30:07 2003
+++ b/arch/sh/kernel/irq.c	Tue Mar  4 19:30:07 2003
@@ -61,7 +61,7 @@
 {
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves, it doesnt deserve
+ * each architecture has to answer this themselves, it doesn't deserve
  * a generic callback i think.
  */
 	printk("unexpected IRQ trap at vector %02x\n", irq);
diff -Nru a/arch/sh/kernel/pci-dma.c b/arch/sh/kernel/pci-dma.c
--- a/arch/sh/kernel/pci-dma.c	Tue Mar  4 19:30:12 2003
+++ b/arch/sh/kernel/pci-dma.c	Tue Mar  4 19:30:12 2003
@@ -24,7 +24,7 @@
 	ret = (void *) __get_free_pages(gfp, get_order(size));
 
 	if (ret != NULL) {
-	        /* Is it neccessary to do the memset? */
+	        /* Is it necessary to do the memset? */
 		memset(ret, 0, size);
 		*dma_handle = virt_to_bus(ret);
 	}
diff -Nru a/arch/sh/kernel/pci-sh7751.c b/arch/sh/kernel/pci-sh7751.c
--- a/arch/sh/kernel/pci-sh7751.c	Tue Mar  4 19:30:11 2003
+++ b/arch/sh/kernel/pci-sh7751.c	Tue Mar  4 19:30:11 2003
@@ -285,7 +285,7 @@
 	struct pci_ops *bios = NULL;
 	struct pci_ops *dir = NULL;
 
-	PCIDBG(1,"PCI: Starting intialization.\n");
+	PCIDBG(1,"PCI: Starting initialization.\n");
 #ifdef CONFIG_PCI_BIOS
 	if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) {
 		pci_probe |= PCI_BIOS_SORT;
diff -Nru a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
--- a/arch/sh/kernel/time.c	Tue Mar  4 19:30:03 2003
+++ b/arch/sh/kernel/time.c	Tue Mar  4 19:30:03 2003
@@ -70,7 +70,7 @@
 #endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */
 #endif /* __sh3__ or __SH4__ */
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 extern unsigned long wall_jiffies;
 #define TICK_SIZE tick
diff -Nru a/arch/sh/stboards/pcidma.c b/arch/sh/stboards/pcidma.c
--- a/arch/sh/stboards/pcidma.c	Tue Mar  4 19:30:08 2003
+++ b/arch/sh/stboards/pcidma.c	Tue Mar  4 19:30:08 2003
@@ -24,7 +24,7 @@
 	ret = (void *) __get_free_pages(gfp, get_order(size));
 
 	if (ret != NULL) {
-	        /* Is it neccessary to do the memset? */
+	        /* Is it necessary to do the memset? */
 		memset(ret, 0, size);
 		*dma_handle = virt_to_bus(ret);
 	}
diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig
--- a/arch/sparc/Kconfig	Tue Mar  4 19:30:03 2003
+++ b/arch/sparc/Kconfig	Tue Mar  4 19:30:03 2003
@@ -148,7 +148,7 @@
 config MCA
 	bool
 	help
-	  EISA is not supported.
+	  MCA is not supported.
 	  Say N
 
 config PCMCIA
diff -Nru a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c
--- a/arch/sparc/kernel/init_task.c	Tue Mar  4 19:30:10 2003
+++ b/arch/sparc/kernel/init_task.c	Tue Mar  4 19:30:10 2003
@@ -12,7 +12,7 @@
 struct mm_struct init_mm = INIT_MM(init_mm);
 struct task_struct init_task = INIT_TASK(init_task);
 
-/* .text section in head.S is aligned at 8k boundry and this gets linked
+/* .text section in head.S is aligned at 8k boundary and this gets linked
  * right after that so that the init_thread_union is aligned properly as well.
  * If this is not aligned on a 8k boundry, then you should change code
  * in etrap.S which assumes it.
diff -Nru a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
--- a/arch/sparc/kernel/ioport.c	Tue Mar  4 19:30:14 2003
+++ b/arch/sparc/kernel/ioport.c	Tue Mar  4 19:30:14 2003
@@ -599,7 +599,7 @@
  * must match what was provided for in a previous pci_map_single call.  All
  * other usages are undefined.
  *
- * After this call, reads by the cpu to the buffer are guarenteed to see
+ * After this call, reads by the cpu to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
 void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size,
diff -Nru a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
--- a/arch/sparc/kernel/time.c	Tue Mar  4 19:30:09 2003
+++ b/arch/sparc/kernel/time.c	Tue Mar  4 19:30:09 2003
@@ -45,7 +45,7 @@
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 enum sparc_clock_type sp_clock_typ;
diff -Nru a/arch/sparc/lib/blockops.S b/arch/sparc/lib/blockops.S
--- a/arch/sparc/lib/blockops.S	Tue Mar  4 19:30:14 2003
+++ b/arch/sparc/lib/blockops.S	Tue Mar  4 19:30:14 2003
@@ -38,7 +38,7 @@
 	 * and (2 * PAGE_SIZE) (for kernel stacks)
 	 * and with a second arg of zero.  We assume in
 	 * all of these cases that the buffer is aligned
-	 * on at least an 8 byte boundry.
+	 * on at least an 8 byte boundary.
 	 *
 	 * Therefore we special case them to make them
 	 * as fast as possible.
diff -Nru a/arch/sparc/lib/checksum.S b/arch/sparc/lib/checksum.S
--- a/arch/sparc/lib/checksum.S	Tue Mar  4 19:30:10 2003
+++ b/arch/sparc/lib/checksum.S	Tue Mar  4 19:30:10 2003
@@ -336,7 +336,7 @@
 	bne	cc_dword_align		! yes, we check for short lengths there
 	 andcc	%g1, 0xffffff80, %g0	! can we use unrolled loop?
 3:	be	3f			! nope, less than one loop remains
-	 andcc	%o1, 4, %g0		! dest aligned on 4 or 8 byte boundry?
+	 andcc	%o1, 4, %g0		! dest aligned on 4 or 8 byte boundary?
 	be	ccdbl + 4		! 8 byte aligned, kick ass
 5:	CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x00,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
 	CSUMCOPY_BIGCHUNK(%o0,%o1,%g7,0x20,%o4,%o5,%g2,%g3,%g4,%g5,%o2,%o3)
diff -Nru a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
--- a/arch/sparc/mm/iommu.c	Tue Mar  4 19:30:14 2003
+++ b/arch/sparc/mm/iommu.c	Tue Mar  4 19:30:14 2003
@@ -112,7 +112,7 @@
 	for (i = 6; i < 9; i++)
 		if ((1 << (i + PAGE_SHIFT)) == ptsize)
 			break;
-        tmp = __get_free_pages(GFP_DMA, i);
+        tmp = __get_free_pages(GFP_KERNEL, i);
 	if (!tmp) {
 		prom_printf("Could not allocate iopte of size 0x%08x\n", ptsize);
 		prom_halt();
diff -Nru a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
--- a/arch/sparc/mm/srmmu.c	Tue Mar  4 19:30:10 2003
+++ b/arch/sparc/mm/srmmu.c	Tue Mar  4 19:30:10 2003
@@ -2120,7 +2120,7 @@
 	srmmu_is_bad();
 }
 
-/* dont laugh, static pagetables */
+/* don't laugh, static pagetables */
 static void srmmu_check_pgt_cache(int low, int high)
 {
 }
diff -Nru a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
--- a/arch/sparc/mm/sun4c.c	Tue Mar  4 19:30:12 2003
+++ b/arch/sparc/mm/sun4c.c	Tue Mar  4 19:30:12 2003
@@ -533,7 +533,7 @@
 	}
 }
 
-/* Addr is always aligned on a page boundry for us already. */
+/* Addr is always aligned on a page boundary for us already. */
 static void sun4c_map_dma_area(unsigned long va, u32 addr, int len)
 {
 	unsigned long page, end;
@@ -1042,7 +1042,7 @@
 		get_locked_segment(addr);
 
 	/* We are changing the virtual color of the page(s)
-	 * so we must flush the cache to guarentee consistency.
+	 * so we must flush the cache to guarantee consistency.
 	 */
 	sun4c_flush_page(pages);
 #ifndef CONFIG_SUN4	
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Tue Mar  4 19:30:13 2003
+++ b/arch/sparc64/Kconfig	Tue Mar  4 19:30:13 2003
@@ -150,18 +150,6 @@
 
 	  If in doubt, say N.
 
-config CPU_FREQ_PROC_INTF
-	tristate "/proc/cpufreq interface (DEPRECATED)"
-	depends on CPU_FREQ && PROC_FS
-	help
-	  This enables the /proc/cpufreq interface for controlling
-	  CPUFreq. Please note that it is recommended to use the sysfs
-	  interface instead (which is built automatically). 
-	  
-	  For details, take a look at linux/Documentation/cpufreq. 
-	  
-	  If in doubt, say N.
-
 config CPU_FREQ_TABLE
        tristate
        default y
@@ -176,6 +164,8 @@
 	  For details, take a look at linux/Documentation/cpufreq. 
 
 	  If in doubt, say N.
+
+source "drivers/cpufreq/Kconfig"
 
 # Identify this as a Sparc64 build
 config SPARC64
diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig
--- a/arch/sparc64/defconfig	Tue Mar  4 19:30:05 2003
+++ b/arch/sparc64/defconfig	Tue Mar  4 19:30:05 2003
@@ -15,12 +15,6 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-# CONFIG_LOG_BUF_SHIFT_17 is not set
-# CONFIG_LOG_BUF_SHIFT_16 is not set
-CONFIG_LOG_BUF_SHIFT_15=y
-# CONFIG_LOG_BUF_SHIFT_14 is not set
-# CONFIG_LOG_BUF_SHIFT_13 is not set
-# CONFIG_LOG_BUF_SHIFT_12 is not set
 CONFIG_LOG_BUF_SHIFT=15
 
 #
@@ -30,6 +24,7 @@
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
 CONFIG_KMOD=y
 
 #
@@ -45,6 +40,7 @@
 CONFIG_NR_CPUS=4
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_PROC_INTF=y
+CONFIG_CPU_FREQ_TABLE=y
 CONFIG_US3_FREQ=m
 CONFIG_SPARC64=y
 CONFIG_HOTPLUG=y
@@ -89,15 +85,52 @@
 #
 # Graphics support
 #
-# CONFIG_FB is not set
+CONFIG_FB=y
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_BW2 is not set
+# CONFIG_FB_CG3 is not set
+CONFIG_FB_CG6=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_PM3 is not set
+CONFIG_FB_SBUS=y
+CONFIG_FB_FFB=y
+# CONFIG_FB_TCX is not set
+# CONFIG_FB_CG14 is not set
+# CONFIG_FB_P9100 is not set
+# CONFIG_FB_LEO is not set
+# CONFIG_FB_PCI is not set
+# CONFIG_FB_VIRTUAL is not set
 
 #
 # Console display driver support
 #
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_MDA_CONSOLE is not set
-CONFIG_PROM_CONSOLE=y
+# CONFIG_PROM_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_PCI_CONSOLE=y
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FONT_SUN8x16=y
+# CONFIG_FONT_SUN12x22 is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
 
 #
 # Serial drivers
@@ -110,7 +143,7 @@
 CONFIG_SERIAL_SUNCORE=y
 CONFIG_SERIAL_SUNZILOG=y
 CONFIG_SERIAL_SUNSU=y
-# CONFIG_SERIAL_SUNSAB is not set
+CONFIG_SERIAL_SUNSAB=m
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 
@@ -190,7 +223,7 @@
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
-CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
@@ -198,7 +231,7 @@
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
-CONFIG_BLK_DEV_NS87415=y
+# CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -221,9 +254,9 @@
 #
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
-CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_ST=m
 CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_SR_EXTRA_DEVS=2
 CONFIG_CHR_DEV_SG=m
@@ -320,11 +353,12 @@
 CONFIG_INET_ESP=y
 CONFIG_XFRM_USER=m
 CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
 
 #
 # SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
+CONFIG_IPV6_SCTP__=m
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_ADLER32 is not set
 # CONFIG_SCTP_DBG_MSG is not set
@@ -395,6 +429,7 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
 CONFIG_SUNLANCE=y
 CONFIG_HAPPYMEAL=y
 CONFIG_SUNBMAC=m
@@ -402,6 +437,7 @@
 CONFIG_SUNGEM=y
 CONFIG_NET_VENDOR_3COM=y
 CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
 
 #
 # Tulip family network device support
@@ -419,9 +455,11 @@
 CONFIG_PCNET32=m
 # CONFIG_AMD8111_ETH is not set
 CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
 CONFIG_B44=m
 CONFIG_DGRS=m
 CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
 CONFIG_E100=m
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
@@ -940,6 +978,7 @@
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_BCSP_TXCRC=y
 CONFIG_BT_HCIVHCI=m
 
 #
diff -Nru a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
--- a/arch/sparc64/kernel/Makefile	Tue Mar  4 19:30:05 2003
+++ b/arch/sparc64/kernel/Makefile	Tue Mar  4 19:30:05 2003
@@ -3,7 +3,7 @@
 #
 
 EXTRA_AFLAGS := -ansi
-CFLAGS += -Werror
+EXTRA_CFLAGS := -Werror
 
 EXTRA_TARGETS	:= head.o init_task.o
 
diff -Nru a/arch/sparc64/kernel/init_task.c b/arch/sparc64/kernel/init_task.c
--- a/arch/sparc64/kernel/init_task.c	Tue Mar  4 19:30:14 2003
+++ b/arch/sparc64/kernel/init_task.c	Tue Mar  4 19:30:14 2003
@@ -12,7 +12,7 @@
 static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
-/* .text section in head.S is aligned at 2 page boundry and this gets linked
+/* .text section in head.S is aligned at 2 page boundary and this gets linked
  * right after that so that the init_thread_union is aligned properly as well.
  * We really don't need this special alignment like the Intel does, but
  * I do it anyways for completeness.
diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
--- a/arch/sparc64/kernel/ioctl32.c	Tue Mar  4 19:30:13 2003
+++ b/arch/sparc64/kernel/ioctl32.c	Tue Mar  4 19:30:13 2003
@@ -3947,7 +3947,7 @@
  *
  *	But how to keep track of these kernel buffers?  We'd need to either
  *	keep track of them in some table _or_ know about usbdevicefs internals
- *	(ie. the exact layout of it's file private, which is actually defined
+ *	(ie. the exact layout of its file private, which is actually defined
  *	in linux/usbdevice_fs.h, the layout of the async queues are private to
  *	devio.c)
  *
diff -Nru a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h
--- a/arch/sparc64/kernel/iommu_common.h	Tue Mar  4 19:30:14 2003
+++ b/arch/sparc64/kernel/iommu_common.h	Tue Mar  4 19:30:14 2003
@@ -40,7 +40,7 @@
 
 /* Two addresses are "virtually contiguous" if and only if:
  * 1) They are equal, or...
- * 2) They are both on a page boundry
+ * 2) They are both on a page boundary
  */
 #define VCONTIG(__X, __Y)	(((__X) == (__Y)) || \
 				 (((__X) | (__Y)) << (64UL - PAGE_SHIFT)) == 0UL)
diff -Nru a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
--- a/arch/sparc64/kernel/pci_common.c	Tue Mar  4 19:30:05 2003
+++ b/arch/sparc64/kernel/pci_common.c	Tue Mar  4 19:30:05 2003
@@ -583,7 +583,7 @@
 	 * the PBM.
 	 *
 	 * However if that parent bridge has interrupt map/mask
-	 * properties of it's own we use the PROM register property
+	 * properties of its own we use the PROM register property
 	 * of the next child device on the path to PDEV.
 	 *
 	 * In detail the two cases are (note that the 'X' below is the
diff -Nru a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
--- a/arch/sparc64/kernel/sbus.c	Tue Mar  4 19:30:14 2003
+++ b/arch/sparc64/kernel/sbus.c	Tue Mar  4 19:30:14 2003
@@ -24,7 +24,7 @@
 #include "iommu_common.h"
 
 /* These should be allocated on an SMP_CACHE_BYTES
- * aligned boundry for optimal performance.
+ * aligned boundary for optimal performance.
  *
  * On SYSIO, using an 8K page size we have 1GB of SBUS
  * DMA space mapped.  We divide this space into equally
diff -Nru a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
--- a/arch/sparc64/kernel/setup.c	Tue Mar  4 19:30:07 2003
+++ b/arch/sparc64/kernel/setup.c	Tue Mar  4 19:30:07 2003
@@ -688,6 +688,7 @@
 	sparc64_cpus = kmalloc(NR_CPUS * sizeof(struct cpu), GFP_KERNEL);
 	if (!sparc64_cpus)
 		return -ENOMEM;
+	memset(sparc64_cpus, 0, NR_CPUS * sizeof(struct cpu));
 	for (i = 0; i < NR_CPUS; i++) {
 		if (cpu_possible(i))
 			register_cpu(&sparc64_cpus[i], i, NULL);
diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c	Tue Mar  4 19:30:13 2003
+++ b/arch/sparc64/kernel/sparc64_ksyms.c	Tue Mar  4 19:30:13 2003
@@ -114,6 +114,8 @@
 extern unsigned long phys_base;
 extern unsigned long pfn_base;
 
+extern unsigned int sys_call_table[];
+
 /* used by various drivers */
 #ifdef CONFIG_SMP
 #ifndef CONFIG_DEBUG_SPINLOCK
@@ -374,3 +376,6 @@
 
 /* for ns8703 */
 EXPORT_SYMBOL(ns87303_lock);
+
+/* for solaris compat module */
+EXPORT_SYMBOL_GPL(sys_call_table);
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c	Tue Mar  4 19:30:08 2003
+++ b/arch/sparc64/kernel/time.c	Tue Mar  4 19:30:08 2003
@@ -47,7 +47,7 @@
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 static unsigned long mstk48t08_regs = 0UL;
 static unsigned long mstk48t59_regs = 0UL;
diff -Nru a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
--- a/arch/sparc64/kernel/traps.c	Tue Mar  4 19:30:14 2003
+++ b/arch/sparc64/kernel/traps.c	Tue Mar  4 19:30:14 2003
@@ -571,7 +571,7 @@
 	unsigned long flush_linesize = ecache_flush_linesize;
 	unsigned long flush_size = ecache_flush_size;
 
-	/* Run through the whole cache to guarentee the timed loop
+	/* Run through the whole cache to guarantee the timed loop
 	 * is really displacing cache lines.
 	 */
 	__asm__ __volatile__("1: subcc	%0, %4, %0\n\t"
diff -Nru a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
--- a/arch/sparc64/kernel/us3_cpufreq.c	Tue Mar  4 19:30:04 2003
+++ b/arch/sparc64/kernel/us3_cpufreq.c	Tue Mar  4 19:30:04 2003
@@ -186,12 +186,16 @@
 	set_cpus_allowed(current, cpus_allowed);
 }
 
-static int us3freq_setpolicy(struct cpufreq_policy *policy)
+static int us3freq_target(struct cpufreq_policy *policy,
+			  unsigned int target_freq,
+			  unsigned int relation)
 {
 	unsigned int new_index = 0;
 
-	if (cpufreq_frequency_table_setpolicy(policy,
+	if (cpufreq_frequency_table_target(policy,
 					      &us3_freq_table[policy->cpu].table[0],
+					      target_freq,
+					      relation,
 					      &new_index))
 		return -EINVAL;
 
@@ -224,6 +228,7 @@
 
 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = 0;
+	policy->cur = clock_tick;
 
 	return cpufreq_frequency_table_cpuinfo(policy, table);
 }
@@ -268,7 +273,7 @@
 		       (NR_CPUS * sizeof(struct us3_freq_percpu_info)));
 
 		driver->verify = us3freq_verify;
-		driver->setpolicy = us3freq_setpolicy;
+		driver->target = us3freq_target;
 		driver->init = us3freq_cpu_init;
 		driver->exit = us3freq_cpu_exit;
 		strcpy(driver->name, "UltraSPARC-III");
diff -Nru a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
--- a/arch/sparc64/lib/Makefile	Tue Mar  4 19:30:04 2003
+++ b/arch/sparc64/lib/Makefile	Tue Mar  4 19:30:04 2003
@@ -3,7 +3,7 @@
 #
 
 EXTRA_AFLAGS := -ansi
-CFLAGS += -Werror
+EXTRA_CFLAGS := -Werror
 
 L_TARGET = lib.a
 obj-y := PeeCeeI.o blockops.o debuglocks.o strlen.o strncmp.o \
diff -Nru a/arch/sparc64/lib/U3copy_from_user.S b/arch/sparc64/lib/U3copy_from_user.S
--- a/arch/sparc64/lib/U3copy_from_user.S	Tue Mar  4 19:30:05 2003
+++ b/arch/sparc64/lib/U3copy_from_user.S	Tue Mar  4 19:30:05 2003
@@ -416,7 +416,7 @@
 
 2:	VISEntryHalf					! MS+MS
 
-	/* Compute (len - (len % 8)) into %g2.  This is guarenteed
+	/* Compute (len - (len % 8)) into %g2.  This is guaranteed
 	 * to be nonzero.
 	 */
 	andn		%o2, 0x7, %g2			! A0	Group
@@ -425,7 +425,7 @@
 	 * one 8-byte longword past the end of src.  It actually
 	 * does not, as %g2 is subtracted as loads are done from
 	 * src, so we always stop before running off the end.
-	 * Also, we are guarenteed to have at least 0x10 bytes
+	 * Also, we are guaranteed to have at least 0x10 bytes
 	 * to move here.
 	 */
 	sub		%g2, 0x8, %g2			! A0	Group (reg-dep)
diff -Nru a/arch/sparc64/lib/U3copy_in_user.S b/arch/sparc64/lib/U3copy_in_user.S
--- a/arch/sparc64/lib/U3copy_in_user.S	Tue Mar  4 19:30:07 2003
+++ b/arch/sparc64/lib/U3copy_in_user.S	Tue Mar  4 19:30:07 2003
@@ -447,7 +447,7 @@
 
 2:	VISEntryHalf					! MS+MS
 
-	/* Compute (len - (len % 8)) into %g2.  This is guarenteed
+	/* Compute (len - (len % 8)) into %g2.  This is guaranteed
 	 * to be nonzero.
 	 */
 	andn		%o2, 0x7, %g2			! A0	Group
@@ -456,7 +456,7 @@
 	 * one 8-byte longword past the end of src.  It actually
 	 * does not, as %g2 is subtracted as loads are done from
 	 * src, so we always stop before running off the end.
-	 * Also, we are guarenteed to have at least 0x10 bytes
+	 * Also, we are guaranteed to have at least 0x10 bytes
 	 * to move here.
 	 */
 	sub		%g2, 0x8, %g2			! A0	Group (reg-dep)
diff -Nru a/arch/sparc64/lib/U3copy_to_user.S b/arch/sparc64/lib/U3copy_to_user.S
--- a/arch/sparc64/lib/U3copy_to_user.S	Tue Mar  4 19:30:03 2003
+++ b/arch/sparc64/lib/U3copy_to_user.S	Tue Mar  4 19:30:03 2003
@@ -463,7 +463,7 @@
 
 2:	VISEntryHalf					! MS+MS
 
-	/* Compute (len - (len % 8)) into %g2.  This is guarenteed
+	/* Compute (len - (len % 8)) into %g2.  This is guaranteed
 	 * to be nonzero.
 	 */
 	andn		%o2, 0x7, %g2			! A0	Group
@@ -472,7 +472,7 @@
 	 * one 8-byte longword past the end of src.  It actually
 	 * does not, as %g2 is subtracted as loads are done from
 	 * src, so we always stop before running off the end.
-	 * Also, we are guarenteed to have at least 0x10 bytes
+	 * Also, we are guaranteed to have at least 0x10 bytes
 	 * to move here.
 	 */
 	sub		%g2, 0x8, %g2			! A0	Group (reg-dep)
diff -Nru a/arch/sparc64/lib/U3memcpy.S b/arch/sparc64/lib/U3memcpy.S
--- a/arch/sparc64/lib/U3memcpy.S	Tue Mar  4 19:30:14 2003
+++ b/arch/sparc64/lib/U3memcpy.S	Tue Mar  4 19:30:14 2003
@@ -344,7 +344,7 @@
 
 2:	VISEntryHalf					! MS+MS
 
-	/* Compute (len - (len % 8)) into %g2.  This is guarenteed
+	/* Compute (len - (len % 8)) into %g2.  This is guaranteed
 	 * to be nonzero.
 	 */
 	andn		%o2, 0x7, %g2			! A0	Group
@@ -353,7 +353,7 @@
 	 * one 8-byte longword past the end of src.  It actually
 	 * does not, as %g2 is subtracted as loads are done from
 	 * src, so we always stop before running off the end.
-	 * Also, we are guarenteed to have at least 0x10 bytes
+	 * Also, we are guaranteed to have at least 0x10 bytes
 	 * to move here.
 	 */
 	sub		%g2, 0x8, %g2			! A0	Group (reg-dep)
diff -Nru a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile
--- a/arch/sparc64/mm/Makefile	Tue Mar  4 19:30:12 2003
+++ b/arch/sparc64/mm/Makefile	Tue Mar  4 19:30:12 2003
@@ -3,7 +3,7 @@
 #
 
 EXTRA_AFLAGS := -ansi
-CFLAGS += -Werror
+EXTRA_CFLAGS := -Werror
 
 obj-y    := ultra.o fault.o init.o generic.o extable.o
 
diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
--- a/arch/sparc64/mm/hugetlbpage.c	Tue Mar  4 19:30:11 2003
+++ b/arch/sparc64/mm/hugetlbpage.c	Tue Mar  4 19:30:11 2003
@@ -25,6 +25,7 @@
 extern long htlbpagemem;
 
 static void zap_hugetlb_resources(struct vm_area_struct *);
+void free_huge_page(struct page *page);
 
 #define MAX_ID 	32
 struct htlbpagekey {
@@ -64,6 +65,7 @@
 	spin_unlock(&htlbpage_lock);
 
 	set_page_count(page, 1);
+	page->lru.prev = (void *)free_huge_page;
 	memset(page_address(page), 0, HPAGE_SIZE);
 
 	return page;
diff -Nru a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile
--- a/arch/sparc64/prom/Makefile	Tue Mar  4 19:30:13 2003
+++ b/arch/sparc64/prom/Makefile	Tue Mar  4 19:30:13 2003
@@ -4,7 +4,7 @@
 #
 
 EXTRA_AFLAGS := -ansi
-CFLAGS += -Werror
+EXTRA_CFLAGS := -Werror
 
 L_TARGET = lib.a
 obj-y   := bootstr.o devops.o init.o memory.o misc.o \
diff -Nru a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
--- a/arch/sparc64/prom/misc.c	Tue Mar  4 19:30:12 2003
+++ b/arch/sparc64/prom/misc.c	Tue Mar  4 19:30:12 2003
@@ -142,7 +142,7 @@
 	return prom_prev;
 }
 
-/* Install Linux trap table so PROM uses that instead of it's own. */
+/* Install Linux trap table so PROM uses that instead of its own. */
 void prom_set_trap_table(unsigned long tba)
 {
 	p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba);
diff -Nru a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
--- a/arch/sparc64/solaris/entry64.S	Tue Mar  4 19:30:03 2003
+++ b/arch/sparc64/solaris/entry64.S	Tue Mar  4 19:30:03 2003
@@ -16,6 +16,7 @@
 #include <asm/signal.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
+#include <asm/thread_info.h>
 
 #include "conv.h"
 
diff -Nru a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
--- a/arch/um/kernel/irq.c	Tue Mar  4 19:30:12 2003
+++ b/arch/um/kernel/irq.c	Tue Mar  4 19:30:12 2003
@@ -45,7 +45,7 @@
 {
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves, it doesnt deserve
+ * each architecture has to answer this themselves, it doesn't deserve
  * a generic callback i think.
  */
 #if CONFIG_X86
diff -Nru a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c
--- a/arch/v850/kernel/irq.c	Tue Mar  4 19:30:12 2003
+++ b/arch/v850/kernel/irq.c	Tue Mar  4 19:30:12 2003
@@ -48,7 +48,7 @@
 {
 	/*
 	 * 'what should we do if we get a hw irq event on an illegal vector'.
-	 * each architecture has to answer this themselves, it doesnt deserve
+	 * each architecture has to answer this themselves, it doesn't deserve
 	 * a generic callback i think.
 	 */
 	printk("received IRQ %d with unknown interrupt type\n", irq);
diff -Nru a/arch/v850/kernel/ma.c b/arch/v850/kernel/ma.c
--- a/arch/v850/kernel/ma.c	Tue Mar  4 19:30:04 2003
+++ b/arch/v850/kernel/ma.c	Tue Mar  4 19:30:04 2003
@@ -61,7 +61,7 @@
 	   specific chips may have more).  */
 	if (chan < 2) {
 		unsigned bits = 0x3 << (chan * 3);
-		/* Specify that the relevent pins on the chip should do
+		/* Specify that the relevant pins on the chip should do
 		   serial I/O, not direct I/O.  */
 		MA_PORT4_PMC |= bits;
 		/* Specify that we're using the UART, not the CSI device.  */
diff -Nru a/arch/v850/kernel/rte_cb_multi.c b/arch/v850/kernel/rte_cb_multi.c
--- a/arch/v850/kernel/rte_cb_multi.c	Tue Mar  4 19:30:05 2003
+++ b/arch/v850/kernel/rte_cb_multi.c	Tue Mar  4 19:30:05 2003
@@ -67,7 +67,7 @@
 
 			if ((word & 0xFC0) == 0x780) {
 				/* A `jr' insn, fix up its offset (and yes, the
-				   wierd half-word swapping is intentional). */
+				   weird half-word swapping is intentional). */
 				unsigned short hi = word & 0xFFFF;
 				unsigned short lo = word >> 16;
 				unsigned long udisp22
diff -Nru a/arch/v850/kernel/rte_ma1_cb.c b/arch/v850/kernel/rte_ma1_cb.c
--- a/arch/v850/kernel/rte_ma1_cb.c	Tue Mar  4 19:30:12 2003
+++ b/arch/v850/kernel/rte_ma1_cb.c	Tue Mar  4 19:30:12 2003
@@ -93,7 +93,7 @@
 		/* Turn on the timer.  */
 		NB85E_TIMER_C_TMCC0 (tc) |= NB85E_TIMER_C_TMCC0_CAE;
 
-	/* Make sure the relevent port0/port1 pins are assigned
+	/* Make sure the relevant port0/port1 pins are assigned
 	   interrupt duty.  We used INTP001-INTP011 (don't screw with
 	   INTP000 because the monitor uses it).  */
 	MA_PORT0_PMC |= 0x4;	/* P02 (INTP001) in IRQ mode.  */
diff -Nru a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
--- a/arch/v850/kernel/time.c	Tue Mar  4 19:30:11 2003
+++ b/arch/v850/kernel/time.c	Tue Mar  4 19:30:11 2003
@@ -25,7 +25,7 @@
 
 #include "mach.h"
 
-u64 jiffies_64;
+u64 jiffies_64 = INITIAL_JIFFIES;
 
 #define TICK_SIZE	(tick_nsec / 1000)
 
diff -Nru a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
--- a/arch/x86_64/ia32/ia32_ioctl.c	Tue Mar  4 19:30:09 2003
+++ b/arch/x86_64/ia32/ia32_ioctl.c	Tue Mar  4 19:30:09 2003
@@ -3196,7 +3196,7 @@
  *
  *	But how to keep track of these kernel buffers?  We'd need to either
  *	keep track of them in some table _or_ know about usbdevicefs internals
- *	(ie. the exact layout of it's file private, which is actually defined
+ *	(ie. the exact layout of its file private, which is actually defined
  *	in linux/usbdevice_fs.h, the layout of the async queues are private to
  *	devio.c)
  *
diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
--- a/arch/x86_64/kernel/apic.c	Tue Mar  4 19:30:04 2003
+++ b/arch/x86_64/kernel/apic.c	Tue Mar  4 19:30:04 2003
@@ -292,7 +292,7 @@
 		__error_in_apic_c();
 
 	/*
-	 * Double-check wether this APIC is really registered.
+	 * Double-check whether this APIC is really registered.
 	 * This is meaningless in clustered apic mode, so we skip it.
 	 */
 	if (!clustered_apic_mode && 
@@ -948,7 +948,7 @@
 /*
  * Local APIC timer interrupt. This is the most natural way for doing
  * local interrupts, but local timer interrupts can be emulated by
- * broadcast interrupts too. [in case the hw doesnt support APIC timers]
+ * broadcast interrupts too. [in case the hw doesn't support APIC timers]
  *
  * [ if a single-CPU system runs an SMP kernel then we call the local
  *   interrupt as well. Thus we cannot inline the local irq ... ]
diff -Nru a/arch/x86_64/kernel/bluesmoke.c b/arch/x86_64/kernel/bluesmoke.c
--- a/arch/x86_64/kernel/bluesmoke.c	Tue Mar  4 19:30:13 2003
+++ b/arch/x86_64/kernel/bluesmoke.c	Tue Mar  4 19:30:13 2003
@@ -111,16 +111,12 @@
 {
 	u32 low, high;
 	int i;
-	unsigned int *cpu = info;
 
-	BUG_ON (*cpu != smp_processor_id());
-
-	preempt_disable();
 	for (i=0; i<banks; i++) {
 		rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
 
 		if ((low | high) != 0) {
-			printk (KERN_EMERG "MCE: The hardware reports a non fatal, correctable incident occured on CPU %d.\n", smp_processor_id());
+			printk (KERN_EMERG "MCE: The hardware reports a non fatal, correctable incident occurred on CPU %d.\n", smp_processor_id());
 			printk (KERN_EMERG "Bank %d: %08x%08x\n", i, high, low);
 
 			/* Scrub the error so we don't pick it up in MCE_RATE seconds time. */
@@ -130,20 +126,12 @@
 			wmb();
 		}
 	}
-	preempt_enable();
 }
 
 
 static void mce_timerfunc (unsigned long data)
 {
-	unsigned int i;
-
-	for (i=0; i<smp_num_cpus; i++) {
-		if (i == smp_processor_id())
-			mce_checkregs(&i);
-		else
-			smp_call_function (mce_checkregs, &i, 1, 1);
-	}
+	on_each_cpu (mce_checkregs, NULL, 1, 1);
 
 	/* Refresh the timer. */
 	mce_timer.expires = jiffies + MCE_RATE;
diff -Nru a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
--- a/arch/x86_64/kernel/e820.c	Tue Mar  4 19:30:05 2003
+++ b/arch/x86_64/kernel/e820.c	Tue Mar  4 19:30:05 2003
@@ -204,7 +204,7 @@
 		request_resource(&iomem_resource, res);
 		if (e820.map[i].type == E820_RAM) {
 			/*
-			 *  We dont't know which RAM region contains kernel data,
+			 *  We don't know which RAM region contains kernel data,
 			 *  so we try it repeatedly and let the resource manager
 			 *  test it.
 			 */
diff -Nru a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
--- a/arch/x86_64/kernel/io_apic.c	Tue Mar  4 19:30:09 2003
+++ b/arch/x86_64/kernel/io_apic.c	Tue Mar  4 19:30:09 2003
@@ -685,7 +685,7 @@
 	entry.vector = vector;
 
 	/*
-	 * The timer IRQ doesnt have to know that behind the
+	 * The timer IRQ doesn't have to know that behind the
 	 * scene we have a 8259A-master in AEOI mode ...
 	 */
 	irq_desc[0].handler = &ioapic_edge_irq_type;
@@ -928,8 +928,7 @@
 
 void print_all_local_APICs (void)
 {
-	smp_call_function(print_local_APIC, NULL, 1, 1);
-	print_local_APIC(NULL);
+	on_each_cpu(print_local_APIC, NULL, 1, 1);
 }
 
 void /*__init*/ print_PIC(void)
@@ -1539,7 +1538,7 @@
 	printk(" failed.\n");
 
 	if (nmi_watchdog) {
-		printk(KERN_WARNING "timer doesnt work through the IO-APIC - disabling NMI Watchdog!\n");
+		printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
 		nmi_watchdog = 0;
 	}
 
diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c	Tue Mar  4 19:30:08 2003
+++ b/arch/x86_64/kernel/irq.c	Tue Mar  4 19:30:08 2003
@@ -87,7 +87,7 @@
 {
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves, it doesnt deserve
+ * each architecture has to answer this themselves, it doesn't deserve
  * a generic callback i think.
  */
 #if CONFIG_X86
diff -Nru a/arch/x86_64/kernel/ldt.c b/arch/x86_64/kernel/ldt.c
--- a/arch/x86_64/kernel/ldt.c	Tue Mar  4 19:30:13 2003
+++ b/arch/x86_64/kernel/ldt.c	Tue Mar  4 19:30:13 2003
@@ -60,12 +60,14 @@
 	pc->size = mincount;
 	wmb();
 	if (reload) {
-		load_LDT(pc);
 #ifdef CONFIG_SMP
 		preempt_disable();
+		load_LDT(pc);
 		if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
 			smp_call_function(flush_ldt, 0, 1, 1);
 		preempt_enable();
+#else
+		load_LDT(pc);
 #endif
 	}
 	if (oldsize) {
diff -Nru a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
--- a/arch/x86_64/kernel/nmi.c	Tue Mar  4 19:30:08 2003
+++ b/arch/x86_64/kernel/nmi.c	Tue Mar  4 19:30:08 2003
@@ -228,7 +228,7 @@
  * as these watchdog NMI IRQs are generated on every CPU, we only
  * have to check the current processor.
  *
- * since NMIs dont listen to _any_ locks, we have to be extremely
+ * since NMIs don't listen to _any_ locks, we have to be extremely
  * careful not to rely on unsafe variables. The printk might lock
  * up though, so we have to break up any console locks first ...
  * [when there will be more tty-related locks, break them up
diff -Nru a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
--- a/arch/x86_64/kernel/pci-gart.c	Tue Mar  4 19:30:08 2003
+++ b/arch/x86_64/kernel/pci-gart.c	Tue Mar  4 19:30:08 2003
@@ -437,6 +437,7 @@
 	}
 	flush_gart(); 
 	
+	global_flush_tlb();
 		
 	printk("PCI-DMA: aperture base @ %x size %u KB\n", aper_base, aper_size>>10); 
 	return 0;
diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c	Tue Mar  4 19:30:05 2003
+++ b/arch/x86_64/kernel/smp.c	Tue Mar  4 19:30:05 2003
@@ -328,7 +328,7 @@
 	preempt_enable();
 }
 
-static inline void do_flush_tlb_all_local(void)
+static void do_flush_tlb_all(void* info)
 {
 	unsigned long cpu = smp_processor_id();
 
@@ -337,18 +337,9 @@
 		leave_mm(cpu);
 }
 
-static void flush_tlb_all_ipi(void* info)
-{
-	do_flush_tlb_all_local();
-}
-
 void flush_tlb_all(void)
 {
-	preempt_disable();
-	smp_call_function (flush_tlb_all_ipi,0,1,1);
-
-	do_flush_tlb_all_local();
-	preempt_enable();
+	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
 }
 
 void smp_kdb_stop(void)
diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
--- a/arch/x86_64/kernel/smpboot.c	Tue Mar  4 19:30:14 2003
+++ b/arch/x86_64/kernel/smpboot.c	Tue Mar  4 19:30:14 2003
@@ -104,7 +104,7 @@
 /*
  * TSC synchronization.
  *
- * We first check wether all CPUs have their TSC's synchronized,
+ * We first check whether all CPUs have their TSC's synchronized,
  * then we print a warning if not, and always resync.
  */
 
@@ -774,7 +774,7 @@
 	}
 
 	/*
-	 * If we couldnt find an SMP configuration at boot time,
+	 * If we couldn't find an SMP configuration at boot time,
 	 * get out of here now!
 	 */
 	if (!smp_found_config) {
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c	Tue Mar  4 19:30:11 2003
+++ b/arch/x86_64/kernel/time.c	Tue Mar  4 19:30:11 2003
@@ -30,7 +30,7 @@
 #include <asm/apic.h>
 #endif
 
-u64 jiffies_64; 
+u64 jiffies_64;
 
 extern int using_apic_timer;
 
diff -Nru a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
--- a/arch/x86_64/mm/ioremap.c	Tue Mar  4 19:30:13 2003
+++ b/arch/x86_64/mm/ioremap.c	Tue Mar  4 19:30:13 2003
@@ -205,6 +205,7 @@
 			iounmap(p); 
 			p = NULL;
 		}
+		global_flush_tlb();
 	} 
 
 	return p;					
@@ -226,6 +227,7 @@
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
 				 p->size >> PAGE_SHIFT,
 				 PAGE_KERNEL); 				 
+		global_flush_tlb();
 	} 
 	kfree(p); 
 }
diff -Nru a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
--- a/arch/x86_64/mm/pageattr.c	Tue Mar  4 19:30:08 2003
+++ b/arch/x86_64/mm/pageattr.c	Tue Mar  4 19:30:08 2003
@@ -123,12 +123,7 @@
 
 static inline void flush_map(unsigned long address)
 {	
-	preempt_disable();
-#ifdef CONFIG_SMP 
-	smp_call_function(flush_kernel_map, (void *)address, 1, 1);
-#endif	
-	flush_kernel_map((void *)address);
-	preempt_enable();
+	on_each_cpu(flush_kernel_map, (void *)address, 1, 1);
 }
 
 struct deferred_page { 
diff -Nru a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
--- a/drivers/acorn/block/fd1772.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/acorn/block/fd1772.c	Tue Mar  4 19:30:05 2003
@@ -1081,7 +1081,7 @@
 		MotorOn = 1;
 		START_TIMEOUT();
 		/* we must wait for the IRQ here, because the ST-DMA is
-		 * released immediatly afterwards and the interrupt may be
+		 * released immediately afterwards and the interrupt may be
 		 * delivered to the wrong driver.
 		 */
 	}
diff -Nru a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
--- a/drivers/acorn/block/mfmhd.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/acorn/block/mfmhd.c	Tue Mar  4 19:30:05 2003
@@ -406,7 +406,7 @@
 
 	outw(command, MFM_COMMAND);
 	status = inw(MFM_STATUS);
-	DBG("issue_command: status immediatly after command issue: %02X:\n ", status >> 8);
+	DBG("issue_command: status immediately after command issue: %02X:\n ", status >> 8);
 }
 
 static void wait_for_completion(void)
@@ -451,7 +451,7 @@
 		return;
 	};
 
-	/* OK so what ever happend its not an error, now I reckon we are left between
+	/* OK so what ever happened it's not an error, now I reckon we are left between
 	   a choice of command end or some data which is ready to be collected */
 	/* I think we have to transfer data while the interrupt line is on and its
 	   not any other type of interrupt */
diff -Nru a/drivers/acorn/net/ether3.c b/drivers/acorn/net/ether3.c
--- a/drivers/acorn/net/ether3.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/acorn/net/ether3.c	Tue Mar  4 19:30:14 2003
@@ -101,7 +101,7 @@
 
 /*
  * ether3 read/write.  Slow things down a bit...
- * The SEEQ8005 doesn't like us writing to it's registers
+ * The SEEQ8005 doesn't like us writing to its registers
  * too quickly.
  */
 static inline void ether3_outb(int v, const int r)
@@ -304,7 +304,7 @@
 	/*
 	 * There is a problem with the NQ8005 in that it occasionally loses the
 	 * last two bytes.  To get round this problem, we receive the CRC as
-	 * well.  That way, if we do loose the last two, then it doesn't matter.
+	 * well.  That way, if we do lose the last two, then it doesn't matter.
 	 */
 	ether3_outw(priv->regs.config1 | CFG1_TRANSEND, REG_CONFIG1);
 	ether3_outw((TX_END>>8) - 1, REG_BUFWIN);
diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	Tue Mar  4 19:30:14 2003
+++ b/drivers/acpi/Kconfig	Tue Mar  4 19:30:14 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 -Nru a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c
--- a/drivers/acpi/acpi_ksyms.c	Tue Mar  4 19:30:06 2003
+++ b/drivers/acpi/acpi_ksyms.c	Tue Mar  4 19:30:06 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 -Nru a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
--- a/drivers/acpi/dispatcher/dsobject.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/acpi/dispatcher/dsobject.c	Tue Mar  4 19:30:04 2003
@@ -396,7 +396,7 @@
 		return_ACPI_STATUS (status);
 	}
 
-	/* Re-type the object according to it's argument */
+	/* Re-type the object according to its argument */
 
 	node->type = ACPI_GET_OBJECT_TYPE (obj_desc);
 
diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/acpi/ec.c	Tue Mar  4 19:30:09 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 -Nru a/drivers/acpi/events/Makefile b/drivers/acpi/events/Makefile
--- a/drivers/acpi/events/Makefile	Tue Mar  4 19:30:03 2003
+++ b/drivers/acpi/events/Makefile	Tue Mar  4 19:30:03 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 -Nru a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
--- a/drivers/acpi/events/evevent.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/acpi/events/evevent.c	Tue Mar  4 19:30:13 2003
@@ -79,7 +79,7 @@
 
 	/*
 	 * Initialize the Fixed and General Purpose acpi_events prior. This is
-	 * done prior to enabling SCIs to prevent interrupts from occuring
+	 * done prior to enabling SCIs to prevent interrupts from occurring
 	 * before handers are installed.
 	 */
 	status = acpi_ev_fixed_event_initialize ();
@@ -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
  *
  ******************************************************************************/
 
@@ -130,16 +130,6 @@
 	if (ACPI_FAILURE (status)) {
 		ACPI_REPORT_ERROR ((
 				"Unable to install System Control Interrupt Handler, %s\n",
-				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);
 	}
diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
--- a/drivers/acpi/events/evgpe.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/acpi/events/evgpe.c	Tue Mar  4 19:30:10 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 -Nru a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/events/evgpeblk.c	Tue Mar  4 19:30:14 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 -Nru a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
--- a/drivers/acpi/events/evmisc.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/acpi/events/evmisc.c	Tue Mar  4 19:30:10 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 -Nru a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
--- a/drivers/acpi/events/evrgnini.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/acpi/events/evrgnini.c	Tue Mar  4 19:30:04 2003
@@ -410,7 +410,7 @@
  *              Get the appropriate address space handler for a newly
  *              created region.
  *
- *              This also performs address space specific intialization.  For
+ *              This also performs address space specific initialization.  For
  *              example, PCI regions must have an _ADR object that contains
  *              a PCI address in the scope of the definition.  This address is
  *              required to perform an access to PCI config space.
diff -Nru a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
--- a/drivers/acpi/events/evsci.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/acpi/events/evsci.c	Tue Mar  4 19:30:11 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 -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
--- a/drivers/acpi/events/evxface.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/acpi/events/evxface.c	Tue Mar  4 19:30:10 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 -Nru a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
--- a/drivers/acpi/events/evxfevnt.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/acpi/events/evxfevnt.c	Tue Mar  4 19:30:05 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);
 		}
 
@@ -463,4 +471,5 @@
 
 	return_ACPI_STATUS (status);
 }
+
 
diff -Nru a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
--- a/drivers/acpi/hardware/hwgpe.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/acpi/hardware/hwgpe.c	Tue Mar  4 19:30:04 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 -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
--- a/drivers/acpi/hardware/hwregs.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/acpi/hardware/hwregs.c	Tue Mar  4 19:30:13 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:
@@ -370,7 +373,7 @@
 
 		/*
 		 * Status Registers are different from the rest.  Clear by
-		 * writing 1, writing 0 has no effect.  So, the only relevent
+		 * writing 1, writing 0 has no effect.  So, the only relevant
 		 * information is the single bit we're interested in, all others should
 		 * be written as 0 so they will be left unchanged
 		 */
diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
--- a/drivers/acpi/hardware/hwsleep.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/acpi/hardware/hwsleep.c	Tue Mar  4 19:30:04 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,13 +327,58 @@
 
 	} 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);
 	}
 
 	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);
+}
+
 
 /******************************************************************************
  *
diff -Nru a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
--- a/drivers/acpi/hardware/hwtimer.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/acpi/hardware/hwtimer.c	Tue Mar  4 19:30:04 2003
@@ -133,7 +133,7 @@
  *              transitions (unlike many CPU timestamp counters) -- making it
  *              a versatile and accurate timer.
  *
- *              Note that this function accomodates only a single timer
+ *              Note that this function accommodates only a single timer
  *              rollover.  Thus for 24-bit timers, this function should only
  *              be used for calculating durations less than ~4.6 seconds
  *              (~20 minutes for 32-bit timers) -- calculations below
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/acpi/osl.c	Tue Mar  4 19:30:12 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,15 +541,40 @@
 			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*/
diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
--- a/drivers/acpi/pci_link.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/acpi/pci_link.c	Tue Mar  4 19:30:04 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 -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c
--- a/drivers/acpi/power.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/acpi/power.c	Tue Mar  4 19:30:09 2003
@@ -351,7 +351,7 @@
 
 	/*
 	 * First we reference all power resources required in the target list
-	 * (e.g. so the device doesn't loose power while transitioning).
+	 * (e.g. so the device doesn't lose power while transitioning).
 	 */
 	for (i=0; i<tl->count; i++) {
 		result = acpi_power_on(tl->handles[i]);
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/acpi/processor.c	Tue Mar  4 19:30:11 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 -Nru a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
--- a/drivers/acpi/resources/rsmemory.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/acpi/resources/rsmemory.c	Tue Mar  4 19:30:13 2003
@@ -278,7 +278,7 @@
 	/*
 	 *  Point to the place in the output buffer where the data portion will
 	 *  begin.
-	 *  1. Set the RESOURCE_DATA * Data to point to it's own address, then
+	 *  1. Set the RESOURCE_DATA * Data to point to its own address, then
 	 *  2. Set the pointer to the next address.
 	 *
 	 *  NOTE: output_struct->Data is cast to u8, otherwise, this addition adds
diff -Nru a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
--- a/drivers/acpi/resources/rsutils.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/acpi/resources/rsutils.c	Tue Mar  4 19:30:04 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 -Nru a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
--- a/drivers/acpi/resources/rsxface.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/acpi/resources/rsxface.c	Tue Mar  4 19:30:11 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
@@ -251,4 +335,65 @@
 
 	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 -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
--- a/drivers/acpi/sleep/main.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/acpi/sleep/main.c	Tue Mar  4 19:30:03 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();
@@ -267,6 +284,10 @@
 		if (ACPI_SUCCESS(status)) {
 			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 -Nru a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
--- a/drivers/acpi/sleep/proc.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/acpi/sleep/proc.c	Tue Mar  4 19:30:11 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 -Nru a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
--- a/drivers/acpi/tables/tbconvrt.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/acpi/tables/tbconvrt.c	Tue Mar  4 19:30:07 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,14 +313,15 @@
 
 	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);
 	}
 }
+
 
 /*******************************************************************************
  *
diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c
--- a/drivers/acpi/tables.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/acpi/tables.c	Tue Mar  4 19:30:07 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 -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
--- a/drivers/acpi/utilities/utcopy.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/acpi/utilities/utcopy.c	Tue Mar  4 19:30:08 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 -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/acpi/utilities/utglobal.c	Tue Mar  4 19:30:04 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 -Nru a/drivers/atm/firestream.c b/drivers/atm/firestream.c
--- a/drivers/atm/firestream.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/atm/firestream.c	Tue Mar  4 19:30:04 2003
@@ -105,7 +105,7 @@
    The FS50 CAM (VP/VC match registers) always take the lowest channel
    number that matches. This is not a problem.
 
-   However, they also ignore wether the channel is enabled or
+   However, they also ignore whether the channel is enabled or
    not. This means that if you allocate channel 0 to 1.2 and then
    channel 1 to 0.0, then disabeling channel 0 and writing 0 to the
    match channel for channel 0 will "steal" the traffic from channel
diff -Nru a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
--- a/drivers/atm/fore200e.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/atm/fore200e.c	Tue Mar  4 19:30:14 2003
@@ -1132,8 +1132,7 @@
 	return;
     } 
 
-	do_gettimeofday(&vcc->timestamp);
-    skb->stamp = vcc->timestamp;
+    do_gettimeofday(&skb->stamp);
     
 #ifdef FORE200E_52BYTE_AAL0_SDU
     if (cell_header) {
diff -Nru a/drivers/atm/horizon.c b/drivers/atm/horizon.c
--- a/drivers/atm/horizon.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/atm/horizon.c	Tue Mar  4 19:30:03 2003
@@ -2874,11 +2874,7 @@
 	// writes to adapter memory (handles IRQ and SMP)
 	spin_lock_init (&dev->mem_lock);
 	
-#if LINUX_VERSION_CODE >= 0x20303
 	init_waitqueue_head (&dev->tx_queue);
-#else
-	dev->tx_queue = 0;
-#endif
 	
 	// vpi in 0..4, vci in 6..10
 	dev->atm_dev->ci_range.vpi_bits = vpi_bits;
diff -Nru a/drivers/atm/horizon.h b/drivers/atm/horizon.h
--- a/drivers/atm/horizon.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/atm/horizon.h	Tue Mar  4 19:30:13 2003
@@ -422,11 +422,7 @@
   unsigned int        tx_regions; // number of remaining regions
 
   spinlock_t          mem_lock;
-#if LINUX_VERSION_CODE >= 0x20303
   wait_queue_head_t   tx_queue;
-#else
-  struct wait_queue * tx_queue;
-#endif
 
   u8                  irq;
   long		      flags;
diff -Nru a/drivers/atm/iphase.c b/drivers/atm/iphase.c
--- a/drivers/atm/iphase.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/atm/iphase.c	Tue Mar  4 19:30:13 2003
@@ -436,7 +436,7 @@
        if (crm == 0) crm = 1;
        f_abr_vc->f_crm = crm & 0xff;
        f_abr_vc->f_pcr = cellrate_to_float(srv_p->pcr);
-       icr = MIN( srv_p->icr, (srv_p->tbe > srv_p->frtt) ?
+       icr = min( srv_p->icr, (srv_p->tbe > srv_p->frtt) ?
 				((srv_p->tbe/srv_p->frtt)*1000000) :
 				(1000000/(srv_p->frtt/srv_p->tbe)));
        f_abr_vc->f_icr = cellrate_to_float(icr);
@@ -2071,7 +2071,7 @@
 		- UBR Table size is 4K  
 		- UBR wait queue is 4K  
 	   since the table and wait queues are contiguous, all the bytes   
-	   can be intialized by one memeset.  
+	   can be initialized by one memeset.  
 	*/  
         
         vcsize_sel = 0;
diff -Nru a/drivers/atm/iphase.h b/drivers/atm/iphase.h
--- a/drivers/atm/iphase.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/atm/iphase.h	Tue Mar  4 19:30:05 2003
@@ -808,7 +808,6 @@
 } r_vc_abr_entry;   
 
 #define MRM 3
-#define MIN(x,y)	((x) < (y)) ? (x) : (y)
 
 typedef struct srv_cls_param {
         u32 class_type;         /* CBR/VBR/ABR/UBR; use the enum above */
@@ -1017,13 +1016,8 @@
         spinlock_t            tx_lock;
         IARTN_Q               tx_return_q;
         u32                   close_pending;
-#if LINUX_VERSION_CODE >= 0x20303
         wait_queue_head_t    close_wait;
         wait_queue_head_t    timeout_wait;
-#else
-        struct wait_queue     *close_wait;
-        struct wait_queue     *timeout_wait;
-#endif
 	struct cpcs_trailer_desc *tx_buf;
         u16 num_tx_desc, tx_buf_sz, rate_limit;
         u32 tx_cell_cnt, tx_pkt_cnt;
diff -Nru a/drivers/atm/lanai.c b/drivers/atm/lanai.c
--- a/drivers/atm/lanai.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/atm/lanai.c	Tue Mar  4 19:30:05 2003
@@ -1300,7 +1300,7 @@
 #define DESCRIPTOR_AAL5_STREAM	(0x00004000)
 #define DESCRIPTOR_CLP		(0x00002000)
 
-/* Add 32-bit descriptor with it's padding */
+/* Add 32-bit descriptor with its padding */
 static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,
 	u32 flags, int len)
 {
diff -Nru a/drivers/atm/suni.c b/drivers/atm/suni.c
--- a/drivers/atm/suni.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/atm/suni.c	Tue Mar  4 19:30:12 2003
@@ -233,8 +233,6 @@
 	if (!(PRIV(dev) = kmalloc(sizeof(struct suni_priv),GFP_KERNEL)))
 		return -ENOMEM;
 
-	MOD_INC_USE_COUNT;
-
 	PRIV(dev)->dev = dev;
 	spin_lock_irqsave(&sunis_lock,flags);
 	first = !sunis;
@@ -280,7 +278,6 @@
 	spin_unlock_irqrestore(&sunis_lock,flags);
 	kfree(PRIV(dev));
 
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -293,7 +290,7 @@
 };
 
 
-int __init suni_init(struct atm_dev *dev)
+int suni_init(struct atm_dev *dev)
 {
 	unsigned char mri;
 
diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile
--- a/drivers/base/Makefile	Tue Mar  4 19:30:13 2003
+++ b/drivers/base/Makefile	Tue Mar  4 19:30:13 2003
@@ -2,7 +2,7 @@
 
 obj-y			:= core.o sys.o interface.o power.o bus.o \
 			   driver.o class.o intf.o platform.o \
-			   cpu.o firmware.o
+			   cpu.o firmware.o init.o
 obj-$(CONFIG_NUMA)	+= node.o  memblk.o
 obj-y			+= fs/
 obj-$(CONFIG_HOTPLUG)	+= hotplug.o
diff -Nru a/drivers/base/base.h b/drivers/base/base.h
--- a/drivers/base/base.h	Tue Mar  4 19:30:07 2003
+++ b/drivers/base/base.h	Tue Mar  4 19:30:07 2003
@@ -1,6 +1,7 @@
 #undef DEBUG
 
 extern struct semaphore device_sem;
+extern struct semaphore devclass_sem;
 
 extern int bus_add_device(struct device * dev);
 extern void bus_remove_device(struct device * dev);
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/base/bus.c	Tue Mar  4 19:30:05 2003
@@ -459,7 +459,7 @@
  *	@drv:	driver.
  *
  *	Detach the driver from the devices it controls, and remove
- *	it from it's bus's list of drivers. Finally, we drop the reference
+ *	it from its bus's list of drivers. Finally, we drop the reference
  *	to the bus we took in bus_add_driver().
  */
 
@@ -544,12 +544,11 @@
 	subsystem_unregister(&bus->subsys);
 }
 
-static int __init bus_subsys_init(void)
+int __init buses_init(void)
 {
 	return subsystem_register(&bus_subsys);
 }
 
-core_initcall(bus_subsys_init);
 
 EXPORT_SYMBOL(bus_for_each_dev);
 EXPORT_SYMBOL(bus_for_each_drv);
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/base/class.c	Tue Mar  4 19:30:14 2003
@@ -13,6 +13,8 @@
 #define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr)
 #define to_class(obj) container_of(obj,struct device_class,subsys.kset.kobj)
 
+DECLARE_MUTEX(devclass_sem);
+
 static ssize_t
 devclass_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
 {
@@ -163,29 +165,34 @@
 	struct device_class * cls;
 	int error = 0;
 
+	down(&devclass_sem);
 	if (dev->driver) {
 		cls = get_devclass(dev->driver->devclass);
-		if (cls) {
-			down_write(&cls->subsys.rwsem);
-			pr_debug("device class %s: adding device %s\n",
-				 cls->name,dev->name);
-			if (cls->add_device) 
-				error = cls->add_device(dev);
-			if (!error) {
-				enum_device(cls,dev);
-				interface_add_dev(dev);
-			}
-
-			list_add_tail(&dev->class_list,&cls->devices.list);
-
-			/* notify userspace (call /sbin/hotplug) */
-			class_hotplug (dev, "add");
-
-			up_write(&cls->subsys.rwsem);
-			if (error)
-				put_devclass(cls);
+
+		if (!cls)
+			goto Done;
+
+		pr_debug("device class %s: adding device %s\n",
+			 cls->name,dev->name);
+		if (cls->add_device) 
+			error = cls->add_device(dev);
+		if (error) {
+			put_devclass(cls);
+			goto Done;
 		}
+
+		down_write(&cls->subsys.rwsem);
+		enum_device(cls,dev);
+		list_add_tail(&dev->class_list,&cls->devices.list);
+		/* notify userspace (call /sbin/hotplug) */
+		class_hotplug (dev, "add");
+
+		up_write(&cls->subsys.rwsem);
+
+		interface_add_dev(dev);
 	}
+ Done:
+	up(&devclass_sem);
 	return error;
 }
 
@@ -193,26 +200,33 @@
 {
 	struct device_class * cls;
 
+	down(&devclass_sem);
 	if (dev->driver) {
 		cls = dev->driver->devclass;
-		if (cls) {
-			down_write(&cls->subsys.rwsem);
-			pr_debug("device class %s: removing device %s\n",
-				 cls->name,dev->name);
-			interface_remove_dev(dev);
-			unenum_device(cls,dev);
-
-			list_del(&dev->class_list);
-
-			/* notify userspace (call /sbin/hotplug) */
-			class_hotplug (dev, "remove");
-
-			if (cls->remove_device)
-				cls->remove_device(dev);
-			up_write(&cls->subsys.rwsem);
-			put_devclass(cls);
-		}
+		if (!cls) 
+			goto Done;
+
+		interface_remove_dev(dev);
+
+		down_write(&cls->subsys.rwsem);
+		pr_debug("device class %s: removing device %s\n",
+			 cls->name,dev->name);
+
+		unenum_device(cls,dev);
+
+		list_del(&dev->class_list);
+
+		/* notify userspace (call /sbin/hotplug) */
+		class_hotplug (dev, "remove");
+
+		up_write(&cls->subsys.rwsem);
+
+		if (cls->remove_device)
+			cls->remove_device(dev);
+		put_devclass(cls);
 	}
+ Done:
+	up(&devclass_sem);
 }
 
 struct device_class * get_devclass(struct device_class * cls)
@@ -252,12 +266,10 @@
 	subsystem_unregister(&cls->subsys);
 }
 
-static int __init class_subsys_init(void)
+int __init classes_init(void)
 {
 	return subsystem_register(&class_subsys);
 }
-
-core_initcall(class_subsys_init);
 
 EXPORT_SYMBOL(devclass_create_file);
 EXPORT_SYMBOL(devclass_remove_file);
diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/base/core.c	Tue Mar  4 19:30:04 2003
@@ -143,7 +143,6 @@
 	INIT_LIST_HEAD(&dev->driver_list);
 	INIT_LIST_HEAD(&dev->bus_list);
 	INIT_LIST_HEAD(&dev->class_list);
-	INIT_LIST_HEAD(&dev->intf_list);
 }
 
 /**
@@ -310,12 +309,10 @@
 	put_device(dev);
 }
 
-static int __init device_subsys_init(void)
+int __init devices_init(void)
 {
 	return subsystem_register(&devices_subsys);
 }
-
-core_initcall(device_subsys_init);
 
 EXPORT_SYMBOL(device_initialize);
 EXPORT_SYMBOL(device_add);
diff -Nru a/drivers/base/cpu.c b/drivers/base/cpu.c
--- a/drivers/base/cpu.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/base/cpu.c	Tue Mar  4 19:30:05 2003
@@ -46,9 +46,8 @@
 }
 
 
-static int __init register_cpu_type(void)
+int __init cpu_dev_init(void)
 {
 	devclass_register(&cpu_devclass);
 	return driver_register(&cpu_driver);
 }
-postcore_initcall(register_cpu_type);
diff -Nru a/drivers/base/firmware.c b/drivers/base/firmware.c
--- a/drivers/base/firmware.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/base/firmware.c	Tue Mar  4 19:30:09 2003
@@ -19,12 +19,10 @@
 	subsystem_unregister(s);
 }
 
-static int __init firmware_init(void)
+int __init firmware_init(void)
 {
 	return subsystem_register(&firmware_subsys);
 }
-
-core_initcall(firmware_init);
 
 EXPORT_SYMBOL(firmware_register);
 EXPORT_SYMBOL(firmware_unregister);
diff -Nru a/drivers/base/hotplug.c b/drivers/base/hotplug.c
--- a/drivers/base/hotplug.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/base/hotplug.c	Tue Mar  4 19:30:03 2003
@@ -17,6 +17,8 @@
 #include <linux/err.h>
 #include <linux/kmod.h>
 #include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/string.h>
 #include "base.h"
 #include "fs/fs.h"
 
diff -Nru a/drivers/base/init.c b/drivers/base/init.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/init.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,34 @@
+
+#include <linux/device.h>
+#include <linux/init.h>
+
+extern int devices_init(void);
+extern int buses_init(void);
+extern int classes_init(void);
+extern int firmware_init(void);
+extern int platform_bus_init(void);
+extern int sys_bus_init(void);
+extern int cpu_dev_init(void);
+
+/**
+ *	driver_init - initialize driver model.
+ *
+ *	Call the driver model init functions to initialize their
+ *	subsystems. Called early from init/main.c.
+ */
+
+void __init driver_init(void)
+{
+	/* These are the core pieces */
+	devices_init();
+	buses_init();
+	classes_init();
+	firmware_init();
+
+	/* These are also core pieces, but must come after the 
+	 * core core pieces.
+	 */
+	platform_bus_init();
+	sys_bus_init();
+	cpu_dev_init();
+}
diff -Nru a/drivers/base/intf.c b/drivers/base/intf.c
--- a/drivers/base/intf.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/base/intf.c	Tue Mar  4 19:30:13 2003
@@ -12,80 +12,31 @@
 
 #define to_intf(node) container_of(node,struct device_interface,kset.kobj.entry)
 
-#define to_data(e) container_of(e,struct intf_data,kobj.entry)
+#define to_dev(d) container_of(d,struct device,class_list)
 
 /**
  *	intf_dev_link - create sysfs symlink for interface.
- *	@data:	interface data descriptor.
+ *	@intf:	interface.
+ *	@dev:	device.
  *
  *	Create a symlink 'phys' in the interface's directory to 
  */
 
-static int intf_dev_link(struct intf_data * data)
+static int intf_dev_link(struct device_interface * intf, struct device * dev)
 {
-	char	name[16];
-	snprintf(name,16,"%d",data->intf_num);
-	return sysfs_create_link(&data->intf->kset.kobj,&data->dev->kobj,name);
+	return sysfs_create_link(&intf->kset.kobj,&dev->kobj,dev->bus_id);
 }
 
 /**
  *	intf_dev_unlink - remove symlink for interface.
- *	@intf:	interface data descriptor.
- *
- */
-
-static void intf_dev_unlink(struct intf_data * data)
-{
-	char	name[16];
-	snprintf(name,16,"%d",data->intf_num);
-	sysfs_remove_link(&data->intf->kset.kobj,name);
-}
-
-
-/**
- *	interface_add_data - attach data descriptor
- *	@data:	interface data descriptor.
- *
- *	This attaches the per-instance interface object to the
- *	interface (by registering its kobject) and the device
- *	itself (by inserting it into the device's list).
- *
- *	Note that there is no explicit protection done in this
- *	function. This should be called from the interface's 
- *	add_device() method, which is called under the protection
- *	of the class's rwsem.
- */
-
-int interface_add_data(struct intf_data * data)
-{
-	struct device_interface * intf = data->intf;
-
-	if (intf) {
-		data->intf_num = intf->devnum++;
-		data->kobj.kset = &intf->kset;
-		kobject_register(&data->kobj);
-
-		list_add_tail(&data->dev_entry,&data->dev->intf_list);
-		return intf_dev_link(data);
-	}
-	return -EINVAL;
-}
-
-
-/**
- *	interface_remove_data - detach data descriptor.
- *	@data:	interface data descriptor.
+ *	@intf:	interface.
+ *	@dev:	device.
  *
- *	This detaches the per-instance data descriptor by removing 
- *	it from the device's list and unregistering the kobject from
- *	the subsystem.
  */
 
-void interface_remove_data(struct intf_data * data)
+static void intf_dev_unlink(struct device_interface * intf, struct device * dev)
 {
-	intf_dev_unlink(data);
-	list_del_init(&data->dev_entry);
-	kobject_unregister(&data->kobj);
+	sysfs_remove_link(&intf->kset.kobj,dev->bus_id);
 }
 
 
@@ -103,33 +54,28 @@
 {
 	int error = 0;
 
-	if (intf->add_device) 
-		error = intf->add_device(dev);
+	if (intf->add_device) {
+		if (!(error = intf->add_device(dev)))
+			intf_dev_link(intf,dev);
+	}
 	pr_debug(" -> %s (%d)\n",dev->bus_id,error);
 	return error;
 }
 
 /**
  *	del - detach device from interface.
- *	@data:	interface data descriptor.
- *
- *	Another simple helper. Remove the data descriptor from 
- *	the device and the interface, then call the interface's 
- *	remove_device() method.
+ *	@intf:	interface.
+ *	@dev:	device.
  */
 
-static void del(struct intf_data * data)
+static void del(struct device_interface * intf, struct device * dev)
 {
-	struct device_interface * intf = data->intf;
-
 	pr_debug(" -> %s ",intf->name);
-	interface_remove_data(data);
 	if (intf->remove_device)
-		intf->remove_device(data);
+		intf->remove_device(dev);
+	intf_dev_unlink(intf,dev);
 }
 
-#define to_dev(entry) container_of(entry,struct device,class_list)
-
 
 /**
  *	add_intf - add class's devices to interface.
@@ -145,10 +91,8 @@
 	struct device_class * cls = intf->devclass;
 	struct list_head * entry;
 
-	down_write(&cls->subsys.rwsem);
 	list_for_each(entry,&cls->devices.list)
 		add(intf,to_dev(entry));
-	up_write(&cls->subsys.rwsem);
 }
 
 /**
@@ -164,6 +108,7 @@
 {
 	struct device_class * cls = get_devclass(intf->devclass);
 
+	down(&devclass_sem);
 	if (cls) {
 		pr_debug("register interface '%s' with class '%s'\n",
 			 intf->name,cls->name);
@@ -173,6 +118,7 @@
 		kset_register(&intf->kset);
 		add_intf(intf);
 	}
+	up(&devclass_sem);
 	return 0;
 }
 
@@ -188,14 +134,13 @@
 
 static void del_intf(struct device_interface * intf)
 {
+	struct device_class * cls = intf->devclass;
 	struct list_head * entry;
 
-	down_write(&intf->devclass->subsys.rwsem);
-	list_for_each(entry,&intf->kset.list) {
-		struct intf_data * data = to_data(entry);
-		del(data);
+	list_for_each(entry,&cls->devices.list) {
+		struct device * dev = to_dev(entry);
+		del(intf,dev);
 	}
-	up_write(&intf->devclass->subsys.rwsem);
 }
 
 /**
@@ -210,6 +155,8 @@
 void interface_unregister(struct device_interface * intf)
 {
 	struct device_class * cls = intf->devclass;
+
+	down(&devclass_sem);
 	if (cls) {
 		pr_debug("unregistering interface '%s' from class '%s'\n",
 			 intf->name,cls->name);
@@ -217,6 +164,7 @@
 		kset_unregister(&intf->kset);
 		put_devclass(cls);
 	}
+	up(&devclass_sem);
 }
 
 
@@ -255,20 +203,21 @@
  *	This is another helper for the class driver core, and called
  *	when the device is being removed from the class. 
  *	
- *	We iterate over the list of interface data descriptors attached
- *	to the device, and call del() [above] for each. Again, the 
- *	class's rwsem is assumed to be held during this.
+ *	We iterate over the list of the class's devices and call del() 
+ *	[above] for each. Again, the class's rwsem is _not_ held, but
+ *	the devclass_sem is (see class.c).
  */
 
 void interface_remove_dev(struct device * dev)
 {
 	struct list_head * entry, * next;
+	struct device_class * cls = dev->driver->devclass;
 
 	pr_debug("interfaces: removing device %s\n",dev->name);
 
-	list_for_each_safe(entry,next,&dev->intf_list) {
-		struct intf_data * intf_data = to_data(entry);
-		del(intf_data);
+	list_for_each_safe(entry,next,&cls->subsys.kset.list) {
+		struct device_interface * intf = to_intf(entry);
+		del(intf,dev);
 	}
 }
 
diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c
--- a/drivers/base/platform.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/base/platform.c	Tue Mar  4 19:30:04 2003
@@ -41,9 +41,29 @@
 	if (pdev)
 		device_unregister(&pdev->dev);
 }
-	
+
+
+/**
+ *	platform_match - bind platform device to platform driver.
+ *	@dev:	device.
+ *	@drv:	driver.
+ *
+ *	Platform device IDs are assumed to be encoded like this: 
+ *	"<name><instance>", where <name> is a short description of the 
+ *	type of device, like "pci" or "floppy", and <instance> is the 
+ *	enumerated instance of the device, like '0' or '42'.
+ *	Driver IDs are simply "<name>". 
+ *	So, extract the <name> from the device, and compare it against 
+ *	the name of the driver. Return whether they match or not.
+ */
+
 static int platform_match(struct device * dev, struct device_driver * drv)
 {
+	char name[BUS_ID_SIZE];
+
+	if (sscanf(dev->bus_id,"%s",name))
+		return (strcmp(name,drv->name) == 0);
+
 	return 0;
 }
 
@@ -52,13 +72,11 @@
 	.match		= platform_match,
 };
 
-static int __init platform_bus_init(void)
+int __init platform_bus_init(void)
 {
 	device_register(&legacy_bus);
 	return bus_register(&platform_bus_type);
 }
-
-postcore_initcall(platform_bus_init);
 
 EXPORT_SYMBOL(platform_device_register);
 EXPORT_SYMBOL(platform_device_unregister);
diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/base/sys.c	Tue Mar  4 19:30:03 2003
@@ -138,13 +138,12 @@
 	.name		= "system",
 };
 
-static int sys_bus_init(void)
+int __init sys_bus_init(void)
 {
 	bus_register(&system_bus_type);
 	return device_register(&system_bus);
 }
 
-postcore_initcall(sys_bus_init);
 EXPORT_SYMBOL(system_bus_type);
 EXPORT_SYMBOL(sys_device_register);
 EXPORT_SYMBOL(sys_device_unregister);
diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/block/cciss.c	Tue Mar  4 19:30:14 2003
@@ -87,7 +87,11 @@
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
-#define MAX_CONFIG_WAIT 1000 
+#define MAX_CONFIG_WAIT 30000 
+#define MAX_IOCTL_CONFIG_WAIT 1000
+
+/*define how many times we will try a command because of bus resets */
+#define MAX_CMD_RETRIES 3
 
 #define READ_AHEAD 	 128
 #define NR_CMDS		 384 /* #commands that can be outstanding */
@@ -116,7 +120,7 @@
 static void start_io( ctlr_info_t *h);
 static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
 	unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
-	unsigned char *scsi3addr);
+	unsigned char *scsi3addr, int cmd_type);
 
 #ifdef CONFIG_PROC_FS
 static int cciss_proc_get_info(char *buffer, char **start, off_t offset, 
@@ -351,7 +355,7 @@
 	if (ctlr >= MAX_CTLR || hba[ctlr] == NULL)
 		return -ENXIO;
 	/*
-	 * Root is allowed to open raw volume zero even if its not configured
+	 * Root is allowed to open raw volume zero even if it's not configured
 	 * so array config can still work.  I don't think I really like this,
 	 * but I'm already using way to many device nodes to claim another one
 	 * for "raw controller".
@@ -467,8 +471,7 @@
                         &(c->cfgtable->HostWrite.CoalIntCount));
 		writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
-		for(i=0;i<MAX_CONFIG_WAIT;i++)
-		{
+		for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
 			if (!(readl(c->vaddr + SA5_DOORBELL) 
 					& CFGTBL_ChangeReq))
 				break;
@@ -476,8 +479,8 @@
 			udelay(1000);
 		}	
 		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-		if (i >= MAX_CONFIG_WAIT)
-			return( -EFAULT);
+		if (i >= MAX_IOCTL_CONFIG_WAIT)
+			return -EAGAIN;
                 return(0);
         }
 	case CCISS_GETNODENAME:
@@ -514,8 +517,7 @@
 			
 		writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
-		for(i=0;i<MAX_CONFIG_WAIT;i++)
-		{
+		for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
 			if (!(readl(c->vaddr + SA5_DOORBELL) 
 					& CFGTBL_ChangeReq))
 				break;
@@ -523,8 +525,8 @@
 			udelay(1000);
 		}	
 		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-		if (i >= MAX_CONFIG_WAIT)
-			return( -EFAULT);
+		if (i >= MAX_IOCTL_CONFIG_WAIT)
+			return -EAGAIN;
                 return(0);
         }
 
@@ -575,6 +577,24 @@
 	case CCISS_REVALIDVOLS:
                 return( revalidate_allvol(inode->i_rdev));
 
+ 	case CCISS_GETLUNINFO: {
+ 		LogvolInfo_struct luninfo;
+ 		struct gendisk *disk = hba[ctlr]->gendisk[dsk];
+ 		drive_info_struct *drv = &hba[ctlr]->drv[dsk];
+ 		int i;
+ 		
+ 		luninfo.LunID = drv->LunID;
+ 		luninfo.num_opens = drv->usage_count;
+ 		luninfo.num_parts = 0;
+ 		/* count partitions 1 to 15 with sizes > 0 */
+ 		for(i=1; i <MAX_PART; i++)
+ 			if (disk->part[i].nr_sects != 0)
+ 				luninfo.num_parts++;
+ 		if (copy_to_user((void *) arg, &luninfo,
+ 				sizeof(LogvolInfo_struct)))
+ 			return -EFAULT;
+ 		return(0);
+ 	}
 	case CCISS_DEREGDISK:
 		return( deregister_disk(ctlr,dsk));
 
@@ -696,7 +716,153 @@
 		cmd_free(h, c, 0);
                 return(0);
 	} 
+	case CCISS_BIG_PASSTHRU: {
+		BIG_IOCTL_Command_struct *ioc;
+		ctlr_info_t *h = hba[ctlr];
+		CommandList_struct *c;
+		unsigned char **buff = NULL;
+		int	*buff_size = NULL;
+		u64bit	temp64;
+		unsigned long flags;
+		BYTE sg_used = 0;
+		int status = 0;
+		int i;
+		DECLARE_COMPLETION(wait);
+		__u32   left;
+		__u32	sz;
+		BYTE    *data_ptr;
 
+		if (!arg)
+			return -EINVAL;
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		ioc = (BIG_IOCTL_Command_struct *) 
+			kmalloc(sizeof(*ioc), GFP_KERNEL);
+		if (!ioc) {
+			status = -ENOMEM;
+			goto cleanup1;
+		}
+		if (copy_from_user(ioc, (void *) arg, sizeof(*ioc)))
+			return -EFAULT;
+		if ((ioc->buf_size < 1) &&
+			(ioc->Request.Type.Direction != XFER_NONE))
+				return -EINVAL;
+		/* Check kmalloc limits  using all SGs */
+		if (ioc->malloc_size > MAX_KMALLOC_SIZE)
+			return -EINVAL;
+		if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES)
+			return -EINVAL;
+		buff = (unsigned char **) kmalloc(MAXSGENTRIES * 
+				sizeof(char *), GFP_KERNEL);
+		if (!buff) {
+			status = -ENOMEM;
+			goto cleanup1;
+		}
+		memset(buff, 0, MAXSGENTRIES);
+		buff_size = (int *) kmalloc(MAXSGENTRIES * sizeof(int), 
+					GFP_KERNEL);
+		if (!buff_size) {
+			status = -ENOMEM;
+			goto cleanup1;
+		}
+		left = ioc->buf_size;
+		data_ptr = (BYTE *) ioc->buf;
+		while (left) {
+			sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
+			buff_size[sg_used] = sz;
+			buff[sg_used] = kmalloc(sz, GFP_KERNEL);
+			if (buff[sg_used] == NULL) {
+				status = -ENOMEM;
+				goto cleanup1;
+			}
+			if (ioc->Request.Type.Direction == XFER_WRITE &&
+				copy_from_user(buff[sg_used], data_ptr, sz)) {
+					status = -ENOMEM;
+					goto cleanup1;			
+			}
+			left -= sz;
+			data_ptr += sz;
+			sg_used++;
+		}
+		if ((c = cmd_alloc(h , 0)) == NULL) {
+			status = -ENOMEM;
+			goto cleanup1;	
+		}
+		c->cmd_type = CMD_IOCTL_PEND;
+		c->Header.ReplyQueue = 0;
+		
+		if( ioc->buf_size > 0) {
+			c->Header.SGList = sg_used;
+			c->Header.SGTotal= sg_used;
+		} else { 
+			c->Header.SGList = 0;
+			c->Header.SGTotal= 0;
+		}
+		c->Header.LUN = ioc->LUN_info;
+		c->Header.Tag.lower = c->busaddr;
+		
+		c->Request = ioc->Request;
+		if (ioc->buf_size > 0 ) {
+			int i;
+			for(i=0; i<sg_used; i++) {
+				temp64.val = pci_map_single( h->pdev, buff[i],
+					buff_size[i],
+					PCI_DMA_BIDIRECTIONAL);
+				c->SG[i].Addr.lower = temp64.val32.lower;
+				c->SG[i].Addr.upper = temp64.val32.upper;
+				c->SG[i].Len = buff_size[i];
+				c->SG[i].Ext = 0;  /* we are not chaining */
+			}
+		}
+		c->waiting = &wait;
+		/* Put the request on the tail of the request queue */
+		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
+		addQ(&h->reqQ, c);
+		h->Qdepth++;
+		start_io(h);
+		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+		wait_for_completion(&wait);
+		/* unlock the buffers from DMA */
+		for(i=0; i<sg_used; i++) {
+			temp64.val32.lower = c->SG[i].Addr.lower;
+			temp64.val32.upper = c->SG[i].Addr.upper;
+			pci_unmap_single( h->pdev, (dma_addr_t) temp64.val,
+				buff_size[i], PCI_DMA_BIDIRECTIONAL);
+		}
+		/* Copy the error information out */
+		ioc->error_info = *(c->err_info);
+		if (copy_to_user((void *) arg, ioc, sizeof(*ioc))) {
+			cmd_free(h, c, 0);
+			status = -EFAULT;
+			goto cleanup1;
+		}
+		if (ioc->Request.Type.Direction == XFER_READ) {
+			/* Copy the data out of the buffer we created */
+			BYTE *ptr = (BYTE  *) ioc->buf;
+	        	for(i=0; i< sg_used; i++) {
+				if (copy_to_user(ptr, buff[i], buff_size[i])) {
+					cmd_free(h, c, 0);
+					status = -EFAULT;
+					goto cleanup1;
+				}
+				ptr += buff_size[i];
+			}
+		}
+		cmd_free(h, c, 0);
+		status = 0;
+cleanup1:
+		if (buff) {
+			for(i=0; i<sg_used; i++)
+				if(buff[i] != NULL)
+					kfree(buff[i]);
+			kfree(buff);
+		}
+		if (buff_size)
+			kfree(buff_size);
+		if (ioc)
+			kfree(ioc);
+		return(status);
+	}
 	default:
 		return -EBADRQC;
 	}
@@ -816,113 +982,154 @@
 	h->drv[logvol].LunID = 0;
 	return(0);
 }
-static int sendcmd_withirq(__u8	cmd,
-	int	ctlr,
-	void	*buff,
-	size_t	size,
-	unsigned int use_unit_num,
-	unsigned int log_unit,
-	__u8	page_code )
+static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
+	size_t size,
+	unsigned int use_unit_num, /* 0: address the controller,
+				      1: address logical volume log_unit,
+				      2: periph device address is scsi3addr */
+	unsigned int log_unit, __u8 page_code, unsigned char *scsi3addr,
+	int cmd_type)
 {
-	ctlr_info_t *h = hba[ctlr];
-	CommandList_struct *c;
-	u64bit	buff_dma_handle;
-	unsigned long flags;
-	int return_status = IO_OK;
-	DECLARE_COMPLETION(wait);
-	
-	if ((c = cmd_alloc(h , 0)) == NULL)
-	{
-		return -ENOMEM;
-	}
-	// Fill in the command type 
+	ctlr_info_t *h= hba[ctlr];
+	u64bit buff_dma_handle;
+	int status = IO_OK;
+
 	c->cmd_type = CMD_IOCTL_PEND;
-	// Fill in Command Header 
-	c->Header.ReplyQueue = 0;  // unused in simple mode
-	if( buff != NULL) 	// buffer to fill 
-	{
+	c->Header.ReplyQueue = 0;
+	if( buff != NULL) {
 		c->Header.SGList = 1;
 		c->Header.SGTotal= 1;
-	} else	// no buffers to fill  
-	{
+	} else {
 		c->Header.SGList = 0;
                 c->Header.SGTotal= 0;
 	}
-	c->Header.Tag.lower = c->busaddr;  // use the kernel address the cmd block for tag
-	// Fill in Request block 	
-	switch(cmd)
-	{
+	c->Header.Tag.lower = c->busaddr;
+
+	c->Request.Type.Type = cmd_type;
+	if (cmd_type == TYPE_CMD) {
+		switch(cmd) {
 		case  CISS_INQUIRY:
 			/* If the logical unit number is 0 then, this is going
-				to controller so It's a physical command
-				mode = 0 target = 0.
-				So we have nothing to write. 
-				Otherwise 
-				mode = 1  target = LUNID
-			*/
-			if(use_unit_num != 0)
-			{
+			to controller so It's a physical command
+			mode = 0 target = 0.  So we have nothing to write.
+			otherwise, if use_unit_num == 1,
+			mode = 1(volume set addressing) target = LUNID
+			otherwise, if use_unit_num == 2,
+			mode = 0(periph dev addr) target = scsi3addr */
+			if (use_unit_num == 1) {
 				c->Header.LUN.LogDev.VolId=
-                                	hba[ctlr]->drv[log_unit].LunID;
+					h->drv[log_unit].LunID;
                         	c->Header.LUN.LogDev.Mode = 1;
+			} else if (use_unit_num == 2) {
+				memcpy(c->Header.LUN.LunAddrBytes,scsi3addr,8);
+				c->Header.LUN.LogDev.Mode = 0;
 			}
-			if(page_code != 0)
-			{
+			/* are we trying to read a vital product page */
+			if(page_code != 0) {
 				c->Request.CDB[1] = 0x01;
 				c->Request.CDB[2] = page_code;
 			}
 			c->Request.CDBLen = 6;
-			c->Request.Type.Type =  TYPE_CMD; // It is a command. 
 			c->Request.Type.Attribute = ATTR_SIMPLE;  
-			c->Request.Type.Direction = XFER_READ; // Read 
-			c->Request.Timeout = 0; // Don't time out 
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
 			c->Request.CDB[0] =  CISS_INQUIRY;
 			c->Request.CDB[4] = size  & 0xFF;  
 		break;
-	case CISS_REPORT_LOG:
+		case CISS_REPORT_LOG:
+		case CISS_REPORT_PHYS:
                         /* Talking to controller so It's a physical command
-                                mode = 00 target = 0.
-                                So we have nothing to write.
+			   mode = 00 target = 0.  Nothing to write.
                         */
-                        c->Request.CDBLen = 12;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE; 
-                        c->Request.Type.Direction = XFER_READ; // Read
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = CISS_REPORT_LOG;
-                        c->Request.CDB[6] = (size >> 24) & 0xFF;  //MSB
-                        c->Request.CDB[7] = (size >> 16) & 0xFF;
-                        c->Request.CDB[8] = (size >> 8) & 0xFF;
-                        c->Request.CDB[9] = size & 0xFF;
-                break;
-	case CCISS_READ_CAPACITY:
-			c->Header.LUN.LogDev.VolId= 
-				hba[ctlr]->drv[log_unit].LunID;
+			c->Request.CDBLen = 12;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = cmd;
+			c->Request.CDB[6] = (size >> 24) & 0xFF;  //MSB
+			c->Request.CDB[7] = (size >> 16) & 0xFF;
+			c->Request.CDB[8] = (size >> 8) & 0xFF;
+			c->Request.CDB[9] = size & 0xFF;
+			break;
+
+		case CCISS_READ_CAPACITY:
+			c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID;
 			c->Header.LUN.LogDev.Mode = 1;
 			c->Request.CDBLen = 10;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE; 
-                        c->Request.Type.Direction = XFER_READ; // Read
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = CCISS_READ_CAPACITY;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = cmd;
+		break;
+		case CCISS_CACHE_FLUSH:
+			c->Request.CDBLen = 12;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_WRITE;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = BMIC_WRITE;
+			c->Request.CDB[6] = BMIC_CACHE_FLUSH;
 		break;
 		default:
 			printk(KERN_WARNING
-				"cciss:  Unknown Command 0x%c sent attempted\n", cmd);
-			cmd_free(h, c, 1);
+				"cciss%d:  Unknown Command 0x%c\n", ctlr, cmd);
 			return(IO_ERROR);
-	};
-
-	// Fill in the scatter gather information
-	if (size > 0 ) 
-	{
-		buff_dma_handle.val = (__u64) pci_map_single( h->pdev, 
+		}
+	} else if (cmd_type == TYPE_MSG) {
+		switch (cmd) {
+		case 3:	/* No-Op message */
+			c->Request.CDBLen = 1;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_WRITE;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = cmd;
+			break;
+		default:
+			printk(KERN_WARNING
+				"cciss%d: unknown message type %d\n",
+				ctlr, cmd);
+			return IO_ERROR;
+		}
+	} else {
+		printk(KERN_WARNING
+			"cciss%d: unknown command type %d\n", ctlr, cmd_type);
+		return IO_ERROR;
+	}
+	/* Fill in the scatter gather information */
+	if (size > 0) {
+		buff_dma_handle.val = (__u64) pci_map_single(h->pdev,
 			buff, size, PCI_DMA_BIDIRECTIONAL);
 		c->SG[0].Addr.lower = buff_dma_handle.val32.lower;
 		c->SG[0].Addr.upper = buff_dma_handle.val32.upper;
 		c->SG[0].Len = size;
-		c->SG[0].Ext = 0;  // we are not chaining
+		c->SG[0].Ext = 0;  /* we are not chaining */
+	}
+	return status;
+}
+static int sendcmd_withirq(__u8	cmd,
+	int	ctlr,
+	void	*buff,
+	size_t	size,
+	unsigned int use_unit_num,
+	unsigned int log_unit,
+	__u8	page_code,
+	int cmd_type)
+{
+	ctlr_info_t *h = hba[ctlr];
+	CommandList_struct *c;
+	u64bit	buff_dma_handle;
+	unsigned long flags;
+	int return_status;
+	DECLARE_COMPLETION(wait);
+	
+	if ((c = cmd_alloc(h , 0)) == NULL)
+		return -ENOMEM;
+	return_status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
+		log_unit, page_code, NULL, cmd_type);
+	if (return_status != IO_OK) {
+		cmd_free(h, c, 0);
+		return return_status;
 	}
+resend_cmd2:
 	c->waiting = &wait;
 	
 	/* Put the request on the tail of the queue and send it */
@@ -934,10 +1141,6 @@
 	
 	wait_for_completion(&wait);
 
-	/* unlock the buffers from DMA */
-        pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val,
-                	size, PCI_DMA_BIDIRECTIONAL);
-
 	if(c->err_info->CommandStatus != 0) 
 	{ /* an error has occurred */ 
 		switch(c->err_info->CommandStatus)
@@ -989,11 +1192,22 @@
 				return_status = IO_ERROR;
 			break;
 			case CMD_UNSOLICITED_ABORT:
-				printk(KERN_WARNING "cciss: cmd %p aborted "
-					"do to an unsolicited abort\n", c);
+				printk(KERN_WARNING 
+					"cciss%d: unsolicited abort %p\n",
+					ctlr, c);
+				if (c->retry_count < MAX_CMD_RETRIES) {
+					printk(KERN_WARNING 
+						"cciss%d: retrying %p\n", 
+						ctlr, c);
+					c->retry_count++;
+					/* erase the old error information */
+					memset(c->err_info, 0,
+						sizeof(ErrorInfo_struct));
+					return_status = IO_OK;
+					INIT_COMPLETION(wait);
+					goto resend_cmd2;
+				}
 				return_status = IO_ERROR;
-
-
 			break;
 			default:
 				printk(KERN_WARNING "cciss: cmd %p returned "
@@ -1002,6 +1216,9 @@
 				return_status = IO_ERROR;
 		}
 	}	
+	/* unlock the buffers from DMA */
+	pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val,
+			size, PCI_DMA_BIDIRECTIONAL);
 	cmd_free(h, c, 0);
         return(return_status);
 
@@ -1015,10 +1232,10 @@
 	memset(inq_buff, 0, sizeof(InquiryData_struct));
 	if (withirq)
 		return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
-			inq_buff, sizeof(*inq_buff), 1, logvol ,0xC1);
+			inq_buff, sizeof(*inq_buff), 1, logvol ,0xC1, TYPE_CMD);
 	else
 		return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff,
-			sizeof(*inq_buff), 1, logvol ,0xC1, NULL);
+			sizeof(*inq_buff), 1, logvol ,0xC1, NULL, TYPE_CMD);
 	if (return_code == IO_OK) {
 		if(inq_buff->data_byte[8] == 0xFF) {
 			printk(KERN_WARNING
@@ -1057,10 +1274,10 @@
 	memset(buf, 0, sizeof(*buf));
 	if (withirq)
 		return_code = sendcmd_withirq(CCISS_READ_CAPACITY,
-			ctlr, buf, sizeof(*buf), 1, logvol, 0 );
+			ctlr, buf, sizeof(*buf), 1, logvol, 0, TYPE_CMD);
 	else
 		return_code = sendcmd(CCISS_READ_CAPACITY,
-			ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL );
+			ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL, TYPE_CMD);
 	if (return_code == IO_OK) {
 		*total_size = be32_to_cpu(*((__u32 *) &buf->total_size[0]))+1;
 		*block_size = be32_to_cpu(*((__u32 *) &buf->block_size[0]));
@@ -1111,7 +1328,7 @@
 		goto mem_msg;
 	
 	return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, 
-			sizeof(ReportLunData_struct), 0, 0, 0 );
+			sizeof(ReportLunData_struct), 0, 0, 0, TYPE_CMD);
 
 	if( return_code == IO_OK)
 	{
@@ -1265,126 +1482,27 @@
 				      2: periph device address is scsi3addr */
 	unsigned int log_unit,
 	__u8	page_code,
-	unsigned char *scsi3addr)
+	unsigned char *scsi3addr,
+	int cmd_type)
 {
 	CommandList_struct *c;
 	int i;
 	unsigned long complete;
 	ctlr_info_t *info_p= hba[ctlr];
 	u64bit buff_dma_handle;
+	int status;
 
-	c = cmd_alloc(info_p, 1);
-	if (c == NULL)
-	{
+	if ((c = cmd_alloc(info_p, 1)) == NULL) {
 		printk(KERN_WARNING "cciss: unable to get memory");
 		return(IO_ERROR);
 	}
-	// Fill in Command Header 
-	c->Header.ReplyQueue = 0;  // unused in simple mode
-	if( buff != NULL) 	// buffer to fill 
-	{
-		c->Header.SGList = 1;
-		c->Header.SGTotal= 1;
-	} else	// no buffers to fill  
-	{
-		c->Header.SGList = 0;
-                c->Header.SGTotal= 0;
-	}
-	c->Header.Tag.lower = c->busaddr;  // use the kernel address the cmd block for tag
-	// Fill in Request block 	
-	switch(cmd)
-	{
-		case  CISS_INQUIRY:
-			/* If the logical unit number is 0 then, this is going
-				to controller so It's a physical command
-				mode = 0 target = 0.
-				So we have nothing to write. 
-				otherwise, if use_unit_num == 1, 
-				mode = 1(volume set addressing) target = LUNID
-				otherwise, if use_unit_num == 2,
-				mode = 0(periph dev addr) target = scsi3addr 
-			*/
-			if(use_unit_num == 1)
-			{
-				c->Header.LUN.LogDev.VolId=
-                                	hba[ctlr]->drv[log_unit].LunID;
-                        	c->Header.LUN.LogDev.Mode = 1;
-			}
-			else if (use_unit_num == 2)
-			{
-				memcpy(c->Header.LUN.LunAddrBytes,scsi3addr,8);
-                        	c->Header.LUN.LogDev.Mode = 0; // phys dev addr 
-			}
-
-			/* are we trying to read a vital product page */
-			if(page_code != 0)
-			{
-				c->Request.CDB[1] = 0x01;
-				c->Request.CDB[2] = page_code;
-			}
-			c->Request.CDBLen = 6;
-			c->Request.Type.Type =  TYPE_CMD; // It is a command. 
-			c->Request.Type.Attribute = ATTR_SIMPLE;  
-			c->Request.Type.Direction = XFER_READ; // Read 
-			c->Request.Timeout = 0; // Don't time out 
-			c->Request.CDB[0] =  CISS_INQUIRY;
-			c->Request.CDB[4] = size  & 0xFF;  
-		break;
-		case CISS_REPORT_LOG:
-		case CISS_REPORT_PHYS:
-                        /* Talking to controller so It's a physical command
-                                mode = 00 target = 0.
-                                So we have nothing to write.
-                        */
-                        c->Request.CDBLen = 12;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE; 
-                        c->Request.Type.Direction = XFER_READ; // Read
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = cmd;
-                        c->Request.CDB[6] = (size >> 24) & 0xFF;  //MSB
-                        c->Request.CDB[7] = (size >> 16) & 0xFF;
-                        c->Request.CDB[8] = (size >> 8) & 0xFF;
-                        c->Request.CDB[9] = size & 0xFF;
-                break;
-
-		case CCISS_READ_CAPACITY:
-			c->Header.LUN.LogDev.VolId= 
-				hba[ctlr]->drv[log_unit].LunID;
-			c->Header.LUN.LogDev.Mode = 1;
-			c->Request.CDBLen = 10;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE; 
-                        c->Request.Type.Direction = XFER_READ; // Read
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = CCISS_READ_CAPACITY;
-		break;
-		case CCISS_CACHE_FLUSH:
-			c->Request.CDBLen = 12;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE;
-                        c->Request.Type.Direction = XFER_WRITE; // No data
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = BMIC_WRITE;  // BMIC Passthru
-                        c->Request.CDB[6] = BMIC_CACHE_FLUSH;
-		break;
-		default:
-			printk(KERN_WARNING
-				"cciss:  Unknown Command 0x%c sent attempted\n",
-				  cmd);
-			cmd_free(info_p, c, 1);
-			return(IO_ERROR);
-	};
-	// Fill in the scatter gather information
-	if (size > 0 ) 
-	{
-		buff_dma_handle.val = (__u64) pci_map_single( info_p->pdev, 
-			buff, size, PCI_DMA_BIDIRECTIONAL);
-		c->SG[0].Addr.lower = buff_dma_handle.val32.lower;
-		c->SG[0].Addr.upper = buff_dma_handle.val32.upper;
-		c->SG[0].Len = size;
-		c->SG[0].Ext = 0;  // we are not chaining
+	status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
+		log_unit, page_code, scsi3addr, cmd_type);
+	if (status != IO_OK) {
+		cmd_free(info_p, c, 1);
+		return status;
 	}
+resend_cmd1:
 	/*
          * Disable interrupt
          */
@@ -1417,9 +1535,6 @@
 	printk(KERN_DEBUG "cciss: command completed\n");
 #endif /* CCISS_DEBUG */
 
-	/* unlock the data buffer from DMA */
-	pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
-                                size, PCI_DMA_BIDIRECTIONAL);
 	if (complete != 1) {
 		if ( (complete & CISS_ERROR_BIT)
 		     && (complete & ~CISS_ERROR_BIT) == c->busaddr)
@@ -1437,8 +1552,30 @@
 			 	))
 			{
 				complete = c->busaddr;
-			} else
-			{
+			} else {
+				if (c->err_info->CommandStatus ==
+						CMD_UNSOLICITED_ABORT) {
+					printk(KERN_WARNING "cciss%d: "
+						"unsolicited abort %p\n",
+						ctlr, c);
+					if (c->retry_count < MAX_CMD_RETRIES) {
+						printk(KERN_WARNING
+						   "cciss%d: retrying %p\n",
+						   ctlr, c);
+						c->retry_count++;
+						/* erase the old error */
+						/* information */
+						memset(c->err_info, 0,
+						   sizeof(ErrorInfo_struct));
+						goto resend_cmd1;
+					} else {
+						printk(KERN_WARNING
+						   "cciss%d: retried %p too "
+						   "many times\n", ctlr, c);
+						status = IO_ERROR;
+						goto cleanup1;
+					}
+				}
 				printk(KERN_WARNING "ciss ciss%d: sendcmd"
 				" Error %x \n", ctlr, 
 					c->err_info->CommandStatus); 
@@ -1448,27 +1585,31 @@
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_size,
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_num,
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
-				cmd_free(info_p,c, 1);
-				return(IO_ERROR);
+				status = IO_ERROR;
+				goto cleanup1;
 			}
 		}
                 if (complete != c->busaddr) {
                         printk( KERN_WARNING "cciss cciss%d: SendCmd "
                       "Invalid command list address returned! (%lx)\n",
                                 ctlr, complete);
-                        cmd_free(info_p, c, 1);
-                        return (IO_ERROR);
+			status = IO_ERROR;
+			goto cleanup1;
                 }
         } else {
                 printk( KERN_WARNING
                         "cciss cciss%d: SendCmd Timeout out, "
                         "No command list address returned!\n",
                         ctlr);
-                cmd_free(info_p, c, 1);
-                return (IO_ERROR);
+		status = IO_ERROR;
         }
+		
+cleanup1:	
+	/* unlock the data buffer from DMA */
+	pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
+				size, PCI_DMA_BIDIRECTIONAL);
 	cmd_free(info_p, c, 1);
-        return (IO_OK);
+	return (status);
 } 
 /*
  * Map (physical) PCI mem into (virtual) kernel space
@@ -1552,27 +1693,35 @@
 	}
 
 } 
+/* Assumes that CCISS_LOCK(h->ctlr) is held. */
+/* Zeros out the error record and then resends the command back */
+/* to the controller */
+static inline void resend_cciss_cmd( ctlr_info_t *h, CommandList_struct *c)
+{
+	/* erase the old error information */
+	memset(c->err_info, 0, sizeof(ErrorInfo_struct));
+
+	/* add it to software queue and then send it to the controller */
+	addQ(&(h->reqQ),c);
+	h->Qdepth++;
+	if(h->Qdepth > h->maxQsinceinit)
+		h->maxQsinceinit = h->Qdepth;
+
+	start_io(h);
+}
 /* checks the status of the job and calls complete buffers to mark all 
  * buffers for the completed job. 
  */ 
-static inline void complete_command( CommandList_struct *cmd, int timeout)
+static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd,
+		int timeout)
 {
 	int status = 1;
 	int i;
+	int retry_cmd = 0;
 	u64bit temp64;
 		
 	if (timeout)
 		status = 0; 
-	/* unmap the DMA mapping for all the scatter gather elements */
-	for(i=0; i<cmd->Header.SGList; i++)
-	{
-		temp64.val32.lower = cmd->SG[i].Addr.lower;
-		temp64.val32.upper = cmd->SG[i].Addr.upper;
-		pci_unmap_page(hba[cmd->ctlr]->pdev,
-			temp64.val, cmd->SG[i].Len, 
-			(cmd->Request.Type.Direction == XFER_READ) ? 
-				PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
-	}
 
 	if(cmd->err_info->CommandStatus != 0) 
 	{ /* an error has occurred */ 
@@ -1646,8 +1795,18 @@
 				status=0;
 			break;
 			case CMD_UNSOLICITED_ABORT:
-				printk(KERN_WARNING "cciss: cmd %p aborted "
-					"do to an unsolicited abort\n", cmd);
+				printk(KERN_WARNING "cciss%d: unsolicited "
+					"abort %p\n", h->ctlr, cmd);
+				if (cmd->retry_count < MAX_CMD_RETRIES) {
+					retry_cmd=1;
+					printk(KERN_WARNING
+						"cciss%d: retrying %p\n",
+						h->ctlr, cmd);
+					cmd->retry_count++;
+				} else
+					printk(KERN_WARNING
+						"cciss%d: %p retried too "
+						"many times\n", h->ctlr, cmd);
 				status=0;
 			break;
 			case CMD_TIMEOUT:
@@ -1662,7 +1821,21 @@
 				status=0;
 		}
 	}
-
+	/* We need to return this command */
+	if(retry_cmd) {
+		resend_cciss_cmd(h,cmd);
+		return;
+	}	
+	/* command did not need to be retried */
+	/* unmap the DMA mapping for all the scatter gather elements */
+	for(i=0; i<cmd->Header.SGList; i++) {
+		temp64.val32.lower = cmd->SG[i].Addr.lower;
+		temp64.val32.upper = cmd->SG[i].Addr.upper;
+		pci_unmap_page(hba[cmd->ctlr]->pdev,
+			temp64.val, cmd->SG[i].Len,
+			(cmd->Request.Type.Direction == XFER_READ) ?
+				PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+	}
 	complete_buffers(cmd->rq->bio, status);
 
 #ifdef CCISS_DEBUG
@@ -1670,6 +1843,7 @@
 #endif /* CCISS_DEBUG */ 
 
 	end_that_request_last(cmd->rq);
+	cmd_free(h,cmd,1);
 }
 
 /* 
@@ -1816,8 +1990,7 @@
 			 if (c->busaddr == a) {
 				removeQ(&h->cmpQ, c);
 				if (c->cmd_type == CMD_RWREQ) {
-					complete_command(c, 0);
-					cmd_free(h, c, 1);
+					complete_command(h, c, 0);
 				} else if (c->cmd_type == CMD_IOCTL_PEND) {
 					complete(c->waiting);
 				}
@@ -2038,12 +2211,15 @@
 		&(c->cfgtable->HostWrite.TransportRequest));
 	writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
-	for(i=0;i<MAX_CONFIG_WAIT;i++)
-	{
+	/* under certain very rare conditions, this can take awhile.
+	 * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right
+	 * as we enter this code.) */
+	for(i=0;i<MAX_CONFIG_WAIT;i++) {
 		if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
 			break;
 		/* delay and try again */
-		udelay(1000);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(10);
 	}	
 
 #ifdef CCISS_DEBUG
@@ -2102,7 +2278,7 @@
         }
 	/* Get the firmware version */ 
 	return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, 
-		sizeof(InquiryData_struct), 0, 0 ,0, NULL );
+		sizeof(InquiryData_struct), 0, 0 ,0, NULL, TYPE_CMD);
 	if (return_code == IO_OK)
 	{
 		hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];
@@ -2116,7 +2292,7 @@
 	}
 	/* Get the number of logical volumes */ 
 	return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, 
-			sizeof(ReportLunData_struct), 0, 0, 0, NULL );
+			sizeof(ReportLunData_struct), 0, 0, 0, NULL, TYPE_CMD);
 
 	if( return_code == IO_OK)
 	{
@@ -2390,7 +2566,8 @@
 	/* sendcmd will turn off interrupt, and send the flush...
 	* To write all data in the battery backed cache to disks */
 	memset(flush_buf, 0, 4);
-	return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL);
+	return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL,
+				TYPE_CMD);
 	if(return_code != IO_OK)
 	{
 		printk(KERN_WARNING "Error Flushing cache on controller %d\n", 
diff -Nru a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
--- a/drivers/block/cciss_cmd.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/block/cciss_cmd.h	Tue Mar  4 19:30:05 2003
@@ -240,6 +240,7 @@
   struct _CommandList_struct *next;
   struct request *	   rq;
   struct completion *waiting;
+  int	 retry_count;
 #ifdef CONFIG_CISS_SCSI_TAPE
   void * scsi_cmd;
 #endif
diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
--- a/drivers/block/cciss_scsi.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/block/cciss_scsi.c	Tue Mar  4 19:30:05 2003
@@ -47,7 +47,8 @@
 				      2: address is in scsi3addr */
 	unsigned int log_unit,
 	__u8	page_code,
-	unsigned char *scsi3addr );
+	unsigned char *scsi3addr,
+	int cmd_type);
 
 
 int __init cciss_scsi_detect(Scsi_Host_Template *tpnt);
@@ -210,7 +211,7 @@
 	stk = &sa->cmd_stack; 
 	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
 
-	// pci_alloc_consistent guarentees 32-bit DMA address will
+	// pci_alloc_consistent guarantees 32-bit DMA address will
 	// be used
 
 	stk->pool = (struct cciss_scsi_cmd_stack_elem_t *)
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/block/cpqarray.c	Tue Mar  4 19:30:04 2003
@@ -715,7 +715,7 @@
 		return -ENXIO;
 
 	/*
-	 * Root is allowed to open raw volume zero even if its not configured
+	 * Root is allowed to open raw volume zero even if it's not configured
 	 * so array config can still work.  I don't think I really like this,
 	 * but I'm already using way to many device nodes to claim another one
 	 * for "raw controller".
diff -Nru a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
--- a/drivers/block/deadline-iosched.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/block/deadline-iosched.c	Tue Mar  4 19:30:12 2003
@@ -98,7 +98,7 @@
 	unsigned long expires;
 };
 
-static inline void deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq);
+static void deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq);
 
 static kmem_cache_t *drq_pool;
 
@@ -205,7 +205,7 @@
 		return;
 	}
 
-	deadline_move_to_dispatch(dd, __alias);
+	deadline_move_request(dd, __alias);
 	goto retry;
 }
 
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/block/genhd.c	Tue Mar  4 19:30:08 2003
@@ -1,17 +1,5 @@
 /*
- *  Code extracted from
- *  linux/kernel/hd.c
- *
- *  Copyright (C) 1991-1998  Linus Torvalds
- *
- *  devfs support - jj, rgooch, 980122
- *
- *  Moved partition checking code to fs/partitions* - Russell King
- *  (linux@arm.uk.linux.org)
- */
-
-/*
- * TODO:  rip out the remaining init crap from this file  --hch
+ *  gendisk handling
  */
 
 #include <linux/config.h>
@@ -29,8 +17,9 @@
 
 static struct subsystem block_subsys;
 
+#define MAX_PROBE_HASH 23	/* random */
 
-struct blk_probe {
+static struct blk_probe {
 	struct blk_probe *next;
 	dev_t dev;
 	unsigned long range;
@@ -38,21 +27,27 @@
 	struct gendisk *(*get)(dev_t dev, int *part, void *data);
 	int (*lock)(dev_t, void *);
 	void *data;
-} *probes[MAX_BLKDEV];
+} *probes[MAX_PROBE_HASH];
 
-/* index in the above */
+/* index in the above - for now: assume no multimajor ranges */
 static inline int dev_to_index(dev_t dev)
 {
-	return MAJOR(dev);
+	return MAJOR(dev) % MAX_PROBE_HASH;
 }
 
+/*
+ * Register device numbers dev..(dev+range-1)
+ * range must be nonzero
+ * The hash chain is sorted on range, so that subranges can override.
+ */
 void blk_register_region(dev_t dev, unsigned long range, struct module *module,
-		    struct gendisk *(*probe)(dev_t, int *, void *),
-		    int (*lock)(dev_t, void *), void *data)
+			 struct gendisk *(*probe)(dev_t, int *, void *),
+			 int (*lock)(dev_t, void *), void *data)
 {
 	int index = dev_to_index(dev);
 	struct blk_probe *p = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
 	struct blk_probe **s;
+
 	p->owner = module;
 	p->get = probe;
 	p->lock = lock;
@@ -71,6 +66,7 @@
 {
 	int index = dev_to_index(dev);
 	struct blk_probe **s;
+
 	down_write(&block_subsys.rwsem);
 	for (s = &probes[index]; *s; s = &(*s)->next) {
 		struct blk_probe *p = *s;
@@ -94,6 +90,7 @@
 static int exact_lock(dev_t dev, void *data)
 {
 	struct gendisk *p = data;
+
 	if (!get_disk(p))
 		return -1;
 	return 0;
@@ -109,14 +106,14 @@
 void add_disk(struct gendisk *disk)
 {
 	disk->flags |= GENHD_FL_UP;
-	blk_register_region(MKDEV(disk->major, disk->first_minor), disk->minors,
-			NULL, exact_match, exact_lock, disk);
+	blk_register_region(MKDEV(disk->major, disk->first_minor),
+			    disk->minors, NULL, exact_match, exact_lock, disk);
 	register_disk(disk);
 	elv_register_queue(disk);
 }
 
 EXPORT_SYMBOL(add_disk);
-EXPORT_SYMBOL(del_gendisk);
+EXPORT_SYMBOL(del_gendisk);	/* in partitions/check.c */
 
 void unlink_gendisk(struct gendisk *disk)
 {
@@ -146,18 +143,17 @@
 		struct gendisk *(*probe)(dev_t, int *, void *);
 		struct module *owner;
 		void *data;
-		if (p->dev > dev || p->dev + p->range <= dev)
+
+		if (p->dev > dev || p->dev + p->range - 1 < dev)
 			continue;
-		if (p->range >= best) {
-			up_read(&block_subsys.rwsem);
-			return NULL;
-		}
+		if (p->range - 1 >= best)
+			break;
 		if (!try_module_get(p->owner))
 			continue;
 		owner = p->owner;
 		data = p->data;
 		probe = p->get;
-		best = p->range;
+		best = p->range - 1;
 		*part = dev - p->dev;
 		if (p->lock && p->lock(dev, data) < 0) {
 			module_put(owner);
@@ -169,7 +165,7 @@
 		module_put(owner);
 		if (disk)
 			return disk;
-		goto retry;
+		goto retry;		/* this terminates: best decreases */
 	}
 	up_read(&block_subsys.rwsem);
 	return NULL;
@@ -245,7 +241,7 @@
 
 static struct gendisk *base_probe(dev_t dev, int *part, void *data)
 {
-	char name[20];
+	char name[30];
 	sprintf(name, "block-major-%d", MAJOR(dev));
 	request_module(name);
 	return NULL;
@@ -256,11 +252,11 @@
 	struct blk_probe *base = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
 	int i;
 	memset(base, 0, sizeof(struct blk_probe));
-	base->dev = MKDEV(1,0);
-	base->range = MKDEV(MAX_BLKDEV-1, 255) - base->dev + 1;
+	base->dev = 1;
+	base->range = ~0;		/* range 1 .. ~0 */
 	base->get = base_probe;
-	for (i = 1; i < MAX_BLKDEV; i++)
-		probes[i] = base;
+	for (i = 0; i < MAX_PROBE_HASH; i++)
+		probes[i] = base;	/* must remain last in chain */
 	blk_dev_init();
 	subsystem_register(&block_subsys);
 	return 0;
@@ -281,12 +277,14 @@
 	ssize_t (*show)(struct gendisk *, char *);
 };
 
-static ssize_t disk_attr_show(struct kobject * kobj, struct attribute * attr,
-			      char * page)
+static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
+			      char *page)
 {
-	struct gendisk * disk = to_disk(kobj);
-	struct disk_attribute * disk_attr = container_of(attr,struct disk_attribute,attr);
+	struct gendisk *disk = to_disk(kobj);
+	struct disk_attribute *disk_attr =
+		container_of(attr,struct disk_attribute,attr);
 	ssize_t ret = 0;
+
 	if (disk_attr->show)
 		ret = disk_attr->show(disk,page);
 	return ret;
@@ -303,11 +301,11 @@
 }
 static ssize_t disk_range_read(struct gendisk * disk, char *page)
 {
-	return sprintf(page, "%d\n",disk->minors);
+	return sprintf(page, "%d\n", disk->minors);
 }
 static ssize_t disk_size_read(struct gendisk * disk, char *page)
 {
-	return sprintf(page, "%llu\n",(unsigned long long)get_capacity(disk));
+	return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
 }
 
 static inline unsigned jiffies_to_msec(unsigned jif)
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/block/ll_rw_blk.c	Tue Mar  4 19:30:04 2003
@@ -1461,6 +1461,7 @@
 	if (blk_rq_tagged(rq))
 		blk_queue_end_tag(q, rq);
 
+	drive_stat_acct(rq, rq->nr_sectors, 1);
 	__elv_add_request(q, rq, !at_head, 0);
 	q->request_fn(q);
 	spin_unlock_irqrestore(q->queue_lock, flags);
@@ -1892,7 +1893,7 @@
 }
 
 /**
- * generic_make_request: hand a buffer to it's device driver for I/O
+ * generic_make_request: hand a buffer to its device driver for I/O
  * @bio:  The bio describing the location in memory and on the device.
  *
  * generic_make_request() is used to make I/O requests of block
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/block/loop.c	Tue Mar  4 19:30:10 2003
@@ -447,7 +447,22 @@
 		goto out_bh;
 	}
 
-	bio = bio_copy(rbh, GFP_NOIO, rbh->bi_rw & WRITE);
+	/*
+	 * When called on the page reclaim -> writepage path, this code can
+	 * trivially consume all memory.  So we drop PF_MEMALLOC to avoid
+	 * stealing all the page reserves and throttle to the writeout rate.
+	 * pdflush will have been woken by page reclaim.  Let it do its work.
+	 */
+	do {
+		int flags = current->flags;
+
+		current->flags &= ~PF_MEMALLOC;
+		bio = bio_copy(rbh, (GFP_ATOMIC & ~__GFP_HIGH) | __GFP_NOWARN,
+					rbh->bi_rw & WRITE);
+		current->flags = flags;
+		if (bio == NULL)
+			blk_congestion_wait(WRITE, HZ/10);
+	} while (bio == NULL);
 
 	bio->bi_end_io = loop_end_io_transfer;
 	bio->bi_private = rbh;
diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
--- a/drivers/block/scsi_ioctl.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/block/scsi_ioctl.c	Tue Mar  4 19:30:14 2003
@@ -60,6 +60,7 @@
 
 	rq->flags |= REQ_NOMERGE;
 	rq->waiting = &wait;
+        drive_stat_acct(rq, rq->nr_sectors, 1);
 	elv_add_request(q, rq, 1, 1);
 	generic_unplug_device(q);
 	wait_for_completion(&wait);
diff -Nru a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
--- a/drivers/cdrom/cdrom.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/cdrom/cdrom.c	Tue Mar  4 19:30:04 2003
@@ -172,8 +172,8 @@
   -- Defined CD_DVD and CD_CHANGER log levels.
   -- Fixed the CDROMREADxxx ioctls.
   -- CDROMPLAYTRKIND uses the GPCMD_PLAY_AUDIO_MSF command - too few
-  drives supported it. We loose the index part, however.
-  -- Small modifications to accomodate opens of /dev/hdc1, required
+  drives supported it. We lose the index part, however.
+  -- Small modifications to accommodate opens of /dev/hdc1, required
   for ide-cd to handle multisession discs.
   -- Export cdrom_mode_sense and cdrom_mode_select.
   -- init_cdrom_command() for setting up a cgc command.
diff -Nru a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
--- a/drivers/cdrom/sbpcd.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/cdrom/sbpcd.c	Tue Mar  4 19:30:05 2003
@@ -341,7 +341,7 @@
  * Trying to merge requests breaks this driver horribly (as in it goes
  * boom and apparently has done so since 2.3.41).  As it is a legacy
  * driver for a horribly slow double speed CD on a hideous interface
- * designed for polled operation, I won't loose any sleep in simply
+ * designed for polled operation, I won't lose any sleep in simply
  * disallowing merging.				Paul G.  02/2001
  *
  * Thu May 30 14:14:47 CEST 2002:
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Tue Mar  4 19:30:13 2003
+++ b/drivers/char/Makefile	Tue Mar  4 19:30:13 2003
@@ -83,7 +83,7 @@
 clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
 
 $(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE)
-	$(call do_cmd,CONMK  $@,$(objtree)/scripts/conmakehash $< > $@)
+	$(call do_cmd,CONMK   $@,$(objtree)/scripts/conmakehash $< > $@)
 
 $(obj)/defkeymap.o:  $(obj)/defkeymap.c
 
diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
--- a/drivers/char/agp/Kconfig	Tue Mar  4 19:30:10 2003
+++ b/drivers/char/agp/Kconfig	Tue Mar  4 19:30:10 2003
@@ -34,14 +34,17 @@
 	depends on AGP
 
 config AGP_INTEL
-	tristate "Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support"
+	tristate "Intel 440LX/BX/GX and I815/I820/830M/I830MP/I840/I845/845G/I850/852GM/855GM/I860/865G support"
 	depends on AGP
 	help
 	  This option gives you AGP support for the GLX component of the
-	  XFree86 4.x on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850 and 860 chipsets.
+	  XFree86 4.x on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850
+	  and 860 chipsets and full support for the 810, 815, 830M, 845G,
+	  852GM, 855GM and 865G integrated graphics chipsets.
 
 	  You should say Y here if you use XFree86 3.3.6 or 4.x and want to
-	  use GLX or DRI.  If unsure, say N.
+	  use GLX or DRI, or if you have any Intel integrated graphics
+	  chipsets.  If unsure, say Y.
 
 #config AGP_I810
 #	tristate "Intel I810/I815/I830M (on-board) support"
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h	Tue Mar  4 19:30:08 2003
+++ b/drivers/char/agp/agp.h	Tue Mar  4 19:30:08 2003
@@ -42,9 +42,8 @@
 
 static void __attribute__((unused)) global_cache_flush(void)
 {
-	if (smp_call_function(ipi_handler, NULL, 1, 1) != 0)
+	if (on_each_cpu(ipi_handler, NULL, 1, 1) != 0)
 		panic(PFX "timed out waiting for the other CPUs!\n");
-	flush_agp_cache();
 }
 #else
 static inline void global_cache_flush(void)
@@ -216,6 +215,21 @@
 
 /* This one is for I830MP w. an external graphic card */
 #define INTEL_I830_ERRSTS	0x92
+
+/* Intel 855GM/852GM registers */
+#define I855_GMCH_GMS_STOLEN_0M		0x0
+#define I855_GMCH_GMS_STOLEN_1M		(0x1 << 4)
+#define I855_GMCH_GMS_STOLEN_4M		(0x2 << 4)
+#define I855_GMCH_GMS_STOLEN_8M		(0x3 << 4)
+#define I855_GMCH_GMS_STOLEN_16M	(0x4 << 4)
+#define I855_GMCH_GMS_STOLEN_32M	(0x5 << 4)
+#define I85X_CAPID			0x44
+#define I85X_VARIANT_MASK		0x7
+#define I85X_VARIANT_SHIFT		5
+#define I855_GME			0x0
+#define I855_GM				0x4
+#define I852_GME			0x2
+#define I852_GM				0x5
 
 /* intel 815 register */
 #define INTEL_815_APCONT	0x51
diff -Nru a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c
--- a/drivers/char/agp/alpha-agp.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/char/agp/alpha-agp.c	Tue Mar  4 19:30:11 2003
@@ -185,7 +185,7 @@
 	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
 	agp_bridge->mode = agp->capability.lw;
 	agp_bridge->cant_use_aperture = 1;
-	agp_bridgevm_ops =  &alpha_core_agp_vm_ops;
+	agp_bridge->vm_ops =  &alpha_core_agp_vm_ops;
 
 	alpha_core_agp_driver.dev = agp_bridge->dev;
 	agp_register_driver(&alpha_core_agp_driver);
diff -Nru a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
--- a/drivers/char/agp/intel-agp.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/char/agp/intel-agp.c	Tue Mar  4 19:30:08 2003
@@ -2,6 +2,11 @@
  * Intel AGPGART routines.
  */
 
+/*
+ * Intel(R) 855GM/852GM and 865G support added by David Dawes
+ * <dawes@tungstengraphics.com>.
+ */
+
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -294,34 +299,62 @@
 	u16 gmch_ctrl;
 	int gtt_entries;
 	u8 rdct;
+	int local = 0;
 	static const int ddt[4] = { 0, 16, 32, 64 };
 
 	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
 
-	switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
-	case I830_GMCH_GMS_STOLEN_512:
-		gtt_entries = KB(512) - KB(132);
-		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
-		break;
-	case I830_GMCH_GMS_STOLEN_1024:
-		gtt_entries = MB(1) - KB(132);
-		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
-		break;
-	case I830_GMCH_GMS_STOLEN_8192:
-		gtt_entries = MB(8) - KB(132);
-		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
-		break;
-	case I830_GMCH_GMS_LOCAL:
-		rdct = INREG8(intel_i830_private.registers,I830_RDRAM_CHANNEL_TYPE);
-		gtt_entries = (I830_RDRAM_ND(rdct) + 1) * MB(ddt[I830_RDRAM_DDT(rdct)]);
-		printk(KERN_INFO PFX "detected %dK local memory.\n",gtt_entries / KB(1));
-		break;
-	default:
-		printk(KERN_INFO PFX "no video memory detected.\n");
-		gtt_entries = 0;
-		break;
+	if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
+	    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
+		switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
+		case I830_GMCH_GMS_STOLEN_512:
+			gtt_entries = KB(512) - KB(132);
+			break;
+		case I830_GMCH_GMS_STOLEN_1024:
+			gtt_entries = MB(1) - KB(132);
+			break;
+		case I830_GMCH_GMS_STOLEN_8192:
+			gtt_entries = MB(8) - KB(132);
+			break;
+		case I830_GMCH_GMS_LOCAL:
+			rdct = INREG8(intel_i830_private.registers,
+				      I830_RDRAM_CHANNEL_TYPE);
+			gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
+					MB(ddt[I830_RDRAM_DDT(rdct)]);
+			local = 1;
+			break;
+		default:
+			gtt_entries = 0;
+			break;
+		}
+	} else {
+		switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
+		case I855_GMCH_GMS_STOLEN_1M:
+			gtt_entries = MB(1) - KB(132);
+			break;
+		case I855_GMCH_GMS_STOLEN_4M:
+			gtt_entries = MB(4) - KB(132);
+			break;
+		case I855_GMCH_GMS_STOLEN_8M:
+			gtt_entries = MB(8) - KB(132);
+			break;
+		case I855_GMCH_GMS_STOLEN_16M:
+			gtt_entries = MB(16) - KB(132);
+			break;
+		case I855_GMCH_GMS_STOLEN_32M:
+			gtt_entries = MB(32) - KB(132);
+			break;
+		default:
+			gtt_entries = 0;
+			break;
+		}
 	}
-
+	if (gtt_entries > 0)
+		printk(KERN_INFO PFX "Detected %dK %s memory.\n",
+		       gtt_entries / KB(1), local ? "local" : "stolen");
+	else
+		printk(KERN_INFO PFX
+		       "No pre-allocated video memory detected.\n");
 	gtt_entries /= KB(4);
 
 	intel_i830_private.gtt_entries = gtt_entries;
@@ -374,9 +407,18 @@
 	u16 gmch_ctrl;
 	struct aper_size_info_fixed *values;
 
-	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
 	values = A_SIZE_FIX(agp_bridge->aperture_sizes);
 
+	if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&
+	    agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {
+		/* 855GM/852GM/865G has 128MB aperture size */
+		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
+		agp_bridge->aperture_size_idx = 0;
+		return(values[0].size);
+	}
+
+	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
+
 	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
 		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
 		agp_bridge->aperture_size_idx = 0;
@@ -558,6 +600,7 @@
 
 	return(0);
 }
+
 static int intel_fetch_size(void)
 {
 	int i;
@@ -1241,7 +1284,7 @@
 	{
 		.device_id	= PCI_DEVICE_ID_INTEL_82830_HB,
 		.chipset	= INTEL_I830_M,
-		.chipset_name	= "i830M",
+		.chipset_name	= "830M",
 		.chipset_setup	= intel_830mp_setup
 	},
 	{
@@ -1259,7 +1302,7 @@
 	{
 		.device_id	= PCI_DEVICE_ID_INTEL_82845G_HB,
 		.chipset	= INTEL_I845_G,
-		.chipset_name	= "i845G",
+		.chipset_name	= "845G",
 		.chipset_setup	= intel_845_setup
 	},
 	{
@@ -1269,11 +1312,23 @@
 		.chipset_setup	= intel_850_setup
 	},
 	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82855_HB,
+		.chipset	= INTEL_I855_PM,
+		.chipset_name	= "855PM",
+		.chipset_setup	= intel_845_setup
+	},
+	{
 		.device_id	= PCI_DEVICE_ID_INTEL_82860_HB,
 		.chipset	= INTEL_I860,
 		.chipset_name	= "i860",
 		.chipset_setup	= intel_860_setup
 	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82865_HB,
+		.chipset	= INTEL_I865_G,
+		.chipset_name	= "865G",
+		.chipset_setup	= intel_845_setup
+	},
 	{ }, /* dummy final entry, always present */
 };
 
@@ -1387,13 +1442,13 @@
 
 		if (i810_dev == NULL) {
 			/* 
-			 * We probably have a I845MP chipset with an external graphics
+			 * We probably have a I845G chipset with an external graphics
 			 * card. It will be initialized later 
 			 */
 			agp_bridge->type = INTEL_I845_G;
 			break;
 		}
-		printk(KERN_INFO PFX "Detected an Intel 845G Chipset.\n");
+		printk(KERN_INFO PFX "Detected an Intel(R) 845G Chipset.\n");
 		agp_bridge->type = INTEL_I810;
 		return intel_i830_setup(i810_dev);
 
@@ -1408,7 +1463,63 @@
 			agp_bridge->type = INTEL_I830_M;
 			break;
 		}
-		printk(KERN_INFO PFX "Detected an Intel 830M Chipset.\n");
+		printk(KERN_INFO PFX "Detected an Intel(R) 830M Chipset.\n");
+		agp_bridge->type = INTEL_I810;
+		return intel_i830_setup(i810_dev);
+
+	case PCI_DEVICE_ID_INTEL_82855_HB:
+		i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855_IG, NULL);
+		if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0)
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855_IG, i810_dev);
+
+		if (i810_dev == NULL) {
+			/* Intel 855PM with external graphic card */
+			/* It will be initialized later */
+			agp_bridge->type = INTEL_I855_PM;
+			break;
+		}
+		{
+			u32 capval = 0;
+			const char *name = "855GM/852GM";
+			pci_read_config_dword(dev, I85X_CAPID, &capval);
+			switch ((capval >> I85X_VARIANT_SHIFT) &
+				I85X_VARIANT_MASK) {
+			case I855_GME:
+				name = "855GME";
+				break;
+			case I855_GM:
+				name = "855GM";
+				break;
+			case I852_GME:
+				name = "852GME";
+				break;
+			case I852_GM:
+				name = "852GM";
+				break;
+			}
+			printk(KERN_INFO PFX
+			       "Detected an Intel(R) %s Chipset.\n", name);
+		}
+		agp_bridge->type = INTEL_I810;
+		return intel_i830_setup(i810_dev);
+
+	case PCI_DEVICE_ID_INTEL_82865_HB:
+		i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82865_IG, NULL);
+		if (i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82865_IG, i810_dev);
+		}
+
+		if (i810_dev == NULL) {
+			/* 
+			 * We probably have a 865G chipset with an external graphics
+			 * card. It will be initialized later 
+			 */
+			agp_bridge->type = INTEL_I865_G;
+			break;
+		}
+		printk(KERN_INFO PFX "Detected an Intel(R) 865G Chipset.\n");
 		agp_bridge->type = INTEL_I810;
 		return intel_i830_setup(i810_dev);
 
diff -Nru a/drivers/char/cd1865.h b/drivers/char/cd1865.h
--- a/drivers/char/cd1865.h	Tue Mar  4 19:30:10 2003
+++ b/drivers/char/cd1865.h	Tue Mar  4 19:30:10 2003
@@ -54,9 +54,9 @@
 #define CD186x_RCSR      0x7a    /* Receiver Character Status Register      */
 #define CD186x_TDR       0x7b    /* Transmit Data Register                  */
 #define CD186x_EOIR      0x7f    /* End of Interrupt Register               */
-#define CD186x_MRAR      0x75    /* Modem Request Acknowlege register       */
-#define CD186x_TRAR      0x76    /* Transmit Request Acknowlege register    */
-#define CD186x_RRAR      0x77    /* Receive Request Acknowlege register     */
+#define CD186x_MRAR      0x75    /* Modem Request Acknowledge register       */
+#define CD186x_TRAR      0x76    /* Transmit Request Acknowledge register    */
+#define CD186x_RRAR      0x77    /* Receive Request Acknowledge register     */
 #define CD186x_SRCR      0x66    /* Service Request Configuration register  */
 
 /* Channel Registers */
diff -Nru a/drivers/char/cyclades.c b/drivers/char/cyclades.c
--- a/drivers/char/cyclades.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/cyclades.c	Tue Mar  4 19:30:05 2003
@@ -151,7 +151,7 @@
  * Revision 2.2.1.4  1998/08/04 11:02:50 ivan
  * /proc/cyclades implementation with great collaboration of 
  * Marc Lewis <marc@blarg.net>;
- * cyy_interrupt was changed to avoid occurence of kernel oopses
+ * cyy_interrupt was changed to avoid occurrence of kernel oopses
  * during PPP operation.
  *
  * Revision 2.2.1.3  1998/06/01 12:09:10 ivan
diff -Nru a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h
--- a/drivers/char/drm/drm_vm.h	Tue Mar  4 19:30:14 2003
+++ b/drivers/char/drm/drm_vm.h	Tue Mar  4 19:30:14 2003
@@ -147,7 +147,7 @@
 }
 
 /* Special close routine which deletes map information if we are the last
- * person to close a mapping and its not in the global maplist.
+ * person to close a mapping and it's not in the global maplist.
  */
 
 void DRM(vm_shm_close)(struct vm_area_struct *vma)
diff -Nru a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h
--- a/drivers/char/drm/i810_drm.h	Tue Mar  4 19:30:03 2003
+++ b/drivers/char/drm/i810_drm.h	Tue Mar  4 19:30:03 2003
@@ -38,7 +38,7 @@
  *    - zbuffer linear offset and pitch -- also invarient
  *    - drawing origin in back and depth buffers.
  *
- * Keep the depth/back buffer state here to acommodate private buffers
+ * Keep the depth/back buffer state here to accommodate private buffers
  * in the future.
  */
 #define I810_DESTREG_DI0  0	/* CMD_OP_DESTBUFFER_INFO (2 dwords) */
diff -Nru a/drivers/char/drm/i830_drm.h b/drivers/char/drm/i830_drm.h
--- a/drivers/char/drm/i830_drm.h	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/drm/i830_drm.h	Tue Mar  4 19:30:07 2003
@@ -68,7 +68,7 @@
  *    - zbuffer linear offset and pitch -- also invarient
  *    - drawing origin in back and depth buffers.
  *
- * Keep the depth/back buffer state here to acommodate private buffers
+ * Keep the depth/back buffer state here to accommodate private buffers
  * in the future.
  */
 
diff -Nru a/drivers/char/epca.c b/drivers/char/epca.c
--- a/drivers/char/epca.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/char/epca.c	Tue Mar  4 19:30:10 2003
@@ -897,7 +897,7 @@
 					Remember copy_from_user WILL generate a page fault if the
 					user memory being accessed has been swapped out.  This can
 					cause this routine to temporarily sleep while this page
-					fault is occuring.
+					fault is occurring.
 				
 				----------------------------------------------------------------- */
 
@@ -1865,7 +1865,7 @@
 			case PCXI:
 				board_id = inb((int)bd->port);
 				if ((board_id & 0x1) == 0x1) 
-				{ /* Begin its an XI card */ 
+				{ /* Begin it's an XI card */ 
 
 					/* Is it a 64K board */
 					if ((board_id & 0x30) == 0) 
@@ -2743,11 +2743,11 @@
 
 		/* ---------------------------------------------------------------
 			Command sets channels iflag structure on the board. Such things 
-			as input soft flow control, handeling of parity errors, and
-			break handeling are all set here.
+			as input soft flow control, handling of parity errors, and
+			break handling are all set here.
 		------------------------------------------------------------------- */
 
-		/* break handeling, parity handeling, input stripping, flow control chars */
+		/* break handling, parity handling, input stripping, flow control chars */
 		fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0);
 	}
 
@@ -3516,7 +3516,7 @@
 /* ------------------------------------------------------------------
 	The below routines pc_throttle and pc_unthrottle are used 
 	to slow (And resume) the receipt of data into the kernels
-	receive buffers.  The exact occurence of this depends on the
+	receive buffers.  The exact occurrence of this depends on the
 	size of the kernels receive buffer and what the 'watermarks'
 	are set to for that buffer.  See the n_ttys.c file for more
 	details. 
diff -Nru a/drivers/char/ftape/lowlevel/ftape-calibr.c b/drivers/char/ftape/lowlevel/ftape-calibr.c
--- a/drivers/char/ftape/lowlevel/ftape-calibr.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/ftape/lowlevel/ftape-calibr.c	Tue Mar  4 19:30:05 2003
@@ -56,7 +56,7 @@
  * used directly to implement fine-grained timeouts.  However, on
  * Alpha PCs, the 8254 is *not* used to implement the clock tick
  * (which is 1024 Hz, normally) and the 8254 timer runs at some
- * "random" frequency (it seems to run at 18Hz, but its not safe to
+ * "random" frequency (it seems to run at 18Hz, but it's not safe to
  * rely on this value).  Instead, we use the Alpha's "rpcc"
  * instruction to read cycle counts.  As this is a 32 bit counter,
  * it will overflow only once per 30 seconds (on a 200MHz machine),
diff -Nru a/drivers/char/ftape/lowlevel/ftape_syms.c b/drivers/char/ftape/lowlevel/ftape_syms.c
--- a/drivers/char/ftape/lowlevel/ftape_syms.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/ftape/lowlevel/ftape_syms.c	Tue Mar  4 19:30:07 2003
@@ -22,7 +22,7 @@
  *
  *      This file contains the symbols that the ftape low level
  *      part of the QIC-40/80/3010/3020 floppy-tape driver "ftape"
- *      exports to it's high level clients
+ *      exports to its high level clients
  */
 
 #include <linux/config.h>
diff -Nru a/drivers/char/ftape/zftape/zftape-vtbl.h b/drivers/char/ftape/zftape/zftape-vtbl.h
--- a/drivers/char/ftape/zftape/zftape-vtbl.h	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/ftape/zftape/zftape-vtbl.h	Tue Mar  4 19:30:07 2003
@@ -176,7 +176,7 @@
 				      const zft_position *pos);
 
 /* this function decrements the zft_seg_pos counter if we are right
- * at the beginning of a segment. This is to handel fsfm/bsfm -- we
+ * at the beginning of a segment. This is to handle fsfm/bsfm -- we
  * need to position before the eof mark.  NOTE: zft_tape_pos is not
  * changed 
  */
diff -Nru a/drivers/char/ftape/zftape/zftape-write.c b/drivers/char/ftape/zftape/zftape-write.c
--- a/drivers/char/ftape/zftape/zftape-write.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/char/ftape/zftape/zftape-write.c	Tue Mar  4 19:30:09 2003
@@ -357,7 +357,7 @@
 	*volume = zft_find_volume(pos->seg_pos);
 	DUMP_VOLINFO(ft_t_noise, "", *volume);
 	zft_just_before_eof = 0;
-	/* now merge with old data if neccessary */
+	/* now merge with old data if necessary */
 	if (!zft_qic_mode && pos->seg_byte_pos != 0){
 		result = zft_fetch_segment(pos->seg_pos,
 					   zft_deblock_buf,
diff -Nru a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
--- a/drivers/char/generic_serial.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/char/generic_serial.c	Tue Mar  4 19:30:09 2003
@@ -142,14 +142,14 @@
  
 		/* Can't copy more? break out! */
 		if (c <= 0) break;
-		if (from_user)
+		if (from_user) {
 			if (copy_from_user (port->xmit_buf + port->xmit_head, 
 					    buf, c)) {
 				up (& port->port_write_sem);
 				return -EFAULT;
 			}
 
-		else
+		} else
 			memcpy (port->xmit_buf + port->xmit_head, buf, c);
 
 		port -> xmit_cnt += c;
diff -Nru a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
--- a/drivers/char/hangcheck-timer.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/hangcheck-timer.c	Tue Mar  4 19:30:07 2003
@@ -16,7 +16,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  * 
- * You should have recieved a copy of the GNU General Public
+ * 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 021110-1307, USA.
diff -Nru a/drivers/char/mwave/tp3780i.h b/drivers/char/mwave/tp3780i.h
--- a/drivers/char/mwave/tp3780i.h	Tue Mar  4 19:30:04 2003
+++ b/drivers/char/mwave/tp3780i.h	Tue Mar  4 19:30:04 2003
@@ -72,7 +72,7 @@
 #define TP_CFG_DisableLBusTimeout 0	/* Enable LBus timeout */
 #define TP_CFG_N_Divisor       32	/* Clock = 39.1608 Mhz */
 #define TP_CFG_M_Multiplier    37	/* " */
-#define TP_CFG_PllBypass        0	/* dont bypass */
+#define TP_CFG_PllBypass        0	/* don't bypass */
 #define TP_CFG_ChipletEnable 0xFFFF	/* Enable all chiplets */
 
 typedef struct {
diff -Nru a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
--- a/drivers/char/n_hdlc.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/n_hdlc.c	Tue Mar  4 19:30:05 2003
@@ -833,7 +833,7 @@
 		poll_wait(filp, &tty->read_wait, wait);
 		poll_wait(filp, &tty->write_wait, wait);
 
-		/* set bits for operations that wont block */
+		/* set bits for operations that won't block */
 		if(n_hdlc->rx_buf_list.head)
 			mask |= POLLIN | POLLRDNORM;	/* readable */
 		if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c
--- a/drivers/char/nvram.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/nvram.c	Tue Mar  4 19:30:07 2003
@@ -606,7 +606,7 @@
 
 #if MACH == COBALT
 
-/* the cobalt CMOS has a wider range of it's checksum */
+/* the cobalt CMOS has a wider range of its checksum */
 static int cobalt_check_checksum(void)
 {
 	int i;
diff -Nru a/drivers/char/nwflash.c b/drivers/char/nwflash.c
--- a/drivers/char/nwflash.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/char/nwflash.c	Tue Mar  4 19:30:14 2003
@@ -215,7 +215,7 @@
 	temp = ((int) (p + count) >> 16) - nBlock + 1;
 
 	/*
-	 * write ends at exactly 64k boundry?
+	 * write ends at exactly 64k boundary?
 	 */
 	if (((int) (p + count) & 0xFFFF) == 0)
 		temp -= 1;
diff -Nru a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
--- a/drivers/char/pcmcia/synclink_cs.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/pcmcia/synclink_cs.c	Tue Mar  4 19:30:07 2003
@@ -4505,7 +4505,7 @@
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("mgslpc_sppp_rx_done(%s)\n",info->netname);	
 	if (skb == NULL) {
-		printk(KERN_NOTICE "%s: cant alloc skb, dropping packet\n",
+		printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n",
 			info->netname);
 		info->netstats.rx_dropped++;
 		return;
diff -Nru a/drivers/char/rio/list.h b/drivers/char/rio/list.h
--- a/drivers/char/rio/list.h	Tue Mar  4 19:30:12 2003
+++ b/drivers/char/rio/list.h	Tue Mar  4 19:30:12 2003
@@ -111,7 +111,7 @@
 /*
 ** can_remove_receive( PacketP, PortP ) returns non-zero if PKT_IN_USE is set
 ** for the next packet on the queue. It will also set PacketP to point to the
-** relevent packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
+** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
 ** then can_remove_receive() returns 0.
 */
 #if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc)
diff -Nru a/drivers/char/rio/parmmap.h b/drivers/char/rio/parmmap.h
--- a/drivers/char/rio/parmmap.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/char/rio/parmmap.h	Tue Mar  4 19:30:13 2003
@@ -31,7 +31,7 @@
  ----------------------------------------------------------------------------
   Date     By                Description
  ----------------------------------------------------------------------------
-6/4/1991   jonb		     Made changes to accomodate Mips R3230 bus
+6/4/1991   jonb		     Made changes to accommodate Mips R3230 bus
  ***************************************************************************/
 
 #ifndef _parmap_h
diff -Nru a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
--- a/drivers/char/rio/rio_linux.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/char/rio/rio_linux.c	Tue Mar  4 19:30:10 2003
@@ -464,7 +464,7 @@
        recursive calls will hang the machine in the interrupt routine. 
 
      - hardware twiddling goes before "recursive". Otherwise when we
-       poll the card, and a recursive interrupt happens, we wont
+       poll the card, and a recursive interrupt happens, we won't
        ack the card, so it might keep on interrupting us. (especially
        level sensitive interrupt systems like PCI).
 
diff -Nru a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
--- a/drivers/char/rio/rioinit.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/rio/rioinit.c	Tue Mar  4 19:30:05 2003
@@ -145,7 +145,7 @@
 	p->RIOHosts[p->RIONumHosts].PaddrP	= info->location;
 
 	/*
-	** Check that we are able to accomodate another host
+	** Check that we are able to accommodate another host
 	*/
 	if ( p->RIONumHosts >= RIO_HOSTS )
 	{
diff -Nru a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
--- a/drivers/char/rio/rioparam.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/char/rio/rioparam.c	Tue Mar  4 19:30:14 2003
@@ -714,7 +714,7 @@
 /*
 ** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set
 ** for the next packet on the queue. It will also set PktP to point to the
-** relevent packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
+** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear,
 ** then can_remove_receive() returns 0.
 */
 int
diff -Nru a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
--- a/drivers/char/rio/rioroute.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/char/rio/rioroute.c	Tue Mar  4 19:30:09 2003
@@ -521,7 +521,7 @@
       /*
       ** If either of the modules on this unit is read-only or write-only
       ** or none-xprint, then we need to transfer that info over to the
-      ** relevent ports.
+      ** relevant ports.
       */
       if ( HostP->Mapping[ThisUnit].SysPort != NO_PORT )
       {
@@ -976,7 +976,7 @@
     /*
     ** We loop for all entries even after finding an entry and
     ** zeroing it because we may have two entries to delete if
-    ** its a 16 port RTA.
+    ** it's a 16 port RTA.
     */
     for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++)
     {
diff -Nru a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
--- a/drivers/char/rio/riotable.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/char/rio/riotable.c	Tue Mar  4 19:30:13 2003
@@ -309,7 +309,7 @@
 	}
 
 	/*
-	** wow! if we get here then its a goody!
+	** wow! if we get here then it's a goody!
 	*/
 
 	/*
diff -Nru a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
--- a/drivers/char/rio/riotty.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/rio/riotty.c	Tue Mar  4 19:30:07 2003
@@ -737,10 +737,10 @@
 RIOCookMode(struct ttystatics *tp)
 {
 	/*
-	** We cant handle tm.c_mstate != 0 on SCO
-	** We cant handle mapping
-	** We cant handle non-ttwrite line disc.
-	** We cant handle lflag XCASE
+	** We can't handle tm.c_mstate != 0 on SCO
+	** We can't handle mapping
+	** We can't handle non-ttwrite line disc.
+	** We can't handle lflag XCASE
 	** We can handle oflag OPOST & (OCRNL, ONLCR, TAB3)
 	*/
 
diff -Nru a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
--- a/drivers/char/rocket_int.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/rocket_int.h	Tue Mar  4 19:30:05 2003
@@ -834,7 +834,7 @@
 
 /***************************************************************************
 Function: sInitChanDefaults
-Purpose:  Initialize a channel structure to it's default state.
+Purpose:  Initialize a channel structure to its default state.
 Call:     sInitChanDefaults(ChP)
           CHANNEL_T *ChP; Ptr to the channel structure
 Comments: This function must be called once for every channel structure
diff -Nru a/drivers/char/scc.h b/drivers/char/scc.h
--- a/drivers/char/scc.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/char/scc.h	Tue Mar  4 19:30:13 2003
@@ -428,7 +428,7 @@
  * for that purpose. They assume that a local variable 'port' is
  * declared and pointing to the port's scc_struct entry. The
  * variants with "_NB" appended should be used if no other SCC
- * accesses follow immediatly (within 0.5 usecs). They just skip the
+ * accesses follow immediately (within 0.5 usecs). They just skip the
  * final delay nops.
  * 
  * Please note that accesses to SCC registers should only take place
diff -Nru a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
--- a/drivers/char/ser_a2232.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/ser_a2232.c	Tue Mar  4 19:30:05 2003
@@ -590,7 +590,7 @@
 									printk("A2232: 65EC02 software sent SYNC event, don't know what to do. Ignoring.");
 									break;
 								default:
-									printk("A2232: 65EC02 software broken, unknown event type %d occured.\n",ibuf[bufpos-1]);
+									printk("A2232: 65EC02 software broken, unknown event type %d occurred.\n",ibuf[bufpos-1]);
 								} /* event type switch */
 								break;
  							case A2232INCTL_CHAR:
@@ -599,7 +599,7 @@
 								bufpos++;
 								break;
  							default:
-								printk("A2232: 65EC02 software broken, unknown data type %d occured.\n",cbuf[bufpos]);
+								printk("A2232: 65EC02 software broken, unknown data type %d occurred.\n",cbuf[bufpos]);
 								bufpos++;
 							} /* switch on input data type */
 						} /* while there's something in the buffer */
diff -Nru a/drivers/char/sx.c b/drivers/char/sx.c
--- a/drivers/char/sx.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/sx.c	Tue Mar  4 19:30:07 2003
@@ -1216,7 +1216,7 @@
 	     recursive calls will hang the machine in the interrupt routine. 
 
 	   - hardware twiddling goes before "recursive". Otherwise when we
-	     poll the card, and a recursive interrupt happens, we wont
+	     poll the card, and a recursive interrupt happens, we won't
 	     ack the card, so it might keep on interrupting us. (especially
 	     level sensitive interrupt systems like PCI).
 
diff -Nru a/drivers/char/synclink.c b/drivers/char/synclink.c
--- a/drivers/char/synclink.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/char/synclink.c	Tue Mar  4 19:30:07 2003
@@ -4260,7 +4260,7 @@
 
 	if ( info->tx_holding_count ) {
 		/* determine if we have enough tx dma buffers
-		 * to accomodate the next tx frame
+		 * to accommodate the next tx frame
 		 */
 		struct tx_holding_buffer *ptx =
 			&info->tx_holding_buffers[info->get_tx_holding_index];
@@ -7621,7 +7621,7 @@
 		status = info->rx_buffer_list[0].status;
 
 		if ( status & (BIT8 + BIT3 + BIT1) ) {
-			/* receive error has occured */
+			/* receive error has occurred */
 			rc = FALSE;
 		} else {
 			if ( memcmp( info->tx_buffer_list[0].virt_addr ,
@@ -8103,7 +8103,7 @@
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("mgsl_sppp_rx_done(%s)\n",info->netname);	
 	if (skb == NULL) {
-		printk(KERN_NOTICE "%s: cant alloc skb, dropping packet\n",
+		printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n",
 			info->netname);
 		info->netstats.rx_dropped++;
 		return;
diff -Nru a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
--- a/drivers/char/synclinkmp.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/synclinkmp.c	Tue Mar  4 19:30:05 2003
@@ -1829,7 +1829,7 @@
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("sppp_rx_done(%s)\n",info->netname);
 	if (skb == NULL) {
-		printk(KERN_NOTICE "%s: cant alloc skb, dropping packet\n",
+		printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n",
 			info->netname);
 		info->netstats.rx_dropped++;
 		return;
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/char/tty_io.c	Tue Mar  4 19:30:10 2003
@@ -1944,27 +1944,25 @@
 		schedule_delayed_work(&tty->flip.work, 1);
 		return;
 	}
+
+	spin_lock_irqsave(&tty->read_lock, flags);
 	if (tty->flip.buf_num) {
 		cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
 		fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
 		tty->flip.buf_num = 0;
-
-		local_irq_save(flags); // FIXME: is this safe?
 		tty->flip.char_buf_ptr = tty->flip.char_buf;
 		tty->flip.flag_buf_ptr = tty->flip.flag_buf;
 	} else {
 		cp = tty->flip.char_buf;
 		fp = tty->flip.flag_buf;
 		tty->flip.buf_num = 1;
-
-		local_irq_save(flags); // FIXME: is this safe?
 		tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
 		tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
 	}
 	count = tty->flip.count;
 	tty->flip.count = 0;
-	local_irq_restore(flags); // FIXME: is this safe?
-	
+	spin_unlock_irqrestore(&tty->read_lock, flags);
+
 	tty->ldisc.receive_buf(tty, cp, fp, count);
 }
 
diff -Nru a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/char/vt.c	Tue Mar  4 19:30:13 2003
@@ -1882,7 +1882,7 @@
 		buf = con_buf;
 	}
 
-	/* At this point 'buf' is guarenteed to be a kernel buffer
+	/* At this point 'buf' is guaranteed to be a kernel buffer
 	 * and therefore no access to userspace (and therefore sleeping)
 	 * will be needed.  The con_buf_sem serializes all tty based
 	 * console rendering and vcs write/read operations.  We hold
@@ -2872,7 +2872,7 @@
  *  this is done in order to maintain compatibility with the EGA/VGA fonts. It 
  *  is upto the actual low-level console-driver convert data into its favorite
  *  format (maybe we should add a `fontoffset' field to the `display'
- *  structure so we wont have to convert the fontdata all the time.
+ *  structure so we won't have to convert the fontdata all the time.
  *  /Jes
  */
 
diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
--- a/drivers/char/watchdog/Kconfig	Tue Mar  4 19:30:11 2003
+++ b/drivers/char/watchdog/Kconfig	Tue Mar  4 19:30:11 2003
@@ -313,6 +313,19 @@
 	  You can compile this driver directly into the kernel, or use
 	  it as a module.  The module will be called sc520_wdt.
 
+config AMD7XX_TCO
+	tristate "AMD 766/768 TCO Timer/Watchdog"
+	depends on WATCHDOG
+	help
+	  This is the driver for the hardware watchdog built in to the
+	  AMD 766/768 chipsets.
+	  This watchdog simply watches your kernel to make sure it doesn't
+	  freeze, and if it does, it reboots your computer after a certain
+	  amount of time.
+	
+	  You can compile this driver directly into the kernel, or use
+	  it as a module.  The module will be called amd7xx_tco.
+
 config ALIM7101_WDT
 	tristate "ALi M7101 PMU Computer Watchdog"
 	depends on WATCHDOG
diff -Nru a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
--- a/drivers/char/watchdog/Makefile	Tue Mar  4 19:30:11 2003
+++ b/drivers/char/watchdog/Makefile	Tue Mar  4 19:30:11 2003
@@ -30,3 +30,4 @@
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
 obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
+obj-$(CONFIG_AMD7XX_TCO) += amd7xx_tco.o
diff -Nru a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
--- a/drivers/char/watchdog/acquirewdt.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/char/watchdog/acquirewdt.c	Tue Mar  4 19:30:10 2003
@@ -141,8 +141,6 @@
 			spin_unlock(&acq_lock);
 			return -EBUSY;
 		}
-		if (nowayout)
-			MOD_INC_USE_COUNT;
 
 		/* Activate */
 		acq_is_open=1;
diff -Nru a/drivers/char/watchdog/amd7xx_tco.c b/drivers/char/watchdog/amd7xx_tco.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/watchdog/amd7xx_tco.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,373 @@
+/*
+ *	AMD 766/768 TCO Timer Driver
+ *	(c) Copyright 2002 Zwane Mwaikambo <zwane@commfireservices.com>
+ *	All Rights Reserved.
+ *
+ *	Parts from;
+ *	Hardware driver for the AMD 768 Random Number Generator (RNG)
+ *	(c) Copyright 2001 Red Hat Inc <alan@redhat.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License version 2
+ *	as published by the Free Software Foundation.
+ *
+ *	The author(s) of this software shall not be held liable for damages
+ *	of any nature resulting due to the use of this software. This
+ *	software is provided AS-IS with no warranties.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#define AMDTCO_MODULE_VER	"build 20020601"
+#define AMDTCO_MODULE_NAME	"amd7xx_tco"
+#define PFX			AMDTCO_MODULE_NAME ": "
+
+#define	MAX_TIMEOUT	38	/* max of 38 seconds */
+
+/* pmbase registers */
+#define GLOBAL_SMI_REG	0x2a
+#define TCO_EN		(1 << 1)	/* bit 1 in global SMI register */
+#define TCO_RELOAD_REG	0x40		/* bits 0-5 are current count, 6-7 are reserved */
+#define TCO_INITVAL_REG	0x41		/* bits 0-5 are value to load, 6-7 are reserved */
+#define TCO_TIMEOUT_MASK	0x3f
+#define TCO_STATUS2_REG	0x46
+#define NDTO_STS2	(1 << 1)	/* we're interested in the second timeout */ 
+#define BOOT_STS	(1 << 2)	/* will be set if NDTO_STS2 was set before reboot */
+#define TCO_CTRL1_REG	0x48
+#define TCO_HALT	(1 << 11)
+
+static char banner[] __initdata = KERN_INFO PFX AMDTCO_MODULE_VER;
+static int timeout = 38;
+static u32 pmbase;		/* PMxx I/O base */
+static struct pci_dev *dev;
+static struct semaphore open_sem;
+spinlock_t amdtco_lock;	/* only for device access */
+static int expect_close = 0;
+
+MODULE_PARM(timeout, "i");
+MODULE_PARM_DESC(timeout, "range is 0-38 seconds, default is 38");
+
+static inline int amdtco_status(void)
+{
+	u16 reg;
+	int status = 0;
+
+	reg = inb(pmbase+TCO_CTRL1_REG);
+	if ((reg & TCO_HALT) == 0)
+		status |= WDIOF_KEEPALIVEPING;
+
+	reg = inb(pmbase+TCO_STATUS2_REG);
+	if (reg & BOOT_STS)
+		status |= WDIOF_CARDRESET;
+
+	return status;
+}
+
+static inline void amdtco_ping(void)
+{
+	u8 reg;
+
+	spin_lock(&amdtco_lock);
+	reg = inb(pmbase+TCO_RELOAD_REG);
+	outb(1 | reg, pmbase+TCO_RELOAD_REG);
+	spin_unlock(&amdtco_lock);
+}
+
+static inline int amdtco_gettimeout(void)
+{
+	return inb(TCO_RELOAD_REG) & TCO_TIMEOUT_MASK;
+}
+
+static inline void amdtco_settimeout(unsigned int timeout)
+{
+	u8 reg;
+
+	spin_lock(&amdtco_lock);
+	reg = inb(pmbase+TCO_INITVAL_REG);
+	reg |= timeout & TCO_TIMEOUT_MASK;
+	outb(reg, pmbase+TCO_INITVAL_REG);
+	spin_unlock(&amdtco_lock);
+}
+
+static inline void amdtco_global_enable(void)
+{
+	u16 reg;
+
+	spin_lock(&amdtco_lock);
+	reg = inw(pmbase+GLOBAL_SMI_REG);
+	reg |= TCO_EN;
+	outw(reg, pmbase+GLOBAL_SMI_REG);
+	spin_unlock(&amdtco_lock);
+}
+
+static inline void amdtco_enable(void)
+{
+	u16 reg;
+	
+	spin_lock(&amdtco_lock);
+	reg = inw(pmbase+TCO_CTRL1_REG);
+	reg &= ~TCO_HALT;
+	outw(reg, pmbase+TCO_CTRL1_REG);
+	spin_unlock(&amdtco_lock);
+}
+
+static inline void amdtco_disable(void)
+{
+	u16 reg;
+
+	spin_lock(&amdtco_lock);
+	reg = inw(pmbase+TCO_CTRL1_REG);
+	reg |= TCO_HALT;
+	outw(reg, pmbase+TCO_CTRL1_REG);
+	spin_unlock(&amdtco_lock);
+}
+
+static int amdtco_fop_open(struct inode *inode, struct file *file)
+{
+	if (down_trylock(&open_sem))
+		return -EBUSY;
+
+	if (timeout > MAX_TIMEOUT)
+		timeout = MAX_TIMEOUT;
+
+	amdtco_settimeout(timeout);	
+	amdtco_global_enable();
+	amdtco_ping();
+	printk(KERN_INFO PFX "Watchdog enabled, timeout = %d/%d seconds",
+		amdtco_gettimeout(), timeout);
+	
+	return 0;
+}
+
+
+static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int new_timeout;
+	int tmp;
+
+	static struct watchdog_info ident = {
+		.options	= WDIOF_SETTIMEOUT | WDIOF_CARDRESET,
+		.identity	= "AMD 766/768"
+	};
+
+	switch (cmd) {
+		default:
+			return -ENOTTY;	
+
+		case WDIOC_GETSUPPORT:
+			if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident))
+				return -EFAULT;
+			return 0;
+
+		case WDIOC_GETSTATUS:
+			return put_user(amdtco_status(), (int *)arg);
+	
+		case WDIOC_KEEPALIVE:
+			amdtco_ping();
+			return 0;
+
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_timeout, (int *)arg))
+				return -EFAULT;
+			
+			if (new_timeout < 0)
+				return -EINVAL;
+		
+			if (new_timeout > MAX_TIMEOUT)
+				new_timeout = MAX_TIMEOUT;
+
+			timeout = new_timeout;
+			amdtco_settimeout(timeout);
+			/* fall through and return the new timeout */
+
+		case WDIOC_GETTIMEOUT:
+			return put_user(amdtco_gettimeout(), (int *)arg);
+	
+		case WDIOC_SETOPTIONS:
+			if (copy_from_user(&tmp, (int *)arg, sizeof tmp))
+                                return -EFAULT;
+
+			if (tmp & WDIOS_DISABLECARD)
+				amdtco_disable();
+
+			if (tmp & WDIOS_ENABLECARD)
+				amdtco_enable();
+			
+			return 0;
+	}
+}
+
+
+static int amdtco_fop_release(struct inode *inode, struct file *file)
+{
+	if (expect_close) {
+		amdtco_disable();	
+		printk(KERN_INFO PFX "Watchdog disabled\n");
+	} else {
+		amdtco_ping();
+		printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds)\n", timeout);
+	}	
+	
+	up(&open_sem);
+	return 0;
+}
+
+
+static ssize_t amdtco_fop_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	
+	if (len) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+		size_t i;
+		char c;
+		expect_close = 0;
+		
+		for (i = 0; i != len; i++) {
+			if (get_user(c, data + i))
+				return -EFAULT;
+
+			if (c == 'V')
+				expect_close = 1;
+		}
+#endif
+		amdtco_ping();
+		return len;
+	}
+
+	return 0;
+}
+
+
+static int amdtco_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		amdtco_disable();
+
+	return NOTIFY_DONE;
+}
+
+
+static struct notifier_block amdtco_notifier =
+{
+	.notifier_call = amdtco_notify_sys
+};
+
+static struct file_operations amdtco_fops =
+{
+	.owner		= THIS_MODULE,
+	.write		= amdtco_fop_write,
+	.ioctl		= amdtco_fop_ioctl,
+	.open		= amdtco_fop_open,
+	.release	= amdtco_fop_release
+};
+
+static struct miscdevice amdtco_miscdev =
+{
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &amdtco_fops
+};
+
+static struct pci_device_id amdtco_pci_tbl[] __initdata = {
+	/* AMD 766 PCI_IDs here */
+	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE (pci, amdtco_pci_tbl);
+
+static int __init amdtco_init(void)
+{
+	int ret;
+
+	sema_init(&open_sem, 1);
+	spin_lock_init(&amdtco_lock);
+
+	pci_for_each_dev(dev) {
+		if (pci_match_device (amdtco_pci_tbl, dev) != NULL)
+			goto found_one;
+	}
+
+	return -ENODEV;
+
+found_one:
+	
+	if ((ret = register_reboot_notifier(&amdtco_notifier))) {
+		printk(KERN_ERR PFX "Unable to register reboot notifier err = %d\n", ret);
+		goto out_clean;
+	}
+
+	if ((ret = misc_register(&amdtco_miscdev))) {
+		printk(KERN_ERR PFX "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR);
+		goto out_unreg_reboot;
+	}
+
+	pci_read_config_dword(dev, 0x58, &pmbase);
+	pmbase &= 0x0000FF00;
+
+	if (pmbase == 0) {
+		printk (KERN_ERR PFX "power management base not set\n");
+		ret = -EIO;
+		goto out_unreg_misc;
+	}
+
+	/* ret = 0; */
+	printk(banner);
+	goto out_clean;
+
+out_unreg_misc:
+	misc_deregister(&amdtco_miscdev);
+out_unreg_reboot:
+	unregister_reboot_notifier(&amdtco_notifier);
+out_clean:
+	return ret;
+}
+
+static void __exit amdtco_exit(void)
+{
+	misc_deregister(&amdtco_miscdev);
+	unregister_reboot_notifier(&amdtco_notifier);
+}
+
+
+#ifndef MODULE
+static int __init amdtco_setup(char *str)
+{
+	int ints[4];
+
+	str = get_options (str, ARRAY_SIZE(ints), ints);
+	if (ints[0] > 0)
+		timeout = ints[1];
+
+	return 1;
+}
+
+__setup("amd7xx_tco=", amdtco_setup);
+#endif
+
+module_init(amdtco_init);
+module_exit(amdtco_exit);
+
+MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
+MODULE_DESCRIPTION("AMD 766/768 TCO Timer Driver");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
+
diff -Nru a/drivers/char/watchdog/i810-tco.c b/drivers/char/watchdog/i810-tco.c
--- a/drivers/char/watchdog/i810-tco.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/char/watchdog/i810-tco.c	Tue Mar  4 19:30:04 2003
@@ -161,7 +161,7 @@
 }
 
 /*
- * Reload (trigger) the timer. Lock is needed so we dont reload it during
+ * Reload (trigger) the timer. Lock is needed so we don't reload it during
  * a reprogramming event
  */
  
@@ -218,7 +218,7 @@
 
 		tco_expect_close = 0;
 
-		/* scan to see wether or not we got the magic character */
+		/* scan to see whether or not we got the magic character */
 		for (i = 0; i != len; i++) {
 			u8 c;
 			if(get_user(c, data+i))
diff -Nru a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
--- a/drivers/char/watchdog/ib700wdt.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/char/watchdog/ib700wdt.c	Tue Mar  4 19:30:13 2003
@@ -50,6 +50,8 @@
 static spinlock_t ibwdt_lock;
 static int expect_close = 0;
 
+#define PFX "ib700wdt: "
+
 /*
  *
  * Watchdog Timer Configuration
@@ -226,8 +228,6 @@
 			spin_unlock(&ibwdt_lock);
 			return -EBUSY;
 		}
-		if (nowayout)
-			MOD_INC_USE_COUNT;
 
 		/* Activate */
 		ibwdt_is_open = 1;
@@ -247,7 +247,7 @@
 		if (expect_close)
 			outb_p(wd_times[wd_margin], WDT_STOP);
 		else
-			printk(KERN_CRIT "WDT device closed unexpectedly.  WDT will not stop!\n");
+			printk(KERN_CRIT PFX "WDT device closed unexpectedly.  WDT will not stop!\n");
 
 		ibwdt_is_open = 0;
 		spin_unlock(&ibwdt_lock);
@@ -300,29 +300,49 @@
 	.priority = 0
 };
 
-static int __init
-ibwdt_init(void)
+static int __init ibwdt_init(void)
 {
-	printk("WDT driver for IB700 single board computer initialising.\n");
+	int res;
+
+	printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n");
 
 	spin_lock_init(&ibwdt_lock);
-	if (misc_register(&ibwdt_miscdev))
-		return -ENODEV;
+	res = misc_register(&ibwdt_miscdev);
+	if (res) {
+		printk (KERN_ERR PFX "failed to register misc device\n");
+		goto out_nomisc;
+	}
+
 #if WDT_START != WDT_STOP
 	if (!request_region(WDT_STOP, 1, "IB700 WDT")) {
-		misc_deregister(&ibwdt_miscdev);
-		return -EIO;
+		printk (KERN_ERR PFX "STOP method I/O %X is not available.\n", WDT_STOP);
+		res = -EIO;
+		goto out_nostopreg;
 	}
 #endif
+
 	if (!request_region(WDT_START, 1, "IB700 WDT")) {
-#if WDT_START != WDT_STOP
-		release_region(WDT_STOP, 1);
-#endif
-		misc_deregister(&ibwdt_miscdev);
-		return -EIO;
+		printk (KERN_ERR PFX "START method I/O %X is not available.\n", WDT_START);
+		res = -EIO;
+		goto out_nostartreg;
+	}
+	res = register_reboot_notifier(&ibwdt_notifier);
+	if (res) {
+		printk (KERN_ERR PFX "Failed to register reboot notifier.\n");
+		goto out_noreboot;
 	}
-	register_reboot_notifier(&ibwdt_notifier);
 	return 0;
+
+out_noreboot:
+	release_region(WDT_START, 1);
+out_nostartreg:
+#if WDT_START != WDT_STOP
+	release_region(WDT_STOP, 1);
+#endif
+out_nostopreg:
+	misc_deregister(&ibwdt_miscdev);
+out_nomisc:
+	return res;
 }
 
 static void __exit
diff -Nru a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
--- a/drivers/char/watchdog/indydog.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/char/watchdog/indydog.c	Tue Mar  4 19:30:13 2003
@@ -53,9 +53,6 @@
 	if( test_and_set_bit(0,&indydog_alive) )
 		return -EBUSY;
 
-	if (nowayout)
-		MOD_INC_USE_COUNT;
-
 	/*
 	 *	Activate timer
 	 */
diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
--- a/drivers/char/watchdog/machzwd.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/watchdog/machzwd.c	Tue Mar  4 19:30:05 2003
@@ -390,9 +390,6 @@
 				return -EBUSY;
 			}
 
-			if (nowayout)
-				MOD_INC_USE_COUNT;
-
 			zf_is_open = 1;
 
 			spin_unlock(&zf_lock);
diff -Nru a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
--- a/drivers/char/watchdog/mixcomwd.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/watchdog/mixcomwd.c	Tue Mar  4 19:30:05 2003
@@ -93,9 +93,7 @@
 	}
 	mixcomwd_ping();
 	
-	if (nowayout) {
-		MOD_INC_USE_COUNT;
-	} else {
+	if (!nowayout) {
 		if(mixcomwd_timer_alive) {
 			del_timer(&mixcomwd_timer);
 			mixcomwd_timer_alive=0;
diff -Nru a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
--- a/drivers/char/watchdog/pcwd.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/char/watchdog/pcwd.c	Tue Mar  4 19:30:04 2003
@@ -430,7 +430,7 @@
 			atomic_inc( &open_allowed );
 			return -EBUSY;
 		}
-		MOD_INC_USE_COUNT;
+
 		/*  Enable the port  */
 		if (revision == PCWD_REVISION_C) {
 			spin_lock(&io_lock);
diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
--- a/drivers/char/watchdog/sbc60xxwdt.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/char/watchdog/sbc60xxwdt.c	Tue Mar  4 19:30:11 2003
@@ -50,7 +50,7 @@
  *
  *  Why `V' ?  Well, `V' is the character in ASCII for the value 86,
  *  and we all know that 86 is _the_ most random number in the universe.
- *  Therefore it is the letter that has the slightest chance of occuring
+ *  Therefore it is the letter that has the slightest chance of occurring
  *  by chance, when the system becomes corrupted.
  *
  */
@@ -206,9 +206,7 @@
 			/* Just in case we're already talking to someone... */
 			if(wdt_is_open)
 				return -EBUSY;
-			if (nowayout) {
-				MOD_INC_USE_COUNT;
-			}
+
 			/* Good, fire up the show */
 			wdt_is_open = 1;
 			wdt_startup();
diff -Nru a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
--- a/drivers/char/watchdog/sc520_wdt.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/char/watchdog/sc520_wdt.c	Tue Mar  4 19:30:08 2003
@@ -229,8 +229,6 @@
 				return -EBUSY;
 			/* Good, fire up the show */
 			wdt_startup();
-			if (nowayout)
-				MOD_INC_USE_COUNT;
 
 			return 0;
 		default:
@@ -253,11 +251,6 @@
 	return 0;
 }
 
-static long long fop_llseek(struct file *file, long long offset, int origin)
-{
-	return -ESPIPE;
-}
-
 static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	unsigned long arg)
 {
@@ -282,7 +275,7 @@
 
 static struct file_operations wdt_fops = {
 	.owner		= THIS_MODULE,
-	.llseek		= fop_llseek,
+	.llseek		= no_llseek,
 	.write		= fop_write,
 	.open		= fop_open,
 	.release	= fop_close,
diff -Nru a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
--- a/drivers/char/watchdog/shwdt.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/char/watchdog/shwdt.c	Tue Mar  4 19:30:05 2003
@@ -1,9 +1,9 @@
 /*
  * drivers/char/shwdt.c
  *
- * Watchdog driver for integrated watchdog in the SuperH 3/4 processors.
+ * Watchdog driver for integrated watchdog in the SuperH processors.
  *
- * Copyright (C) 2001 Paul Mundt <lethal@chaoticdreams.org>
+ * Copyright (C) 2001, 2002 Paul Mundt <lethal@0xd6.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -26,14 +26,17 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#if defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH5)
+  #define WTCNT		CPRC_BASE + 0x10
+  #define WTCSR		CPRC_BASE + 0x18
+#elif defined(CONFIG_CPU_SH4)
   #define WTCNT		0xffc00008
   #define WTCSR		0xffc0000c
 #elif defined(CONFIG_CPU_SH3)
   #define WTCNT		0xffffff84
   #define WTCSR		0xffffff86
 #else
-  #error "Can't use SH 3/4 watchdog on non-SH 3/4 processor."
+  #error "Can't use SuperH watchdog on this platform"
 #endif
 
 #define WTCNT_HIGH	0x5a00
@@ -186,10 +189,6 @@
 			if (test_and_set_bit(0, &sh_is_open))
 				return -EBUSY;
 
-			if (nowayout) {
-				MOD_INC_USE_COUNT;
-			}
-
 			sh_wdt_start();
 
 			break;
@@ -405,8 +404,8 @@
 	misc_deregister(&sh_wdt_miscdev);
 }
 
-MODULE_AUTHOR("Paul Mundt <lethal@chaoticdreams.org>");
-MODULE_DESCRIPTION("SH 3/4 watchdog driver");
+MODULE_AUTHOR("Paul Mundt <lethal@0xd6.org>");
+MODULE_DESCRIPTION("SuperH watchdog driver");
 MODULE_LICENSE("GPL");
 MODULE_PARM(clock_division_ratio, "i");
 MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). Defaults to 0x7.");
diff -Nru a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
--- a/drivers/char/watchdog/softdog.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/char/watchdog/softdog.c	Tue Mar  4 19:30:08 2003
@@ -103,9 +103,7 @@
 {
 	if(test_and_set_bit(0, &timer_alive))
 		return -EBUSY;
-	if (nowayout) {
-		MOD_INC_USE_COUNT;
-	}
+
 	/*
 	 *	Activate timer
 	 */
diff -Nru a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
--- a/drivers/char/watchdog/wdt.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/char/watchdog/wdt.c	Tue Mar  4 19:30:09 2003
@@ -175,7 +175,7 @@
  *
  *	Handle an interrupt from the board. These are raised when the status
  *	map changes in what the board considers an interesting way. That means
- *	a failure condition occuring.
+ *	a failure condition occurring.
  */
  
 void wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
diff -Nru a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
--- a/drivers/char/watchdog/wdt977.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/char/watchdog/wdt977.c	Tue Mar  4 19:30:12 2003
@@ -99,8 +99,6 @@
 
 	if (nowayout)
 	{
-		MOD_INC_USE_COUNT;
-
 		/* do not permit disabling the watchdog by writing 0 to reg. 0xF2 */
 		if (!timeoutM) timeoutM = DEFAULT_TIMEOUT;
 	}
diff -Nru a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
--- a/drivers/char/watchdog/wdt_pci.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/char/watchdog/wdt_pci.c	Tue Mar  4 19:30:10 2003
@@ -158,7 +158,7 @@
  *
  *	Handle an interrupt from the board. These are raised when the status
  *	map changes in what the board considers an interesting way. That means
- *	a failure condition occuring.
+ *	a failure condition occurring.
  */
  
 static void wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -365,9 +365,6 @@
 			if (down_trylock(&open_sem))
 				return -EBUSY;
 
-			if (nowayout) {
-				MOD_INC_USE_COUNT;
-			}
 			/*
 			 *	Activate 
 			 */
diff -Nru a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
--- a/drivers/cpufreq/Kconfig	Tue Mar  4 19:30:13 2003
+++ b/drivers/cpufreq/Kconfig	Tue Mar  4 19:30:13 2003
@@ -9,3 +9,30 @@
 	  For details, take a look at linux/Documentation/cpufreq. 
 	  
 	  If in doubt, say N.
+
+config CPU_FREQ_GOV_USERSPACE
+       tristate "'userspace' governor for userspace frequency scaling"
+       depends on CPU_FREQ
+       help
+	  Enable this cpufreq governor when you either want to set the
+	  CPU frequency manually or when an userspace programm shall
+          be able to set the CPU dynamically, like on LART 
+	  ( http://www.lart.tudelft.nl/ )
+
+	  For details, take a look at linux/Documentation/cpufreq. 
+
+	  If in doubt, say Y.
+
+config CPU_FREQ_24_API
+	bool "/proc/sys/cpu/ interface (2.4. / OLD)"
+	depends on CPU_FREQ && SYSCTL && CPU_FREQ_GOV_USERSPACE
+	help
+	  This enables the /proc/sys/cpu/ sysctl interface for controlling
+	  the CPUFreq,"userspace" governor. This is the same interface
+	  as known from the.4.-kernel patches for CPUFreq, and offers
+	  the same functionality as long as "userspace" is the
+	  selected governor for the specified CPU.
+	
+	  For details, take a look at linux/Documentation/cpufreq. 
+
+	  If in doubt, say N.
diff -Nru a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
--- a/drivers/cpufreq/Makefile	Tue Mar  4 19:30:14 2003
+++ b/drivers/cpufreq/Makefile	Tue Mar  4 19:30:14 2003
@@ -1,3 +1,4 @@
 #CPUfreq governors and cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
 obj-$(CONFIG_CPU_FREQ_PROC_INTF)	+= proc_intf.o
+obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)	+= userspace.o
diff -Nru a/drivers/cpufreq/userspace.c b/drivers/cpufreq/userspace.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/cpufreq/userspace.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,596 @@
+/*
+ *  drivers/cpufreq/userspace.c
+ *
+ *  Copyright (C)  2001 Russell King
+ *            (C)  2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+ * $Id:$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ctype.h>
+#include <linux/cpufreq.h>
+#include <linux/sysctl.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+
+#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
+                .ctl_name	= CPU_NR_FREQ_MAX, \
+                .data		= &cpu_max_freq[cpunr], \
+                .procname	= "speed-max", \
+                .maxlen		= sizeof(cpu_max_freq[cpunr]),\
+                .mode		= 0444, \
+                .proc_handler	= proc_dointvec, }
+
+#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
+                .ctl_name	= CPU_NR_FREQ_MIN, \
+                .data		= &cpu_min_freq[cpunr], \
+                .procname	= "speed-min", \
+                .maxlen		= sizeof(cpu_min_freq[cpunr]),\
+                .mode		= 0444, \
+                .proc_handler	= proc_dointvec, }
+
+#define CTL_CPU_VARS_SPEED(cpunr) { \
+                .ctl_name	= CPU_NR_FREQ, \
+                .procname	= "speed", \
+                .mode		= 0644, \
+                .proc_handler	= cpufreq_procctl, \
+                .strategy	= cpufreq_sysctl, \
+                .extra1		= (void*) (cpunr), }
+
+#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
+                CTL_CPU_VARS_SPEED_MAX(cpunr), \
+                CTL_CPU_VARS_SPEED_MIN(cpunr), \
+                CTL_CPU_VARS_SPEED(cpunr),  \
+                { .ctl_name = 0, }, }
+
+/* the ctl_table entry for each CPU */
+#define CPU_ENUM(s) { \
+                .ctl_name	= (CPU_NR + s), \
+                .procname	= #s, \
+                .mode		= 0555, \
+                .child		= ctl_cpu_vars_##s }
+
+/**
+ * A few values needed by the userspace governor
+ */
+static unsigned int	cpu_max_freq[NR_CPUS];
+static unsigned int	cpu_min_freq[NR_CPUS];
+static unsigned int	cpu_cur_freq[NR_CPUS];
+static unsigned int	cpu_is_managed[NR_CPUS];
+static struct cpufreq_policy current_policy[NR_CPUS];
+
+static DECLARE_MUTEX	(userspace_sem); 
+
+
+/* keep track of frequency transitions */
+static int 
+userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
+                       void *data)
+{
+        struct cpufreq_freqs *freq = data;
+
+	cpu_cur_freq[freq->cpu] = freq->new;
+
+        return 0;
+}
+
+static struct notifier_block userspace_cpufreq_notifier_block = {
+        .notifier_call  = userspace_cpufreq_notifier
+};
+
+
+/** 
+ * cpufreq_set - set the CPU frequency
+ * @freq: target frequency in kHz
+ * @cpu: CPU for which the frequency is to be set
+ *
+ * Sets the CPU frequency to freq.
+ */
+int cpufreq_set(unsigned int freq, unsigned int cpu)
+{
+	int ret = -EINVAL;
+
+	down(&userspace_sem);
+	if (!cpu_is_managed[cpu])
+		goto err;
+
+	if (freq < cpu_min_freq[cpu])
+		freq = cpu_min_freq[cpu];
+	if (freq > cpu_max_freq[cpu])
+		freq = cpu_max_freq[cpu];
+
+	ret = cpufreq_driver_target_l(&current_policy[cpu], freq, 
+	      CPUFREQ_RELATION_L);
+
+ err:
+	up(&userspace_sem);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cpufreq_set);
+
+
+/** 
+ * cpufreq_setmax - set the CPU to the maximum frequency
+ * @cpu - affected cpu;
+ *
+ * Sets the CPU frequency to the maximum frequency supported by
+ * this CPU.
+ */
+int cpufreq_setmax(unsigned int cpu)
+{
+	if (!cpu_is_managed[cpu] || !cpu_online(cpu))
+		return -EINVAL;
+	return cpufreq_set(cpu_max_freq[cpu], cpu);
+}
+EXPORT_SYMBOL_GPL(cpufreq_setmax);
+
+
+/** 
+ * cpufreq_get - get the current CPU frequency (in kHz)
+ * @cpu: CPU number
+ *
+ * Get the CPU current (static) CPU frequency
+ */
+unsigned int cpufreq_get(unsigned int cpu)
+{
+	return cpu_cur_freq[cpu];
+}
+EXPORT_SYMBOL(cpufreq_get);
+
+
+#ifdef CONFIG_CPU_FREQ_24_API
+
+
+/*********************** cpufreq_sysctl interface ********************/
+static int
+cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
+		void *buffer, size_t *lenp)
+{
+	char buf[16], *p;
+	int cpu = (int) ctl->extra1;
+	int len, left = *lenp;
+
+	if (!left || (filp->f_pos && !write) || !cpu_online(cpu)) {
+		*lenp = 0;
+		return 0;
+	}
+
+	if (write) {
+		unsigned int freq;
+
+		len = left;
+		if (left > sizeof(buf))
+			left = sizeof(buf);
+		if (copy_from_user(buf, buffer, left))
+			return -EFAULT;
+		buf[sizeof(buf) - 1] = '\0';
+
+		freq = simple_strtoul(buf, &p, 0);
+		cpufreq_set(freq, cpu);
+	} else {
+		len = sprintf(buf, "%d\n", cpufreq_get(cpu));
+		if (len > left)
+			len = left;
+		if (copy_to_user(buffer, buf, len))
+			return -EFAULT;
+	}
+
+	*lenp = len;
+	filp->f_pos += len;
+	return 0;
+}
+
+static int
+cpufreq_sysctl(ctl_table *table, int *name, int nlen,
+	       void *oldval, size_t *oldlenp,
+	       void *newval, size_t newlen, void **context)
+{
+	int cpu = (int) table->extra1;
+
+	if (!cpu_online(cpu))
+		return -EINVAL;
+
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(unsigned int))
+			return -EINVAL;
+
+		if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
+		    put_user(sizeof(unsigned int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		unsigned int freq;
+
+		if (newlen != sizeof(unsigned int))
+			return -EINVAL;
+
+		if (get_user(freq, (unsigned int *)newval))
+			return -EFAULT;
+
+		cpufreq_set(freq, cpu);
+	}
+	return 1;
+}
+
+/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
+/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
+        CTL_TABLE_CPU_VARS(0);
+#if NR_CPUS > 1
+	CTL_TABLE_CPU_VARS(1);
+#endif
+#if NR_CPUS > 2
+	CTL_TABLE_CPU_VARS(2);
+#endif
+#if NR_CPUS > 3
+	CTL_TABLE_CPU_VARS(3);
+#endif
+#if NR_CPUS > 4
+	CTL_TABLE_CPU_VARS(4);
+#endif
+#if NR_CPUS > 5
+	CTL_TABLE_CPU_VARS(5);
+#endif
+#if NR_CPUS > 6
+	CTL_TABLE_CPU_VARS(6);
+#endif
+#if NR_CPUS > 7
+	CTL_TABLE_CPU_VARS(7);
+#endif
+#if NR_CPUS > 8
+	CTL_TABLE_CPU_VARS(8);
+#endif
+#if NR_CPUS > 9
+	CTL_TABLE_CPU_VARS(9);
+#endif
+#if NR_CPUS > 10
+	CTL_TABLE_CPU_VARS(10);
+#endif
+#if NR_CPUS > 11
+	CTL_TABLE_CPU_VARS(11);
+#endif
+#if NR_CPUS > 12
+	CTL_TABLE_CPU_VARS(12);
+#endif
+#if NR_CPUS > 13
+	CTL_TABLE_CPU_VARS(13);
+#endif
+#if NR_CPUS > 14
+	CTL_TABLE_CPU_VARS(14);
+#endif
+#if NR_CPUS > 15
+	CTL_TABLE_CPU_VARS(15);
+#endif
+#if NR_CPUS > 16
+	CTL_TABLE_CPU_VARS(16);
+#endif
+#if NR_CPUS > 17
+	CTL_TABLE_CPU_VARS(17);
+#endif
+#if NR_CPUS > 18
+	CTL_TABLE_CPU_VARS(18);
+#endif
+#if NR_CPUS > 19
+	CTL_TABLE_CPU_VARS(19);
+#endif
+#if NR_CPUS > 20
+	CTL_TABLE_CPU_VARS(20);
+#endif
+#if NR_CPUS > 21
+	CTL_TABLE_CPU_VARS(21);
+#endif
+#if NR_CPUS > 22
+	CTL_TABLE_CPU_VARS(22);
+#endif
+#if NR_CPUS > 23
+	CTL_TABLE_CPU_VARS(23);
+#endif
+#if NR_CPUS > 24
+	CTL_TABLE_CPU_VARS(24);
+#endif
+#if NR_CPUS > 25
+	CTL_TABLE_CPU_VARS(25);
+#endif
+#if NR_CPUS > 26
+	CTL_TABLE_CPU_VARS(26);
+#endif
+#if NR_CPUS > 27
+	CTL_TABLE_CPU_VARS(27);
+#endif
+#if NR_CPUS > 28
+	CTL_TABLE_CPU_VARS(28);
+#endif
+#if NR_CPUS > 29
+	CTL_TABLE_CPU_VARS(29);
+#endif
+#if NR_CPUS > 30
+	CTL_TABLE_CPU_VARS(30);
+#endif
+#if NR_CPUS > 31
+	CTL_TABLE_CPU_VARS(31);
+#endif
+#if NR_CPUS > 32
+#error please extend CPU enumeration
+#endif
+
+/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
+static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
+	CPU_ENUM(0),
+#if NR_CPUS > 1
+	CPU_ENUM(1),
+#endif
+#if NR_CPUS > 2
+	CPU_ENUM(2),
+#endif
+#if NR_CPUS > 3
+	CPU_ENUM(3),
+#endif
+#if NR_CPUS > 4
+	CPU_ENUM(4),
+#endif
+#if NR_CPUS > 5
+	CPU_ENUM(5),
+#endif
+#if NR_CPUS > 6
+	CPU_ENUM(6),
+#endif
+#if NR_CPUS > 7
+	CPU_ENUM(7),
+#endif
+#if NR_CPUS > 8
+	CPU_ENUM(8),
+#endif
+#if NR_CPUS > 9
+	CPU_ENUM(9),
+#endif
+#if NR_CPUS > 10
+	CPU_ENUM(10),
+#endif
+#if NR_CPUS > 11
+	CPU_ENUM(11),
+#endif
+#if NR_CPUS > 12
+	CPU_ENUM(12),
+#endif
+#if NR_CPUS > 13
+	CPU_ENUM(13),
+#endif
+#if NR_CPUS > 14
+	CPU_ENUM(14),
+#endif
+#if NR_CPUS > 15
+	CPU_ENUM(15),
+#endif
+#if NR_CPUS > 16
+	CPU_ENUM(16),
+#endif
+#if NR_CPUS > 17
+	CPU_ENUM(17),
+#endif
+#if NR_CPUS > 18
+	CPU_ENUM(18),
+#endif
+#if NR_CPUS > 19
+	CPU_ENUM(19),
+#endif
+#if NR_CPUS > 20
+	CPU_ENUM(20),
+#endif
+#if NR_CPUS > 21
+	CPU_ENUM(21),
+#endif
+#if NR_CPUS > 22
+	CPU_ENUM(22),
+#endif
+#if NR_CPUS > 23
+	CPU_ENUM(23),
+#endif
+#if NR_CPUS > 24
+	CPU_ENUM(24),
+#endif
+#if NR_CPUS > 25
+	CPU_ENUM(25),
+#endif
+#if NR_CPUS > 26
+	CPU_ENUM(26),
+#endif
+#if NR_CPUS > 27
+	CPU_ENUM(27),
+#endif
+#if NR_CPUS > 28
+	CPU_ENUM(28),
+#endif
+#if NR_CPUS > 29
+	CPU_ENUM(29),
+#endif
+#if NR_CPUS > 30
+	CPU_ENUM(30),
+#endif
+#if NR_CPUS > 31
+	CPU_ENUM(31),
+#endif
+#if NR_CPUS > 32
+#error please extend CPU enumeration
+#endif
+	{
+		.ctl_name	= 0,
+	}
+};
+
+static ctl_table ctl_cpu[2] = {
+	{
+		.ctl_name	= CTL_CPU,
+		.procname	= "cpu",
+		.mode		= 0555,
+		.child		= ctl_cpu_table,
+	},
+	{
+		.ctl_name	= 0,
+	}
+};
+
+struct ctl_table_header *cpufreq_sysctl_table;
+
+static inline void cpufreq_sysctl_init(void)
+{
+	cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
+}
+
+static inline void cpufreq_sysctl_exit(void)
+{
+	unregister_sysctl_table(cpufreq_sysctl_table);
+}
+
+#else
+#define cpufreq_sysctl_init() do {} while(0)
+#define cpufreq_sysctl_exit() do {} while(0)
+#endif /* CONFIG_CPU_FREQ_24API */
+
+
+/************************** sysfs interface ************************/
+static inline int to_cpu_nr (struct device *dev)
+{
+	struct sys_device * cpu_sys_dev = container_of(dev, struct sys_device, dev);
+	return (cpu_sys_dev->id);
+}
+
+static ssize_t show_speed (struct device *dev, char *buf)
+{
+	unsigned int cpu = to_cpu_nr(dev);
+
+	return sprintf (buf, "%u\n", cpu_cur_freq[cpu]);
+}
+
+static ssize_t 
+store_speed (struct device *dev, const char *buf, size_t count) 
+{
+	unsigned int cpu = to_cpu_nr(dev);
+	unsigned int freq = 0;
+	unsigned int ret;
+
+	ret = sscanf (buf, "%u", &freq);
+	if (ret != 1)
+		return -EINVAL;
+
+	cpufreq_set(freq, cpu);
+
+	return count;
+}
+
+static DEVICE_ATTR(scaling_setspeed, (S_IRUGO | S_IWUSR), show_speed, store_speed);
+
+
+static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
+				   unsigned int event)
+{
+	unsigned int cpu = policy->cpu;
+	switch (event) {
+	case CPUFREQ_GOV_START:
+		if ((!cpu_online(cpu)) || (!try_module_get(THIS_MODULE)) ||
+		    !policy->cur)
+			return -EINVAL;
+		down(&userspace_sem);
+		cpu_is_managed[cpu] = 1;		
+		cpu_min_freq[cpu] = policy->min;
+		cpu_max_freq[cpu] = policy->max;
+		cpu_cur_freq[cpu] = policy->cur;
+		device_create_file (policy->intf.dev, &dev_attr_scaling_setspeed);
+		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
+		up(&userspace_sem);
+		break;
+	case CPUFREQ_GOV_STOP:
+		down(&userspace_sem);
+		cpu_is_managed[cpu] = 0;
+		cpu_min_freq[cpu] = 0;
+		cpu_max_freq[cpu] = 0;
+		device_remove_file (policy->intf.dev, &dev_attr_scaling_setspeed);
+		up(&userspace_sem);
+		module_put(THIS_MODULE);
+		break;
+	case CPUFREQ_GOV_LIMITS:
+		down(&userspace_sem);
+		cpu_min_freq[cpu] = policy->min;
+		cpu_max_freq[cpu] = policy->max;
+		if (policy->max < cpu_cur_freq[cpu])
+			cpufreq_driver_target(&current_policy[cpu], policy->max, 
+			      CPUFREQ_RELATION_H);
+		else if (policy->min > cpu_cur_freq[cpu])
+			cpufreq_driver_target(&current_policy[cpu], policy->min, 
+			      CPUFREQ_RELATION_L);
+		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
+		up(&userspace_sem);
+		break;
+	}
+	return 0;
+}
+
+/* on ARM SA1100 we need to rely on the values of cpufreq_get() - because 
+ * of this, cpu_cur_freq[] needs to be set early.
+ */
+#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_SA1100)
+extern unsigned int sa11x0_getspeed(void);
+
+static void cpufreq_sa11x0_compat(void)
+{
+	cpu_cur_freq[0] = sa11x0_getspeed();
+}
+#else
+#define cpufreq_sa11x0_compat() do {} while(0)
+#endif
+
+
+static struct cpufreq_governor cpufreq_gov_userspace = {
+	.name		= "userspace",
+	.governor	= cpufreq_governor_userspace,
+	.owner		= THIS_MODULE,
+};
+EXPORT_SYMBOL(cpufreq_gov_userspace);
+
+static int already_init = 0;
+
+int cpufreq_gov_userspace_init(void)
+{
+	if (!already_init) {
+		down(&userspace_sem);
+		cpufreq_sa11x0_compat();
+		cpufreq_sysctl_init();
+		cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+		already_init = 1;
+		up(&userspace_sem);
+	}
+	return cpufreq_register_governor(&cpufreq_gov_userspace);
+}
+EXPORT_SYMBOL(cpufreq_gov_userspace_init);
+
+
+static void __exit cpufreq_gov_userspace_exit(void)
+{
+	cpufreq_unregister_governor(&cpufreq_gov_userspace);
+        cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+	cpufreq_sysctl_exit();
+}
+
+
+MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'");
+MODULE_LICENSE ("GPL");
+
+module_init(cpufreq_gov_userspace_init);
+module_exit(cpufreq_gov_userspace_exit);
diff -Nru a/drivers/hotplug/Makefile b/drivers/hotplug/Makefile
--- a/drivers/hotplug/Makefile	Tue Mar  4 19:30:11 2003
+++ b/drivers/hotplug/Makefile	Tue Mar  4 19:30:11 2003
@@ -18,7 +18,7 @@
 
 cpqphp-objs		:=	cpqphp_core.o	\
 				cpqphp_ctrl.o	\
-				cpqphp_proc.o	\
+				cpqphp_sysfs.o	\
 				cpqphp_pci.o
 
 ibmphp-objs		:=	ibmphp_core.o	\
diff -Nru a/drivers/hotplug/acpiphp_glue.c b/drivers/hotplug/acpiphp_glue.c
--- a/drivers/hotplug/acpiphp_glue.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/hotplug/acpiphp_glue.c	Tue Mar  4 19:30:05 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;
 
-		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;
-			break;
+	acpi_resource_to_address64(resource, &address);
 
-		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;
-			break;
+	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_END_TAG:
-			done = 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_IO_RANGE:
+			res->next = bridge->io_head;
+			bridge->io_head = res;
+			break;
+		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;
@@ -1357,7 +1279,7 @@
 			if (sta != ACPI_STA_ALL) {
 				retval = acpiphp_disable_slot(slot);
 				if (retval) {
-					err("Error occured in enabling\n");
+					err("Error occurred in enabling\n");
 					up(&slot->crit_sect);
 					goto err_exit;
 				}
@@ -1368,7 +1290,7 @@
 			if (sta == ACPI_STA_ALL) {
 				retval = acpiphp_enable_slot(slot);
 				if (retval) {
-					err("Error occured in enabling\n");
+					err("Error occurred in enabling\n");
 					up(&slot->crit_sect);
 					goto err_exit;
 				}
diff -Nru a/drivers/hotplug/acpiphp_pci.c b/drivers/hotplug/acpiphp_pci.c
--- a/drivers/hotplug/acpiphp_pci.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/hotplug/acpiphp_pci.c	Tue Mar  4 19:30:03 2003
@@ -194,133 +194,6 @@
 	return 0;
 }
 
-
-/* enable pci_dev */
-static int configure_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct acpiphp_func *func;
-	struct acpiphp_bridge *bridge;
-	struct pci_dev *dev;
-
-	func = (struct acpiphp_func *)wrapped_dev->data;
-	bridge = (struct acpiphp_bridge *)wrapped_bus->data;
-	dev = wrapped_dev->dev;
-
-	/* TBD: support PCI-to-PCI bridge case */
-	if (!func || !bridge)
-		return 0;
-
-	//pci_proc_attach_device(dev);
-	//pci_announce_device_to_drivers(dev);
-	info("Device %s configured\n", dev->slot_name);
-
-	return 0;
-}
-
-
-static int is_pci_dev_in_use (struct pci_dev* dev)
-{
-	/*
-	 * dev->driver will be set if the device is in use by a new-style
-	 * driver -- otherwise, check the device's regions to see if any
-	 * driver has claimed them
-	 */
-
-	int i, inuse=0;
-
-	if (dev->driver) return 1; //assume driver feels responsible
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-		if (!pci_resource_start(dev, i))
-			continue;
-
-		if (pci_resource_flags(dev, i) & IORESOURCE_IO)
-			inuse = check_region(pci_resource_start(dev, i),
-					     pci_resource_len(dev, i));
-		else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
-			inuse = check_mem_region(pci_resource_start(dev, i),
-						 pci_resource_len(dev, i));
-	}
-
-	return inuse;
-}
-
-
-static int pci_hp_remove_device (struct pci_dev *dev)
-{
-	if (is_pci_dev_in_use(dev)) {
-		err("***Cannot safely power down device -- "
-		       "it appears to be in use***\n");
-		return -EBUSY;
-	}
-	pci_remove_device(dev);
-	return 0;
-}
-
-
-/* remove device driver */
-static int unconfigure_pci_dev_driver (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	dbg("attempting removal of driver for device %s\n", dev->slot_name);
-
-	/* Now, remove the Linux Driver Representation */
-	if (dev->driver) {
-		if (dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return is_pci_dev_in_use(dev);
-}
-
-
-/* remove pci_dev itself from system */
-static int unconfigure_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	/* Now, remove the Linux Representation */
-	if (dev) {
-		if (pci_hp_remove_device(dev) == 0) {
-			info("Device %s removed\n", dev->slot_name);
-			kfree(dev); /* Now, remove */
-		} else {
-			return -1; /* problems while freeing, abort visitation */
-		}
-	}
-
-	return 0;
-}
-
-
-/* remove pci_bus itself from system */
-static int unconfigure_pci_bus (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
-{
-	struct pci_bus *bus = wrapped_bus->bus;
-
-#ifdef CONFIG_PROC_FS
-	/* Now, remove the Linux Representation */
-	if (bus->procdir) {
-		pci_proc_detach_bus(bus);
-	}
-#endif
-	/* the cleanup code should live in the kernel ... */
-	bus->self->subordinate = NULL;
-	/* unlink from parent bus */
-	list_del(&bus->node);
-
-	/* Now, remove */
-	if (bus)
-		kfree(bus);
-
-	return 0;
-}
-
-
 /* detect_used_resource - subtract resource under dev from bridge */
 static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
 {
@@ -592,22 +465,6 @@
 	return retval;
 }
 
-
-/* for pci_visit_dev() */
-static struct pci_visit configure_functions = {
-	.post_visit_pci_dev =	configure_pci_dev
-};
-
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	unconfigure_pci_dev_driver
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	unconfigure_pci_bus,
-	.post_visit_pci_dev =	unconfigure_pci_dev
-};
-
-
 /**
  * acpiphp_configure_function - configure PCI function
  * @func: function to be configured
@@ -618,33 +475,10 @@
  */
 int acpiphp_configure_function (struct acpiphp_func *func)
 {
-	int retval = 0;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-	struct acpiphp_bridge *bridge;
-
-	/* if pci_dev is NULL, ignore it */
-	if (!func->pci_dev)
-		goto err_exit;
-
-	bridge = func->slot->bridge;
-
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-	wrapped_dev.dev = func->pci_dev;
-	wrapped_dev.data = func;
-	wrapped_bus.bus = bridge->pci_bus;
-	wrapped_bus.data = bridge;
-
-	retval = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
-
- err_exit:
-	return retval;
+	/* all handled by the pci core now */
+	return 0;
 }
 
-
 /**
  * acpiphp_unconfigure_function - unconfigure PCI function
  * @func: function to be unconfigured
@@ -653,28 +487,13 @@
 int acpiphp_unconfigure_function (struct acpiphp_func *func)
 {
 	struct acpiphp_bridge *bridge;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	int retval = 0;
 
 	/* if pci_dev is NULL, ignore it */
 	if (!func->pci_dev)
 		goto err_exit;
 
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-	wrapped_dev.dev = func->pci_dev;
-	//wrapped_dev.data = func;
-	wrapped_bus.bus = func->slot->bridge->pci_bus;
-	//wrapped_bus.data = func->slot->bridge;
-
-	retval = pci_visit_dev(&unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
-
-	retval = pci_visit_dev(&unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
+	pci_remove_bus_device(func->pci_dev);
 
 	/* free all resources */
 	bridge = func->slot->bridge;
diff -Nru a/drivers/hotplug/cpci_hotplug_pci.c b/drivers/hotplug/cpci_hotplug_pci.c
--- a/drivers/hotplug/cpci_hotplug_pci.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/hotplug/cpci_hotplug_pci.c	Tue Mar  4 19:30:11 2003
@@ -483,29 +483,6 @@
 	return 0;
 }
 
-static int unconfigure_visit_pci_dev_phase1(struct pci_dev_wrapped *wrapped_dev,
-				 struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	dbg("attempting removal of driver for device %02x:%02x.%x",
-	    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-
-	/* Now, remove the Linux Driver representation */
-	if(dev->driver) {
-		dbg("device is attached to a driver");
-		if(dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was removed");
-		}
-		dev->driver = NULL;
-	}
-	dbg("%s - exit", __FUNCTION__);
-	return pci_is_dev_in_use(dev);
-}
-
 static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
 					    struct pci_bus_wrapped *wrapped_bus)
 {
@@ -577,10 +554,6 @@
 	.visit_pci_dev = configure_visit_pci_dev,
 };
 
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev = unconfigure_visit_pci_dev_phase1
-};
-
 static struct pci_visit unconfigure_functions_phase2 = {
 	.post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
 	.post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
@@ -668,13 +641,6 @@
 		if(dev) {
 			wrapped_dev.dev = dev;
 			wrapped_bus.bus = dev->bus;
-			dbg("%s - unconfigure phase 1", __FUNCTION__);
-			rc = pci_visit_dev(&unconfigure_functions_phase1,
-					   &wrapped_dev, &wrapped_bus);
-			if(rc) {
-				break;
-			}
-
 			dbg("%s - unconfigure phase 2", __FUNCTION__);
 			rc = pci_visit_dev(&unconfigure_functions_phase2,
 					   &wrapped_dev, &wrapped_bus);
diff -Nru a/drivers/hotplug/cpqphp.h b/drivers/hotplug/cpqphp.h
--- a/drivers/hotplug/cpqphp.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/hotplug/cpqphp.h	Tue Mar  4 19:30:13 2003
@@ -403,31 +403,8 @@
 #define msg_button_ignore	"PCI slot #%d - button press ignored.  (action in progress...)\n"
 
 
-/* Proc functions for the hotplug controller info */
-#ifdef CONFIG_PROC_FS
-extern int cpqhp_proc_init_ctrl		(void);
-extern int cpqhp_proc_destroy_ctrl	(void);
-extern int cpqhp_proc_create_ctrl	(struct controller *ctrl);
-extern int cpqhp_proc_remove_ctrl	(struct controller *ctrl);
-#else
-static inline int cpqhp_proc_init_ctrl (void)
-{
-	return 0;
-}
-static inline int cpqhp_proc_destroy_ctrl (void)
-{
-	return 0;
-}
-static inline int cpqhp_proc_create_ctrl (struct controller *ctrl)
-{
-	return 0;
-}
-static inline int cpqhp_proc_remove_ctrl (struct controller *ctrl)
-{
-	return 0;
-}
-#endif
-
+/* sysfs functions for the hotplug controller info */
+extern void cpqhp_create_ctrl_files		(struct controller *ctrl);
 
 /* controller functions */
 extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
diff -Nru a/drivers/hotplug/cpqphp_core.c b/drivers/hotplug/cpqphp_core.c
--- a/drivers/hotplug/cpqphp_core.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/hotplug/cpqphp_core.c	Tue Mar  4 19:30:03 2003
@@ -1038,6 +1038,7 @@
 	dbg ("    pcix_support           %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported");
 
 	ctrl->pci_dev = pdev;
+	pci_set_drvdata(pdev, ctrl);
 
 	/* make our own copy of the pci bus structure, as we like tweaking it a lot */
 	ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
@@ -1231,11 +1232,7 @@
 	// Done with exclusive hardware access
 	up(&ctrl->crit_sect);
 
-	rc = cpqhp_proc_create_ctrl (ctrl);
-	if (rc) {
-		err("cpqhp_proc_create_ctrl failed\n");
-		goto err_free_irq;
-	}
+	cpqhp_create_ctrl_files (ctrl);
 
 	return 0;
 
@@ -1309,10 +1306,6 @@
 		goto error;
 	}
 
-	retval = cpqhp_proc_init_ctrl();
-	if (retval)
-		goto error;
-
 	initialized = 1;
 
 	return retval;
@@ -1343,8 +1336,6 @@
 	ctrl = cpqhp_ctrl_list;
 
 	while (ctrl) {
-		cpqhp_proc_remove_ctrl (ctrl);
-
 		if (ctrl->hpc_reg) {
 			u16 misc;
 			rc = read_slot_enable (ctrl);
@@ -1431,8 +1422,6 @@
 		}
 	}
 
-	remove_proc_entry("hpc", 0);
-
 	// Stop the notification mechanism
 	cpqhp_event_stop_thread();
 
@@ -1490,9 +1479,6 @@
 
 static void __exit cpqhpc_cleanup(void)
 {
-	dbg("cleaning up proc entries\n");
-	cpqhp_proc_destroy_ctrl();
-
 	dbg("unload_cpqphpd()\n");
 	unload_cpqphpd();
 
diff -Nru a/drivers/hotplug/cpqphp_pci.c b/drivers/hotplug/cpqphp_pci.c
--- a/drivers/hotplug/cpqphp_pci.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/hotplug/cpqphp_pci.c	Tue Mar  4 19:30:13 2003
@@ -44,48 +44,6 @@
 
 static u16 unused_IRQ;
 
-
-static int is_pci_dev_in_use(struct pci_dev* dev) 
-{
-	/* 
-	 * dev->driver will be set if the device is in use by a new-style 
-	 * driver -- otherwise, check the device's regions to see if any
-	 * driver has claimed them
-	 */
-
-	int i, inuse=0;
-
-	if (dev->driver) return 1; //assume driver feels responsible
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-		if (!pci_resource_start(dev, i))
-			continue;
-
-		if (pci_resource_flags(dev, i) & IORESOURCE_IO)
-			inuse = check_region(pci_resource_start(dev, i),
-					     pci_resource_len(dev, i));
-		else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
-			inuse = check_mem_region(pci_resource_start(dev, i),
-						 pci_resource_len(dev, i));
-	}
-
-	return inuse;
-
-}
-
-
-static int pci_hp_remove_device(struct pci_dev *dev)
-{
-	if (is_pci_dev_in_use(dev)) {
-		err("***Cannot safely power down device -- "
-		       "it appears to be in use***\n");
-		return -EBUSY;
-	}
-	pci_remove_device(dev);
-	return 0;
-}
-
-
 /*
  * detect_HRT_floating_pointer
  *
@@ -122,144 +80,14 @@
 	return fp;
 }
 
-static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_bus* bus = wrapped_bus->bus;
-	struct pci_dev* dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i=0;
-
-	//We need to fix up the hotplug function representation with the linux representation
-	do {
-		temp_func = cpqhp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (temp_func) {
-		temp_func->pci_dev = dev;
-	} else {
-		//We did not even find a hotplug rep of the function, create it
-		//This code might be taken out if we can guarantee the creation of functions
-		//in parallel (hotplug and Linux at the same time).
-		dbg("@@@@@@@@@@@ cpqhp_slot_create in %s\n", __FUNCTION__);
-		temp_func = cpqhp_slot_create(bus->number);
-		if (temp_func == NULL)
-			return -ENOMEM;
-		temp_func->pci_dev = dev;
-	}
-
-	//Create /proc/bus/pci proc entry for this device and bus device is on
-	//Notify the drivers of the change
-	if (temp_func->pci_dev) {
-//		pci_insert_device (temp_func->pci_dev, bus);
-//		pci_proc_attach_device(temp_func->pci_dev);
-//		pci_announce_device_to_drivers(temp_func->pci_dev);
-	}
-
-	return 0;
-}
-
-
-static int unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_dev* dev = wrapped_dev->dev;
-
-	struct pci_func *temp_func;
-	int i=0;
-
-	//We need to remove the hotplug function representation with the linux representation
-	do {
-		temp_func = cpqhp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
-		if (temp_func) {
-			dbg("temp_func->function = %d\n", temp_func->function);
-		}
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	//Now, remove the Linux Representation
-	if (dev) {
-		if (pci_hp_remove_device(dev) == 0) {
-			kfree(dev); //Now, remove
-		} else {
-			return -1; // problems while freeing, abort visitation
-		}
-	}
-
-	if (temp_func) {
-		temp_func->pci_dev = NULL;
-	} else {
-		dbg("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
-	}
-
-	return 0;
-}
-
-
-static int unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev) 
-{
-	struct pci_bus* bus = wrapped_bus->bus;
-
-	//The cleanup code for proc entries regarding buses should be in the kernel...
-	if (bus->procdir)
-		dbg("detach_pci_bus %s\n", bus->procdir->name);
-	pci_proc_detach_bus(bus);
-	// The cleanup code should live in the kernel...
-	bus->self->subordinate = NULL;
-	// unlink from parent bus
-	list_del(&bus->node);
-
-	// Now, remove
-	if (bus)
-		kfree(bus);
-
-	return 0;
-}
-
-
-static int unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_dev* dev = wrapped_dev->dev;
-
-	dbg("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	//Now, remove the Linux Driver Representation 
-	if (dev->driver) {
-		if (dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return is_pci_dev_in_use(dev);
-}
-
-
-static struct pci_visit configure_functions = {
-	.visit_pci_dev =	configure_visit_pci_dev,
-};
-
-
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	unconfigure_visit_pci_dev_phase1
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	unconfigure_visit_pci_bus_phase2,               
-	.post_visit_pci_dev =	unconfigure_visit_pci_dev_phase2
-};
-
 
 int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  
 {
 	unsigned char bus;
 	struct pci_dev dev0;
 	struct pci_bus *child;
-	struct pci_dev* temp;
 	int rc = 0;
 
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-
 	memset(&dev0, 0, sizeof(struct pci_dev));
 
 	if (func->pci_dev == NULL)
@@ -287,44 +115,22 @@
 
 	}
 
-	temp = func->pci_dev;
-
-	if (temp) {
-		wrapped_dev.dev = temp;
-		wrapped_bus.bus = temp->bus;
-		rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-	}
 	return rc;
 }
 
 
 int cpqhp_unconfigure_device(struct pci_func* func) 
 {
-	int rc = 0;
 	int j;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-
 	dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
 
 	for (j=0; j<8 ; j++) {
 		struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
-		if (temp) {
-			wrapped_dev.dev = temp;
-			wrapped_bus.bus = temp->bus;
-			rc = pci_visit_dev(&unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-
-			rc = pci_visit_dev(&unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-		}
+		if (temp)
+			pci_remove_bus_device(temp);
 	}
-	return rc;
+	return 0;
 }
 
 static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
diff -Nru a/drivers/hotplug/cpqphp_proc.c b/drivers/hotplug/cpqphp_proc.c
--- a/drivers/hotplug/cpqphp_proc.c	Tue Mar  4 19:30:13 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,197 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/workqueue.h>
-#include <linux/pci.h>
-#include "cpqphp.h"
-
-
-
-static struct proc_dir_entry *ctrl_proc_root;
-
-/* A few routines that create proc entries for the hot plug controller */
-
-static int read_ctrl (char *buf, char **start, off_t offset, int len, int *eof, void *data)
-{
-	struct controller *ctrl = (struct controller *)data;
-	char * out = buf;
-	int index;
-	struct pci_resource *res;
-
-	if (offset > 0)	return 0; /* no partial requests */
-	len  = 0;
-	*eof = 1;
-
-	out += sprintf(out, "hot plug ctrl Info Page\n");
-	out += sprintf(out, "bus = %d, device = %d, function = %d\n",
-		       ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
-		       PCI_FUNC(ctrl->pci_dev->devfn));
-	out += sprintf(out, "Free resources: memory\n");
-	index = 11;
-	res = ctrl->mem_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: prefetchable memory\n");
-	index = 11;
-	res = ctrl->p_mem_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: IO\n");
-	index = 11;
-	res = ctrl->io_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: bus numbers\n");
-	index = 11;
-	res = ctrl->bus_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-
-	*start = buf;
-	len = out-buf;
-
-	return len;
-}
-
-static int read_dev (char *buf, char **start, off_t offset, int len, int *eof, void *data)
-{
-	struct controller *ctrl = (struct controller *)data;
-	char * out = buf;
-	int index;
-	struct pci_resource *res;
-	struct pci_func *new_slot;
-	struct slot *slot;
-
-	if (offset > 0)	return 0; /* no partial requests */
-	len  = 0;
-	*eof = 1;
-
-	out += sprintf(out, "hot plug ctrl Info Page\n");
-	out += sprintf(out, "bus = %d, device = %d, function = %d\n",
-		       ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
-		       PCI_FUNC(ctrl->pci_dev->devfn));
-
-	slot=ctrl->slot;
-
-	while (slot) {
-		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
-		if (!new_slot)
-			break;
-		out += sprintf(out, "assigned resources: memory\n");
-		index = 11;
-		res = new_slot->mem_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: prefetchable memory\n");
-		index = 11;
-		res = new_slot->p_mem_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: IO\n");
-		index = 11;
-		res = new_slot->io_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: bus numbers\n");
-		index = 11;
-		res = new_slot->bus_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		slot=slot->next;
-	}
-
-	*start = buf;
-	len = out-buf;
-
-	return len;
-}
-
-int cpqhp_proc_create_ctrl (struct controller *ctrl)
-{
-	strcpy(ctrl->proc_name, "hpca");
-	ctrl->proc_name[3] = 'a' + ctrl->bus;
-
-	ctrl->proc_entry = create_proc_entry(ctrl->proc_name, S_IFREG | S_IRUGO, ctrl_proc_root);
-	ctrl->proc_entry->data = ctrl;
-	ctrl->proc_entry->read_proc = &read_ctrl;
-
-	strcpy(ctrl->proc_name2, "slot_a");
-	ctrl->proc_name2[5] = 'a' + ctrl->bus;
-	ctrl->proc_entry2 = create_proc_entry(ctrl->proc_name2, S_IFREG | S_IRUGO, ctrl_proc_root);
-	ctrl->proc_entry2->data = ctrl;
-	ctrl->proc_entry2->read_proc = &read_dev;
-
-	return 0;
-}
-
-int cpqhp_proc_remove_ctrl (struct controller *ctrl)
-{
-	if (ctrl->proc_entry)
-		remove_proc_entry(ctrl->proc_name, ctrl_proc_root);
-	if (ctrl->proc_entry2)
-		remove_proc_entry(ctrl->proc_name2, ctrl_proc_root);
-
-	return 0;
-}
-	
-int cpqhp_proc_init_ctrl (void)
-{
-	ctrl_proc_root = proc_mkdir("hpc", proc_root_driver);
-	if (!ctrl_proc_root)
-		return -ENOMEM;
-	ctrl_proc_root->owner = THIS_MODULE;
-	return 0;
-}
-
-int cpqhp_proc_destroy_ctrl (void)
-{
-	remove_proc_entry("hpc", proc_root_driver);
-	return 0;
-}
-
diff -Nru a/drivers/hotplug/cpqphp_sysfs.c b/drivers/hotplug/cpqphp_sysfs.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/hotplug/cpqphp_sysfs.c	Tue Mar  4 19:30:13 2003
@@ -0,0 +1,143 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include "cpqphp.h"
+
+
+/* A few routines that create sysfs entries for the hot plug controller */
+
+static int show_ctrl (struct device *dev, char *buf)
+{
+	struct pci_dev *pci_dev;
+	struct controller *ctrl;
+	char * out = buf;
+	int index;
+	struct pci_resource *res;
+
+	pci_dev = container_of (dev, struct pci_dev, dev);
+	ctrl = pci_get_drvdata(pci_dev);
+
+	out += sprintf(buf, "Free resources: memory\n");
+	index = 11;
+	res = ctrl->mem_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: prefetchable memory\n");
+	index = 11;
+	res = ctrl->p_mem_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: IO\n");
+	index = 11;
+	res = ctrl->io_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: bus numbers\n");
+	index = 11;
+	res = ctrl->bus_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+
+	return out - buf;
+}
+static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
+
+static int show_dev (struct device *dev, char *buf)
+{
+	struct pci_dev *pci_dev;
+	struct controller *ctrl;
+	char * out = buf;
+	int index;
+	struct pci_resource *res;
+	struct pci_func *new_slot;
+	struct slot *slot;
+
+	pci_dev = container_of (dev, struct pci_dev, dev);
+	ctrl = pci_get_drvdata(pci_dev);
+
+	slot=ctrl->slot;
+
+	while (slot) {
+		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
+		if (!new_slot)
+			break;
+		out += sprintf(out, "assigned resources: memory\n");
+		index = 11;
+		res = new_slot->mem_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: prefetchable memory\n");
+		index = 11;
+		res = new_slot->p_mem_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: IO\n");
+		index = 11;
+		res = new_slot->io_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: bus numbers\n");
+		index = 11;
+		res = new_slot->bus_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		slot=slot->next;
+	}
+
+	return out - buf;
+}
+static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
+
+void cpqhp_create_ctrl_files (struct controller *ctrl)
+{
+	device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
+	device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
+}
diff -Nru a/drivers/hotplug/ibmphp.h b/drivers/hotplug/ibmphp.h
--- a/drivers/hotplug/ibmphp.h	Tue Mar  4 19:30:04 2003
+++ b/drivers/hotplug/ibmphp.h	Tue Mar  4 19:30:04 2003
@@ -683,11 +683,6 @@
 #define ENABLE		1
 #define DISABLE		0
 
-#define ADD		0
-#define REMOVE		1
-#define DETAIL		2
-
-#define MAX_OPS		3
 #define CARD_INFO	0x07
 #define PCIX133		0x07
 #define PCIX66		0x05
@@ -761,6 +756,7 @@
 
 extern int ibmphp_init_devno (struct slot **);	/* This function is called from EBDA, so we need it not be static */
 extern int ibmphp_disable_slot (struct hotplug_slot *);	/* This function is called from HPC, so we need it to not be static */
+extern int ibmphp_do_disable_slot (struct slot *slot_cur);
 extern int ibmphp_update_slot_info (struct slot *);	/* This function is called from HPC, so we need it to not be be static */
 extern int ibmphp_configure_card (struct pci_func *, u8);
 extern int ibmphp_unconfigure_card (struct slot **, int);
diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
--- a/drivers/hotplug/ibmphp_core.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/hotplug/ibmphp_core.c	Tue Mar  4 19:30:14 2003
@@ -55,7 +55,6 @@
 MODULE_LICENSE ("GPL");
 MODULE_DESCRIPTION (DRIVER_DESC);
 
-static int *ops[MAX_OPS + 1];
 struct pci_bus *ibmphp_pci_bus;
 static int max_slots;
 
@@ -550,20 +549,6 @@
 	struct list_head *tmp;
 	int retval;
 	int rc;
-	int j;
-
-	for (j = 0; j < MAX_OPS; j++) {
-		ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL);
-		memset (ops[j], 0, (max_slots + 1) * sizeof (int));
-		if (!ops[j]) {
-			err ("out of system memory \n");
-			return -ENOMEM;
-		}
-	}
-
-	ops[ADD][0] = 0;
-	ops[REMOVE][0] = 0;
-	ops[DETAIL][0] = 0;
 
 	list_for_each (tmp, &ibmphp_slot_head) {
 		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
@@ -588,24 +573,15 @@
 		if (retval)
 			return retval;
 
-		debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status);
-		debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status));
-
-		if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
-			/* No power, adapter, and latch closed */
-			ops[ADD][slot_cur->number] = 1;
-		else
-			ops[ADD][slot_cur->number] = 0;
-
-		ops[DETAIL][slot_cur->number] = 1;
-
-		if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
-			/*Power,adapter,latch closed */
-			ops[REMOVE][slot_cur->number] = 1;
-		else
-			ops[REMOVE][slot_cur->number] = 0;
-
-		if ((SLOT_PWRGD (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) {
+		debug ("status = %x\n", slot_cur->status);
+		debug ("ext_status = %x\n", slot_cur->ext_status);
+		debug ("SLOT_POWER = %x\n", SLOT_POWER (slot_cur->status));
+		debug ("SLOT_PRESENT = %x\n", SLOT_PRESENT (slot_cur->status));
+		debug ("SLOT_LATCH = %x\n", SLOT_LATCH (slot_cur->status));
+
+		if ((SLOT_PWRGD (slot_cur->status)) && 
+		    !(SLOT_PRESENT (slot_cur->status)) && 
+		    !(SLOT_LATCH (slot_cur->status))) {
 			debug ("BEFORE POWER OFF COMMAND\n");
 				rc = power_off (slot_cur);
 				if (rc)
@@ -643,35 +619,20 @@
 	if (retval)
 		return retval;
 
-	if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
-	    && !(SLOT_LATCH (slot_cur->status)))
-		ops[ADD][number] = 1;
-	else
-		ops[ADD][number] = 0;
-
-	ops[DETAIL][number] = 1;
-
-	if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
-	    && !(SLOT_LATCH (slot_cur->status)))
-		ops[REMOVE][number] = 1;
-	else
-		ops[REMOVE][number] = 0;
-
 	switch (opn) {
 		case ENABLE:
-			if (ops[ADD][number])
+			if (!(SLOT_PWRGD (slot_cur->status)) && 
+			     (SLOT_PRESENT (slot_cur->status)) && 
+			     !(SLOT_LATCH (slot_cur->status)))
 				return 0;
 			break;
 		case DISABLE:
-			if (ops[REMOVE][number])
-				return 0;
-			break;
-		case DETAIL:
-			if (ops[DETAIL][number])
+			if ((SLOT_PWRGD (slot_cur->status)) && 
+			    (SLOT_PRESENT (slot_cur->status)) &&
+			    !(SLOT_LATCH (slot_cur->status)))
 				return 0;
 			break;
 		default:
-			return -EINVAL;
 			break;
 	}
 	err ("validate failed....\n");
@@ -820,174 +781,23 @@
 	debug ("%s -- exit\n", __FUNCTION__);
 }
 
-static int ibm_is_pci_dev_in_use (struct pci_dev *dev)
-{
-	int i = 0;
-	int inuse = 0;
-
-	if (dev->driver)
-		return 1;
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-
-		if (!pci_resource_start (dev, i))
-			continue;
-
-		if (pci_resource_flags (dev, i) & IORESOURCE_IO)
-			inuse = check_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
-
-		else if (pci_resource_flags (dev, i) & IORESOURCE_MEM)
-			inuse = check_mem_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
-	}
-
-	return inuse;
-}
-
-static int ibm_pci_hp_remove_device (struct pci_dev *dev)
-{
-	if (ibm_is_pci_dev_in_use (dev)) {
-		err ("***Cannot safely power down device -- it appears to be in use***\n");
-		return -EBUSY;
-	}
-	pci_remove_device (dev);
-	return 0;
-}
-
-static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i = 0;
-
-	do {
-		temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (dev) {
-		if (ibm_pci_hp_remove_device (dev) == 0)
-			kfree (dev);    /* Now, remove */
-		else
-			return -1;
-	}
-
-	if (temp_func)
-		temp_func->dev = NULL;
-	else
-		debug ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
-
-	return 0;
-}
-
-static int ibm_unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
-{
-	struct pci_bus *bus = wrapped_bus->bus;
-
-	pci_proc_detach_bus (bus);
-	/* The cleanup code should live in the kernel... */
-	bus->self->subordinate = NULL;
-	/* unlink from parent bus */
-	list_del (&bus->node);
-
-	/* Now, remove */
-	if (bus)
-		kfree (bus);
-
-	return 0;
-}
-
-static int ibm_unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	debug ("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT (dev->devfn), PCI_FUNC (dev->devfn));
-
-	/* Now, remove the Linux Driver Representation */
-	if (dev->driver) {
-		debug ("is there a driver?\n");
-		if (dev->driver->remove) {
-			dev->driver->remove (dev);
-			debug ("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return ibm_is_pci_dev_in_use (dev);
-}
-
-static struct pci_visit ibm_unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase1,
-};
-
-static struct pci_visit ibm_unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	ibm_unconfigure_visit_pci_bus_phase2,
-	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase2,
-};
-
 static int ibm_unconfigure_device (struct pci_func *func)
 {
-	int rc = 0;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	struct pci_dev *temp;
 	u8 j;
 
-	memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
-	debug ("inside ibm_unconfigure_device\n");
+	debug ("inside %s\n", __FUNCTION__);
 	debug ("func->device = %x, func->function = %x\n", func->device, func->function);
 	debug ("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
 
 	for (j = 0; j < 0x08; j++) {
 		temp = pci_find_slot (func->busno, (func->device << 3) | j);
-		if (temp) {
-			wrapped_dev.dev = temp;
-			wrapped_bus.bus = temp->bus;
-			rc = pci_visit_dev (&ibm_unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-
-			rc = pci_visit_dev (&ibm_unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-		}
+		if (temp)
+			pci_remove_bus_device(temp);
 	}
-	debug ("rc in ibm_unconfigure_device b4 returning is %d \n", rc);
-	return rc;
-}
-
-static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	//      struct pci_bus *bus = wrapped_bus->bus; /* We don't need this, since we don't create in the else statement */
-	struct pci_dev *dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i = 0;
-
-	do {
-		temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (temp_func)
-		temp_func->dev = dev;
-	else {
-		/* This should not really happen, since we create functions
-		   first and then call to configure */
-		debug (" We shouldn't come here \n");
-	}
-
-	if (temp_func->dev) {
-//		pci_proc_attach_device (temp_func->dev);
-//		pci_announce_device_to_drivers (temp_func->dev);
-	}
-
 	return 0;
 }
 
-static struct pci_visit configure_functions = {
-	.visit_pci_dev =configure_visit_pci_dev,
-};
-
-
 /*
  * The following function is to fix kernel bug regarding 
  * getting bus entries, here we manually add those primary 
@@ -1037,15 +847,9 @@
 	unsigned char bus;
 	struct pci_dev dev0;
 	struct pci_bus *child;
-	struct pci_dev *temp;
 	int rc = 0;
 	int flag = 0;	/* this is to make sure we don't double scan the bus, for bridged devices primarily */
 
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-
-	memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
 	memset (&dev0, 0, sizeof (struct pci_dev));
 
 	if (!(bus_structure_fixup (func->busno)))
@@ -1073,12 +877,6 @@
 		pci_do_scan_bus (child);
 	}
 
-	temp = func->dev;
-	if (temp) {
-		wrapped_dev.dev = temp;
-		wrapped_bus.bus = temp->bus;
-		rc = pci_visit_dev (&configure_functions, &wrapped_dev, &wrapped_bus);
-	}
 	return rc;
 }
 
@@ -1274,7 +1072,6 @@
 	int rc, i, rcpr;
 	struct slot *slot_cur;
 	u8 function;
-	u8 faulted = 0;
 	struct pci_func *tmp_func;
 
 	ibmphp_lock_operations ();
@@ -1284,16 +1081,7 @@
 
 	if ((rc = validate (slot_cur, ENABLE))) {
 		err ("validate function failed \n");
-		attn_off (slot_cur);	/* need to turn off if was blinking b4 */
-		attn_on (slot_cur);
-		rc = slot_update (&slot_cur);
-		if (rc) {
-			ibmphp_unlock_operations();
-			return rc;
-		}
-		ibmphp_update_slot_info (slot_cur);
-                ibmphp_unlock_operations ();
-		return rc;
+		goto error_nopower;
 	}
 
 	attn_LED_blink (slot_cur);
@@ -1301,10 +1089,7 @@
 	rc = set_bus (slot_cur);
 	if (rc) {
 		err ("was not able to set the bus \n");
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		ibmphp_unlock_operations ();
-		return -ENODEV;
+		goto error_nopower;
 	}
 
 	/*-----------------debugging------------------------------*/
@@ -1314,18 +1099,12 @@
 
 	rc = check_limitations (slot_cur);
 	if (rc) {
-		err ("Adding this card exceeds the limitations of this bus. \n");
-		err ("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus \n. Try hot-adding into another bus \n");
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-
-		if (slot_update (&slot_cur)) {
-			ibmphp_unlock_operations ();
-			return -ENODEV;
-		}
-		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return -EINVAL;
+		err ("Adding this card exceeds the limitations of this bus.\n");
+		err ("(i.e., >1 133MHz cards running on same bus, or "
+		     ">2 66 PCI cards running on same bus\n.");
+		err ("Try hot-adding into another bus \n");
+		rc = -EINVAL;
+		goto error_nopower;
 	}
 
 	rc = power_on (slot_cur);
@@ -1338,22 +1117,21 @@
 		if (slot_update (&slot_cur)) {
 			attn_off (slot_cur);
 			attn_on (slot_cur);
-			ibmphp_unlock_operations ();
-			return -ENODEV;
+			rc = -ENODEV;
+			goto exit;
 		}
 		/* Check to see the error of why it failed */
 		if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PWRGD (slot_cur->status)))
-			err ("power fault occured trying to power up \n");
+			err ("power fault occurred trying to power up \n");
 		else if (SLOT_BUS_SPEED (slot_cur->status)) {
-			err ("bus speed mismatch occured.  please check current bus speed and card capability \n");
+			err ("bus speed mismatch occurred.  please check current bus speed and card capability \n");
 			print_card_capability (slot_cur);
 		} else if (SLOT_BUS_MODE (slot_cur->ext_status)) {
-			err ("bus mode mismatch occured.  please check current bus mode and card capability \n");
+			err ("bus mode mismatch occurred.  please check current bus mode and card capability \n");
 			print_card_capability (slot_cur);
 		}
 		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return rc;
+		goto exit;
 	}
 	debug ("after power_on\n");
 	/*-----------------------debugging---------------------------*/
@@ -1362,61 +1140,32 @@
 	/*----------------------------------------------------------*/
 
 	rc = slot_update (&slot_cur);
-	if (rc) {
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		rcpr = power_off (slot_cur);
-		if (rcpr) {
-			ibmphp_unlock_operations ();
-			return rcpr;
-		}
-		ibmphp_unlock_operations ();
-		return rc;
-	}
+	if (rc)
+		goto error_power;
 	
+	rc = -EINVAL;
 	if (SLOT_POWER (slot_cur->status) && !(SLOT_PWRGD (slot_cur->status))) {
-		faulted = 1;
-		err ("power fault occured trying to power up... \n");
-	} else if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
-		faulted = 1;
-		err ("bus speed mismatch occured.  please check current bus speed and card capability \n");
+		err ("power fault occurred trying to power up... \n");
+		goto error_power;
+	}
+	if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
+		err ("bus speed mismatch occurred.  please check current bus speed and card capability \n");
 		print_card_capability (slot_cur);
+		goto error_power;
 	} 
 	/* Don't think this case will happen after above checks... but just in case, for paranoia sake */
-	else if (!(SLOT_POWER (slot_cur->status))) {
+	if (!(SLOT_POWER (slot_cur->status))) {
 		err ("power on failed... \n");
-		faulted = 1;
-	}
-	if (faulted) {
-		attn_off (slot_cur);	/* need to turn off b4 on */
-		attn_on (slot_cur);
-		rcpr = power_off (slot_cur);
-		if (rcpr) {
-			ibmphp_unlock_operations ();
-			return rcpr;
-		}
-			
-		if (slot_update (&slot_cur)) {                      
-			ibmphp_unlock_operations ();	
-			return -ENODEV;
-		}
-		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return -EINVAL;
+		goto error_power;
 	}
 
 	slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
-	if (!slot_cur->func) { /* We cannot do update_slot_info here, since no memory for kmalloc n.e.ways, and update_slot_info allocates some */
+	if (!slot_cur->func) {
+		/* We cannot do update_slot_info here, since no memory for
+		 * kmalloc n.e.ways, and update_slot_info allocates some */
 		err ("out of system memory \n");
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		rcpr = power_off (slot_cur);
-		if (rcpr) {
-			ibmphp_unlock_operations ();
-			return rcpr;
-		}
-		ibmphp_unlock_operations ();
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto error_power;
 	}
 	memset (slot_cur->func, 0, sizeof (struct pci_func));
 	slot_cur->func->busno = slot_cur->bus;
@@ -1431,21 +1180,10 @@
 		ibmphp_unconfigure_card (&slot_cur, 1); /* true because don't need to actually deallocate resources, just remove references */
 		debug ("after unconfigure_card\n");
 		slot_cur->func = NULL;
-		attn_off (slot_cur);	/* need to turn off in case was blinking */
-		attn_on (slot_cur);
-		rcpr = power_off (slot_cur);
-		if (rcpr) {
-			ibmphp_unlock_operations ();
-			return rcpr;
-		}
-		if (slot_update (&slot_cur)) {
-			ibmphp_unlock_operations();
-			return -ENODEV;
-		}
-		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto error_power;
 	}
+
 	function = 0x00;
 	do {
 		tmp_func = ibm_slot_find (slot_cur->bus, slot_cur->func->device, function++);
@@ -1455,13 +1193,36 @@
 
 	attn_off (slot_cur);
 	if (slot_update (&slot_cur)) {
-		ibmphp_unlock_operations ();
-		return -EFAULT;
+		rc = -EFAULT;
+		goto exit;
 	}
 	ibmphp_print_test ();
 	rc = ibmphp_update_slot_info (slot_cur);
+exit:
 	ibmphp_unlock_operations(); 
 	return rc;
+
+error_nopower:
+	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
+	attn_on (slot_cur);
+error_cont:
+	rcpr = slot_update (&slot_cur);
+	if (rcpr) {
+		rc = rcpr;
+		goto exit;
+	}
+	ibmphp_update_slot_info (slot_cur);
+	goto exit;
+
+error_power:
+	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
+	attn_on (slot_cur);
+	rcpr = power_off (slot_cur);
+	if (rcpr) {
+		rc = rcpr;
+		goto exit;
+	}
+	goto error_cont;
 }
 
 /**************************************************************
@@ -1472,45 +1233,34 @@
 **************************************************************/
 int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
 {
+	struct slot *slot = hotplug_slot->private;
+	int rc;
+	
+	ibmphp_lock_operations();
+	rc = ibmphp_do_disable_slot(slot);
+	ibmphp_unlock_operations();
+	return rc;
+}
+
+int ibmphp_do_disable_slot (struct slot *slot_cur)
+{
 	int rc;
-	struct slot *slot_cur = (struct slot *) hotplug_slot->private;
 	u8 flag;
 	int parm = 0;
 
 	debug ("DISABLING SLOT... \n"); 
 		
-	if (slot_cur == NULL) {
-		ibmphp_unlock_operations (); 
-		return -ENODEV;
-	}
-	
-	if (slot_cur->ctrl == NULL) {
-		ibmphp_unlock_operations ();
+	if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
 		return -ENODEV;
 	}
 	
-	flag = slot_cur->flag;	/* to see if got here from polling */
-	
-	if (flag)
-		ibmphp_lock_operations ();
-	
+	flag = slot_cur->flag;
 	slot_cur->flag = TRUE;
 
 	if (flag == TRUE) {
 		rc = validate (slot_cur, DISABLE);	/* checking if powered off already & valid slot # */
-		if (rc) {
-			/*  Need to turn off if was blinking b4 */
-			attn_off (slot_cur);
-			attn_on (slot_cur);
-			if (slot_update (&slot_cur)) {
-				ibmphp_unlock_operations ();
-				return -EFAULT;
-			}
-		
-			ibmphp_update_slot_info (slot_cur);
-			ibmphp_unlock_operations ();
-			return rc;
-		}
+		if (rc)
+			goto error;
 	}
 	attn_LED_blink (slot_cur);
 
@@ -1519,10 +1269,8 @@
 		slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
 		if (!slot_cur->func) {
 			err ("out of system memory \n");
-			attn_off (slot_cur);
-			attn_on (slot_cur);
-			ibmphp_unlock_operations ();
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto error;
 		}
 		memset (slot_cur->func, 0, sizeof (struct pci_func));
 		slot_cur->func->busno = slot_cur->bus;
@@ -1531,11 +1279,9 @@
 
 	if ((rc = ibm_unconfigure_device (slot_cur->func))) {
 		err ("removing from kernel failed... \n");
-		err ("Please check to see if it was statically linked or is in use otherwise. (perhaps the driver is not 'hot-removable')\n");
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		ibmphp_unlock_operations ();
-		return rc;
+		err ("Please check to see if it was statically linked or is "
+		     "in use otherwise. (perhaps the driver is not 'hot-removable')\n");
+		goto error;
 	}
         
 	/* If we got here from latch suddenly opening on operating card or 
@@ -1554,43 +1300,34 @@
 	debug ("in disable_slot. after unconfigure_card\n");
 	if (rc) {
 		err ("could not unconfigure card.\n");
-		attn_off (slot_cur);	/* need to turn off if was blinking b4 */
-		attn_on (slot_cur);
-
-		if (slot_update (&slot_cur)) {
-			ibmphp_unlock_operations ();
-			return -EFAULT;
-		}
-
-		if (flag)
-			ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return -EFAULT;
+		goto error;
 	}
 
-	rc = ibmphp_hpc_writeslot (hotplug_slot->private, HPC_SLOT_OFF);
-	if (rc) {
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		if (slot_update (&slot_cur)) {
-			ibmphp_unlock_operations ();
-			return -EFAULT;
-		}
-
-		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return rc;
-	}
+	rc = ibmphp_hpc_writeslot (slot_cur, HPC_SLOT_OFF);
+	if (rc)
+		goto error;
 
 	attn_off (slot_cur);
-	if (slot_update (&slot_cur)) {
-		ibmphp_unlock_operations ();
-		return -EFAULT;
-	}
+	rc = slot_update (&slot_cur);
+	if (rc)
+		goto exit;
+
 	rc = ibmphp_update_slot_info (slot_cur);
 	ibmphp_print_test ();
-	ibmphp_unlock_operations();
+exit:
 	return rc;
+
+error:
+	/*  Need to turn off if was blinking b4 */
+	attn_off (slot_cur);
+	attn_on (slot_cur);
+	if (slot_update (&slot_cur)) {
+		rc = -EFAULT;
+		goto exit;
+	}
+	if (flag)		
+		ibmphp_update_slot_info (slot_cur);
+	goto exit;
 }
 
 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
@@ -1622,6 +1359,7 @@
 	debug ("after ebda hpc \n");
 	ibmphp_free_ebda_pci_rsrc_queue ();
 	debug ("after ebda pci rsrc \n");
+	kfree (ibmphp_pci_bus);
 }
 
 static int __init ibmphp_init (void)
@@ -1637,13 +1375,15 @@
 	ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL);
 	if (!ibmphp_pci_bus) {
 		err ("out of memory\n");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto exit;
 	}
 
 	bus = ibmphp_find_bus (0);
 	if (!bus) {
 		err ("Can't find the root pci bus, can not continue\n");
-		return -ENODEV;
+		rc = -ENODEV;
+		goto error;
 	}
 	memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
 
@@ -1654,39 +1394,39 @@
 	for (i = 0; i < 16; i++)
 		irqs[i] = 0;
 
-	if ((rc = ibmphp_access_ebda ())) {
-		ibmphp_unload ();
-		return rc;
-	}
+	if ((rc = ibmphp_access_ebda ()))
+		goto error;
 	debug ("after ibmphp_access_ebda ()\n");
 
-	if ((rc = ibmphp_rsrc_init ())) {
-		ibmphp_unload ();
-		return rc;
-	}
+	if ((rc = ibmphp_rsrc_init ()))
+		goto error;
 	debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
 
 	max_slots = get_max_slots ();
 	
-	if ((rc = ibmphp_register_pci ())) {
-		ibmphp_unload ();
-		return rc;
-	}
+	if ((rc = ibmphp_register_pci ()))
+		goto error;
 
 	if (init_ops ()) {
-		ibmphp_unload ();
-		return -ENODEV;
+		rc = -ENODEV;
+		goto error;
 	}
+
 	ibmphp_print_test ();
 	if ((rc = ibmphp_hpc_start_poll_thread ())) {
-		ibmphp_unload ();
-		return -ENODEV;
+		goto error;
 	}
 
-	/* if no NVRAM module selected, lock ourselves into memory with a 
-	 * module count of -1 so that no one can unload us. */
+	/* lock ourselves into memory with a module 
+	 * count of -1 so that no one can unload us. */
 	MOD_DEC_USE_COUNT;
-	return 0;
+
+exit:
+	return rc;
+
+error:
+	ibmphp_unload ();
+	goto exit;
 }
 
 static void __exit ibmphp_exit (void)
diff -Nru a/drivers/hotplug/ibmphp_hpc.c b/drivers/hotplug/ibmphp_hpc.c
--- a/drivers/hotplug/ibmphp_hpc.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/hotplug/ibmphp_hpc.c	Tue Mar  4 19:30:05 2003
@@ -1063,7 +1063,7 @@
 	if (disable) {
 		debug ("process_changeinstatus - disable slot\n");
 		pslot->flag = FALSE;
-		rc = ibmphp_disable_slot (pslot->hotplug_slot);
+		rc = ibmphp_do_disable_slot (pslot);
 	}
 
 	if (update || disable) {
diff -Nru a/drivers/hotplug/ibmphp_res.c b/drivers/hotplug/ibmphp_res.c
--- a/drivers/hotplug/ibmphp_res.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/hotplug/ibmphp_res.c	Tue Mar  4 19:30:13 2003
@@ -740,7 +740,7 @@
 				res->nextRange = NULL;
 			}
 		} else {
-			/* this is the case where it is 1st occurence of the range */
+			/* this is the case where it is 1st occurrence of the range */
 			if (!res_prev) {
 				/* at the beginning of the resource list */
 				res->next = NULL;
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/hotplug/pci_hotplug_core.c	Tue Mar  4 19:30:13 2003
@@ -67,8 +67,6 @@
 
 //////////////////////////////////////////////////////////////////
 
-static spinlock_t list_lock;
-
 static LIST_HEAD(pci_hotplug_slot_list);
 
 static struct subsystem hotplug_slots_subsys;
@@ -531,23 +529,16 @@
 	if ((slot->info == NULL) || (slot->ops == NULL))
 		return -EINVAL;
 
-	/* make sure we have not already registered this slot */
-	spin_lock (&list_lock);
-	if (get_slot_from_name (slot->name) != NULL) {
-		spin_unlock (&list_lock);
-		return -EINVAL;
-	}
-
 	strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
 	kobj_set_kset_s(slot, hotplug_slots_subsys);
 
+	/* this can fail if we have already registered a slot with the same name */
 	if (kobject_register(&slot->kobj)) {
 		err("Unable to register kobject");
 		return -EINVAL;
 	}
 		
 	list_add (&slot->slot_list, &pci_hotplug_slot_list);
-	spin_unlock (&list_lock);
 
 	result = fs_add_slot (slot);
 	dbg ("Added slot %s to the list\n", slot->name);
@@ -570,16 +561,11 @@
 	if (slot == NULL)
 		return -ENODEV;
 
-	/* make sure we have this slot in our list before trying to delete it */
-	spin_lock (&list_lock);
 	temp = get_slot_from_name (slot->name);
 	if (temp != slot) {
-		spin_unlock (&list_lock);
 		return -ENODEV;
 	}
-
 	list_del (&slot->slot_list);
-	spin_unlock (&list_lock);
 
 	fs_remove_slot (slot);
 	dbg ("Removed slot %s from the list\n", slot->name);
@@ -638,8 +624,6 @@
 static int __init pci_hotplug_init (void)
 {
 	int result;
-
-	spin_lock_init(&list_lock);
 
 	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
 	result = subsystem_register(&hotplug_slots_subsys);
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/i2c/busses/i2c-amd8111.c	Tue Mar  4 19:30:13 2003
@@ -8,10 +8,8 @@
  * the Free Software Foundation version 2.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <asm/io.h>
 #include <linux/kernel.h>
 #include <linux/stddef.h>
 #include <linux/sched.h>
@@ -19,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <asm/io.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR ("Vojtech Pavlik <vojtech@suse.cz>");
@@ -204,8 +203,6 @@
 			protocol |= AMD_SMB_PRTCL_BYTE_DATA;
 			break;
 
-		case I2C_SMBUS_WORD_DATA_PEC:
-			protocol |= AMD_SMB_PRTCL_PEC;
 		case I2C_SMBUS_WORD_DATA:
 			amd_ec_write(smbus, AMD_SMB_CMD, command);
 			if (read_write == I2C_SMBUS_WRITE) {
@@ -215,8 +212,6 @@
 			protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
 			break;
 
-		case I2C_SMBUS_BLOCK_DATA_PEC:
-			protocol |= AMD_SMB_PRTCL_PEC;
 		case I2C_SMBUS_BLOCK_DATA:
 			amd_ec_write(smbus, AMD_SMB_CMD, command);
 			if (read_write == I2C_SMBUS_WRITE) {
@@ -238,8 +233,6 @@
 			protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
 			break;
 
-		case I2C_SMBUS_PROC_CALL_PEC:
-			protocol |= AMD_SMB_PRTCL_PEC;
 		case I2C_SMBUS_PROC_CALL:
 			amd_ec_write(smbus, AMD_SMB_CMD, command);
 			amd_ec_write(smbus, AMD_SMB_DATA, data->word);
@@ -248,8 +241,6 @@
 			read_write = I2C_SMBUS_READ;
 			break;
 
-		case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
-			protocol |= AMD_SMB_PRTCL_PEC;
 		case I2C_SMBUS_BLOCK_PROC_CALL:
 			protocol |= pec;
 			len = min_t(u8, data->block[0], 31);
@@ -261,6 +252,13 @@
 			read_write = I2C_SMBUS_READ;
 			break;
 
+		case I2C_SMBUS_WORD_DATA_PEC:
+		case I2C_SMBUS_BLOCK_DATA_PEC:
+		case I2C_SMBUS_PROC_CALL_PEC:
+		case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+			printk(KERN_WARNING "i2c-amd8111.c: Unexpected software PEC transaction %d\n.", size);
+			return -1;
+
 		default:
 			printk(KERN_WARNING "i2c-amd8111.c: Unsupported transaction %d\n", size);
 			return -1;
@@ -296,18 +294,14 @@
 			break;
 
 		case I2C_SMBUS_WORD_DATA:
-		case I2C_SMBUS_WORD_DATA_PEC:
 		case I2C_SMBUS_PROC_CALL:
-		case I2C_SMBUS_PROC_CALL_PEC:
 			amd_ec_read(smbus, AMD_SMB_DATA, temp + 0);
 			amd_ec_read(smbus, AMD_SMB_DATA + 1, temp + 1);
 			data->word = (temp[1] << 8) | temp[0];
 			break;
 
 		case I2C_SMBUS_BLOCK_DATA:
-		case I2C_SMBUS_BLOCK_DATA_PEC:
 		case I2C_SMBUS_BLOCK_PROC_CALL:
-		case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
 			amd_ec_read(smbus, AMD_SMB_BCNT, &len);
 			len = min_t(u8, len, 32);
 		case I2C_SMBUS_I2C_BLOCK_DATA:
@@ -320,13 +314,12 @@
 	return 0;
 }
 
+
 u32 amd8111_func(struct i2c_adapter *adapter)
 {
 	return	I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
-		I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_WORD_DATA_PEC |
-		I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_DATA_PEC |
-		I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_PROC_CALL_PEC |
-		I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC |
+		I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
+		I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
 		I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC;
 }
 
@@ -337,78 +330,81 @@
 	.functionality = amd8111_func,
 };
 
+
+static struct pci_device_id amd8111_ids[] __devinitdata = {
+	{ 0x1022, 0x746a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ 0, }
+};
+
 static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	struct amd_smbus *smbus;
+	int error = -ENODEV;
 
 	if (~pci_resource_flags(dev, 0) & IORESOURCE_IO)
-		return -1;
+		return -ENODEV;
 
-	if (!(smbus = (void*)kmalloc(sizeof(struct amd_smbus), GFP_KERNEL)))
-		return -1;
+	smbus = kmalloc(sizeof(struct amd_smbus), GFP_KERNEL);
+	if (!smbus)
+		return -ENOMEM;
 	memset(smbus, 0, sizeof(struct amd_smbus));
 
-	pci_set_drvdata(dev, smbus);
 	smbus->dev = dev;
 	smbus->base = pci_resource_start(dev, 0);
 	smbus->size = pci_resource_len(dev, 0);
 
-	if (!request_region(smbus->base, smbus->size, "amd8111 SMBus 2.0")) {
-		kfree(smbus);
-		return -1;
-	}
+	if (!request_region(smbus->base, smbus->size, "amd8111 SMBus 2.0"))
+		goto out_kfree;
 
 	smbus->adapter.owner = THIS_MODULE;
-	sprintf(smbus->adapter.name, "SMBus2 AMD8111 adapter at %04x", smbus->base);
+	sprintf(smbus->adapter.name,
+			"SMBus2 AMD8111 adapter at %04x", smbus->base);
 	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111;
 	smbus->adapter.algo = &smbus_algorithm;
 	smbus->adapter.algo_data = smbus;
 
-	if (i2c_add_adapter(&smbus->adapter)) {
-		printk(KERN_WARNING "i2c-amd8111.c: Failed to register adapter.\n");
-		release_region(smbus->base, smbus->size);
-		kfree(smbus);
-		return -1;
-	}
+	error = i2c_add_adapter(&smbus->adapter);
+	if (error)
+		goto out_release_region;
 
 	pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
-
-	printk(KERN_INFO "i2c-amd8111.c: AMD8111 SMBus 2.0 adapter at %#x\n", smbus->base);
+	pci_set_drvdata(dev, smbus);
 	return 0;
+
+ out_release_region:
+	release_region(smbus->base, smbus->size);
+ out_kfree:
+	kfree(smbus);
+	return -1;
 }
 
+
 static void __devexit amd8111_remove(struct pci_dev *dev)
 {
-	struct amd_smbus *smbus = (void*) pci_get_drvdata(dev);
-	if (i2c_del_adapter(&smbus->adapter)) {
-		printk(KERN_WARNING "i2c-amd8111.c: Failed to unregister adapter.\n");
-		return;
-	}
+	struct amd_smbus *smbus = pci_get_drvdata(dev);
+
+	i2c_del_adapter(&smbus->adapter);
 	release_region(smbus->base, smbus->size);
 	kfree(smbus);
 }
 
-static struct pci_device_id amd8111_id_table[] __devinitdata =
-{{ 0x1022, 0x746a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0 }};
-
-
 static struct pci_driver amd8111_driver = {
-	.name = "amd8111 smbus 2.0",
-	.id_table = amd8111_id_table,
-	.probe = amd8111_probe,
-	.remove = __devexit_p(amd8111_remove),
+	.name		= "amd8111 smbus 2.0",
+	.id_table	= amd8111_ids,
+	.probe		= amd8111_probe,
+	.remove		= __devexit_p(amd8111_remove),
 };
 
-int __init amd8111_init(void)
+static int __init i2c_amd8111_init(void)
 {
 	return pci_module_init(&amd8111_driver);
 }
 
-void __exit amd8111_exit(void)
+
+static void __exit i2c_amd8111_exit(void)
 {
 	pci_unregister_driver(&amd8111_driver);
 }
 
-module_init(amd8111_init);
-module_exit(amd8111_exit);
+module_init(i2c_amd8111_init);
+module_exit(i2c_amd8111_exit);
diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/i2c/chips/adm1021.c	Tue Mar  4 19:30:04 2003
@@ -311,18 +311,14 @@
 		goto error3;
 
 	/* Register a new directory entry with module sensors */
-	if ((i = i2c_register_entry(new_client,
-					type_name,
-					data->type ==
-					adm1021 ?
-					adm1021_dir_table_template :
-					adm1021_max_dir_table_template,
-					THIS_MODULE)) < 0) {
-		err = i;
+	err = i2c_register_entry(new_client, type_name,
+			(data->type == adm1021) ?
+				adm1021_dir_table_template :
+				adm1021_max_dir_table_template);
+	if (err < 0)
 		goto error4;
-	}
-	data->sysctl_id = i;
 
+	data->sysctl_id = err;
 	/* Initialize the ADM1021 chip */
 	adm1021_init_client(new_client);
 	return 0;
diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
--- a/drivers/i2c/chips/lm75.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/i2c/chips/lm75.c	Tue Mar  4 19:30:03 2003
@@ -191,9 +191,8 @@
 		goto error3;
 
 	/* Register a new directory entry with module sensors */
-	if ((i = i2c_register_entry(new_client, type_name,
-					lm75_dir_table_template,
-					THIS_MODULE)) < 0) {
+	i = i2c_register_entry(new_client, type_name, lm75_dir_table_template);
+	if (i < 0) {
 		err = i;
 		goto error4;
 	}
diff -Nru a/drivers/i2c/i2c-adap-ite.c b/drivers/i2c/i2c-adap-ite.c
--- a/drivers/i2c/i2c-adap-ite.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/i2c/i2c-adap-ite.c	Tue Mar  4 19:30:05 2003
@@ -265,7 +265,7 @@
 MODULE_PARM(i2c_debug,"i");
 
 
-/* Called when module is loaded or when kernel is intialized.
+/* Called when module is loaded or when kernel is initialized.
  * If MODULES is defined when this file is compiled, then this function will
  * resolve to init_module (the function called when insmod is invoked for a
  * module).  Otherwise, this function is called early in the boot, when the
diff -Nru a/drivers/i2c/i2c-algo-ibm_ocp.c b/drivers/i2c/i2c-algo-ibm_ocp.c
--- a/drivers/i2c/i2c-algo-ibm_ocp.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/i2c/i2c-algo-ibm_ocp.c	Tue Mar  4 19:30:11 2003
@@ -758,7 +758,7 @@
         // Check to see if the bus is busy
         //
         ret = iic_inb(adap, iic->extsts);
-        // Mask off the irrelevent bits
+        // Mask off the irrelevant bits
         ret = ret & 0x70;
         // When the bus is free, the BCS bits in the EXTSTS register are 0b100
         if(ret != 0x40) return IIC_ERR_LOST_ARB;
diff -Nru a/drivers/i2c/i2c-algo-ite.c b/drivers/i2c/i2c-algo-ite.c
--- a/drivers/i2c/i2c-algo-ite.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/i2c/i2c-algo-ite.c	Tue Mar  4 19:30:13 2003
@@ -860,7 +860,7 @@
  * is loaded via insmod) when this file is compiled with MODULES defined.
  * Otherwise (i.e. if you want this driver statically linked to the kernel),
  * a pointer to this function is stored in a table and called
- * during the intialization of the kernel (in do_basic_setup in /init/main.c) 
+ * during the initialization of the kernel (in do_basic_setup in /init/main.c) 
  *
  * All this functionality is complements of the macros defined in linux/init.h
  */
diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/i2c/i2c-core.c	Tue Mar  4 19:30:04 2003
@@ -61,11 +61,9 @@
 
 /**** adapter list */
 static struct i2c_adapter *adapters[I2C_ADAP_MAX];
-static int adap_count;
 
 /**** drivers list */
 static struct i2c_driver *drivers[I2C_DRIVER_MAX];
-static int driver_count;
 
 /**** debug level */
 static int i2c_debug;
@@ -116,7 +114,6 @@
 	}
 
 	adapters[i] = adap;
-	adap_count++;
 	ADAP_UNLOCK();
 	
 	/* init data types */
@@ -161,7 +158,6 @@
 ERROR1:
 	ADAP_LOCK();
 	adapters[i] = NULL;
-	adap_count--;
 ERROR0:
 	ADAP_UNLOCK();
 	return res;
@@ -227,7 +223,6 @@
 #endif /* def CONFIG_PROC_FS */
 
 	adapters[i] = NULL;
-	adap_count--;
 	
 	ADAP_UNLOCK();	
 	DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name));
@@ -265,7 +260,6 @@
 	}
 
 	drivers[i] = driver;
-	driver_count++;
 	
 	DRV_UNLOCK();	/* driver was successfully added */
 	
@@ -361,7 +355,6 @@
 	}
 	ADAP_UNLOCK();
 	drivers[i] = NULL;
-	driver_count--;
 	DRV_UNLOCK();
 	
 	DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name));
@@ -465,73 +458,6 @@
 	module_put(client->adapter->owner);
 }
 
-struct i2c_client *i2c_get_client(int driver_id, int adapter_id, 
-					struct i2c_client *prev)
-{
-	int i,j;
-	
-	/* Will iterate through the list of clients in each adapter of adapters-list
-	   in search for a client that matches the search criteria. driver_id or 
-	   adapter_id are ignored if set to 0. If both are ignored this returns 
-	   first client found. */
-	
-	i = j = 0;  
-	
-	/* set starting point */ 
-	if(prev)
-	{
-		if(!(prev->adapter))
-			return (struct i2c_client *) -EINVAL;
-		
-		for(j=0; j < I2C_ADAP_MAX; j++)
-			if(prev->adapter == adapters[j])
-				break;
-		
-		/* invalid starting point? */
-		if (I2C_ADAP_MAX == j) {
-			printk(KERN_WARNING " i2c-core.o: get_client adapter for client:[%s] not found\n",
-				prev->name);
-			return (struct i2c_client *) -ENODEV;
-		}	
-		
-		for(i=0; i < I2C_CLIENT_MAX; i++)
-			if(prev == adapters[j]->clients[i])
-				break;
-		
-		/* invalid starting point? */
-		if (I2C_CLIENT_MAX == i) {
-			printk(KERN_WARNING " i2c-core.o: get_client client:[%s] not found\n",
-				prev->name);
-			return (struct i2c_client *) -ENODEV;
-		}	
-		
-		i++; /* start from one after prev */
-	}
-	
-	for(; j < I2C_ADAP_MAX; j++)
-	{
-		if(!adapters[j])
-			continue;
-			
-		if(adapter_id && (adapters[j]->id != adapter_id))
-			continue;
-		
-		for(; i < I2C_CLIENT_MAX; i++)
-		{
-			if(!adapters[j]->clients[i])
-				continue;
-				
-			if(driver_id && (adapters[j]->clients[i]->driver->id != driver_id))
-				continue;
-			if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE)	
-				return adapters[j]->clients[i];
-		}
-		i = 0;
-	}
-
-	return 0;
-}
-
 int i2c_use_client(struct i2c_client *client)
 {
 	if (!i2c_inc_use_client(client))
@@ -1421,11 +1347,9 @@
 EXPORT_SYMBOL(i2c_del_driver);
 EXPORT_SYMBOL(i2c_attach_client);
 EXPORT_SYMBOL(i2c_detach_client);
-EXPORT_SYMBOL(i2c_get_client);
 EXPORT_SYMBOL(i2c_use_client);
 EXPORT_SYMBOL(i2c_release_client);
 EXPORT_SYMBOL(i2c_check_addr);
-
 
 EXPORT_SYMBOL(i2c_master_send);
 EXPORT_SYMBOL(i2c_master_recv);
diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/i2c/i2c-dev.c	Tue Mar  4 19:30:12 2003
@@ -77,6 +77,7 @@
 static struct i2c_adapter *i2cdev_adaps[I2CDEV_ADAPS_MAX];
 
 static struct i2c_driver i2cdev_driver = {
+	.owner		= THIS_MODULE,
 	.name		= "i2c-dev dummy driver",
 	.id		= I2C_DRIVERID_I2CDEV,
 	.flags		= I2C_DF_DUMMY,
@@ -340,47 +341,42 @@
 	return 0;
 }
 
-int i2cdev_open (struct inode *inode, struct file *file)
+static int i2cdev_open(struct inode *inode, struct file *file)
 {
 	unsigned int minor = minor(inode->i_rdev);
 	struct i2c_client *client;
 
-	if ((minor >= I2CDEV_ADAPS_MAX) || ! (i2cdev_adaps[minor])) {
-#ifdef DEBUG
-		printk(KERN_DEBUG "i2c-dev.o: Trying to open unattached adapter i2c-%d\n",
-		       minor);
-#endif
+	if ((minor >= I2CDEV_ADAPS_MAX) || !(i2cdev_adaps[minor]))
 		return -ENODEV;
-	}
 
-	/* Note that we here allocate a client for later use, but we will *not*
-	   register this client! Yes, this is safe. No, it is not very clean. */
-	if(! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
+	client = kmalloc(sizeof(*client), GFP_KERNEL);
+	if (!client)
 		return -ENOMEM;
-	memcpy(client,&i2cdev_client_template,sizeof(struct i2c_client));
+	memcpy(client, &i2cdev_client_template, sizeof(*client));
+
+	/* registered with adapter, passed as client to user */
 	client->adapter = i2cdev_adaps[minor];
 	file->private_data = client;
 
-	if (!try_module_get(i2cdev_adaps[minor]->owner)) {
-		kfree(client);
-		return -ENODEV;
-	}
+	/* use adapter module, i2c-dev handled with fops */
+	if (!try_module_get(client->adapter->owner))
+		goto out_kfree;
 
-#ifdef DEBUG
-	printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor);
-#endif
 	return 0;
+
+ out_kfree:
+	kfree(client);
+	return -ENODEV;
 }
 
-static int i2cdev_release (struct inode *inode, struct file *file)
+static int i2cdev_release(struct inode *inode, struct file *file)
 {
-	unsigned int minor = minor(inode->i_rdev);
-	kfree(file->private_data);
-	file->private_data=NULL;
-#ifdef DEBUG
-	printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor);
-#endif
-	module_put(i2cdev_adaps[minor]->owner);
+	struct i2c_client *client = file->private_data;
+
+	module_put(client->adapter->owner);
+	kfree(client);
+	file->private_data = NULL;
+
 	return 0;
 }
 
diff -Nru a/drivers/i2c/i2c-proc.c b/drivers/i2c/i2c-proc.c
--- a/drivers/i2c/i2c-proc.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/i2c/i2c-proc.c	Tue Mar  4 19:30:09 2003
@@ -125,17 +125,12 @@
    ctl_template should be a template of the newly created directory. It is
    copied in memory. The extra2 field of each file is set to point to client.
    If any driver wants subdirectories within the newly created directory,
-   this function must be updated! 
-   controlling_mod is the controlling module. It should usually be
-   THIS_MODULE when calling. Note that this symbol is not defined in
-   kernels before 2.3.13; define it to NULL in that case. We will not use it
-   for anything older than 2.3.27 anyway. */
+   this function must be updated!  */
 int i2c_register_entry(struct i2c_client *client, const char *prefix,
-			   ctl_table * ctl_template,
-			   struct module *controlling_mod)
+			   ctl_table * ctl_template)
 {
 	int i, res, len, id;
-	ctl_table *new_table;
+	ctl_table *new_table, *client_tbl, *tbl;
 	char *name;
 	struct ctl_table_header *new_header;
 
@@ -150,26 +145,33 @@
 		kfree(name);
 		return -ENOMEM;
 	}
-	id += 256;
 
+	id += 256;
+	
 	len = 0;
 	while (ctl_template[len].procname)
 		len++;
-	len += 7;
-	if (!(new_table = kmalloc(sizeof(ctl_table) * len, GFP_KERNEL))) {
+	if (!(new_table = kmalloc(sizeof(sysctl_table) + sizeof(ctl_table) * (len + 1), 
+				  GFP_KERNEL))) {
 		kfree(name);
 		return -ENOMEM;
 	}
 
-	memcpy(new_table, sysctl_table, 6 * sizeof(ctl_table));
-	new_table[0].child = &new_table[2];
-	new_table[2].child = &new_table[4];
-	new_table[4].child = &new_table[6];
-	new_table[4].procname = name;
-	new_table[4].ctl_name = id;
-	memcpy(new_table + 6, ctl_template, (len - 6) * sizeof(ctl_table));
-	for (i = 6; i < len; i++)
-		new_table[i].extra2 = client;
+	memcpy(new_table, sysctl_table, sizeof(sysctl_table));
+	tbl = new_table; /* sys/ */
+	tbl = tbl->child = tbl + 2; /* dev/ */
+	tbl = tbl->child = tbl + 2; /* sensors/ */	
+       	client_tbl = tbl->child = tbl + 2; /* XX-chip-YY-ZZ/ */
+
+	client_tbl->procname = name;
+	client_tbl->ctl_name = id;
+	client_tbl->child = client_tbl + 2;
+
+	/* Next the client sysctls. --km */
+	tbl = client_tbl->child;
+	memcpy(tbl, ctl_template, sizeof(ctl_table) * (len+1));
+	for (i = 0; i < len; i++)
+		tbl[i].extra2 = client;
 
 	if (!(new_header = register_sysctl_table(new_table, 0))) {
 		printk(KERN_ERR "i2c-proc.o: error: sysctl interface not supported by kernel!\n");
@@ -178,21 +180,21 @@
 		return -EPERM;
 	}
 
-	i2c_entries[id - 256] = new_header;
+ 	i2c_entries[id - 256] = new_header;
 
 	i2c_clients[id - 256] = client;
+
 #ifdef DEBUG
 	if (!new_header || !new_header->ctl_table ||
 	    !new_header->ctl_table->child ||
 	    !new_header->ctl_table->child->child ||
-	    !new_header->ctl_table->child->child->de) {
+	    !new_header->ctl_table->child->child->de ) {
 		printk
 		    (KERN_ERR "i2c-proc.o: NULL pointer when trying to install fill_inode fix!\n");
 		return id;
 	}
 #endif				/* DEBUG */
-	new_header->ctl_table->child->child->de->owner = controlling_mod;
-
+	client_tbl->de->owner = client->driver->owner;
 	return id;
 }
 
@@ -515,7 +517,7 @@
 	return 0;
 }
 
-int i2c_write_reals(int nrels, void *buffer, size_t *bufsize,
+static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize,
 			 long *results, int magnitude)
 {
 #define BUFLEN 20
diff -Nru a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
--- a/drivers/ide/arm/icside.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/ide/arm/icside.c	Tue Mar  4 19:30:09 2003
@@ -731,7 +731,7 @@
 
 static int icside_dma_timeout(ide_drive_t *drive)
 {
-	printk(KERN_ERR "%s: DMA timeout occured: ", drive->name);
+	printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
 
 	if (icside_dma_test_irq(drive))
 		return 0;
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/ide/ide-cd.c	Tue Mar  4 19:30:08 2003
@@ -19,7 +19,7 @@
  * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
  * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
  *
- * Drives that deviate from these standards will be accomodated as much
+ * Drives that deviate from these standards will be accommodated as much
  * as possible via compile time or command-line options.  Since I only have
  * a few drives, you generally need to send me patches...
  *
diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
--- a/drivers/ide/ide-dma.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/ide/ide-dma.c	Tue Mar  4 19:30:09 2003
@@ -196,9 +196,9 @@
  *	@drive: the drive to build the DMA table for
  *	@rq: the request holding the sg list
  *
- *	Perform the PCI mapping magic neccessary to access the source or
+ *	Perform the PCI mapping magic necessary to access the source or
  *	target buffers of a request via PCI DMA. The lower layers of the
- *	kernel provide the neccessary cache management so that we can
+ *	kernel provide the necessary cache management so that we can
  *	operate in a portable fashion
  */
  
@@ -226,9 +226,9 @@
  *	@drive: the drive to build the DMA table for
  *	@rq: the request holding the sg list
  *
- *	Perform the PCI mapping magic neccessary to access the source or
+ *	Perform the PCI mapping magic necessary to access the source or
  *	target buffers of a taskfile request via PCI DMA. The lower layers 
- *	of the  kernel provide the neccessary cache management so that we can
+ *	of the  kernel provide the necessary cache management so that we can
  *	operate in a portable fashion
  */
  
@@ -454,7 +454,7 @@
  *	An IDE DMA transfer timed out. In the event of an error we ask
  *	the driver to resolve the problem, if a DMA transfer is still
  *	in progress we continue to wait (arguably we need to add a 
- *	secondary 'I dont care what the drive thinks' timeout here)
+ *	secondary 'I don't care what the drive thinks' timeout here)
  *	Finally if we have an interrupt but for some reason got the
  *	timeout first we complete the I/O. This can occur if an 
  *	interrupt is lost or due to bugs.
diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
--- a/drivers/ide/ide-io.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/ide/ide-io.c	Tue Mar  4 19:30:13 2003
@@ -379,7 +379,7 @@
  *	@drive: drive the completion interrupt occurred on
  *
  *	drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
- *	We do any neccessary daya reading and then wait for the drive to
+ *	We do any necessary daya reading and then wait for the drive to
  *	go non busy. At that point we may read the error data and complete
  *	the request
  */
@@ -652,7 +652,7 @@
  *	@hwgroup: hardware group to select on
  *
  *	choose_drive() selects the next drive which will be serviced.
- *	This is neccessary because the IDE layer can't issue commands
+ *	This is necessary because the IDE layer can't issue commands
  *	to both drives on the same cable, unlike SCSI.
  */
  
diff -Nru a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
--- a/drivers/ide/pci/pdc202xx_new.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/ide/pci/pdc202xx_new.c	Tue Mar  4 19:30:12 2003
@@ -327,7 +327,7 @@
 #endif /* PDC202_DEBUG_CABLE */
 			break;
 		default:
-			/* If its not one we know we should never
+			/* If it's not one we know we should never
 			   arrive here.. */
 			BUG();
 	}
diff -Nru a/drivers/ide/pci/triflex.h b/drivers/ide/pci/triflex.h
--- a/drivers/ide/pci/triflex.h	Tue Mar  4 19:30:11 2003
+++ b/drivers/ide/pci/triflex.h	Tue Mar  4 19:30:11 2003
@@ -18,31 +18,26 @@
 
 static ide_pci_device_t triflex_devices[] __devinitdata = {
 	{
-		.vendor 	PCI_VENDOR_ID_COMPAQ,
-		.device		PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE,
-		.name		"TRIFLEX",
-		.init_chipset	init_chipset_triflex,
-		.init_iops	NULL,
-		.init_hwif	init_hwif_triflex,
-		.channels	2,
-		.autodma	AUTODMA,
-		.enablebits	{{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
-		.bootable	ON_BOARD,
-		.extra		0,
+		.vendor 	= PCI_VENDOR_ID_COMPAQ,
+		.device		= PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE,
+		.name		= "TRIFLEX",
+		.init_chipset	= init_chipset_triflex,
+		.init_iops	= NULL,
+		.init_hwif	= init_hwif_triflex,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
+		.bootable	= ON_BOARD,
 	},{	
-		.vendor		0,
-		.device		0,
-		.channels	0,
-		.bootable	EOL,
+		.bootable	= EOL,
 	}
 };
 
 #ifdef CONFIG_PROC_FS
 static ide_pci_host_proc_t triflex_proc __initdata = {
-		name:		"triflex",
-		set:		1,
-		get_info: 	triflex_get_info,
-		parent: 	NULL,
+	.name		= "triflex",
+	.set		= 1,
+	.get_info 	= triflex_get_info,
 };
 #endif
 
diff -Nru a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
--- a/drivers/ide/ppc/mpc8xx.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/ide/ppc/mpc8xx.c	Tue Mar  4 19:30:14 2003
@@ -331,7 +331,7 @@
 					(0x80000000 >> ioport_dsc[data_port].irq);
 
 #ifdef CONFIG_IDE_8xx_PCCARD
-	/* Make sure we dont get garbage irq */
+	/* Make sure we don't get garbage irq */
 	((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pscr = 0xFFFF;
 
 	/* Enable falling edge irq */
diff -Nru a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
--- a/drivers/ide/ppc/pmac.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/ide/ppc/pmac.c	Tue Mar  4 19:30:04 2003
@@ -1400,7 +1400,7 @@
 	 * to system memory when the disk interrupt occurs.
 	 * 
 	 * The trick here is to increment drive->waiting_for_dma,
-	 * and return as if no interrupt occured. If the counter
+	 * and return as if no interrupt occurred. If the counter
 	 * reach a certain timeout value, we then return 1. If
 	 * we really got the interrupt, it will happen right away
 	 * again.
diff -Nru a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
--- a/drivers/ide/setup-pci.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/ide/setup-pci.c	Tue Mar  4 19:30:07 2003
@@ -470,7 +470,7 @@
  *	@hwif: Hardware interface we are configuring
  *
  *	Set up the DMA base for the interface. Enable the master bits as
- *	neccessary and attempt to bring the device DMA into a ready to use
+ *	necessary and attempt to bring the device DMA into a ready to use
  *	state
  */
  
@@ -573,7 +573,7 @@
  *	@index: ata index to update
  *
  *	Scan the interfaces attached to this device and do any
- *	neccessary per port setup. Attach the devices and ask the
+ *	necessary per port setup. Attach the devices and ask the
  *	generic DMA layer to do its work for us.
  *
  *	Normally called automaticall from do_ide_pci_setup_device,
diff -Nru a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile
--- a/drivers/ieee1394/Makefile	Tue Mar  4 19:30:14 2003
+++ b/drivers/ieee1394/Makefile	Tue Mar  4 19:30:14 2003
@@ -18,13 +18,6 @@
 
 clean-files := oui.c
 
-ieee1394.o: $(ieee1394-objs)
-	$(LD) $(LDFLAGS) -r -o $@ $(ieee1394-objs)
-
-ifeq ($(obj),)
-obj = .
-endif
-
 $(obj)/oui.o: $(obj)/oui.c
 $(obj)/oui.c: $(obj)/oui.db $(obj)/oui2c.sh
 	$(CONFIG_SHELL) $(obj)/oui2c.sh < $(obj)/oui.db > $(obj)/oui.c
diff -Nru a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c
--- a/drivers/ieee1394/amdtp.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/ieee1394/amdtp.c	Tue Mar  4 19:30:10 2003
@@ -74,6 +74,8 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
+#include <linux/ioctl32.h>
+#include <linux/compat.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 
@@ -228,7 +230,7 @@
 	/* The cycle_count and cycle_offset fields are used for the
 	 * synchronization timestamps (syt) in the cip header.  They
 	 * are incremented by at least a cycle every time we put a
-	 * time stamp in a packet.  As we dont time stamp all
+	 * time stamp in a packet.  As we don't time stamp all
 	 * packages, cycle_count isn't updated in every cycle, and
 	 * sometimes it's incremented by 2.  Thus, we have
 	 * cycle_count2, which is simply incremented by one with each
@@ -748,7 +750,7 @@
 
 		/* This next addition should be modulo 8000 (0x1f40),
 		 * but we only use the lower 4 bits of cycle_count, so
-		 * we dont need the modulo. */
+		 * we don't need the modulo. */
 		atomic_add(s->cycle_offset.integer / 3072, &s->cycle_count);
 		s->cycle_offset.integer %= 3072;
 	}
@@ -1262,8 +1264,11 @@
 
 static int __init amdtp_init_module (void)
 {
-	if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_AMDTP,
-				      THIS_MODULE, &amdtp_fops)) {
+	int ret;
+
+	ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_AMDTP,
+					THIS_MODULE, &amdtp_fops);
+	if (ret) {
 		HPSB_ERR("amdtp: unable to get minor device block");
  		return -EIO;
  	}
@@ -1276,6 +1281,15 @@
 		return -EIO;
 	}
 
+#ifdef CONFIG_COMPAT
+	ret = register_ioctl32_conversion(AMDTP_IOC_CHANNEL, NULL);
+	ret |= register_ioctl32_conversion(AMDTP_IOC_PLUG, NULL);
+	ret |= register_ioctl32_conversion(AMDTP_IOC_PING, NULL);
+	ret |= register_ioctl32_conversion(AMDTP_IOC_ZAP, NULL);
+	if (ret)
+		HPSB_ERR("amdtp: Error registering ioctl32 translations");
+#endif
+
 	HPSB_INFO("Loaded AMDTP driver");
 
 	return 0;
@@ -1283,6 +1297,17 @@
 
 static void __exit amdtp_exit_module (void)
 {
+#ifdef CONFIG_COMPAT
+	int ret;
+
+	ret = unregister_ioctl32_conversion(AMDTP_IOC_CHANNEL);
+	ret |= unregister_ioctl32_conversion(AMDTP_IOC_PLUG);
+	ret |= unregister_ioctl32_conversion(AMDTP_IOC_PING);
+	ret |= unregister_ioctl32_conversion(AMDTP_IOC_ZAP);
+	if (ret)
+		HPSB_ERR("amdtp: Error unregistering ioctl32 translations");
+#endif
+
         hpsb_unregister_highlevel(amdtp_highlevel);
         ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_AMDTP);
 
diff -Nru a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
--- a/drivers/ieee1394/dma.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/ieee1394/dma.c	Tue Mar  4 19:30:09 2003
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/mm.h>
 #include "dma.h"
 
 /* dma_prog_region */
diff -Nru a/drivers/ieee1394/dv1394-private.h b/drivers/ieee1394/dv1394-private.h
--- a/drivers/ieee1394/dv1394-private.h	Tue Mar  4 19:30:10 2003
+++ b/drivers/ieee1394/dv1394-private.h	Tue Mar  4 19:30:10 2003
@@ -488,7 +488,7 @@
 	struct frame *frames[DV1394_MAX_FRAMES];
 	
 	/* n_frames also serves as an indicator that this struct video_card is
-	   intialized and ready to run DMA buffers */
+	   initialized and ready to run DMA buffers */
 
 	int n_frames;
 
diff -Nru a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
--- a/drivers/ieee1394/dv1394.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/ieee1394/dv1394.c	Tue Mar  4 19:30:11 2003
@@ -111,6 +111,8 @@
 #include <linux/wrapper.h>
 #include <linux/vmalloc.h>
 #include <linux/string.h>
+#include <linux/ioctl32.h>
+#include <linux/compat.h>
 
 #include "ieee1394.h"
 #include "ieee1394_types.h"
@@ -2701,7 +2703,7 @@
 	struct ti_ohci *ohci;
 	struct video_card *video = NULL;
 	unsigned long flags;
-	struct list_head *lh;
+	struct list_head *lh, *templh;
 	char buf[32];
 	int	n;
 	
@@ -2715,7 +2717,7 @@
 	/* find the corresponding video_cards */
 	spin_lock_irqsave(&dv1394_cards_lock, flags);
 	if(!list_empty(&dv1394_cards)) {
-		list_for_each(lh, &dv1394_cards) {
+		list_for_each_safe(lh, templh, &dv1394_cards) {
 			video = list_entry(lh, struct video_card, list);
 			if((video->id >> 2) == ohci->id)
 				dv1394_un_init(video);
@@ -2907,6 +2909,98 @@
 	.host_reset =   dv1394_host_reset,
 };
 
+#ifdef CONFIG_COMPAT
+
+#define DV1394_IOC32_INIT       _IOW('#', 0x06, struct dv1394_init32)
+#define DV1394_IOC32_GET_STATUS _IOR('#', 0x0c, struct dv1394_status32)
+
+struct dv1394_init32 {
+	u32 api_version;
+	u32 channel;
+	u32 n_frames;
+	u32 format;
+	u32 cip_n;
+	u32 cip_d;
+	u32 syt_offset;
+};
+
+struct dv1394_status32 {
+	struct dv1394_init32 init;
+	s32 active_frame;
+	u32 first_clear_frame;
+	u32 n_clear_frames;
+	u32 dropped_frames;
+};
+
+static int handle_dv1394_init(unsigned int fd, unsigned int cmd, unsigned long arg,
+			      struct file *file)
+{
+	struct dv1394_init32 dv32;
+	struct dv1394_init dv;
+	mm_segment_t old_fs;
+	int ret;
+
+	if (file->f_op->ioctl != dv1394_ioctl)
+		return -EFAULT;
+
+	if (copy_from_user(&dv32, (void *)arg, sizeof(dv32)))
+		return -EFAULT;
+
+	dv.api_version = dv32.api_version;
+	dv.channel = dv32.channel;
+	dv.n_frames = dv32.n_frames;
+	dv.format = dv32.format;
+	dv.cip_n = (unsigned long)dv32.cip_n;
+	dv.cip_d = (unsigned long)dv32.cip_d;
+	dv.syt_offset = dv32.syt_offset;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = dv1394_ioctl(file->f_dentry->d_inode, file,
+			   DV1394_IOC_INIT, (unsigned long)&dv);
+	set_fs(old_fs);
+
+	return ret;
+}
+
+static int handle_dv1394_get_status(unsigned int fd, unsigned int cmd, unsigned long arg,
+				    struct file *file)
+{
+	struct dv1394_status32 dv32;
+	struct dv1394_status dv;
+	mm_segment_t old_fs;
+	int ret;
+
+	if (file->f_op->ioctl != dv1394_ioctl)
+		return -EFAULT;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = dv1394_ioctl(file->f_dentry->d_inode, file,
+			   DV1394_IOC_GET_STATUS, (unsigned long)&dv);
+	set_fs(old_fs);
+
+	if (!ret) {
+		dv32.init.api_version = dv.init.api_version;
+		dv32.init.channel = dv.init.channel;
+		dv32.init.n_frames = dv.init.n_frames;
+		dv32.init.format = dv.init.format;
+		dv32.init.cip_n = (u32)dv.init.cip_n;
+		dv32.init.cip_d = (u32)dv.init.cip_d;
+		dv32.init.syt_offset = dv.init.syt_offset;
+		dv32.active_frame = dv.active_frame;
+		dv32.first_clear_frame = dv.first_clear_frame;
+		dv32.n_clear_frames = dv.n_clear_frames;
+		dv32.dropped_frames = dv.dropped_frames;
+
+		if (copy_to_user((struct dv1394_status32 *)arg, &dv32, sizeof(dv32)))
+			ret = -EFAULT;
+	}
+
+	return ret;
+}
+#endif /* CONFIG_COMPAT */
+
 
 /*** KERNEL MODULE HANDLERS ************************************************/
 
@@ -2917,6 +3011,20 @@
 
 static void __exit dv1394_exit_module(void)
 {
+#ifdef CONFIG_COMPAT
+	int ret;
+
+	ret = unregister_ioctl32_conversion(DV1394_IOC_SHUTDOWN);
+	ret |= unregister_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES);
+	ret |= unregister_ioctl32_conversion(DV1394_IOC_WAIT_FRAMES);
+	ret |= unregister_ioctl32_conversion(DV1394_IOC_RECEIVE_FRAMES);
+	ret |= unregister_ioctl32_conversion(DV1394_IOC_START_RECEIVE);
+	ret |= unregister_ioctl32_conversion(DV1394_IOC32_INIT);
+	ret |= unregister_ioctl32_conversion(DV1394_IOC32_GET_STATUS);
+	if (ret)
+		printk(KERN_ERR "dv1394: Error unregistering ioctl32 translations\n");
+#endif
+
 	hpsb_unregister_highlevel (hl_handle);
 	ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
 #ifdef CONFIG_DEVFS_FS
@@ -2929,14 +3037,18 @@
 
 static int __init dv1394_init_module(void)
 {
-	if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_DV1394,
-				      THIS_MODULE, &dv1394_fops)) {
+	int ret;
+
+	ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_DV1394,
+					THIS_MODULE, &dv1394_fops);
+	if (ret) {
 		printk(KERN_ERR "dv1394: unable to register character device\n");
 		return -EIO;
 	}
 
 #ifdef CONFIG_DEVFS_FS
-	if (dv1394_devfs_add_dir("dv", NULL, NULL) < 0) {
+	ret = dv1394_devfs_add_dir("dv", NULL, NULL);
+	if (ret < 0) {
 		printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/dv\n");
 		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
 		return -ENOMEM;
@@ -2944,7 +3056,8 @@
 #endif
 
 #ifdef CONFIG_PROC_FS
-	if (dv1394_procfs_add_dir("dv",NULL,NULL) < 0) {
+	ret = dv1394_procfs_add_dir("dv",NULL,NULL);
+	if (ret < 0) {
 		printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/dv\n");
 		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
 #ifdef CONFIG_DEVFS_FS
@@ -2967,9 +3080,23 @@
 		return -ENOMEM;
 	}
 
+#ifdef CONFIG_COMPAT
+	/* First compatible ones */
+	ret = register_ioctl32_conversion(DV1394_IOC_SHUTDOWN, NULL);
+	ret |= register_ioctl32_conversion(DV1394_IOC_SUBMIT_FRAMES, NULL);
+	ret |= register_ioctl32_conversion(DV1394_IOC_WAIT_FRAMES, NULL);
+	ret |= register_ioctl32_conversion(DV1394_IOC_RECEIVE_FRAMES, NULL);
+	ret |= register_ioctl32_conversion(DV1394_IOC_START_RECEIVE, NULL);
+
+	/* These need to be handled by translation */
+	ret |= register_ioctl32_conversion(DV1394_IOC32_INIT, handle_dv1394_init);
+	ret |= register_ioctl32_conversion(DV1394_IOC32_GET_STATUS, handle_dv1394_get_status);
+	if (ret)
+		printk(KERN_ERR "dv1394: Error registering ioctl32 translations\n");
+#endif
+
 	return 0;
 }
 
 module_init(dv1394_init_module);
 module_exit(dv1394_exit_module);
-
diff -Nru a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
--- a/drivers/ieee1394/eth1394.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/ieee1394/eth1394.c	Tue Mar  4 19:30:10 2003
@@ -65,6 +65,7 @@
 #include "ieee1394_transactions.h"
 #include "ieee1394.h"
 #include "highlevel.h"
+#include "iso.h"
 #include "eth1394.h"
 
 #define ETH1394_PRINT_G(level, fmt, args...) \
@@ -77,7 +78,7 @@
 	printk(KERN_ERR fmt, ## args)
 
 static char version[] __devinitdata =
-	"$Rev: 770 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 806 $ Ben Collins <bcollins@debian.org>";
 
 /* Our ieee1394 highlevel driver */
 #define ETHER1394_DRIVER_NAME "ether1394"
@@ -101,6 +102,9 @@
 MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)");
 MODULE_LICENSE("GPL");
 
+static void ether1394_iso(struct hpsb_iso *iso);
+
+
 /* Find our host_info struct for a given host pointer. Must be called
  * under spinlock.  */
 static inline struct host_info *find_host_info (struct hpsb_host *host)
@@ -178,15 +182,26 @@
  * XXX: This is where we need to create a list of skb's for fragmented
  * packets.  */
 static inline void ether1394_encapsulate (struct sk_buff *skb, struct net_device *dev,
-			    int proto)
+                                          int proto, struct packet_task *ptask)
 {
 	union eth1394_hdr *hdr =
 		(union eth1394_hdr *)skb_push (skb, hdr_type_len[ETH1394_HDR_LF_UF]);
 
+	hdr->words.word1 = 0;
 	hdr->common.lf = ETH1394_HDR_LF_UF;
 	hdr->words.word1 = htons(hdr->words.word1);
 	hdr->uf.ether_type = proto;
 
+	/* Set the transmission type for the packet.  Right now only ARP
+	 * packets are sent via GASP.  IP broadcast and IP multicast are not
+	 * yet supported properly, they too should use GASP. */
+	switch(proto) {
+	case __constant_htons(ETH_P_ARP):
+		ptask->tx_type = ETH1394_GASP;
+		break;
+	default:
+		ptask->tx_type = ETH1394_WRREQ;
+	}
 	return;
 }
 
@@ -199,14 +214,14 @@
 {
 	struct eth1394_priv *priv =
 		(struct eth1394_priv *)(dev->priv);
-	u16 phy_id = priv->host->node_id & NODE_MASK;
+	u16 phy_id = NODEID_TO_NODE(priv->host->node_id);
 
 	unsigned char *arp_ptr = (unsigned char *)skb->data;
 	struct eth1394_arp *arp1394 = (struct eth1394_arp *)skb->data;
 	unsigned char arp_data[2*(dev->addr_len+4)];
 
 	/* Copy the main data that we need */
-	arp_ptr = memcpy (arp_data, arp_ptr + sizeof(struct arphdr), sizeof (arp_data));
+	memcpy (arp_data, arp_ptr + sizeof(struct arphdr), sizeof (arp_data));
 
 	/* Extend the buffer enough for our new header */
 	skb_put (skb, sizeof (struct eth1394_arp) -
@@ -214,7 +229,7 @@
 
 #define PROCESS_MEMBER(ptr,val,len) \
   memcpy (val, ptr, len); ptr += len
-	arp_ptr += arp1394->hw_addr_len;
+	arp_ptr = arp_data + arp1394->hw_addr_len;
 	PROCESS_MEMBER (arp_ptr, &arp1394->sip, arp1394->ip_addr_len);
 	arp_ptr += arp1394->hw_addr_len;
 	PROCESS_MEMBER (arp_ptr, &arp1394->tip, arp1394->ip_addr_len);
@@ -279,7 +294,8 @@
 {
 	unsigned long flags;
 	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
-	int phy_id = priv->host->node_id & NODE_MASK;
+	int phy_id = NODEID_TO_NODE(priv->host->node_id);
+	struct hpsb_host *host = priv->host;
 
 	spin_lock_irqsave (&priv->lock, flags);
 
@@ -289,20 +305,23 @@
 	memset (priv->fifo_hi, 0, sizeof (priv->fifo_hi));
 	memset (priv->fifo_lo, 0, sizeof (priv->fifo_lo));
 
+	priv->bc_state = ETHER1394_BC_CHECK;
+
 	/* Register our limits now */
-	ether1394_register_limits (phy_id, (be32_to_cpu(priv->host->csr.rom[2]) >> 12) & 0xf,
-				   priv->host->speed_map[(phy_id << 6) + phy_id],
-				   (u64)(((u64)be32_to_cpu(priv->host->csr.rom[3]) << 32) |
-				   be32_to_cpu(priv->host->csr.rom[4])),
+	ether1394_register_limits (phy_id, (be32_to_cpu(host->csr.rom[2]) >> 12) & 0xf,
+				   host->speed_map[(phy_id << 6) + phy_id],
+				   (u64)(((u64)be32_to_cpu(host->csr.rom[3]) << 32) |
+				   be32_to_cpu(host->csr.rom[4])),
 				   ETHER1394_REGION_ADDR >> 32,
 				   ETHER1394_REGION_ADDR & 0xffffffff, priv);
 
 	/* We'll use our max_rec as the default mtu */
 	if (set_mtu)
-		dev->mtu = (1 << (priv->max_rec[phy_id] + 1)) - sizeof (union eth1394_hdr);
+		dev->mtu = (1 << (priv->max_rec[phy_id] + 1)) - /* mtu = max_rec - */
+			(sizeof (union eth1394_hdr) + 8);	/* (hdr + GASP) */
 
 	/* Set our hardware address while we're at it */
-	*(nodeid_t *)dev->dev_addr = htons (priv->host->node_id);
+	*(nodeid_t *)dev->dev_addr = htons (host->node_id);
 
 	spin_unlock_irqrestore (&priv->lock, flags);
 }
@@ -383,6 +402,15 @@
 	list_add_tail (&hi->list, &host_info_list);
 	spin_unlock_irq (&host_info_lock);
 
+	/* Ignore validity in hopes that it will be set in the future.  It'll
+	 * check it on transmit. */
+	priv->broadcast_channel = host->csr.broadcast_channel & 0x3f;
+
+	priv->iso = hpsb_iso_recv_init(host, 8 * 4096, 8, priv->broadcast_channel,
+				       1, ether1394_iso);
+	if (priv->iso == NULL) {
+		priv->bc_state = ETHER1394_BC_CLOSED;
+	}
 	return;
 
 out:
@@ -396,11 +424,14 @@
 /* Remove a card from our list */
 static void ether1394_remove_host (struct hpsb_host *host)
 {
+	struct eth1394_priv *priv;
 	struct host_info *hi;
 
 	spin_lock_irq (&host_info_lock);
 	hi = find_host_info (host);
 	if (hi != NULL) {
+		priv = (struct eth1394_priv *)hi->dev->priv;
+		priv->bc_state = ETHER1394_BC_CLOSED;
 		unregister_netdev (hi->dev);
 		kfree (hi->dev);
 		list_del (&hi->list);
@@ -480,7 +511,7 @@
 	 * about the sending machine.  */
 	if (hdr->uf.ether_type == __constant_htons (ETH_P_ARP)) {
 		unsigned long flags;
-		u16 phy_id = srcid & NODE_MASK;
+		u16 phy_id = NODEID_TO_NODE(srcid);
 		struct eth1394_priv *priv =
 			(struct eth1394_priv *)dev->priv;
 		struct eth1394_arp arp1394;
@@ -498,7 +529,7 @@
 		spin_unlock_irqrestore (&priv->lock, flags);
 
 #define PROCESS_MEMBER(ptr,val,len) \
-  ptr = memcpy (ptr, val, len) + len
+  memcpy (ptr, val, len); ptr += len
                 PROCESS_MEMBER (arp_ptr, src_hw, dev->addr_len);
                 PROCESS_MEMBER (arp_ptr, &arp1394.sip, 4);
                 PROCESS_MEMBER (arp_ptr, dest_hw, dev->addr_len);
@@ -591,6 +622,104 @@
 	return RCODE_COMPLETE;
 }
 
+static void ether1394_iso(struct hpsb_iso *iso)
+{
+	struct sk_buff *skb;
+	quadlet_t *data;
+	char *buf;
+	int flags;
+	struct net_device *dev = ether1394_find_dev(iso->host);
+	struct eth1394_priv *priv;
+	unsigned int len;
+	u32 specifier_id;
+	u16 source_id;
+	int i;
+	int nready;
+
+	if (dev == NULL) {
+		ETH1394_PRINT_G (KERN_ERR, "Could not find net device for host %s\n",
+				 iso->host->driver->name);
+		return;
+	}
+
+	nready = hpsb_iso_n_ready(iso);
+	for(i = 0; i < nready; i++) {
+		struct hpsb_iso_packet_info *info = &iso->infos[iso->first_packet + i];
+		data = (quadlet_t*) (iso->data_buf.kvirt + info->offset);
+
+		/* skip over GASP header */
+		buf = (char *)data + 8;
+		len = info->len - 8;
+
+		specifier_id = (((be32_to_cpu(data[0]) & 0xffff) << 8) |
+				((be32_to_cpu(data[1]) & 0xff000000) >> 24));
+		source_id = be32_to_cpu(data[0]) >> 16;
+
+		priv = (struct eth1394_priv *)dev->priv;
+
+		if (info->channel != priv->broadcast_channel ||
+		    specifier_id != ETHER1394_GASP_SPECIFIER_ID) {
+			/* This packet is not for us */
+			continue;
+		}
+
+		/* A packet has been received by the ieee1394 bus. Build an skbuff
+		 * around it so we can pass it to the high level network layer. */
+		skb = dev_alloc_skb (len + dev->hard_header_len + 15);
+		if (!skb) {
+			HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
+			priv->stats.rx_dropped++;
+			break;
+		}
+
+		skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
+
+		memcpy (skb_put (skb, len), buf, len);
+
+		/* Write metadata, and then pass to the receive level */
+		skb->dev = dev;
+		skb->ip_summed = CHECKSUM_UNNECESSARY;	/* don't check it */
+
+		/* Parse the encapsulation header. This actually does the job of
+		 * converting to an ethernet frame header, aswell as arp
+		 * conversion if needed. ARP conversion is easier in this
+		 * direction, since we are using ethernet as our backend.  */
+		skb->protocol = ether1394_parse_encap (skb, dev, source_id,
+						       LOCAL_BUS | ALL_NODES);
+
+		spin_lock_irqsave (&priv->lock, flags);
+		if (!skb->protocol) {
+			priv->stats.rx_errors++;
+			priv->stats.rx_dropped++;
+			dev_kfree_skb_any(skb);
+			goto bad_proto;
+		}
+
+		netif_stop_queue(dev);
+		if (netif_rx (skb) == NET_RX_DROP) {
+			priv->stats.rx_errors++;
+			priv->stats.rx_dropped++;
+			goto bad_proto;
+		}
+
+		/* Statistics */
+		priv->stats.rx_packets++;
+		priv->stats.rx_bytes += skb->len;
+
+	bad_proto:
+		spin_unlock_irqrestore (&priv->lock, flags);
+	}
+
+	hpsb_iso_recv_release_packets(iso, i);
+
+	netif_start_queue(dev);
+	
+	dev->last_rx = jiffies;
+
+	return;
+}
+
+
 /* This function is our scheduled write */
 static void hpsb_write_sched (void *__ptask)
 {
@@ -598,13 +727,26 @@
 	struct sk_buff *skb = ptask->skb;
 	struct net_device *dev = ptask->skb->dev;
 	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
-        unsigned long flags;
+	unsigned long flags;
+	int status;
+ 
+	if (ptask->tx_type == ETH1394_GASP) {
+		status  = hpsb_send_gasp(priv->host, priv->broadcast_channel,
+					 get_hpsb_generation(priv->host),
+					 (quadlet_t *)skb->data, skb->len,
+					 ETHER1394_GASP_SPECIFIER_ID,
+					 ETHER1394_GASP_VERSION);
+	} else {
+		status = hpsb_write(priv->host, ptask->dest_node,
+				    get_hpsb_generation(priv->host),
+				    ptask->addr, (quadlet_t *)skb->data,
+				    skb->len);
+	}
+
 
 	/* Statistics */
 	spin_lock_irqsave (&priv->lock, flags);
-	if (!hpsb_write(priv->host, ptask->dest_node,
-			get_hpsb_generation(priv->host),
-			ptask->addr, (quadlet_t *)skb->data, skb->len)) {
+	if (!status) {
 		priv->stats.tx_bytes += skb->len;
 		priv->stats.tx_packets++;
 	} else {
@@ -636,6 +778,67 @@
 	struct packet_task *ptask = NULL;
 	int ret = 0;
 
+	spin_lock_irqsave (&priv->lock, flags);
+	if (priv->bc_state == ETHER1394_BC_CLOSED) {
+		ETH1394_PRINT(KERN_ERR, dev->name,
+			      "Cannot send packet, no broadcast channel available.");
+		ret = -EAGAIN;
+		goto fail;
+	}
+
+	/* First time sending?  Need a broadcast channel for ARP and for
+	 * listening on */
+	if (priv->bc_state == ETHER1394_BC_CHECK) {
+		quadlet_t bc;
+
+		/* Get the local copy of the broadcast channel and check its
+		 * validity (the IRM should validate it for us) */
+
+		bc = priv->host->csr.broadcast_channel;
+
+		if ((bc & 0xc0000000) != 0xc0000000) {
+			/* broadcast channel not validated yet */
+			ETH1394_PRINT(KERN_WARNING, dev->name,
+				      "Error BROADCAST_CHANNEL register valid "
+				      "bit not set, can't send IP traffic\n");
+			hpsb_iso_shutdown(priv->iso);
+			priv->bc_state = ETHER1394_BC_CLOSED;
+			ret = -EAGAIN;
+			spin_unlock_irqrestore (&priv->lock, flags);
+			goto fail;
+		}
+		if (priv->broadcast_channel != (bc & 0x3f)) {
+			/* This really shouldn't be possible, but just in case
+			 * the IEEE 1394 spec changes regarding broadcast
+			 * channels in the future. */
+			hpsb_iso_shutdown(priv->iso);
+
+			priv->broadcast_channel = bc & 0x3f;
+			ETH1394_PRINT(KERN_WARNING, dev->name,
+				      "Changing to broadcast channel %d...\n",
+				      priv->broadcast_channel);
+
+			priv->iso = hpsb_iso_recv_init(priv->host, 8 * 4096,
+						       8, priv->broadcast_channel,
+						       1, ether1394_iso);
+			if (priv->iso == NULL) {
+				ret = -EAGAIN;
+				goto fail;
+			}
+		}
+		if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) {
+			ETH1394_PRINT(KERN_ERR, dev->name,
+				      "Could not start async reception\n");
+			hpsb_iso_shutdown(priv->iso);
+			priv->bc_state = ETHER1394_BC_CLOSED;
+			ret = -EAGAIN;
+			spin_unlock_irqrestore (&priv->lock, flags);
+			goto fail;
+		}
+		priv->bc_state = ETHER1394_BC_OPENED;
+	}
+	spin_unlock_irqrestore (&priv->lock, flags);
+
 	if ((skb = skb_share_check (skb, kmflags)) == NULL) {
 		ret = -ENOMEM;
 		goto fail;
@@ -654,8 +857,14 @@
 	if (proto == __constant_htons (ETH_P_ARP))
 		ether1394_arp_to_1394arp (skb, dev);
 
+	ptask = kmem_cache_alloc(packet_task_cache, kmflags);
+	if (ptask == NULL) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
 	/* Now add our encapsulation header */
-	ether1394_encapsulate (skb, dev, proto);
+	ether1394_encapsulate (skb, dev, proto, ptask);
 
 	/* TODO: The above encapsulate function needs to recognize when a
 	 * packet needs to be split for a specified node. It should create
@@ -663,23 +872,17 @@
 	 * call to schedule our writes.  */
 
 	/* XXX: Right now we accept that we don't exactly follow RFC. When
-	 * we do, we will send ARP requests via GASP format, and so we wont
+	 * we do, we will send ARP requests via GASP format, and so we won't
 	 * need this hack.  */
 
 	spin_lock_irqsave (&priv->lock, flags);
-	addr = (u64)priv->fifo_hi[dest_node & NODE_MASK] << 32 |
-		priv->fifo_lo[dest_node & NODE_MASK];
+	addr = (u64)priv->fifo_hi[NODEID_TO_NODE(dest_node)] << 32 |
+		priv->fifo_lo[NODEID_TO_NODE(dest_node)];
 	spin_unlock_irqrestore (&priv->lock, flags);
 
 	if (!addr)
 		addr = ETHER1394_REGION_ADDR;
 
-	ptask = kmem_cache_alloc(packet_task_cache, kmflags);
-	if (ptask == NULL) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
 	ptask->skb = skb;
 	ptask->addr = addr;
 	ptask->dest_node = dest_node;
@@ -702,7 +905,7 @@
 		netif_wake_queue (dev);
 	spin_unlock_irqrestore (&priv->lock, flags);
 
-	return ret;
+	return 0;  /* returning non-zero causes serious problems */
 }
 
 /* Function for incoming 1394 packets */
@@ -738,6 +941,19 @@
 
 static void __exit ether1394_exit_module (void)
 {
+	struct list_head *lh;
+	struct host_info *hi;
+	struct eth1394_priv *priv;
+
+	lh = host_info_list.next;
+	while (lh != &host_info_list) {
+		hi = list_entry (lh, struct host_info, list);
+		priv = (struct eth1394_priv*)hi->dev->priv;
+		if (priv->bc_state != ETHER1394_BC_CLOSED) {
+			hpsb_iso_shutdown(priv->iso);
+		}
+		lh = lh->next;
+	}
 	hpsb_unregister_highlevel (hl_handle);
 	kmem_cache_destroy(packet_task_cache);
 }
diff -Nru a/drivers/ieee1394/eth1394.h b/drivers/ieee1394/eth1394.h
--- a/drivers/ieee1394/eth1394.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/ieee1394/eth1394.h	Tue Mar  4 19:30:13 2003
@@ -30,9 +30,16 @@
 #define ETHER1394_REGION_ADDR		0xfffff0200000ULL
 #define ETHER1394_REGION_ADDR_END	(ETHER1394_REGION_ADDR + ETHER1394_REGION_ADDR_LEN)
 
+/* GASP identifier numbers for IPv4 over IEEE 1394 */
+#define ETHER1394_GASP_SPECIFIER_ID	0x00005E
+#define ETHER1394_GASP_VERSION		1
+
 /* Node set == 64 */
 #define NODE_SET			(ALL_NODES + 1)
 
+enum eth1394_bc_states { ETHER1394_BC_CLOSED, ETHER1394_BC_OPENED,
+			 ETHER1394_BC_CHECK };
+
 /* Private structure for our ethernet driver */
 struct eth1394_priv {
 	struct net_device_stats stats;	/* Device stats			 */
@@ -43,6 +50,9 @@
 	u32 fifo_lo[ALL_NODES];		/* 32bit lo fifo offset per node */
 	u64 eui[ALL_NODES];		/* EUI-64 per node		 */
 	spinlock_t lock;		/* Private lock			 */
+	int broadcast_channel;		/* Async stream Broadcast Channel */
+	enum eth1394_bc_states bc_state; /* broadcast channel state	 */
+	struct hpsb_iso *iso;		/* Async stream recv handle	 */
 };
 
 struct host_info {
@@ -51,12 +61,15 @@
 	struct net_device *dev;
 };
 
+typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type;
+
 /* This is our task struct. It's used for the packet complete callback.  */
 struct packet_task {
 	struct sk_buff *skb;	/* Socket buffer we are sending */
 	nodeid_t dest_node;	/* Destination of the packet */
 	u64 addr;		/* Address */
 	struct hpsb_queue_struct tq;	/* The task */
+	eth1394_tx_type tx_type;	/* Send data via GASP or Write Req. */
 };
 
 /* IP1394 headers */
diff -Nru a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
--- a/drivers/ieee1394/hosts.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/ieee1394/hosts.c	Tue Mar  4 19:30:07 2003
@@ -71,9 +71,6 @@
         list_for_each(lh, &hosts) {
                 if (host == list_entry(lh, struct hpsb_host, host_list)) {
 			if (try_module_get(host->driver->owner)) {
-				/* we're doing this twice and don't seem
-				   to undo it..  --hch */
-				(void)try_module_get(host->driver->owner);
 				host->refcount++;
 				retval = 1;
 			}
diff -Nru a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h
--- a/drivers/ieee1394/ieee1394-ioctl.h	Tue Mar  4 19:30:04 2003
+++ b/drivers/ieee1394/ieee1394-ioctl.h	Tue Mar  4 19:30:04 2003
@@ -4,8 +4,8 @@
 #ifndef __IEEE1394_IOCTL_H
 #define __IEEE1394_IOCTL_H
 
-#include <asm/ioctl.h>
-#include <asm/types.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
 
 
 /* AMDTP Gets 6 */
@@ -91,7 +91,7 @@
 #define RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL	\
 	_IOW ('#', 0x23, unsigned char)
 #define RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK	\
-	_IOW ('#', 0x24, u64)
+	_IOW ('#', 0x24, __u64)
 #define RAW1394_IOC_ISO_RECV_PACKETS		\
 	_IOW ('#', 0x25, struct raw1394_iso_packets)
 #define RAW1394_IOC_ISO_RECV_RELEASE_PACKETS	\
diff -Nru a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
--- a/drivers/ieee1394/ieee1394_core.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/ieee1394/ieee1394_core.c	Tue Mar  4 19:30:05 2003
@@ -361,7 +361,7 @@
                 host->topology_map[host->selfid_count++] = sid;
         } else {
                 HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
-			    sid, (host->node_id & BUS_MASK) >> 6);
+			    sid, NODEID_TO_BUS(host->node_id));
         }
 }
 
@@ -396,9 +396,6 @@
         /* irm_id is kept up to date by check_selfids() */
         if (host->irm_id == host->node_id) {
                 host->is_irm = 1;
-                host->is_busmgr = 1;
-                host->busmgr_id = host->node_id;
-                host->csr.bus_manager_id = host->node_id;
         } else {
                 host->is_busmgr = 0;
                 host->is_irm = 0;
@@ -535,8 +532,8 @@
 
         if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
                 packet->speed_code =
-                        host->speed_map[(host->node_id & NODE_MASK) * 64
-                                       + (packet->node_id & NODE_MASK)];
+                        host->speed_map[NODEID_TO_NODE(host->node_id) * 64
+                                       + NODEID_TO_NODE(packet->node_id)];
         }
 
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
@@ -748,7 +745,7 @@
 					addr, 4, flags);
 
                 if (!write_acked
-                    && (((data[0] >> 16) & NODE_MASK) != NODE_MASK)
+                    && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
                     && (rcode >= 0)) {
                         /* not a broadcast write, reply */
                         PREP_REPLY_PACKET(0);
@@ -763,7 +760,7 @@
 					addr, data[3]>>16, flags);
 
                 if (!write_acked
-                    && (((data[0] >> 16) & NODE_MASK) != NODE_MASK)
+                    && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
                     && (rcode >= 0)) {
                         /* not a broadcast write, reply */
                         PREP_REPLY_PACKET(0);
@@ -1248,6 +1245,7 @@
 EXPORT_SYMBOL(hpsb_write);
 EXPORT_SYMBOL(hpsb_lock);
 EXPORT_SYMBOL(hpsb_lock64);
+EXPORT_SYMBOL(hpsb_send_gasp);
 EXPORT_SYMBOL(hpsb_packet_success);
 
 /** highlevel.c **/
diff -Nru a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
--- a/drivers/ieee1394/ieee1394_transactions.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/ieee1394/ieee1394_transactions.c	Tue Mar  4 19:30:05 2003
@@ -98,6 +98,17 @@
         packet->speed_code = SPEED_100; /* Force speed to be 100Mbps */
 }
 
+static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
+				     int channel, int tag, int sync)
+{
+	packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
+		| (TCODE_STREAM_DATA << 4) | sync;
+
+	packet->header_size = 4;
+	packet->data_size = length;
+	packet->type = hpsb_async;
+	packet->tcode = TCODE_ISO_DATA;
+}
 
 /**
  * hpsb_get_tlabel - allocate a transaction label
@@ -495,7 +506,6 @@
 }
 
 
-/* We need a hpsb_lock64 function for the 64 bit equivalent.  Probably. */
 int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
 	      u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
 {
@@ -557,4 +567,59 @@
 	free_hpsb_packet(packet);
 
         return retval;
+}
+
+int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
+		   quadlet_t *buffer, size_t length, u32 specifier_id,
+		   unsigned int version)
+{
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	int i;
+#endif
+
+	struct hpsb_packet *packet;
+	int retval = 0;
+	u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8;
+	u8 specifier_id_lo = specifier_id & 0xff;
+
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	HPSB_DEBUG("Send GASP: channel = %d, length = %d", channel, length);
+#endif
+
+	length += 8;
+
+	packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
+	if (!packet)
+		return -ENOMEM;
+
+	if (length % 4) {
+		packet->data[length / 4] = 0;
+	}
+
+	packet->host = host;
+	fill_async_stream_packet(packet, length, channel, 3, 0);
+        
+	packet->data[0] = cpu_to_be32((host->node_id << 16) | specifier_id_hi);
+	packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff));
+
+	memcpy(&(packet->data[2]), buffer, length - 4);
+
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	HPSB_DEBUG("GASP: packet->header_size = %d", packet->header_size);
+	HPSB_DEBUG("GASP: packet->data_size = %d", packet->data_size);
+
+	for(i=0; i<(packet->data_size/4); i++)
+		HPSB_DEBUG("GASP: data[%d]: 0x%08x", i*4, be32_to_cpu(packet->data[i]));
+#endif
+
+	packet->generation = generation;
+
+	packet->no_waiter = 1;
+
+	if (!hpsb_send_packet(packet)) {
+		free_hpsb_packet(packet);
+		retval = -EINVAL;
+	}
+
+	return retval;
 }
diff -Nru a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h
--- a/drivers/ieee1394/ieee1394_transactions.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/ieee1394/ieee1394_transactions.h	Tue Mar  4 19:30:05 2003
@@ -55,5 +55,8 @@
 	      u64 addr, int extcode, quadlet_t *data, quadlet_t arg);
 int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation,
 		u64 addr, int extcode, octlet_t *data, octlet_t arg);
+int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
+                   quadlet_t *buffer, size_t length, u32 specifier_id,
+                   unsigned int version);
 
 #endif /* _IEEE1394_TRANSACTIONS_H */
diff -Nru a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h
--- a/drivers/ieee1394/ieee1394_types.h	Tue Mar  4 19:30:12 2003
+++ b/drivers/ieee1394/ieee1394_types.h	Tue Mar  4 19:30:12 2003
@@ -97,14 +97,17 @@
 typedef u16 arm_length_t;
 
 #define BUS_MASK  0xffc0
+#define BUS_SHIFT 6
 #define NODE_MASK 0x003f
 #define LOCAL_BUS 0xffc0
 #define ALL_NODES 0x003f
 
+#define NODEID_TO_BUS(nodeid)	((nodeid & BUS_MASK) >> BUS_SHIFT)
+#define NODEID_TO_NODE(nodeid)	(nodeid & NODE_MASK)
+
 /* Can be used to consistently print a node/bus ID. */
-#define NODE_BUS_FMT    "%02d:%04d"
-#define NODE_BUS_ARGS(nodeid) \
-	(nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
+#define NODE_BUS_FMT		"%02d:%04d"
+#define NODE_BUS_ARGS(nodeid)	NODEID_TO_NODE(nodeid), NODEID_TO_BUS(nodeid)
 
 #define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
 
diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
--- a/drivers/ieee1394/nodemgr.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/ieee1394/nodemgr.c	Tue Mar  4 19:30:10 2003
@@ -1210,6 +1210,52 @@
 	return;
 }
 
+/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other
+ * nodes of the broadcast channel.  (Really we're only setting the validity
+ * bit). */
+static void nodemgr_do_irm_duties(struct hpsb_host *host)
+{
+	quadlet_t bc;
+        
+	if (!host->is_irm)
+		return;
+
+	host->csr.broadcast_channel |= 0x40000000;  /* set validity bit */
+
+	bc = cpu_to_be32(host->csr.broadcast_channel);
+
+	hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host),
+		   (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL),
+		   &bc,
+		   sizeof(quadlet_t));
+}
+
+/* We need to ensure that if we are not the IRM, that the IRM node is capable of
+ * everything we can do, otherwise issue a bus reset and try to become the IRM
+ * ourselves. */
+static int nodemgr_check_root_capability(struct hpsb_host *host)
+{
+	quadlet_t bc;
+	int status;
+
+	if (host->is_irm)
+		return 1;
+
+	status = hpsb_read(host, LOCAL_BUS | (host->irm_id),
+			   get_hpsb_generation(host),
+			   (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL),
+			   &bc, sizeof(quadlet_t));
+
+	if (status < 0 || !(be32_to_cpu(bc) & 0x80000000)) {
+		/* The root node does not have a valid BROADCAST_CHANNEL
+		 * register and we do, so reset the bus with force_root set */
+		HPSB_INFO("Remote root is not IRM capable, resetting...");
+		hpsb_reset_bus(host, LONG_RESET_FORCE_ROOT);
+		return 0;
+	}
+	return 1;
+}
+
 static int nodemgr_host_thread(void *__hi)
 {
 	struct host_info *hi = (struct host_info *)__hi;
@@ -1217,12 +1263,21 @@
 	/* No userlevel access needed */
 	daemonize("knodemgrd");
 	allow_signal(SIGTERM);
-
+	
 	/* Sit and wait for a signal to probe the nodes on the bus. This
 	 * happens when we get a bus reset. */
 	while (!down_interruptible(&hi->reset_sem) &&
 	       !down_interruptible(&nodemgr_serialize)) {
+
+		if (!nodemgr_check_root_capability(hi->host)) {
+			/* Do nothing, we are resetting */
+			up(&nodemgr_serialize);
+			continue;
+		}
+
 		nodemgr_node_probe(hi->host);
+		nodemgr_do_irm_duties(hi->host);
+
 		up(&nodemgr_serialize);
 	}
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
diff -Nru a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
--- a/drivers/ieee1394/ohci1394.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/ieee1394/ohci1394.c	Tue Mar  4 19:30:13 2003
@@ -31,9 +31,9 @@
  *
  * Things implemented, but still in test phase:
  * . Iso Transmit
+ * . Async Stream Packets Transmit (Receive done via Iso interface)
  * 
  * Things not implemented:
- * . Async Stream Packets
  * . DMA error recovery
  *
  * Known bugs:
@@ -160,7 +160,7 @@
 printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 
 static char version[] __devinitdata =
-	"$Rev: 762 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 801 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 MODULE_PARM(phys_dma,"i");
@@ -649,18 +649,31 @@
                 } else {
                         d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
                                 (packet->header[0] & 0xFFFF);
-                        d->prg_cpu[idx]->data[1] =
-                                (packet->header[1] & 0xFFFF) | 
-                                (packet->header[0] & 0xFFFF0000);
-                        d->prg_cpu[idx]->data[2] = packet->header[2];
-                        d->prg_cpu[idx]->data[3] = packet->header[3];
+
+			if (packet->tcode == TCODE_ISO_DATA) {
+				/* Sending an async stream packet */
+				d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000;
+			} else {
+				/* Sending a normal async request or response */
+				d->prg_cpu[idx]->data[1] =
+					(packet->header[1] & 0xFFFF) | 
+					(packet->header[0] & 0xFFFF0000);
+				d->prg_cpu[idx]->data[2] = packet->header[2];
+				d->prg_cpu[idx]->data[3] = packet->header[3];
+			}
 			packet_swab(d->prg_cpu[idx]->data, packet->tcode);
                 }
 
                 if (packet->data_size) { /* block transmit */
-                        d->prg_cpu[idx]->begin.control =
-                                cpu_to_le32(DMA_CTL_OUTPUT_MORE |
-					    DMA_CTL_IMMEDIATE | 0x10);
+			if (packet->tcode == TCODE_STREAM_DATA){
+				d->prg_cpu[idx]->begin.control =
+					cpu_to_le32(DMA_CTL_OUTPUT_MORE |
+						    DMA_CTL_IMMEDIATE | 0x8);
+			} else {
+				d->prg_cpu[idx]->begin.control =
+					cpu_to_le32(DMA_CTL_OUTPUT_MORE |
+						    DMA_CTL_IMMEDIATE | 0x10);
+			}
                         d->prg_cpu[idx]->end.control =
                                 cpu_to_le32(DMA_CTL_OUTPUT_LAST |
 					    DMA_CTL_IRQ | 
@@ -827,10 +840,10 @@
 		return 0;
 	}
 
-	/* Decide wether we have an iso, a request, or a response packet */
+	/* Decide whether we have an iso, a request, or a response packet */
 	if (packet->type == hpsb_raw)
 		d = &ohci->at_req_context;
-	else if (packet->tcode == TCODE_ISO_DATA) {
+	else if ((packet->tcode == TCODE_ISO_DATA) && (packet->type == hpsb_iso)) {
 		/* The legacy IT DMA context is initialized on first
 		 * use.  However, the alloc cannot be run from
 		 * interrupt context, so we bail out if that is the
@@ -856,7 +869,7 @@
 		}
 		
 		d = &ohci->it_legacy_context;
-	} else if (packet->tcode & 0x02)
+	} else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA))
 		d = &ohci->at_resp_context;
 	else 
 		d = &ohci->at_req_context;
@@ -1295,6 +1308,8 @@
 	u32 *prev_branch = NULL;
 
 	for (blk = 0; blk < recv->nblocks; blk++) {
+		u32 control;
+
 		/* the DMA descriptor */
 		struct dma_cmd *cmd = &recv->block[blk];
 
@@ -1305,29 +1320,29 @@
 		unsigned long buf_offset = blk * recv->buf_stride;
 
 		if (recv->dma_mode == BUFFER_FILL_MODE) {
-			cmd->control = 2 << 28; /* INPUT_MORE */
+			control = 2 << 28; /* INPUT_MORE */
 		} else {
-			cmd->control = 3 << 28; /* INPUT_LAST */
+			control = 3 << 28; /* INPUT_LAST */
 		}
 
-		cmd->control |= 8 << 24; /* s = 1, update xferStatus and resCount */
+		control |= 8 << 24; /* s = 1, update xferStatus and resCount */
 
 		/* interrupt on last block, and at intervals */
 		if (blk == recv->nblocks-1 || (blk % recv->block_irq_interval) == 0) {
-			cmd->control |= 3 << 20; /* want interrupt */
+			control |= 3 << 20; /* want interrupt */
 		}
 
-		cmd->control |= 3 << 18; /* enable branch to address */
-		cmd->control |= recv->buf_stride;
+		control |= 3 << 18; /* enable branch to address */
+		control |= recv->buf_stride;
 
-		cmd->address = dma_region_offset_to_bus(&iso->data_buf, buf_offset);
+		cmd->control = cpu_to_le32(control);
+		cmd->address = cpu_to_le32(dma_region_offset_to_bus(&iso->data_buf, buf_offset));
 		cmd->branchAddress = 0; /* filled in on next loop */
-		cmd->status = recv->buf_stride;
+		cmd->status = cpu_to_le32(recv->buf_stride);
 
 		/* link the previous descriptor to this one */
 		if (prev_branch) {
-			*prev_branch = dma_prog_region_offset_to_bus(&recv->prog, prog_offset);
-			*prev_branch |= 1; /* set Z=1 */
+			*prev_branch = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog, prog_offset) | 1);
 		}
 
 		prev_branch = &cmd->branchAddress;
@@ -1485,18 +1500,18 @@
 	/* 'next' becomes the new end of the DMA chain,
 	   so disable branch and enable interrupt */
 	next->branchAddress = 0;
-	next->control |= 3 << 20;
+	next->control |= cpu_to_le32(3 << 20);
 
 	/* link prev to next */	
-	prev->branchAddress = dma_prog_region_offset_to_bus(&recv->prog,
-							    sizeof(struct dma_cmd) * next_i)
-		| 1; /* Z=1 */
+	prev->branchAddress = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog,
+									sizeof(struct dma_cmd) * next_i)
+					  | 1); /* Z=1 */
 
 	/* disable interrupt on previous DMA descriptor, except at intervals */
 	if((prev_i % recv->block_irq_interval) == 0) {
-		prev->control |= 3 << 20; /* enable interrupt */
+		prev->control |= cpu_to_le32(3 << 20); /* enable interrupt */
 	} else {
-		prev->control &= ~(3<<20); /* disable interrupt */
+		prev->control &= cpu_to_le32(~(3<<20)); /* disable interrupt */
 	}
 	wmb();
 
@@ -1720,8 +1735,8 @@
 		struct dma_cmd *il = ((struct dma_cmd*) recv->prog.kvirt) + iso->pkt_dma;
 
 		/* check the DMA descriptor for new writes to xferStatus */
-		u16 xferstatus = il->status >> 16;
-		u16 rescount = il->status & 0xFFFF;
+		u16 xferstatus = le32_to_cpu(il->status) >> 16;
+		u16 rescount = le32_to_cpu(il->status) & 0xFFFF;
 
 		unsigned char event = xferstatus & 0x1F;
 
@@ -1903,7 +1918,7 @@
 		struct iso_xmit_cmd *cmd = dma_region_i(&xmit->prog, struct iso_xmit_cmd, iso->pkt_dma);
 		
 		/* check for new writes to xferStatus */
-		u16 xferstatus = cmd->output_last.status >> 16;
+		u16 xferstatus = le32_to_cpu(cmd->output_last.status) >> 16;
 		u8  event = xferstatus & 0x1F;
 
 		if(!event) {
@@ -1919,7 +1934,7 @@
 		wake = 1;
 		
 		/* parse cycle */
-		cycle = cmd->output_last.status & 0x1FFF;
+		cycle = le32_to_cpu(cmd->output_last.status) & 0x1FFF;
 
 		/* tell the subsystem the packet has gone out */
 		hpsb_iso_packet_sent(iso, cycle, event != 0x11);
@@ -1972,7 +1987,7 @@
 
 	/* set up the OUTPUT_MORE_IMMEDIATE descriptor */
 	memset(next, 0, sizeof(struct iso_xmit_cmd));
-	next->output_more_immediate.control = 0x02000008;
+	next->output_more_immediate.control = cpu_to_le32(0x02000008);
 
 	/* ISO packet header is embedded in the OUTPUT_MORE_IMMEDIATE */
 
@@ -1990,28 +2005,28 @@
 	next->iso_hdr[7] = len >> 8;
 
 	/* set up the OUTPUT_LAST */
-	next->output_last.control = 1 << 28;
-	next->output_last.control |= 1 << 27; /* update timeStamp */
-	next->output_last.control |= 3 << 20; /* want interrupt */
-	next->output_last.control |= 3 << 18; /* enable branch */
-	next->output_last.control |= len;
+	next->output_last.control = cpu_to_le32(1 << 28);
+	next->output_last.control |= cpu_to_le32(1 << 27); /* update timeStamp */
+	next->output_last.control |= cpu_to_le32(3 << 20); /* want interrupt */
+	next->output_last.control |= cpu_to_le32(3 << 18); /* enable branch */
+	next->output_last.control |= cpu_to_le32(len);
 
 	/* payload bus address */
-	next->output_last.address = dma_region_offset_to_bus(&iso->data_buf, offset);
+	next->output_last.address = cpu_to_le32(dma_region_offset_to_bus(&iso->data_buf, offset));
 
 	/* leave branchAddress at zero for now */
 
 	/* re-write the previous DMA descriptor to chain to this one */
 
 	/* set prev branch address to point to next (Z=3) */
-	prev->output_last.branchAddress =
-		dma_prog_region_offset_to_bus(&xmit->prog, sizeof(struct iso_xmit_cmd) * next_i) | 3;
+	prev->output_last.branchAddress = cpu_to_le32(
+		dma_prog_region_offset_to_bus(&xmit->prog, sizeof(struct iso_xmit_cmd) * next_i) | 3);
 
 	/* disable interrupt, unless required by the IRQ interval */
 	if(prev_i % iso->irq_interval) {
-		prev->output_last.control &= ~(3 << 20); /* no interrupt */
+		prev->output_last.control &= cpu_to_le32(~(3 << 20)); /* no interrupt */
 	} else {
-		prev->output_last.control |= 3 << 20; /* enable interrupt */
+		prev->output_last.control |= cpu_to_le32(3 << 20); /* enable interrupt */
 	}
 
 	wmb();
@@ -2266,7 +2281,7 @@
 	if (event & OHCI1394_cycleInconsistent) {
 		/* We subscribe to the cycleInconsistent event only to
 		 * clear the corresponding event bit... otherwise,
-		 * isochronous cycleMatch DMA wont work. */
+		 * isochronous cycleMatch DMA won't work. */
 		DBGMSG(ohci->id, "OHCI1394_cycleInconsistent");
 		event &= ~OHCI1394_cycleInconsistent;
 	}
@@ -2366,7 +2381,7 @@
 			if (!(node_id & 0x80000000)) {
 				PRINT(KERN_ERR, ohci->id,
 				      "SelfID received, but NodeID invalid "
-				      "(probably new bus reset occured): %08X",
+				      "(probably new bus reset occurred): %08X",
 				      node_id);
 				goto selfid_not_valid;
 			}
@@ -3473,10 +3488,10 @@
 
 static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
 	{
-		.class = 		PCI_CLASS_FIREWIRE_OHCI,
-		.class_mask = 	0x00ffffff,
-		.vendor =		PCI_ANY_ID,
-		.device =		PCI_ANY_ID,
+		.class = 	PCI_CLASS_FIREWIRE_OHCI,
+		.class_mask = 	~0,
+		.vendor =	PCI_ANY_ID,
+		.device =	PCI_ANY_ID,
 		.subvendor =	PCI_ANY_ID,
 		.subdevice =	PCI_ANY_ID,
 	},
@@ -3530,7 +3545,7 @@
 	tasklet_init(&tasklet->tasklet, func, data);
 	tasklet->type = type;
 	/* We init the tasklet->link field, so we can list_del() it
-	 * without worrying wether it was added to the list or not. */
+	 * without worrying whether it was added to the list or not. */
 	INIT_LIST_HEAD(&tasklet->link);
 }
 
diff -Nru a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h
--- a/drivers/ieee1394/ohci1394.h	Tue Mar  4 19:30:04 2003
+++ b/drivers/ieee1394/ohci1394.h	Tue Mar  4 19:30:04 2003
@@ -405,12 +405,12 @@
 					   truncated */
 #define EVT_OVERRUN		0x5	/* A recv FIFO overflowed on reception of ISO
 					   packet */
-#define EVT_DESCRIPTOR_READ	0x6	/* An unrecoverable error occured while host was
+#define EVT_DESCRIPTOR_READ	0x6	/* An unrecoverable error occurred while host was
 					   reading a descriptor block */
-#define EVT_DATA_READ		0x7	/* An error occured while host controller was
+#define EVT_DATA_READ		0x7	/* An error occurred while host controller was
 					   attempting to read from host memory in the data
 					   stage of descriptor processing */
-#define EVT_DATA_WRITE		0x8	/* An error occured while host controller was
+#define EVT_DATA_WRITE		0x8	/* An error occurred while host controller was
 					   attempting to write either during the data stage
 					   of descriptor processing, or when processing a single
 					   16-bit host memory write */
diff -Nru a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
--- a/drivers/ieee1394/raw1394.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/ieee1394/raw1394.c	Tue Mar  4 19:30:03 2003
@@ -238,7 +238,7 @@
                 list_del(&hi->list);
                 host_count--;
                 /* 
-                   FIXME: addressranges should be removed 
+                   FIXME: address ranges should be removed 
                    and fileinfo states should be initialized
                    (including setting generation to 
                    internal-generation ...)
@@ -281,8 +281,8 @@
                                         req->req.misc = (host->node_id << 16)
                                                 | host->node_count;
                                         if (fi->protocol_version > 3) {
-                                                req->req.misc |= ((host->irm_id
-                                                                   & NODE_MASK) << 8);
+                                                req->req.misc |= (NODEID_TO_NODE(host->irm_id)
+                                                                  << 8);
                                         }
 
                                         queue_complete_req(req);
@@ -571,8 +571,7 @@
                         req->req.misc = (fi->host->node_id << 16) 
                                 | fi->host->node_count;
                         if (fi->protocol_version > 3) {
-                                req->req.misc |=
-                                        (fi->host->irm_id & NODE_MASK) << 8;
+                                req->req.misc |= NODEID_TO_NODE(fi->host->irm_id) << 8;
                         }
                 } else {
                         req->req.error = RAW1394_ERROR_INVALID_ARG;
@@ -2440,7 +2439,7 @@
         spin_unlock_irq(&host_info_lock);
         if (fail > 0) {
                 printk(KERN_ERR "raw1394: during addr_list-release "
-                        "error(s) occured \n");
+                        "error(s) occurred \n");
         }
 
         while (!done) {
diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/ieee1394/sbp2.c	Tue Mar  4 19:30:04 2003
@@ -27,30 +27,6 @@
  * driver. It also registers as a SCSI lower-level driver in order to accept
  * SCSI commands for transport using SBP-2.
  *
- *
- * Driver Loading:
- *
- * Currently, the SBP-2 driver is supported only as a module. Because the 
- * Linux SCSI stack is not Plug-N-Play aware, module load order is 
- * important. Assuming the SCSI core drivers are either built into the 
- * kernel or already loaded as modules, you should load the IEEE-1394 modules 
- * in the following order:
- *
- * 	ieee1394 (e.g. insmod ieee1394)
- *	ohci1394 (e.g. insmod ohci1394)
- *	sbp2 (e.g. insmod sbp2)
- *
- * The SBP-2 driver will attempt to discover any attached SBP-2 devices when first
- * loaded, or after any IEEE-1394 bus reset (e.g. a hot-plug). It will then print 
- * out a debug message indicating if it was able to discover a SBP-2 device.
- *
- * Currently, the SBP-2 driver will catch any attached SBP-2 devices during the
- * initial scsi bus scan (when the driver is first loaded). To add or remove
- * SBP-2 devices "after" this initial scan (i.e. if you plug-in or un-plug a 
- * device after the SBP-2 driver is loaded), you must either use the scsi procfs
- * add-single-device, remove-single-device, or a shell script such as 
- * rescan-scsi-bus.sh.
- *
  * The easiest way to add/detect new SBP-2 devices is to run the shell script
  * rescan-scsi-bus.sh (or re-load the SBP-2 driver). This script may be 
  * found at:
@@ -136,14 +112,6 @@
  *	- Error Handling: SCSI aborts and bus reset requests are handled somewhat
  *	  but the code needs additional debugging.
  *
- *	- Module: The SBP-2 driver is currently only supported as a module. It would not take
- *	  much work to allow it to be compiled into the kernel, but you'd have to 
- *	  add some init code to the kernel to support this... and modules are much
- *	  more flexible anyway.   ;-)
- *
- *	- Hot-plugging: Interaction with the SCSI stack and support for hot-plugging could
- *	  stand some improvement.
- *
  *
  * History:
  *
@@ -295,10 +263,11 @@
  *	04/23/02 - Fix for Sony CD-ROM drives. Only send fetch agent reset to sbp2 device if it
  *		   returns the dead bit in status. Thanks to Chandan (chandan@toad.net) for this one.
  *	04/27/02 - Fix sbp2 login problem on SMP systems, enable real spinlocks by default. (JSG)
- *	06/09/02 - Don't force 36-bute SCSI inquiry, but leave in a define for badly behaved devices. (JSG)   
+ *	06/09/02 - Don't force 36-byte SCSI inquiry, but leave in a define for badly behaved devices. (JSG)   
  *	02/04/03 - Fixed a SMP deadlock (don't hold sbp2_command_lock while calling sbp2scsi_complete_command).
  *		   Also save/restore irq flags in sbp2scsi_complete_command  - Sancho Dauskardt <sda@bdit.de>
  *	02/06/03 - Removed spinlock debugging; use kernel stuff instead (sda)
+ *	02/10/03 - Adopt to new hot-plug aware SCSI inferface (hch@lst.de)
  *
  */
 
@@ -350,7 +319,7 @@
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-	"$Rev: 779 $ James Goodwin <jamesg@filanet.com>";
+	"$Rev: 797 $ James Goodwin <jamesg@filanet.com>";
 
 /*
  * Module load parameter definitions
@@ -497,6 +466,15 @@
  * Globals
  */
 
+static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi,
+					   struct scsi_id_instance_data *scsi_id,
+					   u32 status);
+
+static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi,
+				      struct scsi_id_instance_data *scsi_id,
+				      u32 scsi_status, Scsi_Cmnd *SCpnt,
+				      void (*done)(Scsi_Cmnd *));
+	
 static Scsi_Host_Template scsi_driver_template;
 
 static u8 sbp2_speedto_maxrec[] = { 0x7, 0x8, 0x9 };
@@ -822,7 +800,7 @@
 {
 	struct sbp2scsi_host_info *hi;
 	
-	hi = (struct sbp2scsi_host_info *) command->Current_SCpnt->device->host->hostdata[0];
+	hi = (struct sbp2scsi_host_info *)&command->Current_SCpnt->device->host->hostdata;
 
 	if (hi == NULL) {
 		printk(KERN_ERR "%s: hi == NULL\n", __FUNCTION__);
@@ -871,59 +849,6 @@
  * IEEE-1394 core driver stack related section
  *********************************************/
 
-/*
- * This function is called at SCSI init in order to register our driver
- * with the IEEE-1394 stack.
- */
-int sbp2_init(void)
-{
-	SBP2_DEBUG("sbp2_init");
-
-	/*
-	 * Register our high level driver with 1394 stack
-	 */
-	sbp2_hl_handle = hpsb_register_highlevel(SBP2_DEVICE_NAME, &sbp2_hl_ops);
-
-	if (sbp2_hl_handle == NULL) {
-		SBP2_ERR("sbp2 failed to register with ieee1394 highlevel");
-		return(-ENOMEM);
-	}
-
-	/*
-	 * Register our sbp2 status address space...
-	 */
-	hpsb_register_addrspace(sbp2_hl_handle, &sbp2_ops, SBP2_STATUS_FIFO_ADDRESS,
-				SBP2_STATUS_FIFO_ADDRESS + 
-				SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(SBP2SCSI_MAX_SCSI_IDS+1));
-
-	/*
-	 * Handle data movement if physical dma is not enabled/supported on host controller
-	 */
-#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
-	hpsb_register_addrspace(sbp2_hl_handle, &sbp2_physdma_ops, 0x0ULL, 0xfffffffcULL);
-#endif
-
-	hpsb_register_protocol(&sbp2_driver);
-
-	return 0;
-}
-
-/*
- * This function is called from cleanup module, or during shut-down, in
- * order to unregister our driver.
- */
-void sbp2_cleanup(void)
-{
-	SBP2_DEBUG("sbp2_cleanup");
-
-	hpsb_unregister_protocol(&sbp2_driver);
-
-	if (sbp2_hl_handle) {
-		hpsb_unregister_highlevel(sbp2_hl_handle);
-		sbp2_hl_handle = NULL;
-	}
-}
-
 static int sbp2_probe(struct unit_directory *ud)
 {
 	struct sbp2scsi_host_info *hi;
@@ -999,35 +924,44 @@
 {
 	struct sbp2scsi_host_info *hi;
 	unsigned long flags;
+	struct Scsi_Host *scsi_host;
 
 	SBP2_DEBUG("sbp2_add_host");
 
-	/* Allocate some memory for our host info structure */
-	hi = (struct sbp2scsi_host_info *)kmalloc(sizeof(struct sbp2scsi_host_info),
-						  in_interrupt() ? SLAB_ATOMIC : SLAB_KERNEL);
-
-	if (hi == NULL) {
-		SBP2_ERR("out of memory in sbp2_add_host");
+	/* Register our host with the SCSI stack. */
+	scsi_host = scsi_register (&scsi_driver_template, sizeof(struct sbp2scsi_host_info));
+	if (!scsi_host) {
+		SBP2_ERR("failed to register scsi host");
 		return;
 	}
 
-	/* Initialize some host stuff */
+	hi = (struct sbp2scsi_host_info *)&scsi_host->hostdata;
 	memset(hi, 0, sizeof(struct sbp2scsi_host_info));
+
+	hi->scsi_host = scsi_host;
 	INIT_LIST_HEAD(&hi->list);
 	hi->host = host;
 	hi->sbp2_command_lock = SPIN_LOCK_UNLOCKED;
+	hi->scsi_host->max_id = SBP2SCSI_MAX_SCSI_IDS;
 
 	spin_lock_irqsave(&sbp2_host_info_lock, flags);
 	list_add_tail(&hi->list, &sbp2_host_info_list);
 	spin_unlock_irqrestore(&sbp2_host_info_lock, flags);
 
-	/* Register our host with the SCSI stack. */
-	hi->scsi_host = scsi_register (&scsi_driver_template, sizeof(void *));
-	if (hi->scsi_host) {
-		hi->scsi_host->hostdata[0] = (unsigned long)hi;
-		hi->scsi_host->max_id = SBP2SCSI_MAX_SCSI_IDS;
+	/*
+	 * XXX(hch): Hopefully the ieee1394 code will be converted
+	 * to the driver model at some point.  Until that happens
+	 * we'll have to pass in NULL here.
+	 */
+	if (scsi_add_host(hi->scsi_host, NULL)) {
+		SBP2_ERR("failed to add scsi host");
+
+		spin_lock_irqsave(&sbp2_host_info_lock, flags);
+		list_del(&hi->list);
+		spin_unlock_irqrestore(&sbp2_host_info_lock, flags);
+
+		scsi_unregister(hi->scsi_host);
 	}
-	scsi_driver_template.present++;
 
 	return;
 }
@@ -1079,16 +1013,15 @@
 	SBP2_DEBUG("sbp2_remove_host");
 
 	spin_lock_irqsave(&sbp2_host_info_lock, flags);
-
 	hi = sbp2_find_host_info(host);
-	if (hi != NULL) {
+	if (hi)
 		list_del(&hi->list);
-		kfree(hi);
-	}
-	else
-		SBP2_ERR("attempt to remove unknown host %p", host);
-
 	spin_unlock_irqrestore(&sbp2_host_info_lock, flags);
+
+	if (hi) {
+		scsi_remove_host(hi->scsi_host);
+		scsi_unregister(hi->scsi_host);
+	}
 }
 
 /*
@@ -1098,6 +1031,7 @@
 static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_directory *ud)
 {
 	struct scsi_id_instance_data *scsi_id = NULL;
+	struct scsi_device *sdev;
 	struct node_entry *ne;
 	int i;
 
@@ -1203,7 +1137,7 @@
 	/*
 	 * Find an empty spot to stick our scsi id instance data. 
 	 */
-	for (i = 0; i < SBP2SCSI_MAX_SCSI_IDS; i++) {
+	for (i = 0; i < hi->scsi_host->max_id; i++) {
 		if (!hi->scsi_id[i]) {
 			hi->scsi_id[i] = scsi_id;
 			scsi_id->id = i;
@@ -1224,7 +1158,7 @@
 	/*
 	 * Make sure we are not out of space
 	 */
-	if (i == SBP2SCSI_MAX_SCSI_IDS) {
+	if (i == hi->scsi_host->max_id) {
 		SBP2_ERR("No slots left for SBP-2 device");
 		sbp2_remove_device(hi, scsi_id);
 		return -EBUSY;
@@ -1256,6 +1190,13 @@
 	 */
 	sbp2_max_speed_and_size(hi, scsi_id);
 
+	/* Add this device to the scsi layer now */
+	sdev = scsi_add_device(hi->scsi_host, 0, scsi_id->id, 0);
+	if (IS_ERR(sdev)) {
+		SBP2_ERR("scsi_add_device failed");
+		return PTR_ERR(sdev);
+	}
+
 	return 0;
 }
 
@@ -1265,13 +1206,21 @@
 static void sbp2_remove_device(struct sbp2scsi_host_info *hi, 
 			       struct scsi_id_instance_data *scsi_id)
 {
+	struct scsi_device *sdev = scsi_find_device(hi->scsi_host, 0, scsi_id->id, 0);
+
 	SBP2_DEBUG("sbp2_remove_device");
 
 	/* Complete any pending commands with selection timeout */
 	sbp2scsi_complete_all_commands(hi, scsi_id, DID_NO_CONNECT);
-       			
+
+	/* Remove it from the scsi layer now */
+	if (scsi_remove_device(sdev))
+		SBP2_ERR("scsi_remove_device failed");
+
 	sbp2util_remove_command_orb_pool(scsi_id, hi);
 
+	hi->scsi_id[scsi_id->id] = NULL;
+
 	if (scsi_id->login_response) {
 		pci_free_consistent(hi->host->pdev,
 				    sizeof(struct sbp2_login_response),
@@ -1305,7 +1254,7 @@
 	}
 
 	SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->id);
-	hi->scsi_id[scsi_id->id] = NULL;
+
 	kfree(scsi_id);
 }
 
@@ -1793,8 +1742,8 @@
 	SBP2_DEBUG("sbp2_max_speed_and_size");
 
 	/* Initial setting comes from the hosts speed map */
-	scsi_id->speed_code = hi->host->speed_map[(hi->host->node_id & NODE_MASK) * 64
-						  + (scsi_id->ne->nodeid & NODE_MASK)];
+	scsi_id->speed_code = hi->host->speed_map[NODEID_TO_NODE(hi->host->node_id) * 64
+						  + NODEID_TO_NODE(scsi_id->ne->nodeid)];
 
 	/* Bump down our speed if the user requested it */
 	if (scsi_id->speed_code > sbp2_max_speed) {
@@ -2661,7 +2610,7 @@
 	/*
 	 * Pull our host info and scsi id instance data from the scsi command
 	 */
-	hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0];
+	hi = (struct sbp2scsi_host_info *) &SCpnt->device->host->hostdata;
 
 	if (!hi) {
 		SBP2_ERR("sbp2scsi_host_info is NULL - this is bad!");
@@ -2766,8 +2715,10 @@
  *
  * This can be called in interrupt context.
  */
-static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, u32 scsi_status,
-				      Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi,
+				      struct scsi_id_instance_data *scsi_id,
+				      u32 scsi_status, Scsi_Cmnd *SCpnt,
+				      void (*done)(Scsi_Cmnd *))
 {
 	unsigned long flags;
 
@@ -2888,7 +2839,7 @@
  */
 static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) 
 {
-	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0];
+	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *)&SCpnt->device->host->hostdata;
 	struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->device->id];
 	struct sbp2_command_info *command;
 	unsigned long flags;
@@ -2938,7 +2889,7 @@
  */
 static int sbp2scsi_reset (Scsi_Cmnd *SCpnt) 
 {
-	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0];
+	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *)&SCpnt->device->host->hostdata;
 	struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->device->id];
 
 	SBP2_ERR("reset requested");
@@ -2951,93 +2902,81 @@
 	return(SUCCESS);
 }
 
-/*
- * Called by scsi stack to get bios parameters (used by fdisk, and at boot).
- */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,43)
-static int sbp2scsi_biosparam (struct scsi_device *sdev,
-                struct block_device *dev, sector_t capacity, int geom[])
+static const char *sbp2scsi_info (struct Scsi_Host *host)
 {
-#else
-static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[])
+        return "SCSI emulation for for IEEE-1394 Storage Devices";
+}
+
+/* Called for contents of procfs */
+#define SPRINTF(args...) \
+        do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
+
+static int sbp2scsi_proc_info(char *buffer, char **start, off_t offset,
+			      int length, int hostno, int inout)
 {
-        unsigned capacity = disk->capacity;
-#endif
-	int heads, sectors, cylinders;
+	Scsi_Device *scd;
+	struct Scsi_Host *host;
+	struct sbp2scsi_host_info *hi;
+	char *pos = buffer;
 
-	SBP2_DEBUG("Request for bios parameters");
+	/* if someone is sending us data, just throw it away */
+	if (inout)
+		return length;
 
-	heads = 64;
-	sectors = 32;
-	cylinders = (int)capacity / (heads * sectors);
+	host = scsi_host_hn_get(hostno);
+	if (!host)  /* if we couldn't find it, we return an error */
+		return -ESRCH;
 
-	if (cylinders > 1024) {
-		heads = 255;
-		sectors = 63;
-		cylinders = (int)capacity / (heads * sectors);
-	}
+	hi = sbp2_find_host_info_scsi(host);
+	if (!hi) /* shouldn't happen, but... */
+		return -ESRCH;
 
-	geom[0] = heads;
-	geom[1] = sectors;
-	geom[2] = cylinders;
+	SPRINTF("Host scsi%d             : SBP-2 IEEE-1394 (%s)\n", hostno,
+		hi->host->driver->name);
+	SPRINTF("Driver version         : %s\n", version);
 
-	return(0);
-}
+	SPRINTF("\nModule options         :\n");
+	SPRINTF("  sbp2_max_speed       : %s\n", hpsb_speedto_str[sbp2_max_speed]);
+	SPRINTF("  sbp2_max_sectors     : %d\n", sbp2_max_sectors);
+	SPRINTF("  sbp2_serialize_io    : %s\n", sbp2_serialize_io ? "yes" : "no");
+	SPRINTF("  sbp2_exclusive_login : %s\n", sbp2_exclusive_login ? "yes" : "no");
 
-/*
- * Called by scsi stack after scsi driver is registered
- */
-static int sbp2scsi_detect (Scsi_Host_Template *tpnt) 
-{
-	SBP2_DEBUG("sbp2scsi_detect");
+	SPRINTF("\nAttached devices       : %s\n", !list_empty(&host->my_devices) ?
+		"" : "none");
 
-	/*
-	 * Call sbp2_init to register with the ieee1394 stack. This
-	 * results in a callback to sbp2_add_host for each ieee1394
-	 * host controller currently registered, and for each of those
-	 * we register a scsi host with the scsi stack.
-	 */
-	
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	spin_unlock_irq(&io_request_lock);
-	sbp2_init();
-	spin_lock_irq(&io_request_lock);
-#else
-	sbp2_init();
-#endif
+	list_for_each_entry (scd, &host->my_devices, siblings) {
+		int i;
 
-	/* We return the number of hosts registered. */
-	return scsi_driver_template.present;
-}
+		SPRINTF("  [Channel: %02d, Id: %02d, Lun: %02d]  ", scd->channel,
+			scd->id, scd->lun);
+		SPRINTF("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ?
+			scsi_device_types[(short) scd->type] : "Unknown device");
 
+		for (i = 0; (i < 8) && (scd->vendor[i] >= 0x20); i++)
+			SPRINTF("%c", scd->vendor[i]);
 
-/*
- * Called for contents of procfs
- */
-static const char *sbp2scsi_info (struct Scsi_Host *host)
-{
-	struct sbp2scsi_host_info *hi = sbp2_find_host_info_scsi(host);
-	static char info[1024];
+		SPRINTF(" ");
 
-	if (!hi) /* shouldn't happen, but... */
-        	return "IEEE-1394 SBP-2 protocol driver";
+		for (i = 0; (i < 16) && (scd->model[i] >= 0x20); i++)
+			SPRINTF("%c", scd->model[i]);
+
+		SPRINTF("\n");
+	}
 
-	sprintf(info, "IEEE-1394 SBP-2 protocol driver (host: %s)\n%s\n"
-		"SBP-2 module load options:\n"
-		"- Max speed supported: %s\n"
-		"- Max sectors per I/O supported: %d\n"
-                "- Serialized I/O (debug): %s\n"
-		"- Exclusive login: %s",
-		hi->host->driver->name,
-		version,
-		hpsb_speedto_str[sbp2_max_speed],
-		sbp2_max_sectors,
-		sbp2_serialize_io ? "yes" : "no",
-		sbp2_exclusive_login ? "yes" : "no");
+	SPRINTF("\n");
 
-	return info;
-}
+	/* release the reference count on this host */
+	scsi_host_put(host);
+	/* Calculate start of next buffer, and return value. */
+	*start = buffer + offset;
 
+	if ((pos - buffer) < offset)
+		return (0);
+	else if ((pos - buffer - offset) < length)
+		return (pos - buffer - offset);
+	else
+		return (length);
+}
 
 MODULE_AUTHOR("James Goodwin <jamesg@filanet.com>");
 MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver");
@@ -3046,25 +2985,23 @@
 
 /* SCSI host template */
 static Scsi_Host_Template scsi_driver_template = {
-	.name =			"IEEE-1394 SBP-2 protocol driver",
-	.info =			sbp2scsi_info,
-	.detect =		sbp2scsi_detect,
-	.queuecommand =		sbp2scsi_queuecommand,
-	.eh_abort_handler =	sbp2scsi_abort,
-	.eh_device_reset_handler =sbp2scsi_reset,
-	.eh_bus_reset_handler =	sbp2scsi_reset,
-	.eh_host_reset_handler =sbp2scsi_reset,
-	.bios_param =		sbp2scsi_biosparam,
-	.this_id =		-1,
-	.sg_tablesize =		SG_ALL,
-	.use_clustering =	ENABLE_CLUSTERING,
-	.cmd_per_lun =		SBP2_MAX_CMDS_PER_LUN,
-	.can_queue = 		SBP2_MAX_SCSI_QUEUE,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	.use_new_eh_code =	TRUE,
-#endif
-	.emulated =		1,
-	.proc_name =		SBP2_DEVICE_NAME,
+	.module =			THIS_MODULE,
+	.name =				"SBP-2 IEEE-1394",
+	.proc_name =			SBP2_DEVICE_NAME,
+	.info =				sbp2scsi_info,
+	.proc_info =			sbp2scsi_proc_info,
+	.queuecommand =			sbp2scsi_queuecommand,
+	.eh_abort_handler =		sbp2scsi_abort,
+	.eh_device_reset_handler =	sbp2scsi_reset,
+	.eh_bus_reset_handler =		sbp2scsi_reset,
+	.eh_host_reset_handler =	sbp2scsi_reset,
+	.this_id =			-1,
+	.sg_tablesize =			SG_ALL,
+	.use_clustering =		ENABLE_CLUSTERING,
+	.cmd_per_lun =			SBP2_MAX_CMDS_PER_LUN,
+	.can_queue = 			SBP2_MAX_SCSI_QUEUE,
+	.emulated =			1,
+	.highmem_io =			1,
 };
 
 static int sbp2_module_init(void)
@@ -3084,23 +3021,36 @@
 	 */
 	scsi_driver_template.max_sectors = sbp2_max_sectors;
 
+
 	/*
-	 * Ideally we would register our scsi_driver_template with the
-	 * scsi stack and after that register with the ieee1394 stack
-	 * and process the add_host callbacks. However, the detect
-	 * function in the scsi host template requires that we find at
-	 * least one host, so we "nest" the registrations by calling
-	 * sbp2_init from the detect function.
-	 */
-	scsi_driver_template.module = THIS_MODULE;
-	if (SCSI_REGISTER_HOST(&scsi_driver_template) ||
-	    !scsi_driver_template.present) {
-		SBP2_ERR("Please load the lower level IEEE-1394 driver "
-			 "(e.g. ohci1394) before sbp2...");
-		sbp2_cleanup();
-		return -ENODEV;
+	 * Register our high level driver with 1394 stack
+	 */
+	sbp2_hl_handle = hpsb_register_highlevel(SBP2_DEVICE_NAME,
+						 &sbp2_hl_ops);
+	if (!sbp2_hl_handle) {
+		SBP2_ERR("sbp2 failed to register with ieee1394 highlevel");
+		return(-ENOMEM);
 	}
 
+	/*
+	 * Register our sbp2 status address space...
+	 */
+	hpsb_register_addrspace(sbp2_hl_handle, &sbp2_ops,
+				SBP2_STATUS_FIFO_ADDRESS,
+				SBP2_STATUS_FIFO_ADDRESS + 
+				SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(
+					SBP2SCSI_MAX_SCSI_IDS+1));
+
+	/*
+	 * Handle data movement if physical dma is not enabled/supported
+	 * on host controller
+	 */
+#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
+	hpsb_register_addrspace(sbp2_hl_handle, &sbp2_physdma_ops,
+			0x0ULL, 0xfffffffcULL);
+#endif
+
+	hpsb_register_protocol(&sbp2_driver);
 	return 0;
 }
 
@@ -3108,17 +3058,9 @@
 {
 	SBP2_DEBUG("sbp2_module_exit");
 
-	/*
-	 * On module unload we unregister with the ieee1394 stack
-	 * which results in remove_host callbacks for all ieee1394
-	 * host controllers.  In the callbacks we unregister the
-	 * corresponding scsi hosts.
-	 */
-	sbp2_cleanup();
-
-	if (SCSI_UNREGISTER_HOST(&scsi_driver_template))
-		SBP2_ERR("sbp2_module_exit: couldn't unregister scsi driver");
-
+	hpsb_unregister_protocol(&sbp2_driver);
+	if (sbp2_hl_handle)
+		hpsb_unregister_highlevel(sbp2_hl_handle);
 }
 
 module_init(sbp2_module_init);
diff -Nru a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
--- a/drivers/ieee1394/sbp2.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/ieee1394/sbp2.h	Tue Mar  4 19:30:05 2003
@@ -22,15 +22,6 @@
 #ifndef SBP2_H
 #define SBP2_H
 
-/* Some compatibility code */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#define SCSI_REGISTER_HOST(tmpl)	scsi_register_module(MODULE_SCSI_HA, tmpl)
-#define SCSI_UNREGISTER_HOST(tmpl)	scsi_unregister_module(MODULE_SCSI_HA, tmpl)
-#else
-#define SCSI_REGISTER_HOST(tmpl)	scsi_register_host(tmpl)
-#define SCSI_UNREGISTER_HOST(tmpl)	scsi_unregister_host(tmpl)
-#endif
-
 #define SBP2_DEVICE_NAME		"sbp2"
 
 /*
@@ -442,8 +433,6 @@
 static void sbp2_add_host(struct hpsb_host *host);
 static struct sbp2scsi_host_info *sbp2_find_host_info(struct hpsb_host *host);
 static void sbp2_remove_host(struct hpsb_host *host);
-int sbp2_init(void);
-void sbp2_cleanup(void);
 static int sbp2_probe(struct unit_directory *ud);
 static void sbp2_disconnect(struct unit_directory *ud);
 static void sbp2_update(struct unit_directory *ud);
@@ -486,24 +475,5 @@
 static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id);
 static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
 static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
-
-/*
- * Scsi interface related prototypes
- */
-static int sbp2scsi_detect (Scsi_Host_Template *tpnt);
-static const char *sbp2scsi_info (struct Scsi_Host *host);
-void sbp2scsi_setup(char *str, int *ints);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,44)
-static int sbp2scsi_biosparam (struct scsi_device *sdev, struct block_device *dev, sector_t capacity, int geom[]);
-#else
-static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[]);
-#endif
-static int sbp2scsi_abort (Scsi_Cmnd *SCpnt); 
-static int sbp2scsi_reset (Scsi_Cmnd *SCpnt); 
-static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
-static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, 
-					   u32 status);
-static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, 
-				      u32 scsi_status, Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
 
 #endif /* SBP2_H */
diff -Nru a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
--- a/drivers/ieee1394/video1394.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/ieee1394/video1394.c	Tue Mar  4 19:30:04 2003
@@ -43,6 +43,8 @@
 #include <linux/vmalloc.h>
 #include <linux/timex.h>
 #include <linux/mm.h>
+#include <linux/ioctl32.h>
+#include <linux/compat.h>
 
 #include "ieee1394.h"
 #include "ieee1394_types.h"
@@ -1338,24 +1340,152 @@
 MODULE_SUPPORTED_DEVICE(VIDEO1394_DRIVER_NAME);
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_COMPAT
+
+#define VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER     \
+	_IOW ('#', 0x12, struct video1394_wait32)
+#define VIDEO1394_IOC32_LISTEN_WAIT_BUFFER      \
+	_IOWR('#', 0x13, struct video1394_wait32)
+#define VIDEO1394_IOC32_TALK_WAIT_BUFFER        \
+	_IOW ('#', 0x17, struct video1394_wait32)
+#define VIDEO1394_IOC32_LISTEN_POLL_BUFFER      \
+	_IOWR('#', 0x18, struct video1394_wait32)
+
+struct video1394_wait32 {
+	u32 channel;
+	u32 buffer;
+	struct compat_timeval filltime;
+};
+
+static int video1394_wr_wait32(unsigned int fd, unsigned int cmd, unsigned long arg,
+			       struct file *file)
+{
+        struct video1394_wait32 wait32;
+        struct video1394_wait wait;
+        mm_segment_t old_fs;
+        int ret;
+
+	if (file->f_op->ioctl != video1394_ioctl)
+		return -EFAULT;
+
+        if (copy_from_user(&wait32, (void *)arg, sizeof(wait32)))
+                return -EFAULT;
+
+        wait.channel = wait32.channel;
+        wait.buffer = wait32.buffer;
+        wait.filltime.tv_sec = (time_t)wait32.filltime.tv_sec;
+        wait.filltime.tv_usec = (suseconds_t)wait32.filltime.tv_usec;
+
+        old_fs = get_fs();
+        set_fs(KERNEL_DS);
+        if (cmd == VIDEO1394_IOC32_LISTEN_WAIT_BUFFER)
+		ret = video1394_ioctl(file->f_dentry->d_inode, file,
+				      VIDEO1394_IOC_LISTEN_WAIT_BUFFER,
+				      (unsigned long) &wait);
+        else
+		ret = video1394_ioctl(file->f_dentry->d_inode, file,
+				      VIDEO1394_IOC_LISTEN_POLL_BUFFER,
+				      (unsigned long) &wait);
+        set_fs(old_fs);
+
+        if (!ret) {
+                wait32.channel = wait.channel;
+                wait32.buffer = wait.buffer;
+                wait32.filltime.tv_sec = (int)wait.filltime.tv_sec;
+                wait32.filltime.tv_usec = (int)wait.filltime.tv_usec;
+
+                if (copy_to_user((struct video1394_wait32 *)arg, &wait32, sizeof(wait32)))
+                        ret = -EFAULT;
+        }
+
+        return ret;
+}
+
+static int video1394_w_wait32(unsigned int fd, unsigned int cmd, unsigned long arg,
+			      struct file *file)
+{
+        struct video1394_wait32 wait32;
+        struct video1394_wait wait;
+        mm_segment_t old_fs;
+        int ret;
+
+	if (file->f_op->ioctl != video1394_ioctl)
+		return -EFAULT;
+
+        if (copy_from_user(&wait32, (void *)arg, sizeof(wait32)))
+                return -EFAULT;
+
+        wait.channel = wait32.channel;
+        wait.buffer = wait32.buffer;
+        wait.filltime.tv_sec = (time_t)wait32.filltime.tv_sec;
+        wait.filltime.tv_usec = (suseconds_t)wait32.filltime.tv_usec;
+
+        old_fs = get_fs();
+        set_fs(KERNEL_DS);
+        if (cmd == VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER)
+		ret = video1394_ioctl(file->f_dentry->d_inode, file,
+				      VIDEO1394_IOC_LISTEN_QUEUE_BUFFER,
+				      (unsigned long) &wait);
+        else
+		ret = video1394_ioctl(file->f_dentry->d_inode, file,
+				      VIDEO1394_IOC_TALK_WAIT_BUFFER,
+				      (unsigned long) &wait);
+        set_fs(old_fs);
+
+        return ret;
+}
+
+static int video1394_queue_buf32(unsigned int fd, unsigned int cmd, unsigned long arg,
+				 struct file *file)
+{
+	if (file->f_op->ioctl != video1394_ioctl)
+		return -EFAULT;
+
+        return -EFAULT;
+
+	return video1394_ioctl(file->f_dentry->d_inode, file,
+				VIDEO1394_IOC_TALK_QUEUE_BUFFER, arg);
+}
+
+#endif /* CONFIG_COMPAT */
+
 static void __exit video1394_exit_module (void)
 {
+#ifdef CONFIG_COMPAT
+	int ret;
+
+	ret = unregister_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL);
+	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL);
+	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_TALK_CHANNEL);
+	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_UNTALK_CHANNEL);
+	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER);
+	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_WAIT_BUFFER);
+	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC_TALK_QUEUE_BUFFER);
+	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER);
+	ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER);
+	if (ret)
+		PRINT_G(KERN_INFO, "Error unregistering ioctl32 translations");
+#endif
+
 	hpsb_unregister_highlevel (hl_handle);
 
 	devfs_unregister(devfs_handle);
 	ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394);
-	
+
 	PRINT_G(KERN_INFO, "Removed " VIDEO1394_DRIVER_NAME " module");
 }
 
 static int __init video1394_init_module (void)
 {
-	if (ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394,
-				      THIS_MODULE, &video1394_fops)) {
+	int ret;
+
+	ret = ieee1394_register_chardev(IEEE1394_MINOR_BLOCK_VIDEO1394,
+					THIS_MODULE, &video1394_fops);
+	if (ret) {
 		PRINT_G(KERN_ERR, "video1394: unable to get minor device block");
- 		return -EIO;
- 	}
-	
+		return -EIO;
+        }
+
 	devfs_handle = devfs_mk_dir(NULL, VIDEO1394_DRIVER_NAME, NULL);
 
 	hl_handle = hpsb_register_highlevel (VIDEO1394_DRIVER_NAME, &hl_ops);
@@ -1366,9 +1496,32 @@
 		return -ENOMEM;
 	}
 
+#ifdef CONFIG_COMPAT
+	/* First the compatible ones */
+	ret = register_ioctl32_conversion(VIDEO1394_IOC_LISTEN_CHANNEL, NULL);
+	ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNLISTEN_CHANNEL, NULL);
+	ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_CHANNEL, NULL);
+	ret |= register_ioctl32_conversion(VIDEO1394_IOC_UNTALK_CHANNEL, NULL);
+
+	/* These need translation */
+	ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_QUEUE_BUFFER,
+				    video1394_w_wait32);
+	ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_WAIT_BUFFER,
+				    video1394_wr_wait32);
+	ret |= register_ioctl32_conversion(VIDEO1394_IOC_TALK_QUEUE_BUFFER,
+				    video1394_queue_buf32);
+	ret |= register_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER,
+				    video1394_w_wait32);
+	ret |= register_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER,
+				    video1394_wr_wait32);
+	if (ret)
+		PRINT_G(KERN_INFO, "Error registering ioctl32 translations");
+#endif
+
 	PRINT_G(KERN_INFO, "Installed " VIDEO1394_DRIVER_NAME " module");
 	return 0;
 }
+
 
 module_init(video1394_init_module);
 module_exit(video1394_exit_module);
diff -Nru a/drivers/isdn/eicon/adapter.h b/drivers/isdn/eicon/adapter.h
--- a/drivers/isdn/eicon/adapter.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/isdn/eicon/adapter.h	Tue Mar  4 19:30:13 2003
@@ -185,7 +185,7 @@
 IDI_CALL	DivasIdiRequest[];
 
 /*
- * intialisation entry point
+ * initialisation entry point
  */
 
 int		DivasInit(void);
diff -Nru a/drivers/isdn/eicon/eicon_idi.c b/drivers/isdn/eicon/eicon_idi.c
--- a/drivers/isdn/eicon/eicon_idi.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/isdn/eicon/eicon_idi.c	Tue Mar  4 19:30:03 2003
@@ -2717,7 +2717,7 @@
 	int twaitpq = 0;
 
 	if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) {
-		/* I dont know why this happens, should not ! */
+		/* I don't know why this happens, should not ! */
 		/* just ignoring this RC */
 		eicon_log(ccard, 16, "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No, 
 			ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id);
diff -Nru a/drivers/isdn/eicon/idi.c b/drivers/isdn/eicon/idi.c
--- a/drivers/isdn/eicon/idi.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/isdn/eicon/idi.c	Tue Mar  4 19:30:05 2003
@@ -435,7 +435,7 @@
     a->ram_out(a, &ReqOut->ReqId, this->Id);
     a->ram_out(a, &ReqOut->ReqCh, this->ReqCh);
 
-        /* if its a specific request (no ASSIGN) ...                */
+        /* if it's a specific request (no ASSIGN) ...                */
 
     if(this->Id &0x1f) {
 
diff -Nru a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c
--- a/drivers/isdn/hardware/eicon/dadapter.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/isdn/hardware/eicon/dadapter.c	Tue Mar  4 19:30:08 2003
@@ -327,7 +327,7 @@
    Adapter array will be written to memory described by 'buffer'
    If the last adapter seen in the returned adapter array is
    IDI_DADAPTER or if last adapter in array does have type '0', then
-   it was enougth space in buffer to accomodate all available
+   it was enougth space in buffer to accommodate all available
    adapter descriptors
   *NOTE 1 (debug interface):
    The IDI adapter of type 'IDI_DIMAINT' does register as 'request'
diff -Nru a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
--- a/drivers/isdn/hardware/eicon/di.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/isdn/hardware/eicon/di.c	Tue Mar  4 19:30:07 2003
@@ -169,7 +169,7 @@
     a->ram_outw(a, &ReqOut->XBuffer.length, length);
     a->ram_out(a, &ReqOut->ReqId, this->Id);
     a->ram_out(a, &ReqOut->ReqCh, this->ReqCh);
-        /* if its a specific request (no ASSIGN) ...                */
+        /* if it's a specific request (no ASSIGN) ...                */
     if(this->Id &0x1f) {
         /* if buffers are left in the list of data buffers do       */
         /* do chaining (LL_MDATA, N_MDATA)                          */
@@ -405,7 +405,7 @@
   a->ram_outw(a, &RAM->XBuffer.length, length);
   a->ram_out(a, &RAM->ReqId, this->Id);
   a->ram_out(a, &RAM->ReqCh, this->ReqCh);
-        /* if its a specific request (no ASSIGN) ...                */
+        /* if it's a specific request (no ASSIGN) ...                */
   if(this->Id &0x1f) {
         /* if buffers are left in the list of data buffers do       */
         /* chaining (LL_MDATA, N_MDATA)                             */
diff -Nru a/drivers/isdn/hardware/eicon/i4l_idi.c b/drivers/isdn/hardware/eicon/i4l_idi.c
--- a/drivers/isdn/hardware/eicon/i4l_idi.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/isdn/hardware/eicon/i4l_idi.c	Tue Mar  4 19:30:08 2003
@@ -2717,7 +2717,7 @@
   int twaitpq = 0;
 
 	if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) {
-		/* I dont know why this happens, should not ! */
+		/* I don't know why this happens, should not ! */
 		/* just ignoring this RC */
 		eicon_log(ccard, 16, "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No, 
 			ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id);
diff -Nru a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c
--- a/drivers/isdn/hardware/eicon/istream.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/isdn/hardware/eicon/istream.c	Tue Mar  4 19:30:05 2003
@@ -142,7 +142,7 @@
   return 0  if zero packet was received
   return -1 if stream is empty
     return -2 if read buffer does not profide sufficient space
-              to accomodate entire segment
+              to accommodate entire segment
   max_length should be at least 68 bytes
   ------------------------------------------------------------------- */
 int diva_istream_read (void* context,
diff -Nru a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
--- a/drivers/isdn/hisax/amd7930_fn.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/isdn/hisax/amd7930_fn.c	Tue Mar  4 19:30:10 2003
@@ -42,7 +42,7 @@
  *
  * Credits:
  * Programming the driver for Formula-n enter:now ISDN PCI and
- * neccessary this driver for the used Amd 7930 D-channel-controller
+ * necessary this driver for the used Amd 7930 D-channel-controller
  * was spnsored by Formula-n Europe AG.
  * Thanks to Karsten Keil and Petr Novak, who gave me support in
  * Hisax-specific questions.
@@ -317,7 +317,7 @@
 								QuickHex(t, cs->rcvbuf, cs->rcvidx);
 								debugl1(cs, cs->dlog);
 							}
-                                                        /* moves recieved data in sk-buffer */
+                                                        /* moves received data in sk-buffer */
 							memcpy(skb_put(skb, cs->rcvidx), cs->rcvbuf, cs->rcvidx);
 							skb_queue_tail(&cs->rq, skb);
 						}
diff -Nru a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c
--- a/drivers/isdn/hisax/asuscom.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/isdn/hisax/asuscom.c	Tue Mar  4 19:30:14 2003
@@ -283,7 +283,7 @@
 						printk(KERN_ERR "AsusPnP: attach failed\n");
 						return 0;
 					}
-					if (pnp_activate_dev(pd, NULL) < 0) {
+					if (pnp_activate_dev(pd) < 0) {
 						printk(KERN_ERR "AsusPnP: activate failed\n");
 						pnp_device_detach(pd);
 						return 0;
diff -Nru a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
--- a/drivers/isdn/hisax/avm_pci.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/isdn/hisax/avm_pci.c	Tue Mar  4 19:30:07 2003
@@ -632,7 +632,7 @@
 						printk(KERN_ERR "FritzPnP: attach failed\n");
 						return 0;
 					}
-					if (pnp_activate_dev(pnp_avm, NULL) < 0) {
+					if (pnp_activate_dev(pnp_avm) < 0) {
 						printk(KERN_ERR "FritzPnP: activate failed\n");
 						pnp_device_detach(pnp_avm);
 						return 0;
diff -Nru a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
--- a/drivers/isdn/hisax/diva.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/isdn/hisax/diva.c	Tue Mar  4 19:30:13 2003
@@ -600,7 +600,7 @@
 							printk(KERN_ERR "Diva PnP: attach failed\n");
 							return 0;
 						}
-						if (pnp_activate_dev(pd, NULL) < 0) {
+						if (pnp_activate_dev(pd) < 0) {
 							printk(KERN_ERR "Diva PnP: activate failed\n");
 							pnp_device_detach(pd);
 							return 0;
diff -Nru a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
--- a/drivers/isdn/hisax/elsa.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/isdn/hisax/elsa.c	Tue Mar  4 19:30:04 2003
@@ -864,7 +864,7 @@
 							printk(KERN_ERR "Elsa PnP: attach failed\n");
 							return 0;
 						}
-						if (pnp_activate_dev(pd, NULL) < 0) {
+						if (pnp_activate_dev(pd) < 0) {
 							pnp_device_detach(pd);
 							printk(KERN_ERR "Elsa PnP: activate failed\n");
 							return 0;
diff -Nru a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c
--- a/drivers/isdn/hisax/enternow_pci.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/isdn/hisax/enternow_pci.c	Tue Mar  4 19:30:12 2003
@@ -49,7 +49,7 @@
  *
  * Credits:
  * Programming the driver for Formula-n enter:now ISDN PCI and
- * neccessary the driver for the used Amd 7930 D-channel-controller
+ * necessary the driver for the used Amd 7930 D-channel-controller
  * was spnsored by Formula-n Europe AG.
  * Thanks to Karsten Keil and Petr Novak, who gave me support in
  * Hisax-specific questions.
diff -Nru a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
--- a/drivers/isdn/hisax/hfc_sx.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/isdn/hisax/hfc_sx.c	Tue Mar  4 19:30:04 2003
@@ -97,7 +97,7 @@
 
 /******************************************/
 /* reset the specified fifo to defaults.  */
-/* If its a send fifo init needed markers */
+/* If it's a send fifo init needed markers */
 /******************************************/
 static void
 reset_fifo(struct IsdnCardState *cs, u8 fifo)
@@ -1200,7 +1200,7 @@
 						printk(KERN_ERR "HFC PnP: attach failed\n");
 						return 0;
 					}
-					if (pnp_activate_dev(pd, NULL) < 0) {
+					if (pnp_activate_dev(pd) < 0) {
 						printk(KERN_ERR "HFC PnP: activate failed\n");
 						pnp_device_detach(pd);
 						return 0;
diff -Nru a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c
--- a/drivers/isdn/hisax/hfcscard.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/isdn/hisax/hfcscard.c	Tue Mar  4 19:30:13 2003
@@ -193,7 +193,7 @@
 						printk(KERN_ERR "HFC PnP: attach failed\n");
 						return 0;
 					}
-					if (pnp_activate_dev(pd, NULL) < 0) {
+					if (pnp_activate_dev(pd) < 0) {
 						printk(KERN_ERR "HFC PnP: activate failed\n");
 						pnp_device_detach(pd);
 						return 0;
diff -Nru a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c
--- a/drivers/isdn/hisax/isurf.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/isdn/hisax/isurf.c	Tue Mar  4 19:30:09 2003
@@ -223,7 +223,7 @@
 					printk(KERN_ERR "ISurfPnP: attach failed\n");
 					return 0;
 				}
-				if (pnp_activate_dev(pd, NULL) < 0) {
+				if (pnp_activate_dev(pd) < 0) {
 					printk(KERN_ERR "ISurfPnP: activate failed\n");
 					pnp_device_detach(pd);
 					return 0;
diff -Nru a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c
--- a/drivers/isdn/hisax/ix1_micro.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/isdn/hisax/ix1_micro.c	Tue Mar  4 19:30:13 2003
@@ -208,7 +208,7 @@
 						printk(KERN_ERR "ITK PnP: attach failed\n");
 						return 0;
 					}
-					if (pnp_activate_dev(pd, NULL) < 0) {
+					if (pnp_activate_dev(pd) < 0) {
 						printk(KERN_ERR "ITK PnP: activate failed\n");
 						pnp_device_detach(pd);
 						return 0;
diff -Nru a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
--- a/drivers/isdn/hisax/l3dss1.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/isdn/hisax/l3dss1.c	Tue Mar  4 19:30:08 2003
@@ -1603,7 +1603,7 @@
 	 * Bearer Capabilities
 	 */
 	p = skb->data;
-	/* only the first occurence 'll be detected ! */
+	/* only the first occurrence 'll be detected ! */
 	if ((p = findie(p, skb->len, 0x04, 0))) {
 		if ((p[1] < 2) || (p[1] > 11))
 			err = 1;
diff -Nru a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
--- a/drivers/isdn/hisax/l3ni1.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/isdn/hisax/l3ni1.c	Tue Mar  4 19:30:05 2003
@@ -1456,7 +1456,7 @@
 	 * Bearer Capabilities
 	 */
 	p = skb->data;
-	/* only the first occurence 'll be detected ! */
+	/* only the first occurrence 'll be detected ! */
 	if ((p = findie(p, skb->len, 0x04, 0))) {
 		if ((p[1] < 2) || (p[1] > 11))
 			err = 1;
diff -Nru a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c
--- a/drivers/isdn/hisax/niccy.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/isdn/hisax/niccy.c	Tue Mar  4 19:30:07 2003
@@ -232,7 +232,7 @@
 				printk(KERN_ERR "NiccyPnP: attach failed\n");
 				return 0;
 			}
-			if (pnp_activate_dev(pd, NULL) < 0) {
+			if (pnp_activate_dev(pd) < 0) {
 				printk(KERN_ERR "NiccyPnP: activate failed\n");
 				pnp_device_detach(pd);
 				return 0;
diff -Nru a/drivers/isdn/hisax/rawhdlc.c b/drivers/isdn/hisax/rawhdlc.c
--- a/drivers/isdn/hisax/rawhdlc.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/isdn/hisax/rawhdlc.c	Tue Mar  4 19:30:05 2003
@@ -34,7 +34,7 @@
  * end-of-frame would occur), so the transmitter performs
  * "bit-stuffing" - inserting a zero bit after every five one bits,
  * irregardless of the original bit after the five ones.  Byte
- * ordering is irrelevent at this point - the data is treated as a
+ * ordering is irrelevant at this point - the data is treated as a
  * string of bits, not bytes.  Since no more than 5 ones may now occur
  * in a row, the flag sequence, with its 6 ones, is unique.
  *
diff -Nru a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
--- a/drivers/isdn/hisax/sedlbauer.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/isdn/hisax/sedlbauer.c	Tue Mar  4 19:30:14 2003
@@ -524,7 +524,7 @@
 							printk(KERN_ERR "Sedlbauer PnP: attach failed\n");
 							return 0;
 						}
-						if (pnp_activate_dev(pd, NULL) < 0) {
+						if (pnp_activate_dev(pd) < 0) {
 							printk(KERN_ERR "Sedlbauer PnP: activate failed\n");
 							pnp_device_detach(pd);
 							return 0;
diff -Nru a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c
--- a/drivers/isdn/hisax/teles3.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/isdn/hisax/teles3.c	Tue Mar  4 19:30:14 2003
@@ -227,7 +227,7 @@
 						printk(KERN_ERR "Teles PnP: attach failed\n");
 						return 0;
 					}
-					if (pnp_activate_dev(pnp_dev, NULL) < 0) {
+					if (pnp_activate_dev(pnp_dev) < 0) {
 						printk(KERN_ERR "Teles PnP: activate failed\n");
 						pnp_device_detach(pnp_dev);
 						return 0;
diff -Nru a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
--- a/drivers/isdn/hysdn/hycapi.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/isdn/hysdn/hycapi.c	Tue Mar  4 19:30:04 2003
@@ -521,7 +521,7 @@
 Receive a capi-message.
 
 All B3_DATA_IND are converted to 64K-extension compatible format.
-New nccis are created if neccessary.
+New nccis are created if necessary.
 *******************************************************************/
 
 void
@@ -702,7 +702,7 @@
 /********************************************************************
 hycapi_capi_create(hysdn_card *card)
 
-Attach the card with it's capi-ctrl.
+Attach the card with its capi-ctrl.
 *********************************************************************/
 
 static void hycapi_fill_profile(hysdn_card *card)
diff -Nru a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
--- a/drivers/isdn/hysdn/hysdn_boot.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/isdn/hysdn/hysdn_boot.c	Tue Mar  4 19:30:08 2003
@@ -357,7 +357,7 @@
 		hysdn_addlog(card, "SysReady Token Data invalid CRC");
 		return (1);
 	}
-	len--;			/* dont check CRC byte */
+	len--;			/* don't check CRC byte */
 	while (len > 0) {
 
 		if (*cp == SYSR_TOK_END)
diff -Nru a/drivers/isdn/i4l/isdn_ppp_ccp.c b/drivers/isdn/i4l/isdn_ppp_ccp.c
--- a/drivers/isdn/i4l/isdn_ppp_ccp.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/isdn/i4l/isdn_ppp_ccp.c	Tue Mar  4 19:30:07 2003
@@ -197,7 +197,7 @@
 		   and increase ids only when an Ack is received for a
 		   given id */
 		id = ccp->reset->lastid++;
-		/* We always expect an Ack if the decompressor doesnt
+		/* We always expect an Ack if the decompressor doesn't
 		   know	better */
 		rp->expra = 1;
 		rp->dtval = 0;
diff -Nru a/drivers/isdn/tpam/tpam_commands.c b/drivers/isdn/tpam/tpam_commands.c
--- a/drivers/isdn/tpam/tpam_commands.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/isdn/tpam/tpam_commands.c	Tue Mar  4 19:30:04 2003
@@ -880,7 +880,7 @@
 		memcpy(skb_put(result, len), data, len);
 	}
 
-	/* In loop mode, resend the data immediatly */
+	/* In loop mode, resend the data immediately */
 	if (card->loopmode) {
 		struct sk_buff *loopskb;
 
diff -Nru a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
--- a/drivers/macintosh/via-pmu.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/macintosh/via-pmu.c	Tue Mar  4 19:30:13 2003
@@ -1179,7 +1179,7 @@
 static inline void
 wait_for_ack(void)
 {
-	/* Sightly increased the delay, I had one occurence of the message
+	/* Sightly increased the delay, I had one occurrence of the message
 	 * reported
 	 */
 	int timeout = 4000;
@@ -2066,7 +2066,7 @@
 
 	/* Make sure the decrementer won't interrupt us */
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-	/* Make sure any pending DEC interrupt occuring while we did
+	/* Make sure any pending DEC interrupt occurring while we did
 	 * the above didn't re-enable the DEC */
 	mb();
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
@@ -2211,7 +2211,7 @@
 
 	/* Make sure the decrementer won't interrupt us */
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-	/* Make sure any pending DEC interrupt occuring while we did
+	/* Make sure any pending DEC interrupt occurring while we did
 	 * the above didn't re-enable the DEC */
 	mb();
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
@@ -2376,7 +2376,7 @@
 
 	/* Make sure the decrementer won't interrupt us */
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-	/* Make sure any pending DEC interrupt occuring while we did
+	/* Make sure any pending DEC interrupt occurring while we did
 	 * the above didn't re-enable the DEC */
 	mb();
 	asm volatile("mtdec %0" : : "r" (0x7fffffff));
diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
--- a/drivers/md/dm-ioctl.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/md/dm-ioctl.c	Tue Mar  4 19:30:05 2003
@@ -173,14 +173,18 @@
  */
 static int register_with_devfs(struct hash_cell *hc)
 {
-	char name[32];
 	struct gendisk *disk = dm_disk(hc->md);
+	char *name = kmalloc(DM_NAME_LEN + strlen(DM_DIR) + 1, GFP_KERNEL);
+	if (!name) {
+		return -ENOMEM;
+	}
 
 	sprintf(name, DM_DIR "/%s", hc->name);
 	devfs_register(NULL, name, DEVFS_FL_CURRENT_OWNER,
 		       disk->major, disk->first_minor,
 		       S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
 		       &dm_blk_dops, NULL);
+	kfree(name);
 	return 0;
 }
 
@@ -545,7 +549,7 @@
 
 static int check_name(const char *name)
 {
-	if (strchr(name, '/')) {
+	if (name[0] == '/') {
 		DMWARN("invalid device name");
 		return -EINVAL;
 	}
@@ -887,6 +891,7 @@
 		dm_table_put(t);
 		return r;
 	}
+	dm_table_put(t);	/* md will have taken its own reference */
 
 	set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG));
 	dm_put(md);
@@ -1122,17 +1127,17 @@
 	return 0;
 
       failed:
+	devfs_remove(DM_DIR "/control");
+	if (misc_deregister(&_dm_misc) < 0)
+		DMERR("misc_deregister failed for control device");
 	dm_hash_exit();
-	misc_deregister(&_dm_misc);
 	return r;
 }
 
 void dm_interface_exit(void)
 {
-	dm_hash_exit();
-
 	devfs_remove(DM_DIR "/control");
-
 	if (misc_deregister(&_dm_misc) < 0)
 		DMERR("misc_deregister failed for control device");
+	dm_hash_exit();
 }
diff -Nru a/drivers/md/dm-table.c b/drivers/md/dm-table.c
--- a/drivers/md/dm-table.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/md/dm-table.c	Tue Mar  4 19:30:14 2003
@@ -79,7 +79,7 @@
 }
 
 #define __HIGH(l, r) if (*(l) < (r)) *(l) = (r)
-#define __LOW(l, r) if (*(l) < (r)) *(l) = (r)
+#define __LOW(l, r) if (*(l) == 0 || *(l) > (r)) *(l) = (r)
 
 /*
  * Combine two io_restrictions, always taking the lower value.
@@ -499,7 +499,7 @@
 }
 
 /*
- * Decrement a devices use count and remove it if neccessary.
+ * Decrement a devices use count and remove it if necessary.
  */
 void dm_put_device(struct dm_target *ti, struct dm_dev *dd)
 {
@@ -591,7 +591,7 @@
 	tgt->type = dm_get_target_type(type);
 	if (!tgt->type) {
 		tgt->error = "unknown target type";
-		goto bad;
+		return -EINVAL;
 	}
 
 	tgt->table = t;
@@ -604,6 +604,7 @@
 	 */
 	if (!adjoin(t, tgt)) {
 		tgt->error = "Gap in table";
+		r = -EINVAL;
 		goto bad;
 	}
 
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/md/md.c	Tue Mar  4 19:30:05 2003
@@ -119,7 +119,7 @@
 		.procname	= "dev",
 		.maxlen		= 0,
 		.mode		= 0555,
-		.proc_handler	= raid_dir_table,
+		.child		= raid_dir_table,
 	},
 	{ .ctl_name = 0 }
 };
@@ -1427,7 +1427,7 @@
 			/*
 			 * 'default chunksize' in the old md code used to
 			 * be PAGE_SIZE, baaad.
-			 * we abort here to be on the safe side. We dont
+			 * we abort here to be on the safe side. We don't
 			 * want to continue the bad practice.
 			 */
 			printk(BAD_CHUNKSIZE);
@@ -1731,7 +1731,7 @@
 			mddev_unlock(mddev);
 		}
 		/* on success, candidates will be empty, on error
-		 * it wont...
+		 * it won't...
 		 */
 		ITERATE_RDEV_GENERIC(candidates,rdev,tmp)
 			export_rdev(rdev);
@@ -2290,7 +2290,7 @@
 				}
 				err = set_array_info(mddev, &info);
 				if (err) {
-					printk(KERN_WARNING "md: couldnt set array info. %d\n", err);
+					printk(KERN_WARNING "md: couldn't set array info. %d\n", err);
 					goto abort_unlock;
 				}
 			}
diff -Nru a/drivers/media/dvb/av7110/saa7146.c b/drivers/media/dvb/av7110/saa7146.c
--- a/drivers/media/dvb/av7110/saa7146.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/media/dvb/av7110/saa7146.c	Tue Mar  4 19:30:04 2003
@@ -1396,7 +1396,7 @@
 		saa7146_write(saa->mem, MC2, (MASK_00 | MASK_16));
 	}
 
-	/* if any error is still present, a fatal error has occured ... */
+	/* if any error is still present, a fatal error has occurred ... */
 	if ( SAA7146_I2C_BBR != (status = i2c_status_check(saa)) ) {
 		hprintk("saa7146: i2c_reset: fatal error, status:0x%08x\n",status);
 		return -EIO;
@@ -1444,7 +1444,7 @@
 
 	/* check for some other mysterious error; we don't handle this here */
 	if ( 0 != ( status & 0xff)) {
-		hprintk("saa7146: i2c_write_out: some error has occured\n");
+		hprintk("saa7146: i2c_write_out: some error has occurred\n");
         	return -EIO;
   	}
 	
@@ -1570,7 +1570,7 @@
 		/* check, if DEBI still active */
 		u32 psr = saa7146_read(saa->mem, PSR);
 		if (0 !=  (psr & SPCI_DEBI_S)) {
-			/* check, if error occured */
+			/* check, if error occurred */
 /*			if ( 0 != (saa7146_read(saa->mem, SSR) & (MASK_23|MASK_22))) { */
 			if ( 0 != (saa7146_read(saa->mem, SSR) & (MASK_22))) {
 				/* clear error status and indicate error */
diff -Nru a/drivers/media/dvb/av7110/saa7146_core.c b/drivers/media/dvb/av7110/saa7146_core.c
--- a/drivers/media/dvb/av7110/saa7146_core.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/media/dvb/av7110/saa7146_core.c	Tue Mar  4 19:30:12 2003
@@ -222,7 +222,7 @@
 		 * we do not start the whole rps1-engine...
 		 */
 
-			/* if address-error occured, don't retry */
+			/* if address-error occurred, don't retry */
 		if (i2c_write_out(a, &a->i2c[i], SAA7146_I2C_TIMEOUT) < 0) {
 			hprintk (KERN_ERR "saa7146_core.o: "
 				"i2c error in address phase\n");
diff -Nru a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
--- a/drivers/media/radio/miropcm20-radio.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/media/radio/miropcm20-radio.c	Tue Mar  4 19:30:05 2003
@@ -15,7 +15,7 @@
  */
 
 /* What ever you think about the ACI, version 0x07 is not very well!
- * I cant get frequency, 'tuner status', 'tuner flags' or mute/mono
+ * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
  * conditions...                Robert 
  */
 
@@ -93,7 +93,7 @@
 	} else {
 		/* stereo */
 		*flags=VIDEO_TUNER_STEREO_ON;
-		/* I cant see stereo, when forced to mono */
+		/* I can't see stereo, when forced to mono */
 		dev->stereo=1;
 	}
 
diff -Nru a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c
--- a/drivers/media/radio/miropcm20-rds-core.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/media/radio/miropcm20-rds-core.c	Tue Mar  4 19:30:13 2003
@@ -91,7 +91,7 @@
 	}
 }
 
-/* dont use any ..._nowait() function if you are not sure what you do... */
+/* don't use any ..._nowait() function if you are not sure what you do... */
 
 static inline void rds_rawwrite_nowait(unsigned char byte)
 {
diff -Nru a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
--- a/drivers/media/radio/radio-aimslab.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/media/radio/radio-aimslab.c	Tue Mar  4 19:30:05 2003
@@ -1,6 +1,6 @@
 /* radiotrack (radioreveal) driver for Linux radio support
  * (c) 1997 M. Kirkwood
- * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Converted to new API by Alan Cox <Alan.Cox@linux.org>
  * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
  * History:
diff -Nru a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
--- a/drivers/media/radio/radio-gemtek.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/media/radio/radio-gemtek.c	Tue Mar  4 19:30:03 2003
@@ -8,7 +8,7 @@
  *    RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
  * 
  *    Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
- *    Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ *    Converted to new API by Alan Cox <Alan.Cox@linux.org>
  *    Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
  * TODO: Allow for more than one of these foolish entities :-)
diff -Nru a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
--- a/drivers/media/radio/radio-rtrack2.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/media/radio/radio-rtrack2.c	Tue Mar  4 19:30:11 2003
@@ -1,7 +1,7 @@
 /* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
  * 
  * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
- * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Converted to new API by Alan Cox <Alan.Cox@linux.org>
  * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
  * TODO: Allow for more than one of these foolish entities :-)
diff -Nru a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
--- a/drivers/media/radio/radio-sf16fmi.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/media/radio/radio-sf16fmi.c	Tue Mar  4 19:30:13 2003
@@ -262,7 +262,7 @@
 		return -ENODEV;
 	if (pnp_device_attach(dev) < 0)
 		return -EAGAIN;
-	if (pnp_activate_dev(dev, NULL) < 0) {
+	if (pnp_activate_dev(dev) < 0) {
 		printk ("radio-sf16fmi: PnP configure failed (out of resources?)\n");
 		pnp_device_detach(dev);
 		return -ENOMEM;
diff -Nru a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
--- a/drivers/media/radio/radio-terratec.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/media/radio/radio-terratec.c	Tue Mar  4 19:30:08 2003
@@ -129,7 +129,7 @@
 	long rest;
      
 	unsigned char buffer[25];		/* we have to bit shift 25 registers */
-	freq = freq1/160;			/* convert the freq. to a nice to handel value */
+	freq = freq1/160;			/* convert the freq. to a nice to handle value */
 	for(i=24;i>-1;i--)
 		buffer[i]=0;
 
diff -Nru a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
--- a/drivers/media/video/saa7110.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/media/video/saa7110.c	Tue Mar  4 19:30:03 2003
@@ -33,7 +33,7 @@
 #define DEBUG(x...)			/* remove when no long debugging */
 
 #define SAA7110_MAX_INPUT	9	/* 6 CVBS, 3 SVHS */
-#define SAA7110_MAX_OUTPUT	0	/* its a decoder only */
+#define SAA7110_MAX_OUTPUT	0	/* it's a decoder only */
 
 #define	I2C_SAA7110		0x9C	/* or 0x9E */
 
diff -Nru a/drivers/media/video/zr36067.c b/drivers/media/video/zr36067.c
--- a/drivers/media/video/zr36067.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/media/video/zr36067.c	Tue Mar  4 19:30:14 2003
@@ -3629,7 +3629,7 @@
 			       ("%s: ioctl VIDIOCCAPTURE: %d\n", zr->name,
 				v));
 
-			/* If there is nothing to do, return immediatly */
+			/* If there is nothing to do, return immediately */
 
 			if ((v && zr->v4l_overlay_active)
 			    || (!v && !zr->v4l_overlay_active))
@@ -4048,7 +4048,7 @@
 
 			zr->params = bp;
 
-			/* Make changes of input and norm go into effect immediatly */
+			/* Make changes of input and norm go into effect immediately */
 
 			/* We switch overlay off and on since a change in the norm
 			   needs different VFE settings */
diff -Nru a/drivers/media/video/zr36120_i2c.c b/drivers/media/video/zr36120_i2c.c
--- a/drivers/media/video/zr36120_i2c.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/media/video/zr36120_i2c.c	Tue Mar  4 19:30:14 2003
@@ -86,7 +86,7 @@
 		if (ztv->tuner_type >= 0)
 		{
 			if (i2c_control_device(&ztv->i2c,I2C_DRIVERID_TUNER,TUNER_SET_TYPE,&ztv->tuner_type)<0)
-			DEBUG(printk(CARD_INFO "attach_inform; tuner wont be set to type %d\n",CARD,ztv->tuner_type));
+			DEBUG(printk(CARD_INFO "attach_inform; tuner won't be set to type %d\n",CARD,ztv->tuner_type));
 		}
 		break;
 	 default:
diff -Nru a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
--- a/drivers/message/fusion/mptlan.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/message/fusion/mptlan.c	Tue Mar  4 19:30:08 2003
@@ -242,7 +242,7 @@
 			//  would Oops because mf has already been set
 			//  to NULL.  So after return from this func,
 			//  mpt_interrupt() will attempt to put (NULL) mf ptr
-			//  item back onto it's adapter FreeQ - Oops!:-(
+			//  item back onto its adapter FreeQ - Oops!:-(
 			//  It's Ok, since mpt_lan_send_turbo() *currently*
 			//  always returns 0, but..., just in case:
 
diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
--- a/drivers/message/fusion/mptscsih.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/message/fusion/mptscsih.c	Tue Mar  4 19:30:07 2003
@@ -116,7 +116,7 @@
 #define MPT_ICFLAG_ECHO		0x02	/* ReadBuffer Echo buffer format */
 #define MPT_ICFLAG_PHYS_DISK	0x04	/* Any SCSI IO but do Phys Disk Format */
 #define MPT_ICFLAG_TAGGED_CMD	0x08	/* Do tagged IO */
-#define MPT_ICFLAG_DID_RESET	0x20	/* Bus Reset occured with this command */
+#define MPT_ICFLAG_DID_RESET	0x20	/* Bus Reset occurred with this command */
 #define MPT_ICFLAG_RESERVED	0x40	/* Reserved has been issued */
 
 typedef struct _internal_cmd {
@@ -4207,7 +4207,7 @@
 	/*
 	 * Need to check ASC here; if it is "special," then
 	 * the ASCQ is variable, and indicates failed component number.
-	 * We must treat the ASCQ as a "dont care" while searching the
+	 * We must treat the ASCQ as a "don't care" while searching the
 	 * mptscsih_ASCQ_Table[] by masking it off, and then restoring it later
 	 * on when we actually need to identify the failed component.
 	 */
diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
--- a/drivers/message/i2o/i2o_block.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/message/i2o/i2o_block.c	Tue Mar  4 19:30:11 2003
@@ -798,7 +798,7 @@
 
 		/* 
 		 *	Queue depths probably belong with some kind of 
-		 *	generic IOP commit control. Certainly its not right 
+		 *	generic IOP commit control. Certainly it's not right 
 		 *	its global!  
 		 */
 		if(atomic_read(&i2ob_queues[dev->unit]->queue_depth) >= dev->depth)
@@ -1729,7 +1729,7 @@
 	 *	We may get further callbacks for ourself. The i2o_core
 	 *	code handles this case reasonably sanely. The problem here
 	 *	is we shouldn't get them .. but a couple of cards feel 
-	 *	obliged to tell us stuff we dont care about.
+	 *	obliged to tell us stuff we don't care about.
 	 *
 	 *	This isnt ideal at all but will do for now.
 	 */
diff -Nru a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c
--- a/drivers/message/i2o/i2o_core.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/message/i2o/i2o_core.c	Tue Mar  4 19:30:10 2003
@@ -340,7 +340,7 @@
 
 /*
  *	Each I2O controller has a chain of devices on it.
- * Each device has a pointer to it's LCT entry to be used
+ * Each device has a pointer to its LCT entry to be used
  * for fun purposes.
  */
 
@@ -2120,7 +2120,7 @@
  *	@iop: controller
  *
  *	This function brings an I2O controller into HOLD state. The adapter
- *	is reset if neccessary and then the queues and resource table
+ *	is reset if necessary and then the queues and resource table
  *	are read. -1 is returned on a failure, 0 on success.
  *	
  */
diff -Nru a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
--- a/drivers/mtd/chips/amd_flash.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/chips/amd_flash.c	Tue Mar  4 19:30:05 2003
@@ -120,10 +120,10 @@
 
 
 static struct mtd_chip_driver amd_flash_chipdrv = {
-	probe: amd_flash_probe,
-	destroy: amd_flash_destroy,
-	name: "amd_flash",
-	module: THIS_MODULE
+	.probe		= amd_flash_probe,
+	.destroy	= amd_flash_destroy,
+	.name		= "amd_flash",
+	.module		= THIS_MODULE
 };
 
 
@@ -424,194 +424,194 @@
 	 */
 	const struct amd_flash_info table[] = {
 	{
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV160DT,
-		name: "AMD AM29LV160DT",
-		size: 0x00200000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-			{ offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV160DB,
-		name: "AMD AM29LV160DB",
-		size: 0x00200000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
-			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_TOSHIBA,
-		dev_id: TC58FVT160,
-		name: "Toshiba TC58FVT160",
-		size: 0x00200000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-			{ offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_FUJITSU,
-		dev_id: MBM29LV160TE,
-		name: "Fujitsu MBM29LV160TE",
-		size: 0x00200000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-			{ offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_TOSHIBA,
-		dev_id: TC58FVB160,
-		name: "Toshiba TC58FVB160",
-		size: 0x00200000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
-			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_FUJITSU,
-		dev_id: MBM29LV160BE,
-		name: "Fujitsu MBM29LV160BE",
-		size: 0x00200000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
-			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BB,
-		name: "AMD AM29LV800BB",
-		size: 0x00100000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
-			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29F800BB,
-		name: "AMD AM29F800BB",
-		size: 0x00100000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
-			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BT,
-		name: "AMD AM29LV800BT",
-		size: 0x00100000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-			{ offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29F800BT,
-		name: "AMD AM29F800BT",
-		size: 0x00100000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-			{ offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BB,
-		name: "AMD AM29LV800BB",
-		size: 0x00100000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-			{ offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W800T,
-		name: "ST M29W800T",
-		size: 0x00100000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-			{ offset: 0x0F0000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x0F8000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x0FC000, erasesize: 0x04000, numblocks:  1 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W160DT,
-		name: "ST M29W160DT",
-		size: 0x00200000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-			{ offset: 0x1F0000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x1F8000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x1FC000, erasesize: 0x04000, numblocks:  1 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W160DB,
-		name: "ST M29W160DB",
-		size: 0x00200000,
-		numeraseregions: 4,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x04000, numblocks:  1 },
-			{ offset: 0x004000, erasesize: 0x02000, numblocks:  2 },
-			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
-			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29BDS323D,
-		name: "AMD AM29BDS323D",
-		size: 0x00400000,
-		numeraseregions: 3,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 48 },
-			{ offset: 0x300000, erasesize: 0x10000, numblocks: 15 },
-			{ offset: 0x3f0000, erasesize: 0x02000, numblocks:  8 },
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29BDS643D,
-		name: "AMD AM29BDS643D",
-		size: 0x00800000,
-		numeraseregions: 3,
-		regions: {
-			{ offset: 0x000000, erasesize: 0x10000, numblocks: 96 },
-			{ offset: 0x600000, erasesize: 0x10000, numblocks: 31 },
-			{ offset: 0x7f0000, erasesize: 0x02000, numblocks:  8 },
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV160DT,
+		.name = "AMD AM29LV160DT",
+		.size = 0x00200000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
+			{ .offset = 0x1F0000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x1F8000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x1FC000, .erasesize = 0x04000, .numblocks  = 1 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV160DB,
+		.name = "AMD AM29LV160DB",
+		.size = 0x00200000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x04000, .numblocks  = 1 },
+			{ .offset = 0x004000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x008000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_TOSHIBA,
+		.dev_id = TC58FVT160,
+		.name = "Toshiba TC58FVT160",
+		.size = 0x00200000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
+			{ .offset = 0x1F0000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x1F8000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x1FC000, .erasesize = 0x04000, .numblocks  = 1 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_FUJITSU,
+		.dev_id = MBM29LV160TE,
+		.name = "Fujitsu MBM29LV160TE",
+		.size = 0x00200000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
+			{ .offset = 0x1F0000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x1F8000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x1FC000, .erasesize = 0x04000, .numblocks  = 1 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_TOSHIBA,
+		.dev_id = TC58FVB160,
+		.name = "Toshiba TC58FVB160",
+		.size = 0x00200000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x04000, .numblocks  = 1 },
+			{ .offset = 0x004000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x008000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_FUJITSU,
+		.dev_id = MBM29LV160BE,
+		.name = "Fujitsu MBM29LV160BE",
+		.size = 0x00200000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x04000, .numblocks  = 1 },
+			{ .offset = 0x004000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x008000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV800BB,
+		.name = "AMD AM29LV800BB",
+		.size = 0x00100000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x04000, .numblocks  = 1 },
+			{ .offset = 0x004000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x008000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29F800BB,
+		.name = "AMD AM29F800BB",
+		.size = 0x00100000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x04000, .numblocks  = 1 },
+			{ .offset = 0x004000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x008000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV800BT,
+		.name = "AMD AM29LV800BT",
+		.size = 0x00100000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
+			{ .offset = 0x0F0000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x0F8000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x0FC000, .erasesize = 0x04000, .numblocks  = 1 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29F800BT,
+		.name = "AMD AM29F800BT",
+		.size = 0x00100000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
+			{ .offset = 0x0F0000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x0F8000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x0FC000, .erasesize = 0x04000, .numblocks  = 1 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV800BB,
+		.name = "AMD AM29LV800BB",
+		.size = 0x00100000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
+			{ .offset = 0x0F0000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x0F8000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x0FC000, .erasesize = 0x04000, .numblocks  = 1 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_ST,
+		.dev_id = M29W800T,
+		.name = "ST M29W800T",
+		.size = 0x00100000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
+			{ .offset = 0x0F0000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x0F8000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x0FC000, .erasesize = 0x04000, .numblocks  = 1 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_ST,
+		.dev_id = M29W160DT,
+		.name = "ST M29W160DT",
+		.size = 0x00200000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
+			{ .offset = 0x1F0000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x1F8000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x1FC000, .erasesize = 0x04000, .numblocks  = 1 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_ST,
+		.dev_id = M29W160DB,
+		.name = "ST M29W160DB",
+		.size = 0x00200000,
+		.numeraseregions = 4,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x04000, .numblocks  = 1 },
+			{ .offset = 0x004000, .erasesize = 0x02000, .numblocks  = 2 },
+			{ .offset = 0x008000, .erasesize = 0x08000, .numblocks  = 1 },
+			{ .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
+		}
+	}, {
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29BDS323D,
+		.name = "AMD AM29BDS323D",
+		.size = 0x00400000,
+		.numeraseregions = 3,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 48 },
+			{ .offset = 0x300000, .erasesize = 0x10000, .numblocks = 15 },
+			{ .offset = 0x3f0000, .erasesize = 0x02000, .numblocks  = 8 },
+		}
+	}, {
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29BDS643D,
+		.name = "AMD AM29BDS643D",
+		.size = 0x00800000,
+		.numeraseregions = 3,
+		.regions = {
+			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 },
+			{ .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 },
+			{ .offset = 0x7f0000, .erasesize = 0x02000, .numblocks  = 8 },
 		}
 	} 
 	};
diff -Nru a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
--- a/drivers/mtd/chips/cfi_cmdset_0001.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c	Tue Mar  4 19:30:05 2003
@@ -47,10 +47,10 @@
 static struct mtd_info *cfi_intelext_setup (struct map_info *);
 
 static struct mtd_chip_driver cfi_intelext_chipdrv = {
-	probe: NULL, /* Not usable directly */
-	destroy: cfi_intelext_destroy,
-	name: "cfi_cmdset_0001",
-	module: THIS_MODULE
+	.probe		= NULL, /* Not usable directly */
+	.destroy	= cfi_intelext_destroy,
+	.name		= "cfi_cmdset_0001",
+	.module		= THIS_MODULE
 };
 
 /* #define DEBUG_LOCK_BITS */
diff -Nru a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
--- a/drivers/mtd/chips/cfi_cmdset_0002.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c	Tue Mar  4 19:30:08 2003
@@ -43,10 +43,10 @@
 
 
 static struct mtd_chip_driver cfi_amdstd_chipdrv = {
-	probe: NULL, /* Not usable directly */
-	destroy: cfi_amdstd_destroy,
-	name: "cfi_cmdset_0002",
-	module: THIS_MODULE
+	.probe		= NULL, /* Not usable directly */
+	.destroy	= cfi_amdstd_destroy,
+	.name		= "cfi_cmdset_0002",
+	.module		= THIS_MODULE
 };
 
 struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
diff -Nru a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
--- a/drivers/mtd/chips/cfi_probe.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/mtd/chips/cfi_probe.c	Tue Mar  4 19:30:12 2003
@@ -294,8 +294,8 @@
 #endif /* DEBUG_CFI */
 
 static struct chip_probe cfi_chip_probe = {
-	name: "CFI",
-	probe_chip: cfi_probe_chip
+	.name		= "CFI",
+	.probe_chip	= cfi_probe_chip
 };
 
 struct mtd_info *cfi_probe(struct map_info *map)
@@ -308,9 +308,9 @@
 }
 
 static struct mtd_chip_driver cfi_chipdrv = {
-	probe: cfi_probe,
-	name: "cfi_probe",
-	module: THIS_MODULE
+	.probe		= cfi_probe,
+	.name		= "cfi_probe",
+	.module		= THIS_MODULE
 };
 
 int __init cfi_probe_init(void)
diff -Nru a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
--- a/drivers/mtd/chips/jedec.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/mtd/chips/jedec.c	Tue Mar  4 19:30:10 2003
@@ -33,14 +33,51 @@
 
 /* Listing of parts and sizes. We need this table to learn the sector
    size of the chip and the total length */
-static const struct JEDECTable JEDEC_table[] = 
-  {{0x013D,"AMD Am29F017D",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-   {0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-   {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH},
-   {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH},
-   {0x20E3,"AMD Am29W040B",512*1024,64*1024,MTD_CAP_NORFLASH},
-   {0xC2AD,"Macronix MX29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-   {}};
+static const struct JEDECTable JEDEC_table[] = {
+	{
+		.jedec		= 0x013D,
+		.name		= "AMD Am29F017D",
+		.size		= 2*1024*1024,
+		.sectorsize	= 64*1024,
+		.capabilities	= MTD_CAP_NORFLASH
+	},
+	{
+		.jedec		= 0x01AD,
+		.name		= "AMD Am29F016",
+		.size		= 2*1024*1024,
+		.sectorsize	= 64*1024,
+		.capabilities	= MTD_CAP_NORFLASH
+	},
+	{
+		.jedec		= 0x01D5,
+		.name		= "AMD Am29F080",
+		.size		= 1*1024*1024,
+		.sectorsize	= 64*1024,
+		.capabilities	= MTD_CAP_NORFLASH
+	},
+	{
+		.jedec		= 0x01A4,
+		.name		= "AMD Am29F040",
+		.size		= 512*1024,
+		.sectorsize	= 64*1024,
+		.capabilities	= MTD_CAP_NORFLASH
+	},
+	{
+		.jedec		= 0x20E3,
+		.name		= "AMD Am29W040B",
+		.size		= 512*1024,
+		.sectorsize	= 64*1024,
+		.capabilities	= MTD_CAP_NORFLASH
+	},
+	{
+		.jedec		= 0xC2AD,
+		.name		= "Macronix MX29F016",
+		.size		= 2*1024*1024,
+		.sectorsize	= 64*1024,
+		.capabilities	= MTD_CAP_NORFLASH
+	},
+	{ .jedec = 0x0 }
+};
 
 static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
 static void jedec_sync(struct mtd_info *mtd) {};
@@ -54,9 +91,9 @@
 
 
 static struct mtd_chip_driver jedec_chipdrv = {
-	probe: jedec_probe,
-	name: "jedec",
-	module: THIS_MODULE
+	.probe	= jedec_probe,
+	.name	= "jedec",
+	.module	= THIS_MODULE
 };
 
 /* Probe entry point */
diff -Nru a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
--- a/drivers/mtd/chips/jedec_probe.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/mtd/chips/jedec_probe.c	Tue Mar  4 19:30:14 2003
@@ -75,176 +75,176 @@
 
 static const struct amd_flash_info jedec_table[] = {
 	{
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV160DT,
-		name: "AMD AM29LV160DT",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,31),
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV160DT,
+		.name = "AMD AM29LV160DT",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x10000,31),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV160DB,
-		name: "AMD AM29LV160DB",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV160DB,
+		.name = "AMD AM29LV160DB",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x04000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x10000,31)
 		}
 	}, {
-		mfr_id: MANUFACTURER_TOSHIBA,
-		dev_id: TC58FVT160,
-		name: "Toshiba TC58FVT160",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,31),
+		.mfr_id = MANUFACTURER_TOSHIBA,
+		.dev_id = TC58FVT160,
+		.name = "Toshiba TC58FVT160",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x10000,31),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_FUJITSU,
-		dev_id: MBM29LV160TE,
-		name: "Fujitsu MBM29LV160TE",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,31),
+		.mfr_id = MANUFACTURER_FUJITSU,
+		.dev_id = MBM29LV160TE,
+		.name = "Fujitsu MBM29LV160TE",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x10000,31),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_TOSHIBA,
-		dev_id: TC58FVB160,
-		name: "Toshiba TC58FVB160",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
+		.mfr_id = MANUFACTURER_TOSHIBA,
+		.dev_id = TC58FVB160,
+		.name = "Toshiba TC58FVB160",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x04000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x10000,31)
 		}
 	}, {
-		mfr_id: MANUFACTURER_FUJITSU,
-		dev_id: MBM29LV160BE,
-		name: "Fujitsu MBM29LV160BE",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
+		.mfr_id = MANUFACTURER_FUJITSU,
+		.dev_id = MBM29LV160BE,
+		.name = "Fujitsu MBM29LV160BE",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x04000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x10000,31)
 		}
 	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BB,
-		name: "AMD AM29LV800BB",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV800BB,
+		.name = "AMD AM29LV800BB",
+		.DevSize = SIZE_1MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x04000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x10000,15),
 		}
 	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29F800BB,
-		name: "AMD AM29F800BB",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29F800BB,
+		.name = "AMD AM29F800BB",
+		.DevSize = SIZE_1MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x04000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x10000,15),
 		}
 	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BT,
-		name: "AMD AM29LV800BT",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,15),
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV800BT,
+		.name = "AMD AM29LV800BT",
+		.DevSize = SIZE_1MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x10000,15),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29F800BT,
-		name: "AMD AM29F800BT",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,15),
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29F800BT,
+		.name = "AMD AM29F800BT",
+		.DevSize = SIZE_1MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x10000,15),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BB,
-		name: "AMD AM29LV800BB",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,15),
+		.mfr_id = MANUFACTURER_AMD,
+		.dev_id = AM29LV800BB,
+		.name = "AMD AM29LV800BB",
+		.DevSize = SIZE_1MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x10000,15),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W800T,
-		name: "ST M29W800T",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,15),
+		.mfr_id = MANUFACTURER_ST,
+		.dev_id = M29W800T,
+		.name = "ST M29W800T",
+		.DevSize = SIZE_1MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x10000,15),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W160DT,
-		name: "ST M29W160DT",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,31),
+		.mfr_id = MANUFACTURER_ST,
+		.dev_id = M29W160DT,
+		.name = "ST M29W160DT",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x10000,31),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x04000,1)
 		}
 	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W160DB,
-		name: "ST M29W160DB",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
+		.mfr_id = MANUFACTURER_ST,
+		.dev_id = M29W160DB,
+		.name = "ST M29W160DB",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 4,
+		.regions = {ERASEINFO(0x04000,1),
 			  ERASEINFO(0x02000,2),
 			  ERASEINFO(0x08000,1),
 			  ERASEINFO(0x10000,31)
 		}
 	}, {
-		mfr_id: MANUFACTURER_ATMEL,
-		dev_id: AT49BV16X4,
-		name: "Atmel AT49BV16X4",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 3,
-		regions: {ERASEINFO(0x02000,8),
+		.mfr_id = MANUFACTURER_ATMEL,
+		.dev_id = AT49BV16X4,
+		.name = "Atmel AT49BV16X4",
+		.DevSize = SIZE_2MiB,
+		.NumEraseRegions = 3,
+		.regions = {ERASEINFO(0x02000,8),
 			  ERASEINFO(0x08000,2),
 			  ERASEINFO(0x10000,30)
 		}
 	}, {
-                mfr_id: MANUFACTURER_ATMEL,
-                dev_id: AT49BV16X4T,
-                name: "Atmel AT49BV16X4T",
-                DevSize: SIZE_2MiB,
-                NumEraseRegions: 3,
-                regions: {ERASEINFO(0x10000,30),
+                .mfr_id = MANUFACTURER_ATMEL,
+                .dev_id = AT49BV16X4T,
+                .name = "Atmel AT49BV16X4T",
+                .DevSize = SIZE_2MiB,
+                .NumEraseRegions = 3,
+                .regions = {ERASEINFO(0x10000,30),
                           ERASEINFO(0x08000,2),
 			  ERASEINFO(0x02000,8)
                 }
@@ -403,8 +403,8 @@
 }
 
 static struct chip_probe jedec_chip_probe = {
-	name: "JEDEC",
-	probe_chip: jedec_probe_chip
+	.name = "JEDEC",
+	.probe_chip = jedec_probe_chip
 };
 
 struct mtd_info *jedec_probe(struct map_info *map)
@@ -417,9 +417,9 @@
 }
 
 static struct mtd_chip_driver jedec_chipdrv = {
-	probe: jedec_probe,
-	name: "jedec_probe",
-	module: THIS_MODULE
+	.probe	= jedec_probe,
+	.name	= "jedec_probe",
+	.module	= THIS_MODULE
 };
 
 int __init jedec_probe_init(void)
diff -Nru a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c
--- a/drivers/mtd/chips/map_absent.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/mtd/chips/map_absent.c	Tue Mar  4 19:30:11 2003
@@ -36,10 +36,10 @@
 
 
 static struct mtd_chip_driver map_absent_chipdrv = {
-	probe: 		map_absent_probe,
-	destroy:	map_absent_destroy,
-	name: 		"map_absent",
-	module: 	THIS_MODULE
+	.probe 		= map_absent_probe,
+	.destroy	= map_absent_destroy,
+	.name 		= "map_absent",
+	.module 	= THIS_MODULE
 };
 
 static struct mtd_info *map_absent_probe(struct map_info *map)
diff -Nru a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
--- a/drivers/mtd/chips/map_ram.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/chips/map_ram.c	Tue Mar  4 19:30:05 2003
@@ -23,9 +23,9 @@
 
 
 static struct mtd_chip_driver mapram_chipdrv = {
-	probe: map_ram_probe,
-	name: "map_ram",
-	module: THIS_MODULE
+	.probe	= map_ram_probe,
+	.name	= "map_ram",
+	.module	= THIS_MODULE
 };
 
 static struct mtd_info *map_ram_probe(struct map_info *map)
diff -Nru a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
--- a/drivers/mtd/chips/map_rom.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/mtd/chips/map_rom.c	Tue Mar  4 19:30:10 2003
@@ -21,9 +21,9 @@
 struct mtd_info *map_rom_probe(struct map_info *map);
 
 static struct mtd_chip_driver maprom_chipdrv = {
-	probe: map_rom_probe,
-	name: "map_rom",
-	module: THIS_MODULE
+	.probe	= map_rom_probe,
+	.name	= "map_rom",
+	.module	= THIS_MODULE
 };
 
 struct mtd_info *map_rom_probe(struct map_info *map)
diff -Nru a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
--- a/drivers/mtd/chips/sharp.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/mtd/chips/sharp.c	Tue Mar  4 19:30:09 2003
@@ -98,10 +98,10 @@
 static void sharp_destroy(struct mtd_info *mtd);
 
 static struct mtd_chip_driver sharp_chipdrv = {
-	probe: sharp_probe,
-	destroy: sharp_destroy,
-	name: "sharp",
-	module: THIS_MODULE
+	.probe		= sharp_probe,
+	.destroy	= sharp_destroy,
+	.name		= "sharp",
+	.module		= THIS_MODULE
 };
 
 
diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
--- a/drivers/mtd/devices/blkmtd.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/mtd/devices/blkmtd.c	Tue Mar  4 19:30:04 2003
@@ -16,7 +16,7 @@
  *       thread writes pages out to the device in the background. This
  *       ensures that writes are order even if a page is updated twice.
  *       Also, since pages in the page cache are never marked as dirty,
- *       we dont have to worry about writepage() being called on some 
+ *       we don't have to worry about writepage() being called on some 
  *       random page which may not be in the write order.
  * 
  *       Erases are handled like writes, so the callback is called after
@@ -33,7 +33,7 @@
  *       Page cache usage may still be a bit wrong. Check we are doing
  *       everything properly.
  * 
- *       Somehow allow writes to dirty the page cache so we dont use too
+ *       Somehow allow writes to dirty the page cache so we don't use too
  *       much memory making copies of outgoing pages. Need to handle case
  *       where page x is written to, then page y, then page x again before
  *       any of them have been committed to disk.
@@ -217,7 +217,7 @@
   DEBUG(3, "blkmtd: readpage: getting kiovec\n");
   err = alloc_kiovec(1, &iobuf);
   if (err) {
-    printk("blkmtd: cant allocate kiobuf\n");
+    printk("blkmtd: can't allocate kiobuf\n");
     SetPageError(page);
     return err;
   }
@@ -226,7 +226,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
   blocks = kmalloc(KIO_MAX_SECTORS * sizeof(*blocks));
   if(blocks == NULL) {
-    printk("blkmtd: cant allocate iobuf blocks\n");
+    printk("blkmtd: can't allocate iobuf blocks\n");
     free_kiovec(1, &iobuf);
     SetPageError(page);
     return -ENOMEM;
@@ -306,7 +306,7 @@
   daemonize("blkmtdd");
 
   if(alloc_kiovec(1, &iobuf)) {
-    printk("blkmtd: write_queue_task cant allocate kiobuf\n");
+    printk("blkmtd: write_queue_task can't allocate kiobuf\n");
     return 0;
   }
 
@@ -314,7 +314,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
   blocks = kmalloc(KIO_MAX_SECTORS * sizeof(unsigned long));
   if(blocks == NULL) {
-    printk("blkmtd: write_queue_task cant allocate iobuf blocks\n");
+    printk("blkmtd: write_queue_task can't allocate iobuf blocks\n");
     free_kiovec(1, &iobuf);
     return 0;
   }
@@ -350,7 +350,7 @@
       int max_sectors = KIO_MAX_SECTORS >> (item->rawdevice->sector_bits - 9);
 
       /* If we are writing to the last page on the device and it doesn't end
-       * on a page boundary, subtract the number of sectors that dont exist.
+       * on a page boundary, subtract the number of sectors that don't exist.
        */
       if(item->rawdevice->partial_last_page && 
 	 (item->pagenr + item->pagecnt -1) == item->rawdevice->partial_last_page) {
@@ -394,7 +394,7 @@
 	err = brw_kiovec(WRITE, 1, &iobuf, item->rawdevice->binding, blocks, item->rawdevice->sector_size);
 	DEBUG(3, "bklmtd: write_task: done, err = %d\n", err);
 	if(err != (cursectors << item->rawdevice->sector_bits)) {
-	  /* if an error occured - set this to exit the loop */
+	  /* if an error occurred - set this to exit the loop */
 	  sectorcnt = 0;
 	} else {
 	  sectorcnt -= cursectors;
@@ -794,7 +794,7 @@
       page = grab_cache_page(&rawdevice->as, pagenr);
       DEBUG(3, "blkmtd: write: got page %d from page cache\n", pagenr);
       if(!page) {
-	printk("blkmtd: write: cant grab cache page %d\n", pagenr);
+	printk("blkmtd: write: can't grab cache page %d\n", pagenr);
 	err = -EIO;
 	goto write_err;
       }
@@ -1090,7 +1090,7 @@
 
   file = filp_open(device, mode, 0);
   if(IS_ERR(file)) {
-    printk("blkmtd: error, cant open device %s\n", device);
+    printk("blkmtd: error, can't open device %s\n", device);
     DEBUG(2, "blkmtd: filp_open returned %ld\n", PTR_ERR(file));
     return 1;
   }
@@ -1144,7 +1144,7 @@
   DEBUG(1, "blkmtd: size = %ld\n", (long int)size);
 
   if(size == 0) {
-    printk("blkmtd: cant determine size\n");
+    printk("blkmtd: can't determine size\n");
     blkdev_put(bdev, BDEV_RAW);
     return 1;
   }
diff -Nru a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
--- a/drivers/mtd/devices/pmc551.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/mtd/devices/pmc551.c	Tue Mar  4 19:30:12 2003
@@ -30,7 +30,7 @@
  *	 
  * Notes:
  *	 Due to what I assume is more buggy SROM, the 64M PMC551 I
- *	 have available claims that all 4 of it's DRAM banks have 64M
+ *	 have available claims that all 4 of its DRAM banks have 64M
  *	 of ram configured (making a grand total of 256M onboard).
  *	 This is slightly annoying since the BAR0 size reflects the
  *	 aperture size, not the dram size, and the V370PDC supplies no
diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
--- a/drivers/mtd/ftl.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/mtd/ftl.c	Tue Mar  4 19:30:13 2003
@@ -155,8 +155,8 @@
 void ftl_freepart(partition_t *part);
 
 static struct mtd_notifier ftl_notifier = {
-	add:	ftl_notify_add,
-	remove:	ftl_notify_remove,
+	.add	= ftl_notify_add,
+	.remove	= ftl_notify_remove,
 };
 
 /* Partition state flags */
diff -Nru a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c
--- a/drivers/mtd/maps/autcpu12-nvram.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/mtd/maps/autcpu12-nvram.c	Tue Mar  4 19:30:13 2003
@@ -83,17 +83,17 @@
 static struct mtd_info *sram_mtd;
 
 struct map_info autcpu12_sram_map = {
-	name: "SRAM",
-	size: 32768,
-	buswidth: 8,
-	read8: autcpu12_read8,
-	read16: autcpu12_read16,
-	read32: autcpu12_read32,
-	copy_from: autcpu12_copy_from,
-	write8: autcpu12_write8,
-	write16: autcpu12_write16,
-	write32: autcpu12_write32,
-	copy_to: autcpu12_copy_to
+	.name		= "SRAM",
+	.size		= 32768,
+	.buswidth	= 8,
+	.read8		= autcpu12_read8,
+	.read16		= autcpu12_read16,
+	.read32		= autcpu12_read32,
+	.copy_from	= autcpu12_copy_from,
+	.write8		= autcpu12_write8,
+	.write16	= autcpu12_write16,
+	.write32	= autcpu12_write32,
+	.copy_to	= autcpu12_copy_to
 };
 
 static int __init init_autcpu12_sram (void)
diff -Nru a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c
--- a/drivers/mtd/maps/cdb89712.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/mtd/maps/cdb89712.c	Tue Mar  4 19:30:14 2003
@@ -14,8 +14,6 @@
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 
-
-
 __u8 cdb89712_read8(struct map_info *map, unsigned long ofs)
 {
 	return __raw_readb(map->map_priv_1 + ofs);
@@ -65,28 +63,27 @@
 	}
 }
 
-
 static struct mtd_info *flash_mtd;
 
 struct map_info cdb89712_flash_map = {
-	name: "flash",
-	size: FLASH_SIZE,
-	buswidth: FLASH_WIDTH,
-	read8: cdb89712_read8,
-	read16: cdb89712_read16,
-	read32: cdb89712_read32,
-	copy_from: cdb89712_copy_from,
-	write8: cdb89712_write8,
-	write16: cdb89712_write16,
-	write32: cdb89712_write32,
-	copy_to: cdb89712_copy_to
+	.name		= "flash",
+	.size		= FLASH_SIZE,
+	.buswidth	= FLASH_WIDTH,
+	.read8		= cdb89712_read8,
+	.read16		= cdb89712_read16,
+	.read32		= cdb89712_read32,
+	.copy_from	= cdb89712_copy_from,
+	.write8		= cdb89712_write8,
+	.write16	= cdb89712_write16,
+	.write32	= cdb89712_write32,
+	.copy_to	= cdb89712_copy_to
 };
 
 struct resource cdb89712_flash_resource = {
-	name:   "Flash",
-	start:  FLASH_START,
-	end:    FLASH_START + FLASH_SIZE - 1,
-	flags:  IORESOURCE_IO | IORESOURCE_BUSY,
+	.name	= "Flash",
+	.start	= FLASH_START,
+	.end	= FLASH_START + FLASH_SIZE - 1,
+	.flags	= IORESOURCE_IO | IORESOURCE_BUSY,
 };
 
 static int __init init_cdb89712_flash (void)
@@ -139,31 +136,27 @@
 	return err;
 }
 
-
-
-
-
 static struct mtd_info *sram_mtd;
 
 struct map_info cdb89712_sram_map = {
-	name: "SRAM",
-	size: SRAM_SIZE,
-	buswidth: SRAM_WIDTH,
-	read8: cdb89712_read8,
-	read16: cdb89712_read16,
-	read32: cdb89712_read32,
-	copy_from: cdb89712_copy_from,
-	write8: cdb89712_write8,
-	write16: cdb89712_write16,
-	write32: cdb89712_write32,
-	copy_to: cdb89712_copy_to
+	.name		= "SRAM",
+	.size		= SRAM_SIZE,
+	.buswidth	= SRAM_WIDTH,
+	.read8		= cdb89712_read8,
+	.read16		= cdb89712_read16,
+	.read32		= cdb89712_read32,
+	.copy_from	= cdb89712_copy_from,
+	.write8		= cdb89712_write8,
+	.write16	= cdb89712_write16,
+	.write32	= cdb89712_write32,
+	.copy_to	= cdb89712_copy_to
 };
 
 struct resource cdb89712_sram_resource = {
-	name:   "SRAM",
-	start:  SRAM_START,
-	end:    SRAM_START + SRAM_SIZE - 1,
-	flags:  IORESOURCE_IO | IORESOURCE_BUSY,
+	.name	= "SRAM",
+	.start	= SRAM_START,
+	.end	= SRAM_START + SRAM_SIZE - 1,
+	.flags	= IORESOURCE_IO | IORESOURCE_BUSY,
 };
 
 static int __init init_cdb89712_sram (void)
@@ -212,29 +205,23 @@
 	return err;
 }
 
-
-
-
-
-
-
 static struct mtd_info *bootrom_mtd;
 
 struct map_info cdb89712_bootrom_map = {
-	name: "BootROM",
-	size: BOOTROM_SIZE,
-	buswidth: BOOTROM_WIDTH,
-	read8: cdb89712_read8,
-	read16: cdb89712_read16,
-	read32: cdb89712_read32,
-	copy_from: cdb89712_copy_from,
+	.name		= "BootROM",
+	.size		= BOOTROM_SIZE,
+	.buswidth	= BOOTROM_WIDTH,
+	.read8		= cdb89712_read8,
+	.read16		= cdb89712_read16,
+	.read32		= cdb89712_read32,
+	.copy_from	= cdb89712_copy_from,
 };
 
 struct resource cdb89712_bootrom_resource = {
-	name:   "BootROM",
-	start:  BOOTROM_START,
-	end:    BOOTROM_START + BOOTROM_SIZE - 1,
-	flags:  IORESOURCE_IO | IORESOURCE_BUSY,
+	.name	= "BootROM",
+	.start	= BOOTROM_START,
+	.end	= BOOTROM_START + BOOTROM_SIZE - 1,
+	.flags	= IORESOURCE_IO | IORESOURCE_BUSY,
 };
 
 static int __init init_cdb89712_bootrom (void)
@@ -282,10 +269,6 @@
 out:
 	return err;
 }
-
-
-
-
 
 static int __init init_cdb89712_maps(void)
 {
diff -Nru a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
--- a/drivers/mtd/maps/ceiva.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/mtd/maps/ceiva.c	Tue Mar  4 19:30:07 2003
@@ -76,15 +76,15 @@
 }
 
 static struct map_info clps_map __initdata = {
-	name:		"clps flash",
-	read8:		clps_read8,
-	read16:		clps_read16,
-	read32:		clps_read32,
-	copy_from:	clps_copy_from,
-	write8:		clps_write8,
-	write16:	clps_write16,
-	write32:	clps_write32,
-	copy_to:	clps_copy_to,
+	.name		= "clps flash",
+	.read8		= clps_read8,
+	.read16		= clps_read16,
+	.read32		= clps_read32,
+	.copy_from	= clps_copy_from,
+	.write8		= clps_write8,
+	.write16	= clps_write16,
+	.write32	= clps_write32,
+	.copy_to	= clps_copy_to,
 };
 
 #ifdef CONFIG_MTD_CEIVA_STATICMAP
@@ -94,7 +94,7 @@
  *
  * Please note:
  *  1. The flash size given should be the largest flash size that can
- *     be accomodated.
+ *     be accommodated.
  *
  *  2. The bus width must defined in clps_setup_flash.
  *
@@ -115,23 +115,25 @@
 
 static struct mtd_partition ceiva_partitions[] = {
 	{
-		name: "Ceiva BOOT partition",
-		size:   BOOT_PARTITION_SIZE_KiB*1024,
-		offset: 0,
+		.name	= "Ceiva BOOT partition",
+		.size	= BOOT_PARTITION_SIZE_KiB*1024,
 
-	},{
-		name: "Ceiva parameters partition",
-		size:   PARAMS_PARTITION_SIZE_KiB*1024,
-		offset: (16 + 8) * 1024,
-	},{
-		name: "Ceiva kernel partition",
-		size: (KERNEL_PARTITION_SIZE_KiB)*1024,
-		offset: 0x20000,
+	},
+	{
+		.name	= "Ceiva parameters partition",
+		.size	= PARAMS_PARTITION_SIZE_KiB*1024,
+		.offset	= (16 + 8) * 1024,
+	},
+	{
+		.name	= "Ceiva kernel partition",
+		.size	= (KERNEL_PARTITION_SIZE_KiB)*1024,
+		.offset	= 0x20000,
 
-	},{
-		name: "Ceiva root filesystem partition",
-		offset: MTDPART_OFS_APPEND,
-		size: (ROOT_PARTITION_SIZE_KiB)*1024,
+	},
+	{
+		.name	= "Ceiva root filesystem partition",
+		.offset	= MTDPART_OFS_APPEND,
+		.size	= (ROOT_PARTITION_SIZE_KiB)*1024,
 	}
 };
 #endif
diff -Nru a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
--- a/drivers/mtd/maps/cfi_flagadm.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/mtd/maps/cfi_flagadm.c	Tue Mar  4 19:30:03 2003
@@ -99,39 +99,39 @@
 }
 
 struct map_info flagadm_map = {
-		name: "FlagaDM flash device",
-		size: FLASH_SIZE,
-		buswidth: 2,
-		read8: flagadm_read8,
-		read16: flagadm_read16,
-		read32: flagadm_read32,
-		copy_from: flagadm_copy_from,
-		write8: flagadm_write8,
-		write16: flagadm_write16,
-		write32: flagadm_write32,
-		copy_to: flagadm_copy_to
+	.name		= "FlagaDM flash device",
+	.size		= FLASH_SIZE,
+	.buswidth	= 2,
+	.read8		= flagadm_read8,
+	.read16		= flagadm_read16,
+	.read32		= flagadm_read32,
+	.copy_from	= flagadm_copy_from,
+	.write8		= flagadm_write8,
+	.write16	= flagadm_write16,
+	.write32	= flagadm_write32,
+	.copy_to	= flagadm_copy_to
 };
 
 struct mtd_partition flagadm_parts[] = {
 	{
-		name	: "Bootloader",
-		offset	: FLASH_PARTITION0_ADDR,
-		size	: FLASH_PARTITION0_SIZE
+		.name	= "Bootloader",
+		.offset	= FLASH_PARTITION0_ADDR,
+		.size	= FLASH_PARTITION0_SIZE
 	},
 	{
-		name	: "Kernel image",
-		offset	: FLASH_PARTITION1_ADDR,
-		size	: FLASH_PARTITION1_SIZE
+		.name	= "Kernel image",
+		.offset	= FLASH_PARTITION1_ADDR,
+		.size	= FLASH_PARTITION1_SIZE
 	},
 	{
-		name	: "Initial ramdisk image",
-		offset	: FLASH_PARTITION2_ADDR,
-		size	: FLASH_PARTITION2_SIZE
+		.name	= "Initial ramdisk image",
+		.offset	= FLASH_PARTITION2_ADDR,
+		.size	= FLASH_PARTITION2_SIZE
 	},
 	{	
-		name	: "Persistant storage",
-		offset	: FLASH_PARTITION3_ADDR,
-		size	: FLASH_PARTITION3_SIZE
+		.name	= "Persistant storage",
+		.offset	= FLASH_PARTITION3_ADDR,
+		.size	= FLASH_PARTITION3_SIZE
 	}
 };
 
diff -Nru a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
--- a/drivers/mtd/maps/cstm_mips_ixx.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/maps/cstm_mips_ixx.c	Tue Mar  4 19:30:05 2003
@@ -5,7 +5,7 @@
  * Config with both CFI and JEDEC device support.
  *
  * Basically physmap.c with the addition of partitions and 
- * an array of mapping info to accomodate more than one flash type per board.
+ * an array of mapping info to accommodate more than one flash type per board.
  *
  * Copyright 2000 MontaVista Software Inc.
  *
@@ -132,20 +132,15 @@
 }
 
 const struct map_info basic_cstm_mips_ixx_map = {
-	NULL,
-	0,
-	0,
-	cstm_mips_ixx_read8,
-	cstm_mips_ixx_read16,
-	cstm_mips_ixx_read32,
-	cstm_mips_ixx_copy_from,
-	cstm_mips_ixx_write8,
-	cstm_mips_ixx_write16,
-	cstm_mips_ixx_write32,
-	cstm_mips_ixx_copy_to,
-        cstm_mips_ixx_set_vpp,
-	0,
-	0
+	.read8		= cstm_mips_ixx_read8,
+	.read16		= cstm_mips_ixx_read16,
+	.read32		= cstm_mips_ixx_read32,
+	.copy_from	= cstm_mips_ixx_copy_from,
+	.write8		= cstm_mips_ixx_write8,
+	.write16	= cstm_mips_ixx_write16,
+	.write32	= cstm_mips_ixx_write32,
+	.copy_to	= cstm_mips_ixx_copy_to,
+	.set_vpp	= cstm_mips_ixx_set_vpp,
 };
 
 /* board and partition description */
@@ -175,9 +170,8 @@
 static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
 {   // 28F128J3A in 2x16 configuration
 	{
-		name: "main partition ",
-		size: 0x02000000, // 128 x 2 x 128k byte sectors
-		offset: 0,
+		.name	= "main partition ",
+		.size	= 0x02000000, // 128 x 2 x 128k byte sectors
 	},
 },
 };
@@ -197,9 +191,8 @@
 static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
 { 
 	{
-		name: "main partition",
-		size:  CONFIG_MTD_CSTM_MIPS_IXX_LEN,
-		offset: 0,
+		.name	= "main partition",
+		.size	= CONFIG_MTD_CSTM_MIPS_IXX_LEN,
 	},
 },
 };
diff -Nru a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
--- a/drivers/mtd/maps/dbox2-flash.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/mtd/maps/dbox2-flash.c	Tue Mar  4 19:30:14 2003
@@ -16,22 +16,28 @@
 /* partition_info gives details on the logical partitions that the split the
  * single flash device into. If the size if zero we use up to the end of the
  * device. */
-static struct mtd_partition partition_info[]= {{name: "BR bootloader",		// raw
-						      size: 128 * 1024, 
-						      offset: 0,                  
-						      mask_flags: MTD_WRITEABLE},
-                                                     {name: "PPC bootloader",		// flfs
-						      size: 128 * 1024, 
-						      offset: MTDPART_OFS_APPEND, 
-						      mask_flags: 0},
-                                                     {name: "Kernel",			// idxfs
-						      size: 768 * 1024, 
-						      offset: MTDPART_OFS_APPEND, 
-						      mask_flags: 0},
-                                                     {name: "System",			// jffs
-						      size: MTDPART_SIZ_FULL, 
-						      offset: MTDPART_OFS_APPEND, 
-						      mask_flags: 0}};
+static struct mtd_partition partition_info[]= {
+	{
+		.name		= "BR bootloader",	/* raw */
+		.size		= 128 * 1024, 
+		.mask_flags	= MTD_WRITEABLE
+	},
+	{
+		.name		= "PPC bootloader",	/* flfs */
+		.size		= 128 * 1024, 
+		.offset		= MTDPART_OFS_APPEND, 
+	},
+	{
+		.name		= "Kernel",		/* idxfs */
+		.size		= 768 * 1024, 
+		.offset		= MTDPART_OFS_APPEND, 
+	},
+	{
+		.name		= "System",		/* jffs */
+		.size		= MTDPART_SIZ_FULL, 
+		.offset		= MTDPART_OFS_APPEND, 
+	}
+};
 
 #define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0]))
 
@@ -84,17 +90,17 @@
 }
 
 struct map_info dbox2_flash_map = {
-	name: "D-Box 2 flash memory",
-	size: WINDOW_SIZE,
-	buswidth: 4,
-	read8: dbox2_flash_read8,
-	read16: dbox2_flash_read16,
-	read32: dbox2_flash_read32,
-	copy_from: dbox2_flash_copy_from,
-	write8: dbox2_flash_write8,
-	write16: dbox2_flash_write16,
-	write32: dbox2_flash_write32,
-	copy_to: dbox2_flash_copy_to
+	.name		= "D-Box 2 flash memory",
+	.size		= WINDOW_SIZE,
+	.buswidth	= 4,
+	.read8		= dbox2_flash_read8,
+	.read16		= dbox2_flash_read16,
+	.read32		= dbox2_flash_read32,
+	.copy_from	= dbox2_flash_copy_from,
+	.write8		= dbox2_flash_write8,
+	.write16	= dbox2_flash_write16,
+	.write32	= dbox2_flash_write32,
+	.copy_to	= dbox2_flash_copy_to
 };
 
 int __init init_dbox2_flash(void)
diff -Nru a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
--- a/drivers/mtd/maps/dc21285.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/mtd/maps/dc21285.c	Tue Mar  4 19:30:07 2003
@@ -92,23 +92,25 @@
 }
 
 struct map_info dc21285_map = {
-	name: "DC21285 flash",
-	size: 16*1024*1024,
-	read8: dc21285_read8,
-	read16: dc21285_read16,
-	read32: dc21285_read32,
-	copy_from: dc21285_copy_from,
-	write8: dc21285_write8,
-	write16: dc21285_write16,
-	write32: dc21285_write32,
-	copy_to: dc21285_copy_to
+	.name		= "DC21285 flash",
+	.size		= 16*1024*1024,
+	.read8		= dc21285_read8,
+	.read16		= dc21285_read16,
+	.read32		= dc21285_read32,
+	.copy_from	= dc21285_copy_from,
+	.write8		= dc21285_write8,
+	.write16	= dc21285_write16,
+	.write32	= dc21285_write32,
+	.copy_to	= dc21285_copy_to
 };
 
-
 /* Partition stuff */
 static struct mtd_partition *dc21285_parts;
 		      
 extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
+extern int parse_cmdline_partitions(struct mtd_info *master,
+				    struct mtd_partition **pparts,
+				    const char *mtd_id);
 
 int __init init_dc21285(void)
 {
@@ -140,18 +142,34 @@
 	mymtd = do_map_probe("cfi_probe", &dc21285_map);
 	if (mymtd) {
 		int nrparts = 0;
+		const char *part_type = NULL;
 
 		mymtd->module = THIS_MODULE;
 			
 		/* partition fixup */
-
+		do {
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+			nrparts = parse_cmdline_partitions(mymtd, &dc21285_parts, "dc21285");
+			if (nrparts > 0) {
+				part_type = "command line";
+				break;
+			}
+#endif
 #ifdef CONFIG_MTD_REDBOOT_PARTS
-		nrparts = parse_redboot_partitions(mymtd, &dc21285_parts);
+			nrparts = parse_redboot_partitions(mymtd, &dc21285_parts);
+			if (nrparts > 0) {
+				part_type = "RedBoot";
+				break;
+			}
 #endif
+		} while (0);
+
 		if (nrparts > 0) {
 			add_mtd_partitions(mymtd, dc21285_parts, nrparts);
+			printk(KERN_NOTICE "DC21285 using %s partition "
+			       "definition\n", part_type);
 		} else if (nrparts == 0) {
-			printk(KERN_NOTICE "RedBoot partition table failed\n");
+			printk(KERN_NOTICE "DC21285 partition table failed\n");
 			add_mtd_device(mymtd);
 		}
 
diff -Nru a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c
--- a/drivers/mtd/maps/edb7312.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/mtd/maps/edb7312.c	Tue Mar  4 19:30:14 2003
@@ -79,17 +79,17 @@
 }
 
 struct map_info edb7312nor_map = {
-	name: "NOR flash on EDB7312",
-	size: WINDOW_SIZE,
-	buswidth: BUSWIDTH,
-	read8: edb7312nor_read8,
-	read16: edb7312nor_read16,
-	read32: edb7312nor_read32,
-	copy_from: edb7312nor_copy_from,
-	write8: edb7312nor_write8,
-	write16: edb7312nor_write16,
-	write32: edb7312nor_write32,
-	copy_to: edb7312nor_copy_to
+	.name		= "NOR flash on EDB7312",
+	.size		= WINDOW_SIZE,
+	.buswidth	= BUSWIDTH,
+	.read8		= edb7312nor_read8,
+	.read16		= edb7312nor_read16,
+	.read32		= edb7312nor_read32,
+	.copy_from	= edb7312nor_copy_from,
+	.write8		= edb7312nor_write8,
+	.write16	= edb7312nor_write16,
+	.write32	= edb7312nor_write32,
+	.copy_to	= edb7312nor_copy_to
 };
 
 #ifdef CONFIG_MTD_PARTITIONS
@@ -97,23 +97,22 @@
 /*
  * MTD partitioning stuff 
  */
-static struct mtd_partition static_partitions[3] =
-{
-    {
-	name: "ARMboot",
-	  size: 0x40000,
-	  offset: 0
-    },
-    {
-	name: "Kernel",
-	  size: 0x200000,
-	  offset: 0x40000
-    },
-    {
-	name: "RootFS",
-	  size: 0xDC0000,
-	  offset: 0x240000
-    },
+static struct mtd_partition static_partitions[3] = {
+	{
+		.name = "ARMboot",
+		.size = 0x40000,
+		.offset = 0
+	},
+	{
+		.name = "Kernel",
+		.size = 0x200000,
+		.offset = 0x40000
+	},
+	{
+		.name = "RootFS",
+		.size = 0xDC0000,
+		.offset = 0x240000
+	},
 };
 
 #define NB_OF(x) (sizeof (x) / sizeof (x[0]))
diff -Nru a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c
--- a/drivers/mtd/maps/elan-104nc.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/mtd/maps/elan-104nc.c	Tue Mar  4 19:30:08 2003
@@ -58,15 +58,20 @@
 /* partition_info gives details on the logical partitions that the split the 
  * single flash device into. If the size if zero we use up to the end of the
  * device. */
-static struct mtd_partition partition_info[]={
-    { name: "ELAN-104NC flash boot partition", 
-      offset: 0, 
-      size: 640*1024 },
-    { name: "ELAN-104NC flash partition 1", 
-      offset: 640*1024, 
-      size: 896*1024 },
-    { name: "ELAN-104NC flash partition 2", 
-      offset: (640+896)*1024 }
+static struct mtd_partition partition_info[] = {
+	{
+		.name	= "ELAN-104NC flash boot partition", 
+		.size	= 640*1024
+	},
+	{
+		.name	= "ELAN-104NC flash partition 1", 
+		.offset	= 640*1024, 
+		.size	= 896*1024
+	},
+	{
+		.name	= "ELAN-104NC flash partition 2", 
+		.offset = (640+896)*1024,
+	}
 };
 #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
 
@@ -195,19 +200,20 @@
 }
 
 static struct map_info elan_104nc_map = {
-	name: "ELAN-104NC flash",
-	size: 8*1024*1024, /* this must be set to a maximum possible amount
-			of flash so the cfi probe routines find all
-			the chips */
-	buswidth: 2,
-	read8: elan_104nc_read8,
-	read16: elan_104nc_read16,
-	read32: elan_104nc_read32,
-	copy_from: elan_104nc_copy_from,
-	write8: elan_104nc_write8,
-	write16: elan_104nc_write16,
-	write32: elan_104nc_write32,
-	copy_to: elan_104nc_copy_to
+	.name		= "ELAN-104NC flash",
+	.size		= 8*1024*1024, /* this must be set to a maximum
+					  possible amount of flash so the
+					  cfi probe routines find all
+					  the chips */
+	.buswidth	= 2,
+	.read8		= elan_104nc_read8,
+	.read16		= elan_104nc_read16,
+	.read32		= elan_104nc_read32,
+	.copy_from	= elan_104nc_copy_from,
+	.write8		= elan_104nc_write8,
+	.write16	= elan_104nc_write16,
+	.write32	= elan_104nc_write32,
+	.copy_to	= elan_104nc_copy_to
 };
 
 /* MTD device for all of the flash. */
diff -Nru a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c
--- a/drivers/mtd/maps/epxa10db-flash.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/mtd/maps/epxa10db-flash.c	Tue Mar  4 19:30:12 2003
@@ -92,17 +92,17 @@
 
 
 static struct map_info epxa_map = {
-	name:		"EPXA flash",
-	size:		FLASH_SIZE,
-	buswidth:	2,
-	read8:		epxa_read8,
-	read16:		epxa_read16,
-	read32:		epxa_read32,
-	copy_from:	epxa_copy_from,
-	write8:		epxa_write8,
-	write16:	epxa_write16,
-	write32:	epxa_write32,
-	copy_to:	epxa_copy_to
+	.name		= "EPXA flash",
+	.size		= FLASH_SIZE,
+	.buswidth	= 2,
+	.read8		= epxa_read8,
+	.read16		= epxa_read16,
+	.read32		= epxa_read32,
+	.copy_from	= epxa_copy_from,
+	.write8		= epxa_write8,
+	.write16	= epxa_write16,
+	.write32	= epxa_write32,
+	.copy_to	= epxa_copy_to
 };
 
 
diff -Nru a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
--- a/drivers/mtd/maps/fortunet.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/maps/fortunet.c	Tue Mar  4 19:30:05 2003
@@ -78,16 +78,16 @@
 }
 
 struct map_info default_map = {
-	size: DEF_WINDOW_SIZE,
-	buswidth: 4,
-	read8: fortunet_read8,
-	read16: fortunet_read16,
-	read32: fortunet_read32,
-	copy_from: fortunet_copy_from,
-	write8: fortunet_write8,
-	write16: fortunet_write16,
-	write32: fortunet_write32,
-	copy_to: fortunet_copy_to
+	.size		= DEF_WINDOW_SIZE,
+	.buswidth	= 4,
+	.read8		= fortunet_read8,
+	.read16		= fortunet_read16,
+	.read32		= fortunet_read32,
+	.copy_from	= fortunet_copy_from,
+	.write8		= fortunet_write8,
+	.write16	= fortunet_write16,
+	.write32	= fortunet_write32,
+	.copy_to	= fortunet_copy_to
 };
 
 static char * __init get_string_option(char *dest,int dest_size,char *sor)
diff -Nru a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c
--- a/drivers/mtd/maps/impa7.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/maps/impa7.c	Tue Mar  4 19:30:05 2003
@@ -82,30 +82,30 @@
 
 static struct map_info impa7_map[NUM_FLASHBANKS] = {
 	{
-	name: "impA7 NOR Flash Bank #0",
-	size: WINDOW_SIZE0,
-	buswidth: BUSWIDTH,
-	read8: impa7_read8,
-	read16: impa7_read16,
-	read32: impa7_read32,
-	copy_from: impa7_copy_from,
-	write8: impa7_write8,
-	write16: impa7_write16,
-	write32: impa7_write32,
-	copy_to: impa7_copy_to
+		.name		= "impA7 NOR Flash Bank #0",
+		.size		= WINDOW_SIZE0,
+		.buswidth	= BUSWIDTH,
+		.read8		= impa7_read8,
+		.read16		= impa7_read16,
+		.read32		= impa7_read32,
+		.copy_from	= impa7_copy_from,
+		.write8		= impa7_write8,
+		.write16	= impa7_write16,
+		.write32	= impa7_write32,
+		.copy_to	= impa7_copy_to
 	},
 	{
-	name: "impA7 NOR Flash Bank #1",
-	size: WINDOW_SIZE1,
-	buswidth: BUSWIDTH,
-	read8: impa7_read8,
-	read16: impa7_read16,
-	read32: impa7_read32,
-	copy_from: impa7_copy_from,
-	write8: impa7_write8,
-	write16: impa7_write16,
-	write32: impa7_write32,
-	copy_to: impa7_copy_to
+		.name		= "impA7 NOR Flash Bank #1",
+		.size		= WINDOW_SIZE1,
+		.buswidth	= BUSWIDTH,
+		.read8		= impa7_read8,
+		.read16		= impa7_read16,
+		.read32		= impa7_read32,
+		.copy_from	= impa7_copy_from,
+		.write8		= impa7_write8,
+		.write16	= impa7_write16,
+		.write32	= impa7_write32,
+		.copy_to = impa7_copy_to
 	},
 };
 
@@ -114,13 +114,12 @@
 /*
  * MTD partitioning stuff 
  */
-static struct mtd_partition static_partitions[] =
-{
-    {
-	name: "FileSystem",
-	  size: 0x800000,
-	  offset: 0x00000000
-    },
+static struct mtd_partition static_partitions[] = {
+	{
+		.name	= "FileSystem",
+		.size	= 0x800000,
+		.offset	= 0x00000000
+	},
 };
 
 #define NB_OF(x) (sizeof (x) / sizeof (x[0]))
@@ -143,8 +142,8 @@
 	const char *part_type = 0;
 	int i;
 	static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = {
-	  { WINDOW_ADDR0, WINDOW_SIZE0 },
-	  { WINDOW_ADDR1, WINDOW_SIZE1 },
+	  { .addr = WINDOW_ADDR0, .size = WINDOW_SIZE0 },
+	  { .addr = WINDOW_ADDR1, .size = WINDOW_SIZE1 },
         };
 	char mtdid[10];
 	int devicesfound = 0;
diff -Nru a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
--- a/drivers/mtd/maps/integrator-flash.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/mtd/maps/integrator-flash.c	Tue Mar  4 19:30:12 2003
@@ -195,16 +195,16 @@
 
 static struct map_info armflash_map =
 {
-	name:		"AFS",
-	read8:		armflash_read8,
-	read16:		armflash_read16,
-	read32:		armflash_read32,
-	copy_from:	armflash_copy_from,
-	write8:		armflash_write8,
-	write16:	armflash_write16,
-	write32:	armflash_write32,
-	copy_to:	armflash_copy_to,
-	set_vpp:	armflash_set_vpp,
+	.name		= "AFS",
+	.read8		= armflash_read8,
+	.read16		= armflash_read16,
+	.read32		= armflash_read32,
+	.copy_from	= armflash_copy_from,
+	.write8		= armflash_write8,
+	.write16	= armflash_write16,
+	.write32	= armflash_write32,
+	.copy_to	= armflash_copy_to,
+	.set_vpp	= armflash_set_vpp,
 };
 
 static struct mtd_info *mtd;
diff -Nru a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c
--- a/drivers/mtd/maps/iq80310.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/mtd/maps/iq80310.c	Tue Mar  4 19:30:13 2003
@@ -67,38 +67,40 @@
 }
 
 static struct map_info iq80310_map = {
-	name: "IQ80310 flash",
-	size: WINDOW_SIZE,
-	buswidth: BUSWIDTH,
-	read8:		iq80310_read8,
-	read16:		iq80310_read16,
-	read32:		iq80310_read32,
-	copy_from:	iq80310_copy_from,
-	write8:		iq80310_write8,
-	write16:	iq80310_write16,
-	write32:	iq80310_write32,
-	copy_to:	iq80310_copy_to
+	.name		= "IQ80310 flash",
+	.size		= WINDOW_SIZE,
+	.buswidth	= BUSWIDTH,
+	.read8		= iq80310_read8,
+	.read16		= iq80310_read16,
+	.read32		= iq80310_read32,
+	.copy_from	= iq80310_copy_from,
+	.write8		= iq80310_write8,
+	.write16	= iq80310_write16,
+	.write32	= iq80310_write32,
+	.copy_to	= iq80310_copy_to
 };
 
 static struct mtd_partition iq80310_partitions[4] = {
 	{
-		name:		"Firmware",
-		size:		0x00080000,
-		offset:		0,
-		mask_flags:	MTD_WRITEABLE  /* force read-only */
-	},{
-		name:		"Kernel",
-		size:		0x000a0000,
-		offset:		0x00080000,
-	},{
-		name:		"Filesystem",
-		size:		0x00600000,
-		offset:		0x00120000
-	},{
-		name:		"RedBoot",
-		size:		0x000e0000,
-		offset:		0x00720000,
-		mask_flags:	MTD_WRITEABLE
+		.name		= "Firmware",
+		.size		= 0x00080000,
+		.mask_flags	= MTD_WRITEABLE  /* force read-only */
+	},
+	{
+		.name		= "Kernel",
+		.size		= 0x000a0000,
+		.offset		= 0x00080000,
+	},
+	{
+		.name		= "Filesystem",
+		.size		= 0x00600000,
+		.offset		= 0x00120000
+	},
+	{
+		.name		= "RedBoot",
+		.size		= 0x000e0000,
+		.offset		= 0x00720000,
+		.mask_flags	= MTD_WRITEABLE
 	}
 };
 
diff -Nru a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c
--- a/drivers/mtd/maps/l440gx.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/mtd/maps/l440gx.c	Tue Mar  4 19:30:13 2003
@@ -76,18 +76,18 @@
 }
 
 struct map_info l440gx_map = {
-	name: "L440GX BIOS",
-	size: WINDOW_SIZE,
-	buswidth: BUSWIDTH,
-	read8: l440gx_read8,
-	read16: l440gx_read16,
-	read32: l440gx_read32,
-	copy_from: l440gx_copy_from,
-	write8: l440gx_write8,
-	write16: l440gx_write16,
-	write32: l440gx_write32,
-	copy_to: l440gx_copy_to,
-	set_vpp: l440gx_set_vpp
+	.name		= "L440GX BIOS",
+	.size		= WINDOW_SIZE,
+	.buswidth	= BUSWIDTH,
+	.read8		= l440gx_read8,
+	.read16		= l440gx_read16,
+	.read32		= l440gx_read32,
+	.copy_from	= l440gx_copy_from,
+	.write8		= l440gx_write8,
+	.write16	= l440gx_write16,
+	.write32	= l440gx_write32,
+	.copy_to	= l440gx_copy_to,
+	.set_vpp	= l440gx_set_vpp
 };
 
 static int __init init_l440gx(void)
diff -Nru a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
--- a/drivers/mtd/maps/netsc520.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/mtd/maps/netsc520.c	Tue Mar  4 19:30:12 2003
@@ -93,27 +93,26 @@
 /* partition_info gives details on the logical partitions that the split the 
  * single flash device into. If the size if zero we use up to the end of the
  * device. */
-static struct mtd_partition partition_info[]={
-    { 
-	    name: "NetSc520 boot kernel", 
-	    offset: 0, 
-	    size: 	0xc0000
-    },
-    { 
-	    name: "NetSc520 Low BIOS", 
-	    offset: 0xc0000, 
-	    size: 	0x40000
-    },
-    { 
-	    name: "NetSc520 file system", 
-	    offset: 0x100000, 
-	    size: 	0xe80000
-    },
-    { 
-	    name: "NetSc520 High BIOS", 
-	    offset: 0xf80000, 
-	    size: 0x80000
-    },
+static struct mtd_partition partition_info[] = {
+	{ 
+		.name	= "NetSc520 boot kernel", 
+		.size	= 0xc0000
+	},
+	{ 
+		.name	= "NetSc520 Low BIOS", 
+		.offset	= 0xc0000, 
+		.size	= 0x40000
+	},
+	{ 
+		.name	= "NetSc520 file system", 
+		.offset	= 0x100000, 
+		.size	= 0xe80000
+	},
+	{ 
+		.name	= "NetSc520 High BIOS", 
+		.offset	= 0xf80000, 
+		.size	= 0x80000
+	},
 };
 #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
 
@@ -127,18 +126,18 @@
 #define WINDOW_ADDR	0x00200000
 
 static struct map_info netsc520_map = {
-	name: "netsc520 Flash Bank",
-	size: WINDOW_SIZE,
-	buswidth: 4,
-	read8: netsc520_read8,
-	read16: netsc520_read16,
-	read32: netsc520_read32,
-	copy_from: netsc520_copy_from,
-	write8: netsc520_write8,
-	write16: netsc520_write16,
-	write32: netsc520_write32,
-	copy_to: netsc520_copy_to,
-	map_priv_2: WINDOW_ADDR
+	.name		= "netsc520 Flash Bank",
+	.size		= WINDOW_SIZE,
+	.buswidth	= 4,
+	.read8		= netsc520_read8,
+	.read16		= netsc520_read16,
+	.read32		= netsc520_read32,
+	.copy_from	= netsc520_copy_from,
+	.write8		= netsc520_write8,
+	.write16	= netsc520_write16,
+	.write32	= netsc520_write32,
+	.copy_to	= netsc520_copy_to,
+	.map_priv_2	= WINDOW_ADDR
 };
 
 #define NUM_FLASH_BANKS	(sizeof(netsc520_map)/sizeof(struct map_info))
diff -Nru a/drivers/mtd/maps/nora.c b/drivers/mtd/maps/nora.c
--- a/drivers/mtd/maps/nora.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/mtd/maps/nora.c	Tue Mar  4 19:30:11 2003
@@ -58,17 +58,17 @@
 }
 
 struct map_info nora_map = {
-	name: "NORA",
-	size: WINDOW_SIZE,
-	buswidth: 2,
-	read8: nora_read8,
-	read16: nora_read16,
-	read32: nora_read32,
-	copy_from: nora_copy_from,
-	write8: nora_write8,
-	write16: nora_write16,
-	write32: nora_write32,
-	copy_to: nora_copy_to
+	.name		= "NORA",
+	.size		= WINDOW_SIZE,
+	.buswidth	= 2,
+	.read8		= nora_read8,
+	.read16		= nora_read16,
+	.read32		= nora_read32,
+	.copy_from	= nora_copy_from,
+	.write8		= nora_write8,
+	.write16	= nora_write16,
+	.write32	= nora_write32,
+	.copy_to	= nora_copy_to
 };
 
 
@@ -106,64 +106,63 @@
 
 static struct mtd_info nora_mtds[4] = {  /* boot, kernel, ramdisk, fs */
 	{
-		type: MTD_NORFLASH,
-		flags: MTD_CAP_NORFLASH,
-		size: 0x60000,
-		erasesize: 0x20000,
-		name: "NORA boot firmware",
-		module: THIS_MODULE,
-		erase: nora_mtd_erase,
-		read: nora_mtd_read,
-		write: nora_mtd_write,
-		suspend: nora_mtd_suspend,
-		resume: nora_mtd_resume,
-		sync: nora_mtd_sync,
-		priv: (void *)0
+		.type		= MTD_NORFLASH,
+		.flags		= MTD_CAP_NORFLASH,
+		.size		= 0x60000,
+		.erasesize	= 0x20000,
+		.name		= "NORA boot firmware",
+		.module		= THIS_MODULE,
+		.erase		= nora_mtd_erase,
+		.read		= nora_mtd_read,
+		.write		= nora_mtd_write,
+		.suspend	= nora_mtd_suspend,
+		.resume		= nora_mtd_resume,
+		.sync		= nora_mtd_sync,
 	},
 	{
-		type: MTD_NORFLASH,
-		flags: MTD_CAP_NORFLASH,
-		size: 0x0a0000,
-		erasesize: 0x20000,
-		name: "NORA kernel",
-		module: THIS_MODULE,
-		erase: nora_mtd_erase,
-		read: nora_mtd_read,
-		write: nora_mtd_write,
-		suspend: nora_mtd_suspend,
-		resume: nora_mtd_resume,
-		sync: nora_mtd_sync,
-		priv: (void *)0x60000
+		.type		= MTD_NORFLASH,
+		.flags		= MTD_CAP_NORFLASH,
+		.size		= 0x0a0000,
+		.erasesize	= 0x20000,
+		.name		= "NORA kernel",
+		.module		= THIS_MODULE,
+		.erase		= nora_mtd_erase,
+		.read		= nora_mtd_read,
+		.write		= nora_mtd_write,
+		.suspend	= nora_mtd_suspend,
+		.resume		= nora_mtd_resume,
+		.sync		= nora_mtd_sync,
+		.priv		= (void *)0x60000
 	},
 	{
-		type: MTD_NORFLASH,
-		flags: MTD_CAP_NORFLASH,
-		size: 0x900000,
-		erasesize: 0x20000,
-		name: "NORA root filesystem",
-		module: THIS_MODULE,
-		erase: nora_mtd_erase,
-		read: nora_mtd_read,
-		write: nora_mtd_write,
-		suspend: nora_mtd_suspend,
-		resume: nora_mtd_resume,
-		sync: nora_mtd_sync,
-		priv: (void *)0x100000
+		.type		= MTD_NORFLASH,
+		.flags		= MTD_CAP_NORFLASH,
+		.size		= 0x900000,
+		.erasesize	= 0x20000,
+		.name		= "NORA root filesystem",
+		.module		= THIS_MODULE,
+		.erase		= nora_mtd_erase,
+		.read		= nora_mtd_read,
+		.write		= nora_mtd_write,
+		.suspend	= nora_mtd_suspend,
+		.resume		= nora_mtd_resume,
+		.sync		= nora_mtd_sync,
+		.priv		= (void *)0x100000
 	},
 	{
-		type: MTD_NORFLASH,
-		flags: MTD_CAP_NORFLASH,
-		size: 0x1600000,
-		erasesize: 0x20000,
-		name: "NORA second filesystem",
-		module: THIS_MODULE,
-		erase: nora_mtd_erase,
-		read: nora_mtd_read,
-		write: nora_mtd_write,
-		suspend: nora_mtd_suspend,
-		resume: nora_mtd_resume,
-		sync: nora_mtd_sync,
-		priv: (void *)0xa00000
+		.type		= MTD_NORFLASH,
+		.flags		= MTD_CAP_NORFLASH,
+		.size		= 0x1600000,
+		.erasesize	= 0x20000,
+		.name		= "NORA second filesystem",
+		.module		= THIS_MODULE,
+		.erase		= nora_mtd_erase,
+		.read		= nora_mtd_read,
+		.write		= nora_mtd_write,
+		.suspend	= nora_mtd_suspend,
+		.resume		= nora_mtd_resume,
+		.sync		= nora_mtd_sync,
+		.priv		= (void *)0xa00000
 	}
 };
 
diff -Nru a/drivers/mtd/maps/ocelot.c b/drivers/mtd/maps/ocelot.c
--- a/drivers/mtd/maps/ocelot.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/mtd/maps/ocelot.c	Tue Mar  4 19:30:14 2003
@@ -70,22 +70,22 @@
 static struct mtd_partition *parsed_parts;
 
 struct map_info ocelot_flash_map = {
-	name: "Ocelot boot flash",
-	size: FLASH_WINDOW_SIZE,
-	buswidth: FLASH_BUSWIDTH,
-	read8: ocelot_read8,
-	copy_from: ocelot_copy_from_cache,
-	write8: ocelot_write8,
+	.name		= "Ocelot boot flash",
+	.size		= FLASH_WINDOW_SIZE,
+	.buswidth	= FLASH_BUSWIDTH,
+	.read8		= ocelot_read8,
+	.copy_from	= ocelot_copy_from_cache,
+	.write8		= ocelot_write8,
 };
 
 struct map_info ocelot_nvram_map = {
-	name: "Ocelot NVRAM",
-	size: NVRAM_WINDOW_SIZE,
-	buswidth: NVRAM_BUSWIDTH,
-	read8: ocelot_read8,
-	copy_from: ocelot_copy_from,
-	write8: ocelot_write8,
-	copy_to: ocelot_copy_to
+	.name		= "Ocelot NVRAM",
+	.size		= NVRAM_WINDOW_SIZE,
+	.buswidth	= NVRAM_BUSWIDTH,
+	.read8		= ocelot_read8,
+	.copy_from	= ocelot_copy_from,
+	.write8		= ocelot_write8,
+	.copy_to	= ocelot_copy_to
 };
 
 static int __init init_ocelot_maps(void)
diff -Nru a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c
--- a/drivers/mtd/maps/octagon-5066.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/maps/octagon-5066.c	Tue Mar  4 19:30:05 2003
@@ -151,32 +151,32 @@
 
 static struct map_info oct5066_map[2] = {
 	{
-		name: "Octagon 5066 Socket",
-		size: 512 * 1024,
-		buswidth: 1,
-		read8: oct5066_read8,
-		read16: oct5066_read16,
-		read32: oct5066_read32,
-		copy_from: oct5066_copy_from,
-		write8: oct5066_write8,
-		write16: oct5066_write16,
-		write32: oct5066_write32,
-		copy_to: oct5066_copy_to,
-		map_priv_1: 1<<6
+		.name		= "Octagon 5066 Socket",
+		.size		= 512 * 1024,
+		.buswidth	= 1,
+		.read8		= oct5066_read8,
+		.read16		= oct5066_read16,
+		.read32		= oct5066_read32,
+		.copy_from	= oct5066_copy_from,
+		.write8		= oct5066_write8,
+		.write16	= oct5066_write16,
+		.write32	= oct5066_write32,
+		.copy_to	= oct5066_copy_to,
+		.map_priv_1	= 1<<6
 	},
 	{
-		name: "Octagon 5066 Internal Flash",
-		size: 2 * 1024 * 1024,
-		buswidth: 1,
-		read8: oct5066_read8,
-		read16: oct5066_read16,
-		read32: oct5066_read32,
-		copy_from: oct5066_copy_from,
-		write8: oct5066_write8,
-		write16: oct5066_write16,
-		write32: oct5066_write32,
-		copy_to: oct5066_copy_to,
-		map_priv_1: 2<<6
+		.name		= "Octagon 5066 Internal Flash",
+		.size		= 2 * 1024 * 1024,
+		.buswidth	= 1,
+		.read8		= oct5066_read8,
+		.read16		= oct5066_read16,
+		.read32		= oct5066_read32,
+		.copy_from	= oct5066_copy_from,
+		.write8		= oct5066_write8,
+		.write16	= oct5066_write16,
+		.write32	= oct5066_write32,
+		.copy_to	= oct5066_copy_to,
+		.map_priv_1	= 2<<6
 	}
 };
 
diff -Nru a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
--- a/drivers/mtd/maps/pci.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/mtd/maps/pci.c	Tue Mar  4 19:30:07 2003
@@ -98,10 +98,10 @@
 }
 
 static struct mtd_pci_info intel_iq80310_info = {
-	init:		intel_iq80310_init,
-	exit:		intel_iq80310_exit,
-	translate:	intel_iq80310_translate,
-	map_name:	"cfi_probe",
+	.init		= intel_iq80310_init,
+	.exit		= intel_iq80310_exit,
+	.translate	= intel_iq80310_translate,
+	.map_name	= "cfi_probe",
 };
 
 /*
@@ -181,10 +181,10 @@
 }
 
 static struct mtd_pci_info intel_dc21285_info = {
-	init:		intel_dc21285_init,
-	exit:		intel_dc21285_exit,
-	translate:	intel_dc21285_translate,
-	map_name:	"jedec_probe",
+	.init		= intel_dc21285_init,
+	.exit		= intel_dc21285_exit,
+	.translate	= intel_dc21285_translate,
+	.map_name	= "jedec_probe",
 };
 
 /*
@@ -193,24 +193,22 @@
 
 static struct pci_device_id mtd_pci_ids[] __devinitdata = {
 	{
-		vendor:		PCI_VENDOR_ID_INTEL,
-		device:		0x530d,
-		subvendor:	PCI_ANY_ID,
-		subdevice:	PCI_ANY_ID,
-		class:		PCI_CLASS_MEMORY_OTHER << 8,
-		class_mask:	0xffff00,
-		driver_data:	(unsigned long)&intel_iq80310_info,
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= 0x530d,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.class		= PCI_CLASS_MEMORY_OTHER << 8,
+		.class_mask	= 0xffff00,
+		.driver_data	= (unsigned long)&intel_iq80310_info,
 	},
 	{
-		vendor:		PCI_VENDOR_ID_DEC,
-		device:		PCI_DEVICE_ID_DEC_21285,
-		subvendor:	0,	/* DC21285 defaults to 0 on reset */
-		subdevice:	0,	/* DC21285 defaults to 0 on reset */
-		class:		0,
-		class_mask:	0,
-		driver_data:	(unsigned long)&intel_dc21285_info,
+		.vendor		= PCI_VENDOR_ID_DEC,
+		.device		= PCI_DEVICE_ID_DEC_21285,
+		.subvendor	= 0,	/* DC21285 defaults to 0 on reset */
+		.subdevice	= 0,	/* DC21285 defaults to 0 on reset */
+		.driver_data	= (unsigned long)&intel_dc21285_info,
 	},
-	{ 0, }
+	{ .vendor = 0, }
 };
 
 /*
@@ -275,14 +273,14 @@
 }
 
 static struct map_info mtd_pci_map = {
-	read8:		mtd_pci_read8,
-	read16:		mtd_pci_read16,
-	read32:		mtd_pci_read32,
-	copy_from:	mtd_pci_copyfrom,
-	write8:		mtd_pci_write8,
-	write16:	mtd_pci_write16,
-	write32:	mtd_pci_write32,
-	copy_to:	mtd_pci_copyto,
+	.read8		= mtd_pci_read8,
+	.read16		= mtd_pci_read16,
+	.read32		= mtd_pci_read32,
+	.copy_from	= mtd_pci_copyfrom,
+	.write8		= mtd_pci_write8,
+	.write16	= mtd_pci_write16,
+	.write32	= mtd_pci_write32,
+	.copy_to	= mtd_pci_copyto,
 };
 
 static int __devinit
@@ -359,10 +357,10 @@
 }
 
 static struct pci_driver mtd_pci_driver = {
-	name:		"MTD PCI",
-	probe:		mtd_pci_probe,
-	remove:		mtd_pci_remove,
-	id_table:	mtd_pci_ids,
+	.name		= "MTD PCI",
+	.probe		= mtd_pci_probe,
+	.remove		= mtd_pci_remove,
+	.id_table	= mtd_pci_ids,
 };
 
 static int __init mtd_pci_maps_init(void)
diff -Nru a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
--- a/drivers/mtd/maps/physmap.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/mtd/maps/physmap.c	Tue Mar  4 19:30:10 2003
@@ -63,17 +63,17 @@
 }
 
 struct map_info physmap_map = {
-	name: "Physically mapped flash",
-	size: WINDOW_SIZE,
-	buswidth: BUSWIDTH,
-	read8: physmap_read8,
-	read16: physmap_read16,
-	read32: physmap_read32,
-	copy_from: physmap_copy_from,
-	write8: physmap_write8,
-	write16: physmap_write16,
-	write32: physmap_write32,
-	copy_to: physmap_copy_to
+	.name		= "Physically mapped flash",
+	.size		= WINDOW_SIZE,
+	.buswidth	= BUSWIDTH,
+	.read8		= physmap_read8,
+	.read16		= physmap_read16,
+	.read32		= physmap_read32,
+	.copy_from	= physmap_copy_from,
+	.write8		= physmap_write8,
+	.write16	= physmap_write16,
+	.write32	= physmap_write32,
+	.copy_to	= physmap_copy_to
 };
 
 int __init init_physmap(void)
diff -Nru a/drivers/mtd/maps/pnc2000.c b/drivers/mtd/maps/pnc2000.c
--- a/drivers/mtd/maps/pnc2000.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/mtd/maps/pnc2000.c	Tue Mar  4 19:30:08 2003
@@ -65,17 +65,17 @@
 }
 
 struct map_info pnc_map = {
-	name: "PNC-2000",
-	size: WINDOW_SIZE,
-	buswidth: 4,
-	read8: pnc_read8,
-	read16: pnc_read16,
-	read32: pnc_read32,
-	copy_from: pnc_copy_from,
-	write8: pnc_write8,
-	write16: pnc_write16,
-	write32: pnc_write32,
-	copy_to: pnc_copy_to
+	.name		= "PNC-2000",
+	.size		= WINDOW_SIZE,
+	.buswidth	= 4,
+	.read8		= pnc_read8,
+	.read16		= pnc_read16,
+	.read32		= pnc_read32,
+	.copy_from	= pnc_copy_from,
+	.write8		= pnc_write8,
+	.write16	= pnc_write16,
+	.write32	= pnc_write32,
+	.copy_to	= pnc_copy_to
 };
 
 
@@ -84,19 +84,18 @@
  */
 static struct mtd_partition pnc_partitions[3] = {
 	{
-		name: "PNC-2000 boot firmware",
-		size: 0x20000,
-		offset: 0
+		.name	= "PNC-2000 boot firmware",
+		.size	= 0x20000,
 	},
 	{
-		name: "PNC-2000 kernel",
-		size: 0x1a0000,
-		offset: 0x20000
+		.name	= "PNC-2000 kernel",
+		.size	= 0x1a0000,
+		.offset	= 0x20000
 	},
 	{
-		name: "PNC-2000 filesystem",
-		size: 0x240000,
-		offset: 0x1c0000
+		.name	= "PNC-2000 filesystem",
+		.size	= 0x240000,
+		.offset	= 0x1c0000
 	}
 };
 
diff -Nru a/drivers/mtd/maps/rpxlite.c b/drivers/mtd/maps/rpxlite.c
--- a/drivers/mtd/maps/rpxlite.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/mtd/maps/rpxlite.c	Tue Mar  4 19:30:14 2003
@@ -61,17 +61,17 @@
 }
 
 struct map_info rpxlite_map = {
-	name: "RPX",
-	size: WINDOW_SIZE,
-	buswidth: 4,
-	read8: rpxlite_read8,
-	read16: rpxlite_read16,
-	read32: rpxlite_read32,
-	copy_from: rpxlite_copy_from,
-	write8: rpxlite_write8,
-	write16: rpxlite_write16,
-	write32: rpxlite_write32,
-	copy_to: rpxlite_copy_to
+	.name		= "RPX",
+	.size		= WINDOW_SIZE,
+	.buswidth	= 4,
+	.read8		= rpxlite_read8,
+	.read16		= rpxlite_read16,
+	.read32		= rpxlite_read32,
+	.copy_from	= rpxlite_copy_from,
+	.write8		= rpxlite_write8,
+	.write16	= rpxlite_write16,
+	.write32	= rpxlite_write32,
+	.copy_to	= rpxlite_copy_to
 };
 
 int __init init_rpxlite(void)
diff -Nru a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
--- a/drivers/mtd/maps/sa1100-flash.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/maps/sa1100-flash.c	Tue Mar  4 19:30:05 2003
@@ -96,7 +96,7 @@
  *  1. We no longer support static flash mappings via the machine io_desc
  *     structure.
  *  2. The flash size given should be the largest flash size that can
- *     be accomodated.
+ *     be accommodated.
  *
  * The MTD layer will detect flash chip aliasing and reduce the size of
  * the map accordingly.
diff -Nru a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c
--- a/drivers/mtd/maps/sbc_gxx.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/mtd/maps/sbc_gxx.c	Tue Mar  4 19:30:10 2003
@@ -90,15 +90,20 @@
 /* partition_info gives details on the logical partitions that the split the 
  * single flash device into. If the size if zero we use up to the end of the
  * device. */
-static struct mtd_partition partition_info[]={
-    { name: "SBC-GXx flash boot partition", 
-      offset: 0, 
-      size:   BOOT_PARTITION_SIZE_KiB*1024 },
-    { name: "SBC-GXx flash data partition", 
-      offset: BOOT_PARTITION_SIZE_KiB*1024, 
-      size: (DATA_PARTITION_SIZE_KiB)*1024 },
-    { name: "SBC-GXx flash application partition", 
-      offset: (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
+static struct mtd_partition partition_info[] = {
+	{
+		.name	= "SBC-GXx flash boot partition", 
+		.size	= BOOT_PARTITION_SIZE_KiB*1024
+	},
+	{
+		.name	= "SBC-GXx flash data partition", 
+		.offset	= BOOT_PARTITION_SIZE_KiB*1024, 
+		.size	= (DATA_PARTITION_SIZE_KiB)*1024
+	},
+	{
+		.name	= "SBC-GXx flash application partition", 
+		.offset	= (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024
+	}
 };
 
 #define NUM_PARTITIONS 3
@@ -203,19 +208,20 @@
 }
 
 static struct map_info sbc_gxx_map = {
-	name: "SBC-GXx flash",
-	size: MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount
-			 of flash so the cfi probe routines find all
-			 the chips */
-	buswidth: 1,
-	read8: sbc_gxx_read8,
-	read16: sbc_gxx_read16,
-	read32: sbc_gxx_read32,
-	copy_from: sbc_gxx_copy_from,
-	write8: sbc_gxx_write8,
-	write16: sbc_gxx_write16,
-	write32: sbc_gxx_write32,
-	copy_to: sbc_gxx_copy_to
+	.name		= "SBC-GXx flash",
+	.size		= MAX_SIZE_KiB*1024, /* this must be set to a maximum
+						possible amount of flash so
+						the cfi probe routines find
+						all the chips */
+	.buswidth	= 1,
+	.read8		= sbc_gxx_read8,
+	.read16		= sbc_gxx_read16,
+	.read32		= sbc_gxx_read32,
+	.copy_from	= sbc_gxx_copy_from,
+	.write8		= sbc_gxx_write8,
+	.write16	= sbc_gxx_write16,
+	.write32	= sbc_gxx_write32,
+	.copy_to	= sbc_gxx_copy_to
 };
 
 /* MTD device for all of the flash. */
diff -Nru a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
--- a/drivers/mtd/maps/sc520cdp.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/mtd/maps/sc520cdp.c	Tue Mar  4 19:30:13 2003
@@ -125,46 +125,46 @@
 
 static struct map_info sc520cdp_map[] = {
 	{
-		name: "SC520CDP Flash Bank #0",
-		size: WINDOW_SIZE_0,
-		buswidth: 4,
-		read8: sc520cdp_read8,
-		read16: sc520cdp_read16,
-		read32: sc520cdp_read32,
-		copy_from: sc520cdp_copy_from,
-		write8: sc520cdp_write8,
-		write16: sc520cdp_write16,
-		write32: sc520cdp_write32,
-		copy_to: sc520cdp_copy_to,
-		map_priv_2: WINDOW_ADDR_0
+		.name		= "SC520CDP Flash Bank #0",
+		.size		= WINDOW_SIZE_0,
+		.buswidth	= 4,
+		.read8		= sc520cdp_read8,
+		.read16		= sc520cdp_read16,
+		.read32		= sc520cdp_read32,
+		.copy_from	= sc520cdp_copy_from,
+		.write8		= sc520cdp_write8,
+		.write16	= sc520cdp_write16,
+		.write32	= sc520cdp_write32,
+		.copy_to	= sc520cdp_copy_to,
+		.map_priv_2	= WINDOW_ADDR_0
 	},
 	{
-		name: "SC520CDP Flash Bank #1",
-		size: WINDOW_SIZE_1,
-		buswidth: 4,
-		read8: sc520cdp_read8,
-		read16: sc520cdp_read16,
-		read32: sc520cdp_read32,
-		copy_from: sc520cdp_copy_from,
-		write8: sc520cdp_write8,
-		write16: sc520cdp_write16,
-		write32: sc520cdp_write32,
-		copy_to: sc520cdp_copy_to,
-		map_priv_2: WINDOW_ADDR_1
+		.name		= "SC520CDP Flash Bank #1",
+		.size		= WINDOW_SIZE_1,
+		.buswidth	= 4,
+		.read8		= sc520cdp_read8,
+		.read16		= sc520cdp_read16,
+		.read32		= sc520cdp_read32,
+		.copy_from	= sc520cdp_copy_from,
+		.write8		= sc520cdp_write8,
+		.write16	= sc520cdp_write16,
+		.write32	= sc520cdp_write32,
+		.copy_to	= sc520cdp_copy_to,
+		.map_priv_2	= WINDOW_ADDR_1
 	},
 	{
-		name: "SC520CDP DIL Flash",
-		size: WINDOW_SIZE_2,
-		buswidth: 1,
-		read8: sc520cdp_read8,
-		read16: sc520cdp_read16,
-		read32: sc520cdp_read32,
-		copy_from: sc520cdp_copy_from,
-		write8: sc520cdp_write8,
-		write16: sc520cdp_write16,
-		write32: sc520cdp_write32,
-		copy_to: sc520cdp_copy_to,
-		map_priv_2: WINDOW_ADDR_2
+		.name		= "SC520CDP DIL Flash",
+		.size		= WINDOW_SIZE_2,
+		.buswidth	= 1,
+		.read8		= sc520cdp_read8,
+		.read16		= sc520cdp_read16,
+		.read32		= sc520cdp_read32,
+		.copy_from	= sc520cdp_copy_from,
+		.write8		= sc520cdp_write8,
+		.write16	= sc520cdp_write16,
+		.write32	= sc520cdp_write32,
+		.copy_to	= sc520cdp_copy_to,
+		.map_priv_2	= WINDOW_ADDR_2
 	},
 };
 
diff -Nru a/drivers/mtd/maps/solutionengine.c b/drivers/mtd/maps/solutionengine.c
--- a/drivers/mtd/maps/solutionengine.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/mtd/maps/solutionengine.c	Tue Mar  4 19:30:13 2003
@@ -42,19 +42,19 @@
 static struct mtd_partition *parsed_parts;
 
 struct map_info soleng_eprom_map = {
-	name: "Solution Engine EPROM",
-	size: 0x400000,
-	buswidth: 4,
-	copy_from: soleng_copy_from,
+	.name		= "Solution Engine EPROM",
+	.size		= 0x400000,
+	.buswidth	= 4,
+	.copy_from	= soleng_copy_from,
 };
 
 struct map_info soleng_flash_map = {
-	name: "Solution Engine FLASH",
-	size: 0x400000,
-	buswidth: 4,
-	read32: soleng_read32,
-	copy_from: soleng_copy_from,
-	write32: soleng_write32,
+	.name		= "Solution Engine FLASH",
+	.size		= 0x400000,
+	.buswidth	= 4,
+	.read32		= soleng_read32,
+	.copy_from	= soleng_copy_from,
+	.write32	= soleng_write32,
 };
 
 static int __init init_soleng_maps(void)
diff -Nru a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
--- a/drivers/mtd/maps/sun_uflash.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/mtd/maps/sun_uflash.c	Tue Mar  4 19:30:11 2003
@@ -91,17 +91,17 @@
 }
 
 struct map_info uflash_map_templ = {
-		name:		"SUNW,???-????",
-		size:		UFLASH_WINDOW_SIZE,
-		buswidth:	UFLASH_BUSWIDTH,
-		read8:		uflash_read8,
-		read16:		uflash_read16,
-		read32:		uflash_read32,
-		copy_from:	uflash_copy_from,
-		write8:		uflash_write8,
-		write16:	uflash_write16,
-		write32:	uflash_write32,
-		copy_to:	uflash_copy_to
+	.name		= "SUNW,???-????",
+	.size		= UFLASH_WINDOW_SIZE,
+	.buswidth	= UFLASH_BUSWIDTH,
+	.read8		= uflash_read8,
+	.read16		= uflash_read16,
+	.read32		= uflash_read32,
+	.copy_from	= uflash_copy_from,
+	.write8		= uflash_write8,
+	.write16	= uflash_write16,
+	.write32	= uflash_write32,
+	.copy_to	= uflash_copy_to
 };
 
 int uflash_devinit(struct linux_ebus_device* edev)
diff -Nru a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
--- a/drivers/mtd/maps/tqm8xxl.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/maps/tqm8xxl.c	Tue Mar  4 19:30:05 2003
@@ -92,17 +92,16 @@
 }
 
 struct map_info tqm8xxl_map = {
-	name: "TQM8xxL",
-	//size: WINDOW_SIZE,
-	buswidth: 4,
-	read8: tqm8xxl_read8,
-	read16: tqm8xxl_read16,
-	read32: tqm8xxl_read32,
-	copy_from: tqm8xxl_copy_from,
-	write8: tqm8xxl_write8,
-	write16: tqm8xxl_write16,
-	write32: tqm8xxl_write32,
-	copy_to: tqm8xxl_copy_to
+	.name		= "TQM8xxL",
+	.buswidth	= 4,
+	.read8		= tqm8xxl_read8,
+	.read16		= tqm8xxl_read16,
+	.read32		= tqm8xxl_read32,
+	.copy_from	= tqm8xxl_copy_from,
+	.write8		= tqm8xxl_write8,
+	.write16	= tqm8xxl_write16,
+	.write32	= tqm8xxl_write32,
+	.copy_to	= tqm8xxl_copy_to
 };
 
 /*
@@ -125,40 +124,39 @@
  */
 static struct mtd_partition tqm8xxl_partitions[] = {
 	{
-	  name: "ppcboot",
-	  offset: 0x00000000,
-	  size: 0x00020000,           /* 128KB           */
-	  mask_flags: MTD_WRITEABLE,  /* force read-only */
+		.name		= "ppcboot",
+		.offset		= 0x00000000,
+		.size 		= 0x00020000,	/* 128KB */
+		.mask_flags	= MTD_WRITEABLE, /* force read-only */
 	},
 	{
-	  name: "kernel",             /* default kernel image */
-	  offset: 0x00020000,
-	  size: 0x000e0000,
-	  mask_flags: MTD_WRITEABLE,  /* force read-only */
+		.name		= "kernel",	/* default kernel image */
+		.offset		= 0x00020000,
+		.size		= 0x000e0000,
+		.mask_flags	= MTD_WRITEABLE, /* force read-only */
 	},
 	{
-	  name: "user",
-	  offset: 0x00100000,
-	  size: 0x00100000,
+		.name		= "user",
+		.offset		= 0x00100000,
+		.size		= 0x00100000,
 	},
 	{
-	  name: "initrd",
-	  offset: 0x00200000,
-	  size: 0x00200000,
+		.name		= "initrd",
+		.offset		= 0x00200000,
+		.size		= 0x00200000,
 	}
 };
 /* partition definition for second flahs bank */
 static struct mtd_partition tqm8xxl_fs_partitions[] = {
 	{
-	  name: "cramfs",
-	  offset: 0x00000000,
-	  size: 0x00200000,
+		.name	= "cramfs",
+		.offset	= 0x00000000,
+		.size	= 0x00200000,
 	},
 	{
-	  name: "jffs",
-	  offset: 0x00200000,
-	  size: 0x00200000,
-	  //size: MTDPART_SIZ_FULL,
+		.name	= "jffs",
+		.offset	= 0x00200000,
+		.size	= 0x00200000,
 	}
 };
 #endif
diff -Nru a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
--- a/drivers/mtd/maps/uclinux.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/mtd/maps/uclinux.c	Tue Mar  4 19:30:13 2003
@@ -66,15 +66,15 @@
 /****************************************************************************/
 
 struct map_info uclinux_ram_map = {
-	name:		"RAM",
-	read8:		uclinux_read8,
-	read16:		uclinux_read16,
-	read32:		uclinux_read32,
-	copy_from:	uclinux_copy_from,
-	write8:		uclinux_write8,
-	write16:	uclinux_write16,
-	write32:	uclinux_write32,
-	copy_to:	uclinux_copy_to,
+	.name		= "RAM",
+	.read8		= uclinux_read8,
+	.read16		= uclinux_read16,
+	.read32		= uclinux_read32,
+	.copy_from	= uclinux_copy_from,
+	.write8		= uclinux_write8,
+	.write16	= uclinux_write16,
+	.write32	= uclinux_write32,
+	.copy_to	= uclinux_copy_to,
 };
 
 struct mtd_info *uclinux_ram_mtdinfo;
@@ -82,7 +82,7 @@
 /****************************************************************************/
 
 struct mtd_partition uclinux_romfs[] = {
-	{ name: "ROMfs", offset: 0 }
+	{ .name = "ROMfs", .offset = 0 }
 };
 
 #define	NUM_PARTITIONS	(sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0]))
diff -Nru a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
--- a/drivers/mtd/maps/vmax301.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/mtd/maps/vmax301.c	Tue Mar  4 19:30:05 2003
@@ -142,34 +142,33 @@
 
 static struct map_info vmax_map[2] = {
 	{
-		name: "VMAX301 Internal Flash",
-		size: 3*2*1024*1024,
-		buswidth: 1,
-		read8: vmax301_read8,
-		read16: vmax301_read16,
-		read32: vmax301_read32,
-		copy_from: vmax301_copy_from,
-		write8: vmax301_write8,
-		write16: vmax301_write16,
-		write32: vmax301_write32,
-		copy_to: vmax301_copy_to,
-		map_priv_1: WINDOW_START + WINDOW_LENGTH,
-		map_priv_2: 0xFFFFFFFF
+		.name		= "VMAX301 Internal Flash",
+		.size		= 3*2*1024*1024,
+		.buswidth	= 1,
+		.read8		= vmax301_read8,
+		.read16		= vmax301_read16,
+		.read32		= vmax301_read32,
+		.copy_from	= vmax301_copy_from,
+		.write8		= vmax301_write8,
+		.write16	= vmax301_write16,
+		.write32	= vmax301_write32,
+		.copy_to	= vmax301_copy_to,
+		.map_priv_1	= WINDOW_START + WINDOW_LENGTH,
+		.map_priv_2	= 0xFFFFFFFF
 	},
 	{
-		name: "VMAX301 Socket",
-		size: 0,
-		buswidth: 1,
-		read8: vmax301_read8,
-		read16: vmax301_read16,
-		read32: vmax301_read32,
-		copy_from: vmax301_copy_from,
-		write8: vmax301_write8,
-		write16: vmax301_write16,
-		write32: vmax301_write32,
-		copy_to: vmax301_copy_to,
-		map_priv_1: WINDOW_START + (3*WINDOW_LENGTH),
-		map_priv_2: 0xFFFFFFFF
+		.name		= "VMAX301 Socket",
+		.buswidth	= 1,
+		.read8		= vmax301_read8,
+		.read16		= vmax301_read16,
+		.read32		= vmax301_read32,
+		.copy_from	= vmax301_copy_from,
+		.write8		= vmax301_write8,
+		.write16	= vmax301_write16,
+		.write32	= vmax301_write32,
+		.copy_to	= vmax301_copy_to,
+		.map_priv_1	= WINDOW_START + (3*WINDOW_LENGTH),
+		.map_priv_2	= 0xFFFFFFFF
 	}
 };
 
diff -Nru a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
--- a/drivers/mtd/mtdchar.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/mtd/mtdchar.c	Tue Mar  4 19:30:11 2003
@@ -19,8 +19,8 @@
 static void mtd_notify_remove(struct mtd_info* mtd);
 
 static struct mtd_notifier notifier = {
-	add:	mtd_notify_add,
-	remove:	mtd_notify_remove,
+	.add	= mtd_notify_add,
+	.remove	= mtd_notify_remove,
 };
 
 #endif
@@ -445,13 +445,13 @@
 } /* memory_ioctl */
 
 static struct file_operations mtd_fops = {
-	owner:		THIS_MODULE,
-	llseek:		mtd_lseek,     	/* lseek */
-	read:		mtd_read,	/* read */
-	write: 		mtd_write, 	/* write */
-	ioctl:		mtd_ioctl,	/* ioctl */
-	open:		mtd_open,	/* open */
-	release:	mtd_close,	/* release */
+	.owner		= THIS_MODULE,
+	.llseek		= mtd_lseek,	/* lseek */
+	.read		= mtd_read,	/* read */
+	.write 		= mtd_write, 	/* write */
+	.ioctl		= mtd_ioctl,	/* ioctl */
+	.open		= mtd_open,	/* open */
+	.release	= mtd_close,	/* release */
 };
 
 
diff -Nru a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c
--- a/drivers/mtd/nand/spia.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/mtd/nand/spia.c	Tue Mar  4 19:30:10 2003
@@ -66,12 +66,15 @@
  * Define partitions for flash device
  */
 const static struct mtd_partition partition_info[] = {
-	{ name: "SPIA flash partition 1",
-	  offset: 0,
-	  size: 2*1024*1024 },
-	{ name: "SPIA flash partition 2",
-	  offset: 2*1024*1024,
-	  size: 6*1024*1024 }
+	{
+		.name	= "SPIA flash partition 1",
+		.size	= 2*1024*1024
+	},
+	{
+		.name	= "SPIA flash partition 2",
+		.offset	= 2*1024*1024,
+		.size	= 6*1024*1024
+	}
 };
 #define NUM_PARTITIONS 2
 
diff -Nru a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
--- a/drivers/mtd/nftlcore.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/mtd/nftlcore.c	Tue Mar  4 19:30:04 2003
@@ -914,8 +914,8 @@
  ****************************************************************************/
 
 static struct mtd_notifier nftl_notifier = {
-	add:	NFTL_notify_add,
-	remove:	NFTL_notify_remove
+	.add	= NFTL_notify_add,
+	.remove	= NFTL_notify_remove
 };
 
 extern char nftlmountrev[];
diff -Nru a/drivers/net/3c501.c b/drivers/net/3c501.c
--- a/drivers/net/3c501.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/net/3c501.c	Tue Mar  4 19:30:03 2003
@@ -494,7 +494,7 @@
  * @regs: Register data (surplus to our requirements)
  *
  * Handle the ether interface interrupts. The 3c501 needs a lot more 
- * hand holding than most cards. In paticular we get a transmit interrupt
+ * hand holding than most cards. In particular we get a transmit interrupt
  * with a collision error because the board firmware isnt capable of rewinding
  * its own transmit buffer pointers. It can however count to 16 for us.
  *
@@ -684,7 +684,7 @@
  * @dev: Device to pull the packets from
  *
  * We have a good packet. Well, not really "good", just mostly not broken.
- * We must check everything to see if it is good. In paticular we occasionally
+ * We must check everything to see if it is good. In particular we occasionally
  * get wild packet sizes from the card. If the packet seems sane we PIO it
  * off the card and queue it for the protocol layers.
  */
diff -Nru a/drivers/net/3c503.c b/drivers/net/3c503.c
--- a/drivers/net/3c503.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/3c503.c	Tue Mar  4 19:30:11 2003
@@ -693,7 +693,7 @@
 MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr, "tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
 MODULE_DESCRIPTION("3Com ISA EtherLink II, II/16 (3c503, 3c503/16) driver");
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/3c509.c	Tue Mar  4 19:30:04 2003
@@ -385,7 +385,7 @@
 					    idev))) {
 			if (pnp_device_attach(idev) < 0)
 				continue;
-			if (pnp_activate_dev(idev, NULL) < 0) {
+			if (pnp_activate_dev(idev) < 0) {
 			      __again:
 			      	pnp_device_detach(idev);
 			      	continue;
@@ -1139,7 +1139,7 @@
 	int ioaddr = dev->base_addr;
 	
 	EL3WINDOW(0);
-	/* obtain current tranceiver via WN4_MEDIA? */	
+	/* obtain current transceiver via WN4_MEDIA? */	
 	tmp = inw(ioaddr + WN0_ADDR_CONF);
 	ecmd->transceiver = XCVR_INTERNAL;
 	switch (tmp >> 14) {
@@ -1548,7 +1548,7 @@
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM_DESC(debug, "debug level (0-6)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr,"tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)");
 MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
 #ifdef __ISAPNP__
 MODULE_PARM(nopnp, "i");
diff -Nru a/drivers/net/3c515.c b/drivers/net/3c515.c
--- a/drivers/net/3c515.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/3c515.c	Tue Mar  4 19:30:04 2003
@@ -469,7 +469,7 @@
 
 			if (pnp_device_attach(idev) < 0)
 				continue;
-			if (pnp_activate_dev(idev, NULL) < 0) {
+			if (pnp_activate_dev(idev) < 0) {
 				printk("pnp activate failed (out of resources?)\n");
 				pnp_device_detach(idev);
 				return -ENOMEM;
diff -Nru a/drivers/net/3c527.c b/drivers/net/3c527.c
--- a/drivers/net/3c527.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/net/3c527.c	Tue Mar  4 19:30:09 2003
@@ -227,7 +227,7 @@
  * Because MCA bus is a real bus and we can scan for cards we could do a
  * single scan for all boards here. Right now we use the passed in device
  * structure and scan for only one board. This needs fixing for modules
- * in paticular.
+ * in particular.
  */
 
 int __init mc32_probe(struct net_device *dev)
@@ -1168,7 +1168,7 @@
  * 	the stack or, if the packet is near MTU sized, we allocate
  *	another buffer and flip the old one up the stack.
  * 
- *	We must succeed in keeping a buffer on the ring. If neccessary we
+ *	We must succeed in keeping a buffer on the ring. If necessary we
  *	will toss a received packet rather than lose a ring entry. Once
  *	the first uncompleted descriptor is found, we move the
  *	End-Of-List bit to include the buffers just processed.
diff -Nru a/drivers/net/8390.c b/drivers/net/8390.c
--- a/drivers/net/8390.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/8390.c	Tue Mar  4 19:30:04 2003
@@ -277,7 +277,7 @@
 	/* Mask interrupts from the ethercard. 
 	   SMP: We have to grab the lock here otherwise the IRQ handler
 	   on another CPU can flip window and race the IRQ mask set. We end
-	   up trashing the mcast filter not disabling irqs if we dont lock */
+	   up trashing the mcast filter not disabling irqs if we don't lock */
 	   
 	spin_lock_irqsave(&ei_local->page_lock, flags);
 	outb_p(0x00, e8390_base + EN0_IMR);
@@ -417,7 +417,7 @@
  * Handle the ether interface interrupts. We pull packets from
  * the 8390 via the card specific functions and fire them at the networking
  * stack. We also handle transmit completions and wake the transmit path if
- * neccessary. We also update the counters and do other housekeeping as
+ * necessary. We also update the counters and do other housekeeping as
  * needed.
  */
 
diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c
--- a/drivers/net/acenic.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/net/acenic.c	Tue Mar  4 19:30:08 2003
@@ -1378,7 +1378,7 @@
 	 * On this platform, we know what the best dma settings
 	 * are.  We use 64-byte maximum bursts, because if we
 	 * burst larger than the cache line size (or even cross
-	 * a 64byte boundry in a single burst) the UltraSparc
+	 * a 64byte boundary in a single burst) the UltraSparc
 	 * PCI controller will disconnect at 64-byte multiples.
 	 *
 	 * Read-multiple will be properly enabled above, and when
diff -Nru a/drivers/net/atp.c b/drivers/net/atp.c
--- a/drivers/net/atp.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/atp.c	Tue Mar  4 19:30:14 2003
@@ -162,7 +162,7 @@
 MODULE_PARM_DESC(debug, "ATP debug level (0-7)");
 MODULE_PARM_DESC(io, "ATP I/O base address(es)");
 MODULE_PARM_DESC(irq, "ATP IRQ number(s)");
-MODULE_PARM_DESC(xcvr, "ATP tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(xcvr, "ATP transceiver(s) (0=internal, 1=external)");
 
 /* The number of low I/O ports used by the ethercard. */
 #define ETHERCARD_TOTAL_SIZE	3
diff -Nru a/drivers/net/b44.h b/drivers/net/b44.h
--- a/drivers/net/b44.h	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/b44.h	Tue Mar  4 19:30:11 2003
@@ -424,7 +424,7 @@
 };
 
 /* There are only 12 bits in the DMA engine for descriptor offsetting
- * so the table must be aligned on a boundry of this.
+ * so the table must be aligned on a boundary of this.
  */
 #define DMA_TABLE_BYTES		4096
 
diff -Nru a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
--- a/drivers/net/cs89x0.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/net/cs89x0.c	Tue Mar  4 19:30:12 2003
@@ -1112,7 +1112,7 @@
 	int i;
 	int ret;
 
-#ifndef CONFIG_SH_HICOSH4 /* uses irq#1, so this wont work */
+#ifndef CONFIG_SH_HICOSH4 /* uses irq#1, so this won't work */
 	if (dev->irq < 2) {
 		/* Allow interrupts to be generated by the chip */
 /* Cirrus' release had this: */
diff -Nru a/drivers/net/declance.c b/drivers/net/declance.c
--- a/drivers/net/declance.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/net/declance.c	Tue Mar  4 19:30:10 2003
@@ -887,7 +887,7 @@
 	cp_to_buf((char *) lp->tx_buf_ptr_cpu[entry], skb->data, skblen);
 
 	/* Clear the slack of the packet, do I need this? */
-	/* For a firewall its a good idea - AC */
+	/* For a firewall it's a good idea - AC */
 /*
    if (len != skblen)
    memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1);
diff -Nru a/drivers/net/dgrs.c b/drivers/net/dgrs.c
--- a/drivers/net/dgrs.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/dgrs.c	Tue Mar  4 19:30:04 2003
@@ -274,7 +274,7 @@
 	ulong	x;
 
 	/*
-	 *	If Space.c says not to use DMA, or if its not a PLX based
+	 *	If Space.c says not to use DMA, or if it's not a PLX based
 	 *	PCI board, or if the expansion ROM space is not PCI
 	 *	configured, then return false.
 	 */
@@ -331,10 +331,10 @@
  *	Initiate DMA using PLX part on PCI board.  Spin the
  *	processor until completed.  All addresses are physical!
  *
- *	If pciaddr is NULL, then its a chaining DMA, and lcladdr is
+ *	If pciaddr is NULL, then it's a chaining DMA, and lcladdr is
  *	the address of the first DMA descriptor in the chain.
  *
- *	If pciaddr is not NULL, then its a single DMA.
+ *	If pciaddr is not NULL, then it's a single DMA.
  *
  *	In either case, "lcladdr" must have been fixed up to make
  *	sure the MSB isn't set using the S2DMA macro before passing
@@ -511,7 +511,7 @@
 	if (priv0->use_dma && priv0->dmadesc_h && len > 64)
 	{
 		/*
-		 *	If we can use DMA and its a long frame, copy it using
+		 *	If we can use DMA and it's a long frame, copy it using
 		 *	DMA chaining.
 		 */
 		DMACHAIN	*ddp_h;	/* Host virtual DMA desc. pointer */
@@ -583,7 +583,7 @@
 	else if (priv0->use_dma)
 	{
 		/*
-		 *	If we can use DMA and its a shorter frame, copy it
+		 *	If we can use DMA and it's a shorter frame, copy it
 		 *	using single DMA transfers.
 		 */
 		uchar		*phys_p;
diff -Nru a/drivers/net/e100/e100.h b/drivers/net/e100/e100.h
--- a/drivers/net/e100/e100.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/e100/e100.h	Tue Mar  4 19:30:05 2003
@@ -706,8 +706,6 @@
 #define IPCB_INSERTVLAN_ENABLE 		BIT_1
 #define IPCB_IP_ACTIVATION_DEFAULT      IPCB_HARDWAREPARSING_ENABLE
 
-#define FOLD_CSUM(_XSUM)  ((((_XSUM << 16) | (_XSUM >> 16)) + _XSUM) >> 16)
-
 /* Transmit Buffer Descriptor (TBD)*/
 typedef struct _tbd_t {
 	u32 tbd_buf_addr;	/* Physical Transmit Buffer Address */
diff -Nru a/drivers/net/e100/e100_config.c b/drivers/net/e100/e100_config.c
--- a/drivers/net/e100/e100_config.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/e100/e100_config.c	Tue Mar  4 19:30:05 2003
@@ -149,7 +149,7 @@
 	 * 32 from the RFD base address, instead of at offset 16. */
 	bdp->config[7] |= CB_CFIG_EXTENDED_RFD;
 
-	/* put the chip into D102 receive mode.  This is neccessary
+	/* put the chip into D102 receive mode.  This is necessary
 	 * for any parsing and offloading features. */
 	bdp->config[22] = CB_CFIG_RECEIVE_GAMLA_MODE;
 
diff -Nru a/drivers/net/e100/e100_eeprom.c b/drivers/net/e100/e100_eeprom.c
--- a/drivers/net/e100/e100_eeprom.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/net/e100/e100_eeprom.c	Tue Mar  4 19:30:07 2003
@@ -138,7 +138,7 @@
 //              is then passed to the read/write functions.
 //
 // Returns:
-//      Size of the eeprom, or zero if an error occured
+//      Size of the eeprom, or zero if an error occurred
 //----------------------------------------------------------------------------------------
 u16
 e100_eeprom_size(struct e100_private *adapter)
diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c
--- a/drivers/net/e100/e100_main.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/net/e100/e100_main.c	Tue Mar  4 19:30:08 2003
@@ -1949,7 +1949,7 @@
 		/* to allow manipulation with current skb we need to unlink it */
 		list_del(&(rx_struct->list_elem));
 
-		/* do not free & unmap badly recieved packet.
+		/* do not free & unmap badly received packet.
 		 * move it to the end of skb list for reuse */
 		if (!(rfd_status & RFD_STATUS_OK)) {
 			e100_add_skb_to_end(bdp, rx_struct);
@@ -2071,32 +2071,6 @@
 }
 
 /**
- * e100_pseudo_hdr_csum - compute IP pseudo-header checksum
- * @ip: points to the header of the IP packet
- *
- * Return the 16 bit checksum of the IP pseudo-header.,which is computed
- * on the fields: IP src, IP dst, next protocol, payload length.
- * The checksum vaule is returned in network byte order.
- */
-static inline u16
-e100_pseudo_hdr_csum(const struct iphdr *ip)
-{
-	u32 pseudo = 0;
-	u32 payload_len = 0;
-
-	payload_len = ntohs(ip->tot_len) - (ip->ihl * 4);
-
-	pseudo += htons(payload_len);
-	pseudo += (ip->protocol << 8);
-	pseudo += ip->saddr & 0x0000ffff;
-	pseudo += (ip->saddr & 0xffff0000) >> 16;
-	pseudo += ip->daddr & 0x0000ffff;
-	pseudo += (ip->daddr & 0xffff0000) >> 16;
-
-	return FOLD_CSUM(pseudo);
-}
-
-/**
  * e100_prepare_xmit_buff - prepare a buffer for transmission
  * @bdp: atapter's private data struct
  * @skb: skb to send
@@ -2140,27 +2114,13 @@
 
 		if ((ip->protocol == IPPROTO_TCP) ||
 		    (ip->protocol == IPPROTO_UDP)) {
-			u16 *chksum;
-
 			tcb->tcbu.ipcb.ip_activation_high =
 				IPCB_HARDWAREPARSING_ENABLE;
 			tcb->tcbu.ipcb.ip_schedule |=
 				IPCB_TCPUDP_CHECKSUM_ENABLE;
 
-			if (ip->protocol == IPPROTO_TCP) {
-				struct tcphdr *tcp;
-
-				tcp = (struct tcphdr *) ((u32 *) ip + ip->ihl);
-				chksum = &(tcp->check);
+			if (ip->protocol == IPPROTO_TCP)
 				tcb->tcbu.ipcb.ip_schedule |= IPCB_TCP_PACKET;
-			} else {
-				struct udphdr *udp;
-
-				udp = (struct udphdr *) ((u32 *) ip + ip->ihl);
-				chksum = &(udp->check);
-			}
-
-			*chksum = e100_pseudo_hdr_csum(ip);
 		}
 	}
 
@@ -2236,7 +2196,7 @@
 	spin_lock_irqsave(&(bdp->bd_lock), lock_flag);
 	switch (bdp->next_cu_cmd) {
 	case RESUME_NO_WAIT:
-		/*last cu command was a CU_RESMUE if this is a 558 or newer we dont need to
+		/*last cu command was a CU_RESMUE if this is a 558 or newer we don't need to
 		 * wait for command word to clear, we reach here only if we are bachlor
 		 */
 		e100_exec_cmd(bdp, SCB_CUC_RESUME);
diff -Nru a/drivers/net/e2100.c b/drivers/net/e2100.c
--- a/drivers/net/e2100.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/net/e2100.c	Tue Mar  4 19:30:13 2003
@@ -389,7 +389,7 @@
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 MODULE_PARM_DESC(mem, " memory base address(es)");
-MODULE_PARM_DESC(xcvr, "tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
 MODULE_DESCRIPTION("Cabletron E2100 ISA ethernet driver");
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/eepro100.c	Tue Mar  4 19:30:11 2003
@@ -148,7 +148,7 @@
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(multicast_filter_limit, "i");
 MODULE_PARM_DESC(debug, "debug level (0-6)");
-MODULE_PARM_DESC(options, "Bits 0-3: tranceiver type, bit 4: full duplex, bit 5: 100Mbps");
+MODULE_PARM_DESC(options, "Bits 0-3: transceiver type, bit 4: full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
 MODULE_PARM_DESC(congenb, "Enable congestion control (1)");
 MODULE_PARM_DESC(txfifo, "Tx FIFO threshold in 4 byte units, (0-15)");
diff -Nru a/drivers/net/eth16i.c b/drivers/net/eth16i.c
--- a/drivers/net/eth16i.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/net/eth16i.c	Tue Mar  4 19:30:13 2003
@@ -1231,7 +1231,7 @@
 	/* Turn off all interrupts from adapter */
 	outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
 
-	/* eth16i_tx wont be called */
+	/* eth16i_tx won't be called */
 	spin_lock(&lp->lock);
 
 	status = inw(ioaddr + TX_STATUS_REG);      /* Get the status */
diff -Nru a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c
--- a/drivers/net/fc/iph5526.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/fc/iph5526.c	Tue Mar  4 19:30:05 2003
@@ -499,7 +499,7 @@
 		fi->q.ptr_tachyon_header[i] = fi->q.ptr_tachyon_header_base + 16*i;
 	
 	/* Allocate memory for indices.
-	 * Indices should be aligned on 32 byte boundries. 
+	 * Indices should be aligned on 32 byte boundaries. 
 	 */
 	fi->q.host_ocq_cons_indx = kmalloc(2*32, GFP_KERNEL);
 	if (fi->q.host_ocq_cons_indx == NULL){ 
@@ -748,7 +748,7 @@
 	else
 		if (current_IMQ_index < fi->q.imq_cons_indx)
 			no_of_entries = IMQ_LENGTH - (fi->q.imq_cons_indx - current_IMQ_index);
-	/* We dont want to look at the same IMQ entry again. 
+	/* We don't want to look at the same IMQ entry again. 
 	 */
 	temp_imq_cons_indx = fi->q.imq_cons_indx + 1;
 	if (no_of_entries != 0)
@@ -2263,7 +2263,7 @@
 u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
 u_int my_mtu = fi->g.my_mtu;
 	ENTER("tx_logi");
-	/* We dont want interrupted for our own logi. 
+	/* We don't want interrupted for our own logi. 
 	 * It screws up the port discovery process. 
 	 */
 	if (d_id == fi->g.my_id)
@@ -2567,7 +2567,7 @@
 	}
 	/* Perform Port Discovery after timer expires.
 	 * We are giving time for the ADISCed nodes to respond
-	 * so that we dont have to perform PLOGI to those whose
+	 * so that we don't have to perform PLOGI to those whose
 	 * login are _still_ valid.
 	 */
 	fi->explore_timer.function = port_discovery_timer;
@@ -3175,38 +3175,6 @@
 	LEAVE("rx_net_mfs_packet");
 }
 
-unsigned short fc_type_trans(struct sk_buff *skb, struct net_device *dev) 
-{
-struct fch_hdr *fch=(struct fch_hdr *)skb->data;
-struct fcllc *fcllc;
-	skb->mac.raw = skb->data;
-	fcllc = (struct fcllc *)(skb->data + sizeof(struct fch_hdr) + 2);
-	skb_pull(skb,sizeof(struct fch_hdr) + 2);
-
-	if(*fch->daddr & 1) {
-		if(!memcmp(fch->daddr,dev->broadcast,FC_ALEN)) 	
-			skb->pkt_type = PACKET_BROADCAST;
-		else
-			skb->pkt_type = PACKET_MULTICAST;
-	}
-	else if(dev->flags & IFF_PROMISC) {
-		if(memcmp(fch->daddr, dev->dev_addr, FC_ALEN))
-			skb->pkt_type=PACKET_OTHERHOST;
-	}
-	
-	/* Strip the SNAP header from ARP packets since we don't 
-	 * pass them through to the 802.2/SNAP layers.
-	 */
-
-	if (fcllc->dsap == EXTENDED_SAP &&
-		(fcllc->ethertype == ntohs(ETH_P_IP) ||
-		 fcllc->ethertype == ntohs(ETH_P_ARP))) {
-		skb_pull(skb, sizeof(struct fcllc));
-		return fcllc->ethertype;
-	}
-	return ntohs(ETH_P_802_2);
-}
-
 static int tx_exchange(struct fc_info *fi, char *data, u_int len, u_int r_ctl, u_int type, u_int d_id, u_int mtu, int int_required, u_short tx_ox_id, u_int frame_class)
 {
 u_char df_ctl; 
@@ -3527,7 +3495,7 @@
 						/* There might be some new nodes to be 
 						 * discovered. But, some of the earlier 
 						 * requests as a result of the RSCN might be 
-						 * in progress. We dont want to duplicate that 
+						 * in progress. We don't want to duplicate that 
 						 * effort. So letz call SCR after a lag.
 						 */
 						fi->explore_timer.function = scr_timer;
diff -Nru a/drivers/net/fc/tach_structs.h b/drivers/net/fc/tach_structs.h
--- a/drivers/net/fc/tach_structs.h	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/fc/tach_structs.h	Tue Mar  4 19:30:11 2003
@@ -248,7 +248,7 @@
 	volatile u_char n_port_try;
 	volatile u_char nport_timer_set;
 	volatile u_char lport_timer_set;
-	/* Hmmm... We dont want to Initialize while closing */
+	/* Hmmm... We don't want to Initialize while closing */
 	u_char dont_init; 
 	u_int my_node_name_high;
 	u_int my_node_name_low;
diff -Nru a/drivers/net/fec.c b/drivers/net/fec.c
--- a/drivers/net/fec.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/fec.c	Tue Mar  4 19:30:04 2003
@@ -828,7 +828,7 @@
 /* 
  * I had some nice ideas of running the MDIO faster...
  * The 971 should support 8MHz and I tried it, but things acted really
- * wierd, so 2.5 MHz ought to be enough for anyone...
+ * weird, so 2.5 MHz ought to be enough for anyone...
  */
 
 static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev)
diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c
--- a/drivers/net/hamachi.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/hamachi.c	Tue Mar  4 19:30:14 2003
@@ -316,7 +316,7 @@
     the new buffer or the function returns non-zero which should case the
     scheduler to reschedule the buffer later.
 
-01/15/1999 EPK Some adjustments were made to the chip intialization.  
+01/15/1999 EPK Some adjustments were made to the chip initialization.  
     End-to-end flow control should now be fully active and the interrupt 
     algorithm vars have been changed.  These could probably use further tuning.
 
diff -Nru a/drivers/net/hp100.c b/drivers/net/hp100.c
--- a/drivers/net/hp100.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/net/hp100.c	Tue Mar  4 19:30:07 2003
@@ -2811,7 +2811,7 @@
 			printk("hp100: %s: Problem logging into the HUB.\n", dev->name);
 			if (lp->chip == HP100_CHIPID_LASSEN) {
 				/* Check allowed Register to find out why there is a problem. */
-				val = hp100_inw(TRAIN_ALLOW);	/* wont work on non-ETR card */
+				val = hp100_inw(TRAIN_ALLOW);	/* won't work on non-ETR card */
 #ifdef HP100_DEBUG_TRAINING
 				printk("hp100: %s: MAC Configuration requested: 0x%04x, HUB allowed: 0x%04x\n", dev->name, hp100_inw(TRAIN_REQUEST), val);
 #endif
@@ -2868,7 +2868,7 @@
 			hp100_andb(~HP100_PCI_RESET, PCICTRL2);
 			hp100_orb(HP100_PCI_RESET, PCICTRL2);
 			/* Wait for min. 300 ns */
-			/* we cant use jiffies here, because it may be */
+			/* we can't use jiffies here, because it may be */
 			/* that we have disabled the timer... */
 			udelay(400);
 			hp100_andb(~HP100_PCI_RESET, PCICTRL2);
diff -Nru a/drivers/net/irda/actisys-sir.c b/drivers/net/irda/actisys-sir.c
--- a/drivers/net/irda/actisys-sir.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/net/irda/actisys-sir.c	Tue Mar  4 19:30:10 2003
@@ -207,7 +207,7 @@
  *	o second put the dongle in a know state
  *
  *	The dongle is powered of the RTS and DTR lines. In the dongle, there
- * is a big capacitor to accomodate the current spikes. This capacitor
+ * is a big capacitor to accommodate the current spikes. This capacitor
  * takes a least 50 ms to be charged. In theory, the Bios set those lines
  * up, so by the time we arrive here we should be set. It doesn't hurt
  * to be on the conservative side, so we will wait...
diff -Nru a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c
--- a/drivers/net/irda/actisys.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/irda/actisys.c	Tue Mar  4 19:30:14 2003
@@ -217,7 +217,7 @@
  *	o second put the dongle in a know state
  *
  *	The dongle is powered of the RTS and DTR lines. In the dongle, there
- * is a big capacitor to accomodate the current spikes. This capacitor
+ * is a big capacitor to accommodate the current spikes. This capacitor
  * takes a least 50 ms to be charged. In theory, the Bios set those lines
  * up, so by the time we arrive here we should be set. It doesn't hurt
  * to be on the conservative side, so we will wait...
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/net/irda/irda-usb.c	Tue Mar  4 19:30:09 2003
@@ -120,7 +120,7 @@
 /************************ TRANSMIT ROUTINES ************************/
 /*
  * Receive packets from the IrDA stack and send them on the USB pipe.
- * Handle speed change, timeout and lot's of uglyness...
+ * Handle speed change, timeout and lot's of ugliness...
  */
 
 /*------------------------------------------------------------------*/
diff -Nru a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
--- a/drivers/net/irda/irtty-sir.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/net/irda/irtty-sir.c	Tue Mar  4 19:30:03 2003
@@ -532,7 +532,7 @@
 		tty->driver.flush_buffer(tty);
 	
 /* from old irtty - but what is it good for?
- * we _are_ the ldisc and we _dont_ implement flush_buffer!
+ * we _are_ the ldisc and we _don't_ implement flush_buffer!
  *
  *	if (tty->ldisc.flush_buffer)
  *		tty->ldisc.flush_buffer(tty);
diff -Nru a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
--- a/drivers/net/irda/sir_dev.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/net/irda/sir_dev.c	Tue Mar  4 19:30:10 2003
@@ -569,7 +569,7 @@
 
 	/* instead of adding tests to protect against drv->do_write==NULL
 	 * at several places we refuse to create a sir_dev instance for
-	 * drivers which dont implement do_write.
+	 * drivers which don't implement do_write.
 	 */
 	if (!drv ||  !drv->do_write)
 		return NULL;
diff -Nru a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c
--- a/drivers/net/irda/sir_kthread.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/net/irda/sir_kthread.c	Tue Mar  4 19:30:12 2003
@@ -151,7 +151,7 @@
 
 	while (irda_rq_queue.thread != NULL) {
 
-		set_task_state(current, TASK_UNINTERRUPTIBLE);
+		set_task_state(current, TASK_INTERRUPTIBLE);
 		add_wait_queue(&irda_rq_queue.kick, &wait);
 		if (list_empty(&irda_rq_queue.request_list))
 			schedule();
diff -Nru a/drivers/net/ne.c b/drivers/net/ne.c
--- a/drivers/net/ne.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/net/ne.c	Tue Mar  4 19:30:08 2003
@@ -205,7 +205,7 @@
 			/* Avoid already found cards from previous calls */
 			if (pnp_device_attach(idev) < 0)
 				continue;
-			if (pnp_activate_dev(idev, NULL) < 0) {
+			if (pnp_activate_dev(idev) < 0) {
 			      	pnp_device_detach(idev);
 			      	continue;
 			}
diff -Nru a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig
--- a/drivers/net/pcmcia/Kconfig	Tue Mar  4 19:30:12 2003
+++ b/drivers/net/pcmcia/Kconfig	Tue Mar  4 19:30:12 2003
@@ -153,19 +153,5 @@
 	  The module will be called ibmtr_cs.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
-config AIRONET4500_CS
-	tristate "Aironet 4500/4800 PCMCIA support"
-	depends on NET_PCMCIA_RADIO && AIRONET4500 && PCMCIA
-	help
-	  Say Y here if you have a PCMCIA Aironet 4500/4800 card which you
-	  want to use with the standard PCMCIA cardservices provided by the
-	  pcmcia-cs package.
-
-	  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 aironet4500_cs. If you want to
-	  compile it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-
 endmenu
 
diff -Nru a/drivers/net/pcmcia/Makefile b/drivers/net/pcmcia/Makefile
--- a/drivers/net/pcmcia/Makefile	Tue Mar  4 19:30:03 2003
+++ b/drivers/net/pcmcia/Makefile	Tue Mar  4 19:30:03 2003
@@ -13,7 +13,4 @@
 obj-$(CONFIG_ARCNET_COM20020_CS)+= com20020_cs.o
 obj-$(CONFIG_PCMCIA_AXNET)	+= axnet_cs.o
 
-# 16-bit wireless client drivers
-obj-$(CONFIG_AIRONET4500_CS)	+= aironet4500_cs.o
-
 obj-$(CONFIG_PCMCIA_IBMTR)	+= ibmtr_cs.o
diff -Nru a/drivers/net/pcmcia/aironet4500_cs.c b/drivers/net/pcmcia/aironet4500_cs.c
--- a/drivers/net/pcmcia/aironet4500_cs.c	Tue Mar  4 19:30:04 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,706 +0,0 @@
-/*
- *	 Aironet 4500 Pcmcia driver
- *
- *		Elmer Joandi, Januar 1999
- *	Copyright Elmer Joandi, all rights restricted
- *	
- *
- *	Revision 0.1 ,started  30.12.1998
- *
- *
- */
-
-#define DRV_NAME	"aironet4500_cs"
-#define DRV_VERSION	"0.1"
-
-static const char *awc_version =
-DRV_NAME ".c v" DRV_VERSION " 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
-
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/in.h>
-#include <linux/ethtool.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ioport.h>
-
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ciscode.h>
-#include <pcmcia/ds.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-#include "../aironet4500.h"
-
-static u_int irq_mask = 0x5eF8;
-static int 	awc_ports[] = {0x140,0x100,0xc0, 0x80 };
-#if LINUX_VERSION_CODE > 0x20100
-MODULE_PARM(irq_mask, "i");
-
-#endif
-
-
-#define RUN_AT(x)               (jiffies+(x))
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
-#define PC_DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"aironet4500_cs.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
-#else
-#define PC_DEBUG(n, args...)
-#endif
-
-/* Index of functions. */
-
-static dev_info_t dev_info = "aironet4500_cs";
-
-static dev_link_t *awc_attach(void);
-static void awc_detach(dev_link_t *);
-static void awc_release(u_long arg);
-static int awc_event(event_t event, int priority,
-					   event_callback_args_t *args);
-
-static dev_link_t *dev_list;
-
-static void cs_error(client_handle_t handle, int func, int ret)
-{
-#if CS_RELEASE_CODE < 0x2911
-    CardServices(ReportError, dev_info, (void *)func, (void *)ret);
-#else
-	error_info_t err = { func, ret };
-	CardServices(ReportError, handle, &err);
-#endif
-}
-
-#define CFG_CHECK(fn, args...) if (CardServices(fn, args) != 0) goto next_entry
-
-static void flush_stale_links(void)
-{
-    dev_link_t *link, *next;
-    for (link = dev_list; link; link = next) {
-	next = link->next;
-	if (link->state & DEV_STALE_LINK)
-	    awc_detach(link);
-    }
-}
-
-
-/*
-   We never need to do anything when a awc device is "initialized"
-   by the net software, because we only register already-found cards.
-*/
-
-static int awc_pcmcia_init(struct net_device *dev)
-{
-	return awc_init(dev);
-
-}
-
-static int awc_pcmcia_open(struct net_device *dev)
-{
-	dev_link_t *link;
-	int status;
-	
-	for (link = dev_list; link; link = link->next)
-		if (link->priv == dev) break;
-	if (!DEV_OK(link))
-		return -ENODEV;
-	
-	status = awc_open(dev);
-	
-	if (!status )
-		link->open++;
-	
-	return status;
-}
-
-static int awc_pcmcia_close(struct net_device *dev)
-{
-//	int ioaddr = dev->base_addr;
-	dev_link_t *link;
-	int ret;
-	
-	for (link = dev_list; link; link = link->next)
-		if (link->priv == dev) break;
-	if (link == NULL)
-		return -ENODEV;
-
-	PC_DEBUG(2, "%s: closing device.\n", dev->name);
-
-	link->open--;
-	ret = awc_close(dev);
-	
-	if (link->state & DEV_STALE_CONFIG) {
-		link->release.expires = RUN_AT( HZ/20 );
-		link->state |= DEV_RELEASE_PENDING;
-		add_timer(&link->release);
-	}
-	return ret;
-}
-
-static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
-{
-	u32 ethcmd;
-
-	/* dev_ioctl() in ../../net/core/dev.c has already checked
-	   capable(CAP_NET_ADMIN), so don't bother with that here.  */
-
-	if (get_user(ethcmd, (u32 *)useraddr))
-		return -EFAULT;
-
-	switch (ethcmd) {
-
-	case ETHTOOL_GDRVINFO: {
-		struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-		strcpy (info.driver, DRV_NAME);
-		strcpy (info.version, DRV_VERSION);
-		sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr);
-		if (copy_to_user (useraddr, &info, sizeof (info)))
-			return -EFAULT;
-		return 0;
-	}
-
-#ifdef PCMCIA_DEBUG
-	/* get message-level */
-	case ETHTOOL_GMSGLVL: {
-		struct ethtool_value edata = {ETHTOOL_GMSGLVL};
-		edata.data = pc_debug;
-		if (copy_to_user(useraddr, &edata, sizeof(edata)))
-			return -EFAULT;
-		return 0;
-	}
-	/* set message-level */
-	case ETHTOOL_SMSGLVL: {
-		struct ethtool_value edata;
-		if (copy_from_user(&edata, useraddr, sizeof(edata)))
-			return -EFAULT;
-		pc_debug = edata.data;
-		return 0;
-	}
-#endif
-
-	default:
-		break;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-static int awc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	switch (cmd) {
-	case SIOCETHTOOL:
-		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
-
-	default:
-		return -EOPNOTSUPP;
-	}
-	return 0;
-}
-
-/*
-	awc_attach() creates an "instance" of the driver, allocating
-	local data structures for one device.  The device is registered
-	with Card Services.
-*/
-
-static dev_link_t *awc_attach(void)
-{
-	client_reg_t client_reg;
-	dev_link_t *link = NULL;
-	struct net_device *dev = NULL;
-	int  ret;
-
-	PC_DEBUG(0, "awc_attach()\n");
-	flush_stale_links();
-
-	/* Create the PC card device object. */
-	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-	if (!link)
-		return NULL;
-	memset(link, 0, sizeof(struct dev_link_t));
-
-	link->dev = kmalloc(sizeof(struct dev_node_t), GFP_KERNEL);
-	if (!link->dev) {
-		kfree(link);
-		return NULL;
-	}
-
-	memset(link->dev, 0, sizeof(struct dev_node_t));
-
-	init_timer(&link->release);
-	link->release.function = &awc_release;
-	link->release.data = (u_long)link;
-//	link->io.NumPorts1 = 32;
-	link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-//	link->io.IOAddrLines = 5;
-	link->irq.Attributes = IRQ_HANDLE_PRESENT ; // |IRQ_TYPE_EXCLUSIVE  ;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-	link->irq.IRQInfo2 = irq_mask;
-	link->irq.Handler = &awc_interrupt;
-	link->conf.Attributes = CONF_ENABLE_IRQ;
-	link->conf.Vcc = 50;
-	link->conf.IntType = INT_MEMORY_AND_IO;
-	link->conf.ConfigIndex = 1;
-	link->conf.Present = PRESENT_OPTION;
-
-	/* Create the network device object. */
-
-	dev = kmalloc(sizeof(struct net_device ), GFP_KERNEL);
-//	dev =  init_etherdev(0, sizeof(struct awc_private) );
-	if (!dev ) {
-		printk(KERN_CRIT "out of mem on dev alloc \n");
-		kfree(link->dev);
-		kfree(link);
-		return NULL;
-	};
-	memset(dev,0,sizeof(struct net_device));
-	dev->priv = kmalloc(sizeof(struct awc_private), GFP_KERNEL);
-	if (!dev->priv ) {printk(KERN_CRIT "out of mem on dev priv alloc \n"); return NULL;};
-	memset(dev->priv,0,sizeof(struct awc_private));
-	
-//	link->dev->minor = dev->minor;
-//	link->dev->major = dev->major;
-
-	/* The 4500-specific entries in the device structure. */
-
-//	dev->tx_queue_len = tx_queue_len;
-
-	dev->hard_start_xmit = 		&awc_start_xmit;
-//	dev->set_config = 		&awc_config_misiganes,aga mitte awc_config;
-	dev->get_stats = 		&awc_get_stats;
-//	dev->set_multicast_list = 	&awc_set_multicast_list;
-	dev->do_ioctl =			&awc_ioctl;
-	
-	strcpy(dev->name, ((struct awc_private *)dev->priv)->node.dev_name);
-
-	ether_setup(dev);
-
-	dev->init = &awc_pcmcia_init;
-	dev->open = &awc_pcmcia_open;
-	dev->stop = &awc_pcmcia_close;
-	
-	link->priv = dev;
-#if CS_RELEASE_CODE > 0x2911
-	link->irq.Instance = dev;
-#endif
-
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	
-        
-	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-	client_reg.EventMask =
-		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-			CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-				CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-	client_reg.event_handler = &awc_event;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = CardServices(RegisterClient, &link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		awc_detach(link);
-		return NULL;
-	}
-
-	return link;
-} /* awc_attach */
-
-/*
-
-	This deletes a driver "instance".  The device is de-registered
-	with Card Services.  If it has been released, all local data
-	structures are freed.  Otherwise, the structures will be freed
-	when the device is released.
-
-*/
-
-static void awc_detach(dev_link_t *link)
-{
-	dev_link_t **linkp;
-	unsigned long flags;
-	int i=0;
-
-	DEBUG(0, "awc_detach(0x%p)\n", link);
-
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link) break;
-	if (*linkp == NULL)
-	return;
-
-	save_flags(flags);
-	cli();
-	if (link->state & DEV_RELEASE_PENDING) {
-		del_timer(&link->release);
-		link->state &= ~DEV_RELEASE_PENDING;
-	}
-	restore_flags(flags);
-
-	if (link->state & DEV_CONFIG) {
-		awc_release((u_long)link);
-		if (link->state & DEV_STALE_CONFIG) {
-			link->state |= DEV_STALE_LINK;
-			return;
-		}
-	}
-
-	if (link->handle)
-		CardServices(DeregisterClient, link->handle);
-
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
-
-	i=0;
-	while ( i < MAX_AWCS) {
-		if (!aironet4500_devices[i])
-			{i++; continue;}
-		if (aironet4500_devices[i] == link->priv){
-			if (awc_proc_unset_fun)
-				awc_proc_unset_fun(i);
-
-			aironet4500_devices[i]=0;
-		}
-		i++;
-	}
-	
-	if (link->priv) {
-		//struct net_device *dev = link->priv;
-		// dam dam damn mif (dev->priv)
-		//	kfree(dev->priv);
-		kfree(link->priv);
-	}
-	kfree(link->dev);
-	kfree(link);
-
-} /* awc_detach */
-
-/*
-
-	awc_pcmcia_config() is scheduled to run after a CARD_INSERTION event
-	is received, to configure the PCMCIA socket, and to make the
-	ethernet device available to the system.
-
-*/
-
-#define CS_CHECK(fn, args...) \
-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
-
-static void awc_pcmcia_config(dev_link_t *link)
-{
-	client_handle_t handle;
-	struct net_device *dev;
-	struct awc_private *lp;
-	tuple_t tuple;
-	int ii;
-	cisparse_t parse;
-	u_short buf[64];
-	int last_fn, last_ret, i = 0;
-//	int ioaddr;
-	u16 *phys_addr;
-	int retval;
-	
-	handle = link->handle;
-	dev = link->priv;
-	phys_addr = (u16 *)dev->dev_addr;
-
-	PC_DEBUG(0, "awc_pcmcia_config(0x%p)\n", link);
-
-	tuple.Attributes = 0;
-	tuple.DesiredTuple = CISTPL_CONFIG;
-	CS_CHECK(GetFirstTuple, handle, &tuple);
-	tuple.TupleData = (cisdata_t *)buf;
-	tuple.TupleDataMax = 64;
-	tuple.TupleOffset = 0;
-	CS_CHECK(GetTupleData, handle, &tuple);
-	CS_CHECK(ParseTuple, handle, &tuple, &parse);
-	link->conf.ConfigBase = parse.config.base;
-	link->conf.Present = parse.config.rmask[0];
-
-
-	/* Configure card */
-	link->state |= DEV_CONFIG;
-
-     	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-        CS_CHECK(GetFirstTuple, handle, &tuple);
-
-    	while (1) {
-		cistpl_cftable_entry_t dflt = { 0 };
-		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-		CFG_CHECK(GetTupleData, handle, &tuple);
-		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
-
-		if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
-		if (cfg->index == 0) goto next_entry;
-		link->conf.ConfigIndex = cfg->index;
-
-		/* Use power settings for Vcc and Vpp if present */
-		/*  Note that the CIS values need to be rescaled */
-		if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
-		    link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
-		else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
-		    link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
-	    
-		if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
-		    link->conf.Vpp1 = link->conf.Vpp2 =
-			cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
-		else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
-		    link->conf.Vpp1 = link->conf.Vpp2 =
-			dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
-	
-		/* Do we need to allocate an interrupt? */
-		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-		    link->conf.Attributes |= CONF_ENABLE_IRQ;
-	
-		/* IO window settings */
-		link->io.NumPorts1 = link->io.NumPorts2 = 0;
-		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-	    		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-	    		link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-	    		if (!(io->flags & CISTPL_IO_8BIT))
-				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-	    		if (!(io->flags & CISTPL_IO_16BIT)) {
-	    			
-				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-				printk(KERN_CRIT "8-bit IO not supported on this aironet 4500 driver \n");
-	    		}
-	    		link->io.BasePort1 = io->win[0].base;
-	    		
-	    		link->io.NumPorts1 = io->win[0].len;
-	    		if (io->nwin > 1) {
-				link->io.Attributes2 = link->io.Attributes1;
-				link->io.BasePort2 = io->win[1].base;
-				link->io.NumPorts2 = io->win[1].len;
-	    		}
-		}
-		ii = 0;
-		last_fn = RequestIO;
-		while ((last_ret = CardServices(RequestIO, link->handle, &link->io)) ){
-		
-			if (ii > 4) 
-				goto cs_failed;
-			link->io.BasePort1 = awc_ports[ii];
-			ii++;
-		};
-
-
-		break;
-	
-    	next_entry:
-		if (CardServices(GetNextTuple, handle, &tuple))
-			break;
-    	}
-    
-    	if (link->conf.Attributes & CONF_ENABLE_IRQ){
-	
-		ii = 0;  last_fn = RequestIRQ; 
-		while ((last_ret  = CardServices(RequestIRQ, link->handle, &link->irq)) ){
-		
-			ii++;	
-			while (!(irq_mask & (1 << ii) ) && ii < 15)
-			 	ii++;
-			link->irq.IRQInfo2 = 1 << ii;
-
-			if(ii > 15)
-				goto cs_failed;
-			printk("trying irq %d , mask %x \n",ii, link->irq.IRQInfo2); 
-			 
-		};
-	}
-
-    	CS_CHECK(RequestConfiguration, link->handle, &link->conf);
-
-
-    	dev->irq = link->irq.AssignedIRQ;
-    	dev->base_addr = link->io.BasePort1;
-
-
-	awc_private_init( dev);
-
-
-	
-	retval = register_netdev(dev);
-	if (retval != 0) {
-		printk(KERN_NOTICE "awc_cs: register_netdev() failed for dev %x retval %x\n",(unsigned int)dev,retval);
-		goto failed;
-	}
-
-    	if(awc_pcmcia_init(dev)) goto failed;
-
-	i=0;
-	while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
-	if (!aironet4500_devices[i]){
-		aironet4500_devices[i]=dev;
-		if (awc_proc_set_fun)
-			awc_proc_set_fun(i);
-	}
-	
-
-	link->state &= ~DEV_CONFIG_PENDING;
-
-	lp = (struct awc_private *)dev->priv;
-
-	DEBUG(1,"pcmcia config complete on port %x \n",(unsigned int)dev->base_addr);
-
-	return;
-
-cs_failed:
-	cs_error(link->handle, last_fn, last_ret);
-	link->dev=NULL;
-failed:
-
-	awc_release((u_long)link);
-	return;
-
-} /* awc_pcmcia_config */
-
-/*
-	After a card is removed, awc_release() will unregister the net
-	device, and release the PCMCIA configuration.  If the device is
-	still open, this will be postponed until it is closed.
-
-*/
-
-static void awc_release(u_long arg)
-{
-	dev_link_t *link = (dev_link_t *)arg;
-	struct net_device *dev = link->priv;
-
-	DEBUG(0, "awc_release(0x%p)\n", link);
-
-	if (link->open) {
-		DEBUG(1, "awc_cs: release postponed, '%s' still open\n",
-			  link->dev->dev_name);
-		link->state |= DEV_STALE_CONFIG;
-		return;
-	}
-
-	CardServices(ReleaseConfiguration, link->handle);
-	CardServices(ReleaseIO, link->handle, &link->io);
-	CardServices(ReleaseIRQ, link->handle, &link->irq);
-
-	CardServices(ReleaseWindow, link->win);
-	if (link->dev)
-		unregister_netdev(dev);
-	// link->dev = NULL;
-
-	link->state &= ~DEV_CONFIG;
-	if (link->state & DEV_STALE_LINK)
-		awc_detach(link);
-
-} /* awc_release */
-
-/*
-
-	The card status event handler.  Mostly, this schedules other
-	stuff to run after an event is received.  A CARD_REMOVAL event
-	also sets some flags to discourage the net drivers from trying
-	to talk to the card any more.
-*/
-
-static int awc_event(event_t event, int priority,
-					   event_callback_args_t *args)
-{
-	dev_link_t *link = args->client_data;
-	struct net_device *dev = link->priv;
-
-	PC_DEBUG(1, "awc_event(0x%06x)\n", event);
-
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(dev);
-			link->release.expires = RUN_AT( HZ/20 );
-			add_timer(&link->release);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		awc_pcmcia_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			if (link->open)
-				netif_device_detach(dev);
-
-			CardServices(ReleaseConfiguration, link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			CardServices(RequestConfiguration, link->handle, &link->conf);
-			if (link->open) {
-				// awc_reset(dev);
-				netif_device_attach(dev);
-			}
-		}
-		break;
-	}
-	return 0;
-} /* awc_event */
-
-
-        
-static int __init aironet_cs_init(void)
-{
-	servinfo_t serv;
-
-	/* Always emit the version, before any failure. */
-	printk(KERN_INFO"%s", awc_version);
-	PC_DEBUG(0, "%s\n", version);
-	CardServices(GetCardServicesInfo, &serv);
-	if (serv.Revision != CS_RELEASE_CODE) {
-		printk(KERN_NOTICE "awc_cs: Card Services release "
-			   "does not match!\n");
-		return -1;
-	}
-	register_pcmcia_driver(&dev_info, &awc_attach, &awc_detach);
-	return 0;
-}
-
-static void __exit aironet_cs_exit(void)
-{
-	DEBUG(0, "awc_cs: unloading %c ",'\n');
-	unregister_pcmcia_driver(&dev_info);
-	
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			awc_release((u_long)dev_list);
-		awc_detach(dev_list);
-	}
-	        
-//	while (dev_list != NULL)
-//		awc_detach(dev_list);
-}
-
-module_init(aironet_cs_init);
-module_exit(aironet_cs_exit);
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
--- a/drivers/net/pcmcia/axnet_cs.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/net/pcmcia/axnet_cs.c	Tue Mar  4 19:30:09 2003
@@ -1226,7 +1226,7 @@
 	/* Mask interrupts from the ethercard. 
 	   SMP: We have to grab the lock here otherwise the IRQ handler
 	   on another CPU can flip window and race the IRQ mask set. We end
-	   up trashing the mcast filter not disabling irqs if we dont lock */
+	   up trashing the mcast filter not disabling irqs if we don't lock */
 	   
 	spin_lock_irqsave(&ei_local->page_lock, flags);
 	outb_p(0x00, e8390_base + EN0_IMR);
@@ -1341,7 +1341,7 @@
  * Handle the ether interface interrupts. We pull packets from
  * the 8390 via the card specific functions and fire them at the networking
  * stack. We also handle transmit completions and wake the transmit path if
- * neccessary. We also update the counters and do other housekeeping as
+ * necessary. We also update the counters and do other housekeeping as
  * needed.
  */
 
diff -Nru a/drivers/net/pppoe.c b/drivers/net/pppoe.c
--- a/drivers/net/pppoe.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/pppoe.c	Tue Mar  4 19:30:11 2003
@@ -292,7 +292,7 @@
 
 				/* Now restart from the beginning of this
 				 * hash chain.  We always NULL out pppoe_dev
-				 * so we are guarenteed to make forward
+				 * so we are guaranteed to make forward
 				 * progress.
 				 */
 				po = item_hash_table[hash];
diff -Nru a/drivers/net/sb1000.c b/drivers/net/sb1000.c
--- a/drivers/net/sb1000.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/sb1000.c	Tue Mar  4 19:30:04 2003
@@ -170,7 +170,7 @@
 		 
 		if (pnp_device_attach(idev) < 0)
 			continue;
-		if (pnp_activate_dev(idev, NULL) < 0) {
+		if (pnp_activate_dev(idev) < 0) {
 		      __again:
 			pnp_device_detach(idev);
 			continue;
diff -Nru a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
--- a/drivers/net/sb1250-mac.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/net/sb1250-mac.c	Tue Mar  4 19:30:13 2003
@@ -512,7 +512,7 @@
  *  	   regidx = index of register to read
  *  	   
  *  Return value:
- *  	   value read, or 0 if an error occured.
+ *  	   value read, or 0 if an error occurred.
  ********************************************************************* */
 
 static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
@@ -554,7 +554,7 @@
 	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT);
 	
 	/* 
-	 * If an error occured, the PHY will signal '1' back
+	 * If an error occurred, the PHY will signal '1' back
 	 */
 	error = SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN;
 	
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/net/sis900.c	Tue Mar  4 19:30:08 2003
@@ -1971,7 +1971,7 @@
 			status = mdio_read(dev, mii_phy->phy_addr, MII_CONTROL);
                 
 			/* enable auto negotiation and reset the negotioation
-			   (I dont really know what the auto negatiotiation reset
+			   (I don't really know what the auto negatiotiation reset
 			   really means, but it sounds for me right to do one here)*/
 			mdio_write(dev, mii_phy->phy_addr,
 				   MII_CONTROL, status | MII_CNTL_AUTO | MII_CNTL_RST_AUTO);
diff -Nru a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
--- a/drivers/net/sk98lin/h/lm80.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/net/sk98lin/h/lm80.h	Tue Mar  4 19:30:13 2003
@@ -126,7 +126,7 @@
 #define LM80_IS_BTI		(1<<1)	/* state of BTI# pin */
 #define LM80_IS_FAN1		(1<<2)	/* count limit exceeded for Fan 1 */
 #define LM80_IS_FAN2		(1<<3)	/* count limit exceeded for Fan 2 */
-#define LM80_IS_CI		(1<<4)	/* Chassis Intrusion occured */
+#define LM80_IS_CI		(1<<4)	/* Chassis Intrusion occurred */
 #define LM80_IS_OS		(1<<5)	/* OS temperature limit exceeded */
 	/* bit 6 and 7 are reserved in LM80_ISRC_2 */
 #define LM80_IS_HT_IRQ_MD	(1<<6)	/* Hot temperature interrupt mode */
diff -Nru a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
--- a/drivers/net/sk98lin/h/skdrv1st.h	Tue Mar  4 19:30:03 2003
+++ b/drivers/net/sk98lin/h/skdrv1st.h	Tue Mar  4 19:30:03 2003
@@ -72,7 +72,7 @@
  * Description:
  *
  * This is the first include file of the driver, which includes all
- * neccessary system header files and some of the GEnesis header files.
+ * necessary system header files and some of the GEnesis header files.
  * It also defines some basic items.
  *
  * Include File Hierarchy:
diff -Nru a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
--- a/drivers/net/sk98lin/h/skdrv2nd.h	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/sk98lin/h/skdrv2nd.h	Tue Mar  4 19:30:14 2003
@@ -85,7 +85,7 @@
  * Description:
  *
  * This is the second include file of the driver, which includes all other
- * neccessary files and defines all structures and constants used by the
+ * necessary files and defines all structures and constants used by the
  * driver and the common modules.
  *
  * Include File Hierarchy:
diff -Nru a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
--- a/drivers/net/sk98lin/h/xmac_ii.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/net/sk98lin/h/xmac_ii.h	Tue Mar  4 19:30:13 2003
@@ -279,7 +279,7 @@
  * XMAC Bit Definitions
  *
  * If the bit access behaviour differs from the register access behaviour
- * (r/w, ro) this is docomented after the bit number. The following bit
+ * (r/w, ro) this is documented after the bit number. The following bit
  * access behaviours are used:
  *	(sc)	self clearing
  *	(ro)	read only
@@ -413,7 +413,7 @@
 #define XM_ST_BC		(1L<<7)		/* Bit	7:	Broadcast packet */
 #define XM_ST_MC		(1L<<6)		/* Bit	6:	Multicast packet */
 #define XM_ST_UC		(1L<<5)		/* Bit	5:	Unicast packet */
-#define XM_ST_TX_UR		(1L<<4)		/* Bit	4:	FIFO Underrun occured */
+#define XM_ST_TX_UR		(1L<<4)		/* Bit	4:	FIFO Underrun occurred */
 #define XM_ST_CS_ERR	(1L<<3)		/* Bit	3:	Carrier Sense Error */
 #define XM_ST_LAT_COL	(1L<<2)		/* Bit	2:	Late Collision Error */
 #define XM_ST_MUL_COL	(1L<<1)		/* Bit	1:	Multiple Collisions */
diff -Nru a/drivers/net/sk98lin/skcsum.c b/drivers/net/sk98lin/skcsum.c
--- a/drivers/net/sk98lin/skcsum.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/sk98lin/skcsum.c	Tue Mar  4 19:30:04 2003
@@ -195,7 +195,7 @@
  *	zero.)
  *
  * Note:
- *	There is a bug in the ASIC whic may lead to wrong checksums.
+ *	There is a bug in the ASIC which may lead to wrong checksums.
  *
  * Arguments:
  *	pAc - A pointer to the adapter context struct.
diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
--- a/drivers/net/sk98lin/skge.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/sk98lin/skge.c	Tue Mar  4 19:30:04 2003
@@ -3627,7 +3627,7 @@
  * Description:
  *	This routine writes a 16 bit value to the pci configuration
  *	space. The flag PciConfigUp indicates whether the config space
- *	is accesible or must be set up first.
+ *	is accessible or must be set up first.
  *
  * Returns:
  *	0 - indicate everything worked ok.
@@ -3650,7 +3650,7 @@
  * Description:
  *	This routine writes a 8 bit value to the pci configuration
  *	space. The flag PciConfigUp indicates whether the config space
- *	is accesible or must be set up first.
+ *	is accessible or must be set up first.
  *
  * Returns:
  *	0 - indicate everything worked ok.
diff -Nru a/drivers/net/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c
--- a/drivers/net/sk98lin/skgehwt.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/net/sk98lin/skgehwt.c	Tue Mar  4 19:30:13 2003
@@ -61,14 +61,14 @@
  *	fix: chg pAc -> pAC
  *	
  *	Revision 1.4  1998/08/10 14:14:52  gklug
- *	rmv: unneccessary SK_ADDR macro
+ *	rmv: unnecessary SK_ADDR macro
  *	
  *	Revision 1.3  1998/08/07 12:53:44  gklug
  *	fix: first compiled version
  *	
  *	Revision 1.2  1998/08/07 09:19:29  gklug
  *	adapt functions to the C coding conventions
- *	rmv unneccessary functions.
+ *	rmv unnecessary functions.
  *	
  *	Revision 1.1  1998/08/05 11:28:36  gklug
  *	first version: adapted from SMT/FDDI
diff -Nru a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
--- a/drivers/net/sk98lin/skgepnmi.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/sk98lin/skgepnmi.c	Tue Mar  4 19:30:11 2003
@@ -236,7 +236,7 @@
  *	-Fixed bug for RX counters. On an RX overflow interrupt the high
  *	 words of all RX counters were incremented.
  *	-SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
- *	 value 0, which has no effect. It is usefull for multiple instance
+ *	 value 0, which has no effect. It is useful for multiple instance
  *	 SETs.
  *	
  *	Revision 1.37  1998/11/20 08:02:04  mhaveman
@@ -1639,7 +1639,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
  *	                         the data.
  *	SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
@@ -1672,13 +1672,13 @@
  * Description:
  *	Calls a general sub-function for all this stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is usefull to check if a set might be successfull.
+ *	new value. This is useful to check if a set might be successful.
  *	If as instance a -1 is passed, an array of values is supposed and
  *	all instance of the OID will be set.
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -1716,13 +1716,13 @@
  * Description:
  *	Calls a general sub-function for all this stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is usefull to check if a set might be successfull.
+ *	new value. This is useful to check if a set might be successful.
  *	If as instance a -1 is passed, an array of values is supposed and
  *	all instance of the OID will be set.
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -1766,7 +1766,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
  *	                         the data.
  *	SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist 
@@ -1935,7 +1935,7 @@
  * Description:
  *	Calls a general sub-function for all this set stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is usefull to check if a set might be successfull.
+ *	new value. This is useful to check if a set might be successful.
  *	The sub-function runs through the IdTable, checks which OIDs are able
  *	to set, and calls the handler function of the OID to perform the
  *	preset. The return value of the function will also be stored in
@@ -1944,7 +1944,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -1983,7 +1983,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -2934,7 +2934,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3002,7 +3002,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3137,7 +3137,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3280,7 +3280,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3427,7 +3427,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3639,7 +3639,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -3758,7 +3758,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -4003,7 +4003,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -4482,7 +4482,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -5189,7 +5189,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -5498,7 +5498,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -5698,7 +5698,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -6362,7 +6362,7 @@
  *
  * Returns:
  *	SK_PNMI_ERR_OK           The request was successfully performed.
- *	SK_PNMI_ERR_GENERAL      A general severe internal error occured.
+ *	SK_PNMI_ERR_GENERAL      A general severe internal error occurred.
  *	SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
  *	                         the correct data (e.g. a 32bit value is
  *	                         needed, but a 16 bit value was passed).
@@ -6813,7 +6813,7 @@
  *
  * Description:
  *	The COMMON module only tells us if the mode is half or full duplex.
- *	But in the decade of auto sensing it is usefull for the user to
+ *	But in the decade of auto sensing it is useful for the user to
  *	know if the mode was negotiated or forced. Therefore we have a
  *	look to the mode, which was last used by the negotiation process.
  *
@@ -7364,7 +7364,7 @@
  *
  * Description:
  *	The trap buffer stores various events. A user application somehow
- *	gets notified that an event occured and retrieves the trap buffer
+ *	gets notified that an event occurred and retrieves the trap buffer
  *	contens (or simply polls the buffer). The buffer is organized as
  *	a ring which stores the newest traps at the beginning. The oldest
  *	traps are overwritten by the newest ones. Each trap entry has a
diff -Nru a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
--- a/drivers/net/sk98lin/skgesirq.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/net/sk98lin/skgesirq.c	Tue Mar  4 19:30:03 2003
@@ -736,14 +736,14 @@
 	/* Check whether XMACs are correctly initialized */
 	if ((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) &&
 		!pAC->GIni.GP[MAC_1].PState) {
-		/* XMAC was not initialized but Packet timeout occured */
+		/* XMAC was not initialized but Packet timeout occurred */
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
 			SKERR_SIRQ_E004MSG);
 	}
 
 	if ((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) &&
 	    !pAC->GIni.GP[MAC_2].PState) {
-		/* XMAC was not initialized but Packet timeout occured */
+		/* XMAC was not initialized but Packet timeout occurred */
 		SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
 			SKERR_SIRQ_E005MSG);
 	}
@@ -1111,7 +1111,7 @@
 			 * otherwise the Linux driver will have a problem.
 			 */
 			/*
-			 * We received a bunch of frames or no CRC error occured on the
+			 * We received a bunch of frames or no CRC error occurred on the
 			 * network -> ok.
 			 */
 			pPrt->PPrevRx = RxCts;
@@ -1379,7 +1379,7 @@
 			pPrt->PAutoNegTOCt ++;
 
 			/*
-			 * Timeout occured.
+			 * Timeout occurred.
 			 * What do we need now?
 			 */
 			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,
@@ -1389,7 +1389,7 @@
 			if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
 				pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
 				/*
-				 * Timeout occured
+				 * Timeout occurred
 				 * Set Link manually up.
 				 */
 				SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
@@ -1872,7 +1872,7 @@
 		pPrt->PAutoNegTimeOut ++;
 		if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
 			/*
-			 * Timeout occured.
+			 * Timeout occurred.
 			 * What do we need now?
 			 */
 			SK_DBG_MSG(pAC,SK_DBGMOD_HWM,
@@ -1882,7 +1882,7 @@
 			if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
 				pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
 				/*
-				 * Timeout occured
+				 * Timeout occurred
 				 * Set Link manually up.
 				 */
 				SkHWSenseSetNext(pAC, IoC, Port,
diff -Nru a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c
--- a/drivers/net/sk98lin/ski2c.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/net/sk98lin/ski2c.c	Tue Mar  4 19:30:03 2003
@@ -178,7 +178,7 @@
  *	Revision 1.2  1998/08/11 07:27:15  gklug
  *	add: functions of the interface
  *	adapt rest of source to C coding Conventions
- *	rmv: unneccessary code taken from Mona Lisa
+ *	rmv: unnecessary code taken from Mona Lisa
  *
  *	Revision 1.1  1998/06/19 14:28:43  malthoff
  *	Created. Sources taken from ML Projekt.
@@ -444,7 +444,7 @@
 /*
  * Receive an ACK.
  *
- * returns	0 If acknoledged
+ * returns	0 If acknowledged
  *		1 in case of an error
  */
 int SkI2cRcvAck(
diff -Nru a/drivers/net/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c
--- a/drivers/net/sk98lin/skqueue.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/sk98lin/skqueue.c	Tue Mar  4 19:30:05 2003
@@ -153,7 +153,7 @@
  *		send command to state machine
  *	end
  *	return error reported by individual Event function
- *		0 if no error occured.
+ *		0 if no error occurred.
  */
 int	SkEventDispatcher(
 SK_AC	*pAC,	/* Adapters Context */
diff -Nru a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
--- a/drivers/net/sk98lin/skvpd.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/net/sk98lin/skvpd.c	Tue Mar  4 19:30:10 2003
@@ -563,7 +563,7 @@
 
 /*
  *	find the Keyword 'key' in the VPD buffer and fills the
- *	parameter sturct 'p' with it's values
+ *	parameter sturct 'p' with its values
  *
  * returns	*p	success
  *		0:	parameter was not found or VPD encoding error
diff -Nru a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
--- a/drivers/net/sk98lin/skxmac2.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/sk98lin/skxmac2.c	Tue Mar  4 19:30:14 2003
@@ -596,7 +596,7 @@
  *	none, National: 80ns).
  *
  * ATTENTION:
- * 	It is absolutely neccessary to reset the SW_RST Bit first
+ * 	It is absolutely necessary to reset the SW_RST Bit first
  *	before calling this function.
  *
  * Returns:
diff -Nru a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
--- a/drivers/net/sk_mca.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/sk_mca.c	Tue Mar  4 19:30:11 2003
@@ -45,7 +45,7 @@
   May 23nd, 1999
 	can receive frames, send frames
   May 24th, 1999
-        modularized intialization of LANCE
+        modularized initialization of LANCE
         loadable as module
 	still Tx problem :-(
   May 26th, 1999
@@ -581,7 +581,7 @@
 	return GetLANCE(dev, LANCE_CSR0);
 }
 
-/* did we loose blocks due to a FIFO overrun ? */
+/* did we lose blocks due to a FIFO overrun ? */
 
 static u16 irqmiss_handler(struct SKMCA_NETDEV *dev, u16 oldcsr0)
 {
diff -Nru a/drivers/net/skfp/h/smc.h b/drivers/net/skfp/h/smc.h
--- a/drivers/net/skfp/h/smc.h	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/skfp/h/smc.h	Tue Mar  4 19:30:04 2003
@@ -320,7 +320,7 @@
 	u_char	evc_rep_required ;		/* report required */
 	u_short	evc_para ;			/* SMT Para Number */
 	u_char	*evc_cond_state ;		/* condition state */
-	u_char	*evc_multiple ;			/* multiple occurence */
+	u_char	*evc_multiple ;			/* multiple occurrence */
 } ;
 
 /*
diff -Nru a/drivers/net/skfp/hwt.c b/drivers/net/skfp/hwt.c
--- a/drivers/net/skfp/hwt.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/skfp/hwt.c	Tue Mar  4 19:30:04 2003
@@ -264,7 +264,7 @@
  * para	start		start time
  *	duration	time to wait
  *
- * NOTE: The fuction will return immediatly, if the timer is not 
+ * NOTE: The fuction will return immediately, if the timer is not 
  *	 started
  ************************/
 void hwt_wait_time(smc,start,duration)
diff -Nru a/drivers/net/slhc.c b/drivers/net/slhc.c
--- a/drivers/net/slhc.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/slhc.c	Tue Mar  4 19:30:05 2003
@@ -265,7 +265,7 @@
 
 	/*  Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or
 	 *  some other control bit is set). Also uncompressible if
-	 *  its a runt.
+	 *  it's a runt.
 	 */
 	if(hlen > isize || th->syn || th->fin || th->rst ||
 	    ! (th->ack)){
diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
--- a/drivers/net/smc-ultra.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/smc-ultra.c	Tue Mar  4 19:30:04 2003
@@ -293,7 +293,7 @@
                         /* Avoid already found cards from previous calls */
                         if (pnp_device_attach(idev) < 0)
                         	continue;
-                        if (pnp_activate_dev(idev, NULL) < 0) {
+                        if (pnp_activate_dev(idev) < 0) {
                               __again:
                         	pnp_device_detach(idev);
                         	continue;
diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c
--- a/drivers/net/sungem.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/net/sungem.c	Tue Mar  4 19:30:14 2003
@@ -2991,7 +2991,7 @@
 	gem_begin_auto_negotiation(gp, NULL);
 	spin_unlock_irq(&gp->lock);
 
-	/* It is guarenteed that the returned buffer will be at least
+	/* It is guaranteed that the returned buffer will be at least
 	 * PAGE_SIZE aligned.
 	 */
 	gp->init_block = (struct gem_init_block *)
diff -Nru a/drivers/net/sungem.h b/drivers/net/sungem.h
--- a/drivers/net/sungem.h	Tue Mar  4 19:30:09 2003
+++ b/drivers/net/sungem.h	Tue Mar  4 19:30:09 2003
@@ -562,7 +562,7 @@
  */
 
 /* Statistics Registers.  All of these registers are 16-bits and
- * track occurances of a specific event.  GEM can be configured
+ * track occurrences of a specific event.  GEM can be configured
  * to interrupt the host cpu when any of these counters overflow.
  * They should all be explicitly initialized to zero when the interface
  * is brought up.
@@ -830,7 +830,7 @@
  * RX Kick register) by the driver it must make sure the buffers are
  * truly ready and that the ownership bits are set properly.
  *
- * Even though GEM modifies the RX descriptors, it guarentees that the
+ * Even though GEM modifies the RX descriptors, it guarantees that the
  * buffer DMA address field will stay the same when it performs these
  * updates.  Therefore it can be used to keep track of DMA mappings
  * by the host driver just as in the TX descriptor case above.
diff -Nru a/drivers/net/sunhme.c b/drivers/net/sunhme.c
--- a/drivers/net/sunhme.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/sunhme.c	Tue Mar  4 19:30:05 2003
@@ -520,7 +520,7 @@
 	ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value));
 
 	/* Welcome to Sun Microsystems, can I take your order please? */
-	if (!hp->happy_flags & HFLAG_FENABLE)
+	if (!(hp->happy_flags & HFLAG_FENABLE))
 		return happy_meal_bb_write(hp, tregs, reg, value);
 
 	/* Would you like fries with that? */
@@ -1198,7 +1198,7 @@
  * (ETH_FRAME_LEN + 64 + 2) = (1514 + 64 + 2) = 1580 bytes.
  *
  * First our alloc_skb() routine aligns the data base to a 64 byte
- * boundry.  We now have 0xf001b040 as our skb data address.  We
+ * boundary.  We now have 0xf001b040 as our skb data address.  We
  * plug this into the receive descriptor address.
  *
  * Next, we skb_reserve() 2 bytes to account for the Happy Meal offset.
@@ -1651,7 +1651,7 @@
 		    hme_read32(hp, etxregs + ETX_CFG) | ETX_CFG_DMAENABLE);
 
 	/* This chip really rots, for the receiver sometimes when you
-	 * write to it's control registers not all the bits get there
+	 * write to its control registers not all the bits get there
 	 * properly.  I cannot think of a sane way to provide complete
 	 * coverage for this hardware bug yet.
 	 */
diff -Nru a/drivers/net/sunhme.h b/drivers/net/sunhme.h
--- a/drivers/net/sunhme.h	Tue Mar  4 19:30:08 2003
+++ b/drivers/net/sunhme.h	Tue Mar  4 19:30:08 2003
@@ -298,7 +298,7 @@
 #define CSCONFIG_NDISABLE       0x8000  /* Disable NRZI                */
 
 /* Happy Meal descriptor rings and such.
- * All descriptor rings must be aligned on a 2K boundry.
+ * All descriptor rings must be aligned on a 2K boundary.
  * All receive buffers must be 64 byte aligned.
  * Always write the address first before setting the ownership
  * bits to avoid races with the hardware scanning the ring.
diff -Nru a/drivers/net/sunlance.c b/drivers/net/sunlance.c
--- a/drivers/net/sunlance.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/sunlance.c	Tue Mar  4 19:30:05 2003
@@ -647,7 +647,7 @@
 	u8 *p8;
 	unsigned long pbuf = (unsigned long) piobuf;
 
-	/* We know here that both src and dest are on a 16bit boundry. */
+	/* We know here that both src and dest are on a 16bit boundary. */
 	*p16++ = sbus_readw(pbuf);
 	p32 = (u32 *) p16;
 	pbuf += 2;
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/net/tg3.c	Tue Mar  4 19:30:09 2003
@@ -25,6 +25,7 @@
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
+#include <linux/workqueue.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -54,8 +55,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.4"
-#define DRV_MODULE_RELDATE	"Feb 1, 2003"
+#define DRV_MODULE_VERSION	"1.4c"
+#define DRV_MODULE_RELDATE	"Feb 18, 2003"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -216,6 +217,12 @@
 	tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
 }
 
+static inline void tg3_cond_int(struct tg3 *tp)
+{
+	if (tp->hw_status->status & SD_STATUS_UPDATED)
+		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+}
+
 static void tg3_enable_ints(struct tg3 *tp)
 {
 	tw32(TG3PCI_MISC_HOST_CTRL,
@@ -223,9 +230,55 @@
 	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000);
 	tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
 
-	if (tp->hw_status->status & SD_STATUS_UPDATED)
-		tw32(GRC_LOCAL_CTRL,
-		     tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+	tg3_cond_int(tp);
+}
+
+/* these netif_xxx funcs should be moved into generic net layer */
+static void netif_poll_disable(struct net_device *dev)
+{
+	while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+	}
+}
+
+static inline void netif_poll_enable(struct net_device *dev)
+{
+	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+}
+
+/* same as netif_rx_complete, except that local_irq_save(flags)
+ * has already been issued
+ */
+static inline void __netif_rx_complete(struct net_device *dev)
+{
+	if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG();
+	list_del(&dev->poll_list);
+	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+}
+
+static inline void netif_tx_disable(struct net_device *dev)
+{
+	spin_lock_bh(&dev->xmit_lock);
+	netif_stop_queue(dev);
+	spin_unlock_bh(&dev->xmit_lock);
+}
+
+static inline void tg3_netif_stop(struct tg3 *tp)
+{
+	netif_poll_disable(tp->dev);
+	netif_tx_disable(tp->dev);
+}
+
+static inline void tg3_netif_start(struct tg3 *tp)
+{
+	netif_wake_queue(tp->dev);
+	/* NOTE: unconditional netif_wake_queue is only appropriate
+	 * so long as all callers are assured to have free tx slots
+	 * (such as after tg3_init_hw)
+	 */
+	netif_poll_enable(tp->dev);
+	tg3_cond_int(tp);
 }
 
 static void tg3_switch_clocks(struct tg3 *tp)
@@ -387,7 +440,6 @@
 }
 
 static int tg3_setup_phy(struct tg3 *);
-static int tg3_halt(struct tg3 *);
 
 static int tg3_set_power_state(struct tg3 *tp, int state)
 {
@@ -458,8 +510,6 @@
 		tg3_setup_phy(tp);
 	}
 
-	tg3_halt(tp);
-
 	pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps);
 
 	if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
@@ -2044,7 +2094,12 @@
 		spin_unlock(&tp->tx_lock);
 	}
 
-	/* run RX thread, within the bounds set by NAPI */
+	spin_unlock_irqrestore(&tp->lock, flags);
+
+	/* run RX thread, within the bounds set by NAPI.
+	 * All RX "locking" is done by ensuring outside
+	 * code synchronizes with dev->poll()
+	 */
 	done = 1;
 	if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) {
 		int orig_budget = *budget;
@@ -2064,12 +2119,12 @@
 
 	/* if no more work, tell net stack and NIC we're done */
 	if (done) {
-		netif_rx_complete(netdev);
+		spin_lock_irqsave(&tp->lock, flags);
+		__netif_rx_complete(netdev);
 		tg3_enable_ints(tp);
+		spin_unlock_irqrestore(&tp->lock, flags);
 	}
 
-	spin_unlock_irqrestore(&tp->lock, flags);
-
 	return (done ? 0 : 1);
 }
 
@@ -2136,17 +2191,21 @@
 
 static void tg3_init_rings(struct tg3 *);
 static int tg3_init_hw(struct tg3 *);
+static int tg3_halt(struct tg3 *);
 
-static void tg3_tx_timeout(struct net_device *dev)
+static void tg3_reset_task(void *_data)
 {
-	struct tg3 *tp = dev->priv;
+	struct tg3 *tp = _data;
+	unsigned int restart_timer;
 
-	printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
-	       dev->name);
+	tg3_netif_stop(tp);
 
 	spin_lock_irq(&tp->lock);
 	spin_lock(&tp->tx_lock);
 
+	restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
+	tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
+
 	tg3_halt(tp);
 	tg3_init_rings(tp);
 	tg3_init_hw(tp);
@@ -2154,7 +2213,20 @@
 	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
-	netif_wake_queue(dev);
+	tg3_netif_start(tp);
+
+	if (restart_timer)
+		mod_timer(&tp->timer, jiffies + 1);
+}
+
+static void tg3_tx_timeout(struct net_device *dev)
+{
+	struct tg3 *tp = dev->priv;
+
+	printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
+	       dev->name);
+
+	schedule_work(&tp->reset_task);
 }
 
 #if !PCI_DMA_BUS_IS_PHYS
@@ -2194,7 +2266,7 @@
 	int i;
 
 #if !PCI_DMA_BUS_IS_PHYS
-	/* IOMMU, just map the guilty area again which is guarenteed to
+	/* IOMMU, just map the guilty area again which is guaranteed to
 	 * use different addresses.
 	 */
 
@@ -2229,7 +2301,7 @@
 		return -1;
 	}
 
-	/* New SKB is guarenteed to be linear. */
+	/* New SKB is guaranteed to be linear. */
 	entry = *start;
 	new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
 				  PCI_DMA_TODEVICE);
@@ -2686,6 +2758,7 @@
 		return 0;
 	}
 
+	tg3_netif_stop(tp);
 	spin_lock_irq(&tp->lock);
 	spin_lock(&tp->tx_lock);
 
@@ -2698,6 +2771,7 @@
 
 	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
+	tg3_netif_start(tp);
 
 	return 0;
 }
@@ -3073,6 +3147,7 @@
 static void tg3_chip_reset(struct tg3 *tp)
 {
 	u32 val;
+	u32 flags_save;
 
 	/* Force NVRAM to settle.
 	 * This deals with a chip bug which can result in EEPROM
@@ -3089,8 +3164,21 @@
 		}
 	}
 
+	/*
+	 * We must avoid the readl() that normally takes place.
+	 * It locks machines, causes machine checks, and other
+	 * fun things.  So, temporarily disable the 5701
+	 * hardware workaround, while we do the reset.
+	 */
+	flags_save = tp->tg3_flags;
+	tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG;
+
+	/* do the reset */
 	tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET);
 
+	/* restore 5701 hardware bug workaround flag */
+	tp->tg3_flags = flags_save;
+
 	/* Flush PCI posted writes.  The normal MMIO registers
 	 * are inaccessible at this time so this is the only
 	 * way to make this reliably.  I tried to use indirect
@@ -3303,7 +3391,7 @@
 	0x00000000
 };
 
-#if 0 /* All zeros, dont eat up space with it. */
+#if 0 /* All zeros, don't eat up space with it. */
 u32 tg3FwData[(TG3_FW_DATA_LEN / sizeof(u32)) + 1] = {
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000
@@ -3736,7 +3824,7 @@
 	0x00000000
 };
 
-#if 0 /* All zeros, dont eat up space with it. */
+#if 0 /* All zeros, don't eat up space with it. */
 u32 tg3TsoFwData[] = {
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000
@@ -4394,9 +4482,11 @@
 	}
 
 	if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
-		tg3_halt(tp);
-		tg3_init_rings(tp);
-		tg3_init_hw(tp);
+		tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
+		spin_unlock(&tp->tx_lock);
+		spin_unlock_irqrestore(&tp->lock, flags);
+		schedule_work(&tp->reset_task);
+		return;
 	}
 
 	/* This part only runs once per second. */
@@ -4527,8 +4617,6 @@
 		return err;
 	}
 
-	netif_start_queue(dev);
-
 	spin_lock_irq(&tp->lock);
 	spin_lock(&tp->tx_lock);
 
@@ -4537,6 +4625,8 @@
 	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
+	netif_start_queue(dev);
+
 	return 0;
 }
 
@@ -5302,6 +5392,7 @@
 		    (ering.tx_pending > TG3_TX_RING_SIZE - 1))
 			return -EINVAL;
 
+		tg3_netif_stop(tp);
 		spin_lock_irq(&tp->lock);
 		spin_lock(&tp->tx_lock);
 
@@ -5315,6 +5406,7 @@
 		netif_wake_queue(tp->dev);
 		spin_unlock(&tp->tx_lock);
 		spin_unlock_irq(&tp->lock);
+		tg3_netif_start(tp);
 
 		return 0;
 	}
@@ -5337,6 +5429,7 @@
 		if (copy_from_user(&epause, useraddr, sizeof(epause)))
 			return -EFAULT;
 
+		tg3_netif_stop(tp);
 		spin_lock_irq(&tp->lock);
 		spin_lock(&tp->tx_lock);
 		if (epause.autoneg)
@@ -5356,6 +5449,7 @@
 		tg3_init_hw(tp);
 		spin_unlock(&tp->tx_lock);
 		spin_unlock_irq(&tp->lock);
+		tg3_netif_start(tp);
 
 		return 0;
 	}
@@ -5941,7 +6035,7 @@
 
 	/* Force memory write invalidate off.  If we leave it on,
 	 * then on 5700_BX chips we have to enable a workaround.
-	 * The workaround is to set the TG3PCI_DMA_RW_CTRL boundry
+	 * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary
 	 * to match the cacheline size.  The Broadcom driver have this
 	 * workaround but turns MWI off all the times so never uses
 	 * it.  This seems to suggest that the workaround is insufficient.
@@ -6710,6 +6804,7 @@
 	spin_lock_init(&tp->lock);
 	spin_lock_init(&tp->tx_lock);
 	spin_lock_init(&tp->indirect_lock);
+	PREPARE_WORK(&tp->reset_task, tg3_reset_task, tp);
 
 	tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
 	if (tp->regs == 0UL) {
@@ -6851,6 +6946,8 @@
 	if (!netif_running(dev))
 		return 0;
 
+	tg3_netif_stop(tp);
+
 	spin_lock_irq(&tp->lock);
 	spin_lock(&tp->tx_lock);
 	tg3_disable_ints(tp);
@@ -6877,6 +6974,7 @@
 		spin_unlock_irq(&tp->lock);
 
 		netif_device_attach(dev);
+		tg3_netif_start(tp);
 	}
 
 	return err;
@@ -6906,6 +7004,8 @@
 
 	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
+
+	tg3_netif_start(tp);
 
 	return 0;
 }
diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h
--- a/drivers/net/tg3.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/tg3.h	Tue Mar  4 19:30:05 2003
@@ -1821,6 +1821,8 @@
 #define TG3_FLAG_GOT_SERDES_FLOWCTL	0x20000000
 #define TG3_FLAG_SPLIT_MODE		0x40000000
 #define TG3_FLAG_INIT_COMPLETE		0x80000000
+	u32				tg3_flags2;
+#define TG3_FLG2_RESTART_TIMER		0x00000001
 
 	u32				split_mode_max_reqs;
 #define SPLIT_MODE_5704_MAX_REQ		3
@@ -1889,6 +1891,7 @@
 
 	struct tg3_hw_stats		*hw_stats;
 	dma_addr_t			stats_mapping;
+	struct work_struct		reset_task;
 };
 
 #endif /* !(_T3_H) */
diff -Nru a/drivers/net/tlan.c b/drivers/net/tlan.c
--- a/drivers/net/tlan.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/tlan.c	Tue Mar  4 19:30:04 2003
@@ -1630,7 +1630,7 @@
 	 *		host_int	The contents of the HOST_INT
 	 *				port.
 	 *
-	 *	This driver is structured to determine EOC occurances by
+	 *	This driver is structured to determine EOC occurrences by
 	 *	reading the CSTAT member of the list structure.  Tx EOC
 	 *	interrupts are disabled via the DIO INTDIS register.
 	 *	However, TLAN chips before revision 3.0 didn't have this
@@ -1753,7 +1753,7 @@
 	 *		host_int	The contents of the HOST_INT
 	 *				port.
 	 *
-	 *	This driver is structured to determine EOC occurances by
+	 *	This driver is structured to determine EOC occurrences by
 	 *	reading the CSTAT member of the list structure.  Rx EOC
 	 *	interrupts are disabled via the DIO INTDIS register.
 	 *	However, TLAN chips before revision 3.0 didn't have this
@@ -2399,7 +2399,7 @@
 	 *		dev	A pointer to the device structure of the
 	 *			TLAN device having the PHYs to be detailed.
 	 *				
-	 *	This function prints the registers a PHY (aka tranceiver).
+	 *	This function prints the registers a PHY (aka transceiver).
 	 *
 	 ********************************************************************/
 
@@ -2515,7 +2515,7 @@
 
 	/* Wait for 50 ms and powerup
 	 * This is abitrary.  It is intended to make sure the
-	 * tranceiver settles.
+	 * transceiver settles.
 	 */
 	TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP );
 
@@ -2535,7 +2535,7 @@
 	TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
 	TLan_MiiSync(dev->base_addr);
 	/* Wait for 500 ms and reset the
-	 * tranceiver.  The TLAN docs say both 50 ms and
+	 * transceiver.  The TLAN docs say both 50 ms and
 	 * 500 ms, so do the longer, just in case.
 	 */
 	TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET );
@@ -2650,7 +2650,7 @@
         	TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
 	}
 
-	/* Wait for 2 sec to give the tranceiver time
+	/* Wait for 2 sec to give the transceiver time
 	 * to establish link.
 	 */
 	TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET );
diff -Nru a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
--- a/drivers/net/tokenring/lanstreamer.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/tokenring/lanstreamer.c	Tue Mar  4 19:30:14 2003
@@ -542,7 +542,7 @@
 
 	writew(readw(streamer_mmio + LAPWWO) + 6, streamer_mmio + LAPA);
 	if (readw(streamer_mmio + LAPD)) {
-		printk(KERN_INFO "tokenring card intialization failed. errorcode : %x\n",
+		printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n",
 		       ntohs(readw(streamer_mmio + LAPD)));
 		release_region(dev->base_addr, STREAMER_IO_SPACE);
 		return -1;
diff -Nru a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
--- a/drivers/net/tokenring/madgemc.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/net/tokenring/madgemc.c	Tue Mar  4 19:30:13 2003
@@ -80,7 +80,7 @@
 static void madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 /*
- * These work around paging, however they dont guarentee you're on the
+ * These work around paging, however they don't guarentee you're on the
  * right page.
  */
 #define SIFREADB(reg) (inb(dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
diff -Nru a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
--- a/drivers/net/tokenring/olympic.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/net/tokenring/olympic.c	Tue Mar  4 19:30:12 2003
@@ -384,7 +384,7 @@
 }
 #endif	
 	if(readw(init_srb+6)) {
-		printk(KERN_INFO "tokenring card intialization failed. errorcode : %x\n",readw(init_srb+6));
+		printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n",readw(init_srb+6));
 		return -ENODEV;
 	}
 
diff -Nru a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
--- a/drivers/net/tokenring/smctr.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/net/tokenring/smctr.c	Tue Mar  4 19:30:08 2003
@@ -417,7 +417,7 @@
         tp->tx_buff_end[BUG_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
 
         /* Allocate MAC receive data buffers.
-         * MAC Rx buffer doesn't have to be on a 256 byte boundry.
+         * MAC Rx buffer doesn't have to be on a 256 byte boundary.
          */
         tp->rx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev,
                 RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]);
@@ -438,7 +438,7 @@
          * To guarantee a minimum of 256 contigous memory to
          * UM_Receive_Packet's lookahead pointer, before a page
          * change or ring end is encountered, place each rx buffer on
-         * a 256 byte boundry.
+         * a 256 byte boundary.
          */
         smctr_malloc(dev, TO_256_BYTE_BOUNDRY(tp->sh_mem_used));
         tp->rx_buff_head[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev,
@@ -1331,7 +1331,7 @@
         mem_used += tp->tx_buff_size[BUG_QUEUE];
 
         /* Allocate MAC receive data buffers.
-         * MAC receive buffers don't have to be on a 256 byte boundry.
+         * MAC receive buffers don't have to be on a 256 byte boundary.
          */
         mem_used += RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE];
 
@@ -1348,7 +1348,7 @@
          *
          * Make sure the mem_used offset at this point is the
          * same as in allocate_shared memory or the following
-         * boundry adjustment will be incorrect (i.e. not allocating
+         * boundary adjustment will be incorrect (i.e. not allocating
          * the non-mac receive buffers above cannot change the 256
          * byte offset).
          *
@@ -3930,7 +3930,7 @@
         return (err);
 }
 
-/* Adapter RAM test. Incremental word ODD boundry data test. */
+/* Adapter RAM test. Incremental word ODD boundary data test. */
 static int smctr_ram_memory_test(struct net_device *dev)
 {
         struct net_local *tp = (struct net_local *)dev->priv;
@@ -3947,7 +3947,7 @@
         pages_of_ram    = tp->ram_size / tp->ram_usable;
         pword           = tp->ram_access;
 
-        /* Incremental word ODD boundry test. */
+        /* Incremental word ODD boundary test. */
         for(page = 0; (page < pages_of_ram) && (~err);
                 page++, start_pattern += 0x8000)
         {
@@ -5598,7 +5598,7 @@
                 /* if all transmit buffer are cleared
                  * need to set the tx_buff_curr[] to tx_buff_head[]
                  * otherwise, tx buffer will be segregate and cannot
-                 * accomodate and buffer greater than (curr - head) and
+                 * accommodate and buffer greater than (curr - head) and
                  * (end - curr) since we do not allow wrap around allocation.
                  */
                 if(tp->tx_buff_used[queue] == 0)
diff -Nru a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
--- a/drivers/net/tulip/interrupt.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/tulip/interrupt.c	Tue Mar  4 19:30:05 2003
@@ -487,7 +487,7 @@
 				 * to the 21142/3 docs that is).
 				 *   -- rmk
 				 */
-				printk(KERN_ERR "%s: (%lu) System Error occured (%d)\n",
+				printk(KERN_ERR "%s: (%lu) System Error occurred (%d)\n",
 					dev->name, tp->nir, error);
 			}
 			/* Clear all error sources, included undocumented ones! */
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/net/tulip/tulip_core.c	Tue Mar  4 19:30:10 2003
@@ -1306,7 +1306,7 @@
 
 	/* Intel Saturn. Switch to 8 long words burst, 8 long word cache aligned
 	   Aries might need this too. The Saturn errata are not pretty reading but
-	   thankfully its an old 486 chipset.
+	   thankfully it's an old 486 chipset.
 	*/
 
 	if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, NULL)) {
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/tulip/winbond-840.c	Tue Mar  4 19:30:05 2003
@@ -597,7 +597,7 @@
 #define mdio_delay(mdio_addr) readl(mdio_addr)
 
 /* Set iff a MII transceiver on any interface requires mdio preamble.
-   This only set with older tranceivers, so the extra
+   This only set with older transceivers, so the extra
    code size of a per-interface flag is not worthwhile. */
 static char mii_preamble_required = 1;
 
diff -Nru a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
--- a/drivers/net/tulip/xircom_cb.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/net/tulip/xircom_cb.c	Tue Mar  4 19:30:12 2003
@@ -121,7 +121,7 @@
 static void investigate_read_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset);
 static void investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsigned int bufferoffset);
 static void read_mac_address(struct xircom_private *card);
-static void tranceiver_voodoo(struct xircom_private *card);
+static void transceiver_voodoo(struct xircom_private *card);
 static void initialize_card(struct xircom_private *card);
 static void trigger_transmit(struct xircom_private *card);
 static void trigger_receive(struct xircom_private *card);
@@ -301,7 +301,7 @@
 	
 	/* start the transmitter to get a heartbeat */
 	/* TODO: send 2 dummy packets here */
-	tranceiver_voodoo(private);
+	transceiver_voodoo(private);
 	
 	spin_lock_irqsave(&private->lock,flags);
 	  activate_transmitter(private);
@@ -1116,15 +1116,15 @@
 
 
 /*
- tranceiver_voodoo() enables the external UTP plug thingy.
+ transceiver_voodoo() enables the external UTP plug thingy.
  it's called voodoo as I stole this code and cannot cross-reference
  it with the specification.
  */
-static void tranceiver_voodoo(struct xircom_private *card)
+static void transceiver_voodoo(struct xircom_private *card)
 {
 	unsigned long flags;
 
-	enter("tranceiver_voodoo");
+	enter("transceiver_voodoo");
 
 	/* disable all powermanagement */
 	pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);
@@ -1143,7 +1143,7 @@
         spin_unlock_irqrestore(&card->lock, flags);
 
 	netif_start_queue(card->dev);
-	leave("tranceiver_voodoo");
+	leave("transceiver_voodoo");
 }
 
 
diff -Nru a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c
--- a/drivers/net/tulip/xircom_tulip_cb.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/tulip/xircom_tulip_cb.c	Tue Mar  4 19:30:04 2003
@@ -486,7 +486,7 @@
 
 /*
  * To quote Arjan van de Ven:
- *   tranceiver_voodoo() enables the external UTP plug thingy.
+ *   transceiver_voodoo() enables the external UTP plug thingy.
  *   it's called voodoo as I stole this code and cannot cross-reference
  *   it with the specification.
  * Actually it seems to go like this:
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/via-rhine.c	Tue Mar  4 19:30:14 2003
@@ -108,11 +108,18 @@
 	- New reset code uses "force reset" cmd on Rhine-II
 	- Various clean ups
 
+	LK1.1.17 (Roger Luethi)
+	- Fix race in via_rhine_start_tx()
+	- On errors, wait for Tx engine to turn off before scavenging
+	- Handle Tx descriptor write-back race on Rhine-II
+	- Force flushing for PCI posted writes
+	- More reset code changes
+
 */
 
 #define DRV_NAME	"via-rhine"
-#define DRV_VERSION	"1.1.16"
-#define DRV_RELDATE	"February-15-2003"
+#define DRV_VERSION	"1.1.17"
+#define DRV_RELDATE	"March-1-2003"
 
 
 /* A few user-configurable values.
@@ -132,7 +139,7 @@
    Both 'options[]' and 'full_duplex[]' should exist for driver
    interoperability.
    The media type is usually passed in 'options[]'.
-   The default is autonegotation for speed and duplex.
+   The default is autonegotiation for speed and duplex.
      This should rarely be overridden.
    Use option values 0x10/0x20 for 10Mbps, 0x100,0x200 for 100Mbps.
    Use option values 0x10 and 0x100 for forcing half duplex fixed speed.
@@ -368,6 +375,8 @@
 #else
 #define RHINE_IOTYPE (PCI_USES_IO  | PCI_USES_MASTER | PCI_ADDR0)
 #endif
+/* Beware of PCI posted writes */
+#define IOSYNC	do { readb(dev->base_addr + StationAddr); } while (0)
 
 /* directly indexed by enum via_rhine_chips, above */
 static struct via_rhine_chip_info via_rhine_chip_info[] __devinitdata =
@@ -403,7 +412,8 @@
 	MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
 	ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
 	RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
-	StickyHW=0x83, WOLcrClr=0xA4, WOLcgClr=0xA7, PwrcsrClr=0xAC,
+	StickyHW=0x83, IntrStatus2=0x84, WOLcrClr=0xA4, WOLcgClr=0xA7,
+	PwrcsrClr=0xAC,
 };
 
 /* Bits in ConfigD */
@@ -430,6 +440,8 @@
 	IntrTxAborted=0x2000, IntrLinkChange=0x4000,
 	IntrRxWakeUp=0x8000,
 	IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260,
+	IntrTxDescRace=0x080000,	/* mapped from IntrStatus2 */
+	IntrTxErrSummary=0x082210,
 };
 
 /* The Rx and Tx buffer descriptors. */
@@ -527,14 +539,28 @@
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int  via_rhine_close(struct net_device *dev);
 
+static inline u32 get_intr_status(struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
+	u32 intr_status;
+
+	intr_status = readw(ioaddr + IntrStatus);
+	/* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
+	if (np->chip_id == VT6102)
+		intr_status |= readb(ioaddr + IntrStatus2) << 16;
+	return intr_status;
+}
+
 static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
 {
 	long ioaddr = dev->base_addr;
+	int boguscnt = 20;
 
-	udelay(5);
+	IOSYNC;
 
 	if (readw(ioaddr + ChipCmd) & CmdReset) {
-		printk(KERN_INFO "%s: Reset did not complete in 5 us. "
+		printk(KERN_INFO "%s: Reset not complete yet. "
 			"Trying harder.\n", name);
 
 		/* Rhine-II needs to be forced sometimes */
@@ -543,12 +569,14 @@
 
 		/* VT86C100A may need long delay after reset (dlink) */
 		/* Seen on Rhine-II as well (rl) */
-		udelay(100);
+		while ((readw(ioaddr + ChipCmd) & CmdReset) && --boguscnt)
+			udelay(5);
+
 	}
 
 	if (debug > 1)
 		printk(KERN_INFO "%s: Reset %s.\n", name,
-			(readw(ioaddr + ChipCmd) & CmdReset) ? "failed" : "succeeded");
+			boguscnt ? "succeeded" : "failed");
 }
 
 #ifdef USE_MEM
@@ -1226,6 +1254,7 @@
 {
 	struct netdev_private *np = dev->priv;
 	unsigned entry;
+	u32 intr_status;
 
 	/* Caution: the write order is important here, set the field
 	   with the "ownership" bits last. */
@@ -1275,8 +1304,15 @@
 
 	/* Non-x86 Todo: explicitly flush cache lines here. */
 
-	/* Wake the potentially-idle transmit channel. */
-	writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+	/*
+	 * Wake the potentially-idle transmit channel unless errors are
+	 * pending (the ISR must sort them out first).
+	 */
+	intr_status = get_intr_status(dev);
+	if ((intr_status & IntrTxErrSummary) == 0) {
+		writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+	}
+	IOSYNC;
 
 	if (np->cur_tx == np->dirty_tx + TX_QUEUE_LEN)
 		netif_stop_queue(dev);
@@ -1303,38 +1339,51 @@
 
 	ioaddr = dev->base_addr;
 	
-	while ((intr_status = readw(ioaddr + IntrStatus))) {
+	while ((intr_status = get_intr_status(dev))) {
 		/* Acknowledge all of the current interrupt sources ASAP. */
+		if (intr_status & IntrTxDescRace)
+			writeb(0x08, ioaddr + IntrStatus2);
 		writew(intr_status & 0xffff, ioaddr + IntrStatus);
+		IOSYNC;
 
 		if (debug > 4)
-			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
+			printk(KERN_DEBUG "%s: Interrupt, status %8.8x.\n",
 				   dev->name, intr_status);
 
 		if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped |
 						   IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf))
 			via_rhine_rx(dev);
 
-		if (intr_status & (IntrTxDone | IntrTxError | IntrTxUnderrun |
-						   IntrTxAborted))
+		if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
+			if (intr_status & IntrTxErrSummary) {
+				int cnt = 20;
+				/* Avoid scavenging before Tx engine turned off */
+				while ((readw(ioaddr+ChipCmd) & CmdTxOn) && --cnt)
+					udelay(5);
+				if (debug > 2 && !cnt)
+					printk(KERN_WARNING "%s: via_rhine_interrupt() "
+						   "Tx engine still on.\n",
+						   dev->name);
+			}
 			via_rhine_tx(dev);
+		}
 
 		/* Abnormal error summary/uncommon events handlers. */
 		if (intr_status & (IntrPCIErr | IntrLinkChange |
 				   IntrStatsMax | IntrTxError | IntrTxAborted |
-				   IntrTxUnderrun))
+				   IntrTxUnderrun | IntrTxDescRace))
 			via_rhine_error(dev, intr_status);
 
 		if (--boguscnt < 0) {
 			printk(KERN_WARNING "%s: Too much work at interrupt, "
-				   "status=0x%4.4x.\n",
+				   "status=%#8.8x.\n",
 				   dev->name, intr_status);
 			break;
 		}
 	}
 
 	if (debug > 3)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%4.4x.\n",
+		printk(KERN_DEBUG "%s: exiting interrupt, status=%8.8x.\n",
 			   dev->name, readw(ioaddr + IntrStatus));
 }
 
@@ -1512,7 +1561,8 @@
 	}
 
 	/* Pre-emptively restart Rx engine. */
-	writew(CmdRxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+	writew(readw(dev->base_addr + ChipCmd) | CmdRxOn | CmdRxDemand,
+		   dev->base_addr + ChipCmd);
 }
 
 /* Clears the "tally counters" for CRC errors and missed frames(?).
@@ -1526,15 +1576,35 @@
 	readw(ioaddr + RxMissed);
 }
 
-static inline void via_rhine_restart_tx(struct net_device *dev) {
+static void via_rhine_restart_tx(struct net_device *dev) {
 	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
 	int entry = np->dirty_tx % TX_RING_SIZE;
+	u32 intr_status;
 
-	/* We know better than the chip where it should continue */
-	writel(np->tx_ring_dma + entry * sizeof(struct tx_desc),
-		   dev->base_addr + TxRingPtr);
+	/*
+	 * If new errors occured, we need to sort them out before doing Tx.
+	 * In that case the ISR will be back here RSN anyway.
+	 */
+	intr_status = get_intr_status(dev);
+
+	if ((intr_status & IntrTxErrSummary) == 0) {
+
+		/* We know better than the chip where it should continue. */
+		writel(np->tx_ring_dma + entry * sizeof(struct tx_desc),
+			   ioaddr + TxRingPtr);
+
+		writew(CmdTxDemand | np->chip_cmd, ioaddr + ChipCmd);
+		IOSYNC;
+	}
+	else {
+		/* This should never happen */
+		if (debug > 1)
+			printk(KERN_WARNING "%s: via_rhine_restart_tx() "
+				   "Another error occured %8.8x.\n",
+				   dev->name, intr_status);
+	}
 
-	writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
 }
 
 static void via_rhine_error(struct net_device *dev, int intr_status)
@@ -1564,9 +1634,8 @@
 	}
 	if (intr_status & IntrTxAborted) {
 		if (debug > 1)
-			printk(KERN_INFO "%s: Abort %4.4x, frame dropped.\n",
+			printk(KERN_INFO "%s: Abort %8.8x, frame dropped.\n",
 				   dev->name, intr_status);
-		via_rhine_restart_tx(dev);
 	}
 	if (intr_status & IntrTxUnderrun) {
 		if (np->tx_thresh < 0xE0)
@@ -1575,15 +1644,21 @@
 			printk(KERN_INFO "%s: Transmitter underrun, Tx "
 				   "threshold now %2.2x.\n",
 				   dev->name, np->tx_thresh);
-		via_rhine_restart_tx(dev);
 	}
+	if (intr_status & IntrTxDescRace) {
+		if (debug > 2)
+			printk(KERN_INFO "%s: Tx descriptor write-back race.\n",
+				   dev->name);
+	}
+	if (intr_status & ( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace ))
+		via_rhine_restart_tx(dev);
+
 	if (intr_status & ~( IntrLinkChange | IntrStatsMax | IntrTxUnderrun |
- 						 IntrTxError | IntrTxAborted | IntrNormalSummary)) {
+ 						 IntrTxError | IntrTxAborted | IntrNormalSummary |
+						 IntrTxDescRace )) {
 		if (debug > 1)
-			printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
-			   dev->name, intr_status);
-		/* Recovery for other fault sources not known. */
-		writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+			printk(KERN_ERR "%s: Something Wicked happened! %8.8x.\n",
+				   dev->name, intr_status);
 	}
 
 	spin_unlock (&np->lock);
diff -Nru a/drivers/net/wan/comx-hw-munich.c b/drivers/net/wan/comx-hw-munich.c
--- a/drivers/net/wan/comx-hw-munich.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/wan/comx-hw-munich.c	Tue Mar  4 19:30:05 2003
@@ -1304,7 +1304,7 @@
 		ch = (struct comx_channel *)dev->priv;
 		hw = (struct slicecom_privdata *)ch->HW_privdata;
 
-		/* We dont trust the "Tx available" info from the TIQ, but check        */
+		/* We don't trust the "Tx available" info from the TIQ, but check        */
 		/* every ring if there is some free room                                        */
 
 		if (ch->init_status && netif_running(dev))
diff -Nru a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
--- a/drivers/net/wan/dlci.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/net/wan/dlci.c	Tue Mar  4 19:30:09 2003
@@ -14,7 +14,7 @@
  *		0.15	Mike Mclagan	Packet freeing, bug in kmalloc call
  *					DLCI_RET handling
  *		0.20	Mike McLagan	More conservative on which packets
- *					are returned for retry and whic are
+ *					are returned for retry and which are
  *					are dropped.  If DLCI_RET_DROP is
  *					returned from the FRAD, the packet is
  *				 	sent back to Linux for re-transmission
diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
--- a/drivers/net/wan/dscc4.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/wan/dscc4.c	Tue Mar  4 19:30:05 2003
@@ -47,7 +47,7 @@
  * Tx direction
  * When the tx ring is full, the xmit routine issues a call to netdev_stop.
  * The device is supposed to be enabled again during an ALLS irq (we could
- * use HI but as it's easy to loose events, it's fscked).
+ * use HI but as it's easy to lose events, it's fscked).
  *
  * Rx direction
  * The received frames aren't supposed to span over multiple receiving areas.
diff -Nru a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
--- a/drivers/net/wan/hostess_sv11.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/wan/hostess_sv11.c	Tue Mar  4 19:30:11 2003
@@ -55,13 +55,13 @@
  
 static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
 {
-	/* Drop the CRC - its not a good idea to try and negotiate it ;) */
+	/* Drop the CRC - it's not a good idea to try and negotiate it ;) */
 	skb_trim(skb, skb->len-2);
 	skb->protocol=__constant_htons(ETH_P_WAN_PPP);
 	skb->mac.raw=skb->data;
 	skb->dev=c->netdevice;
 	/*
-	 *	Send it to the PPP layer. We dont have time to process
+	 *	Send it to the PPP layer. We don't have time to process
 	 *	it right now.
 	 */
 	netif_rx(skb);
diff -Nru a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
--- a/drivers/net/wan/lmc/lmc_main.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/wan/lmc/lmc_main.c	Tue Mar  4 19:30:05 2003
@@ -1024,7 +1024,7 @@
 }
 
 
-/* This is the entry point.  This is what is called immediatly. */
+/* This is the entry point.  This is what is called immediately. */
 /* This goes out and finds the card */
 
 int lmc_probe_fake(struct net_device *dev) /*fold00*/
@@ -2149,7 +2149,7 @@
         /* owned by 21140 */
         sc->lmc_rxring[i].status = 0x80000000;
 
-        /* used to be PKT_BUF_SZ now uses skb since we loose some to head room */
+        /* used to be PKT_BUF_SZ now uses skb since we lose some to head room */
         sc->lmc_rxring[i].length = skb->end - skb->data;
 
         /* use to be tail which is dumb since you're thinking why write
diff -Nru a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
--- a/drivers/net/wan/sbni.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/net/wan/sbni.c	Tue Mar  4 19:30:07 2003
@@ -684,7 +684,7 @@
 
 		/*
 		 * if CRC is right but framelen incorrect then transmitter
-		 * error was occured... drop entire packet
+		 * error was occurred... drop entire packet
 		 */
 		else if( (frame_ok = skip_tail( dev->base_addr, framelen, crc ))
 			 != 0 )
diff -Nru a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c
--- a/drivers/net/wan/sdla_chdlc.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/net/wan/sdla_chdlc.c	Tue Mar  4 19:30:08 2003
@@ -3529,7 +3529,7 @@
 					card->devname);
 		}else{ 
 			/* IP addresses are the same and the link is up, 
-                         * we dont have to do anything here. Therefore, exit */
+                         * we don't have to do anything here. Therefore, exit */
 			return 0;
 		}
 	}
diff -Nru a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
--- a/drivers/net/wan/sdla_fr.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/wan/sdla_fr.c	Tue Mar  4 19:30:14 2003
@@ -107,7 +107,7 @@
 *                                  the if clause for it(0,dev->tbusy) 
 *				   forever.
 *				   The code got into this stage due to an 
-*				   interrupt occuring within the if clause for 
+*				   interrupt occurring within the if clause for 
 *				   set_bit(0,dev->tbusy).  Since an interrupt 
 *				   disables furhter transmit interrupt and 
 * 				   makes dev->tbusy = 0, this effect was undone 
@@ -1726,7 +1726,7 @@
 
 
 /*============================================================================
- * Setup so that a frame can be transmitted on the occurence of a transmit
+ * Setup so that a frame can be transmitted on the occurrence of a transmit
  * interrupt.
  */
 static int setup_for_delayed_transmit (netdevice_t* dev, struct sk_buff *skb)
@@ -2071,7 +2071,7 @@
 			++card->statistics.isr_intr_test;
 	    		break;	
 
-                case FR_INTR_DLC: /* Event interrupt occured */
+                case FR_INTR_DLC: /* Event interrupt occurred */
 			mbox->cmd.command = FR_READ_STATUS;
 			mbox->cmd.length = 0;
 			err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
@@ -2747,7 +2747,7 @@
 		return 1;
 	}
 
-	/* If we get here, its an IPX-data packet so it'll get passed up the 
+	/* If we get here, it's an IPX-data packet so it'll get passed up the 
 	 * stack.
 	 * switch the network numbers 
 	 */
diff -Nru a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c
--- a/drivers/net/wan/sdla_ppp.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/wan/sdla_ppp.c	Tue Mar  4 19:30:05 2003
@@ -2004,7 +2004,7 @@
 					(unsigned long)card->u.p.txbuf, *card->u.p.txbuf_next,
 					(unsigned long)card->rxmb, *card->u.p.rxbuf_next);
 
-				/* Tell timer interrupt that PPP event occured */
+				/* Tell timer interrupt that PPP event occurred */
 				ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT;
 				flags->imask |= PPP_INTR_TIMER;
 
@@ -2221,7 +2221,7 @@
 
 		return 1;
 	} else {
-		//If we get here's its an IPX-data packet, so it'll get passed up the stack.
+		//If we get here it's an IPX-data packet, so it'll get passed up the stack.
 
 		//switch the network numbers
 		switch_net_numbers(sendpacket, network_number, 1);	
@@ -3418,7 +3418,7 @@
 					card->devname);
 		}else{ 
 			/* IP addresses are the same and the link is up, 
-                         * we dont have to do anything here. Therefore, exit */
+                         * we don't have to do anything here. Therefore, exit */
 			return 0;
 		}
 	}
diff -Nru a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c
--- a/drivers/net/wan/sdla_x25.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/wan/sdla_x25.c	Tue Mar  4 19:30:11 2003
@@ -1598,7 +1598,7 @@
 }
 
 /*============================================================================
- * Setup so that a frame can be transmitted on the occurence of a transmit
+ * Setup so that a frame can be transmitted on the occurrence of a transmit
  * interrupt.
  *===========================================================================*/
 
@@ -3064,7 +3064,7 @@
 
 		/* Bug Fix: Mar 14 2000
                  * The Protocol violation error conditions were  
-                 * not handeled previously */
+                 * not handled previously */
 
 		switch (mb->cmd.pktType & 0x7F){
 
@@ -3178,7 +3178,7 @@
  *	   when clearing a call because protocol encapsulation is not 
  *	   supported.
  *	4. If an incoming call is received while a call request is 
- *	   pending (i.e. call collision has occured), the incoming call 
+ *	   pending (i.e. call collision has occurred), the incoming call 
  *	   shall be rejected and call request shall be retried.
  *====================================================================*/
 
@@ -4088,7 +4088,7 @@
 
 		return 1;
 	} else {
-		/*If we get here its an IPX-data packet, so it'll get passed up the stack.
+		/*If we get here it's an IPX-data packet, so it'll get passed up the stack.
 		 */
 		/* switch the network numbers */
 		switch_net_numbers(sendpacket, network_number, 1);	
diff -Nru a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c
--- a/drivers/net/wan/sdlamain.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/net/wan/sdlamain.c	Tue Mar  4 19:30:12 2003
@@ -38,7 +38,7 @@
 *				replaced it with 'wandev->enable_tx_int'. 
 * May 29, 1997	Jaspreet Singh	Flow Control Problem
 *				added "wandev->tx_int_enabled=1" line in the
-*				init module. This line intializes the flag for 
+*				init module. This line initializes the flag for 
 *				preventing Interrupt disabled with device set to
 *				busy
 * Jan 15, 1997	Gene Kozin	Version 3.1.0
@@ -434,7 +434,7 @@
 	}
 
 	/* If the current card has already been configured
-         * or its a piggyback card, do not try to allocate
+         * or it's a piggyback card, do not try to allocate
          * resources.
 	 */
 	if (!card->wandev.piggyback && !card->configured){
diff -Nru a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
--- a/drivers/net/wan/sealevel.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/net/wan/sealevel.c	Tue Mar  4 19:30:10 2003
@@ -56,13 +56,13 @@
  
 static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb)
 {
-	/* Drop the CRC - its not a good idea to try and negotiate it ;) */
+	/* Drop the CRC - it's not a good idea to try and negotiate it ;) */
 	skb_trim(skb, skb->len-2);
 	skb->protocol=htons(ETH_P_WAN_PPP);
 	skb->mac.raw=skb->data;
 	skb->dev=c->netdevice;
 	/*
-	 *	Send it to the PPP layer. We dont have time to process
+	 *	Send it to the PPP layer. We don't have time to process
 	 *	it right now.
 	 */
 	netif_rx(skb);
diff -Nru a/drivers/net/wan/wanpipe_multppp.c b/drivers/net/wan/wanpipe_multppp.c
--- a/drivers/net/wan/wanpipe_multppp.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/wan/wanpipe_multppp.c	Tue Mar  4 19:30:14 2003
@@ -2283,7 +2283,7 @@
 
 	Intr_test_counter = 0;
 
-	/* The critical flag is unset because during intialization (if_open) 
+	/* The critical flag is unset because during initialization (if_open) 
 	 * we want the interrupts to be enabled so that when the wpc_isr is
 	 * called it does not exit due to critical flag set.
 	 */ 
diff -Nru a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
--- a/drivers/net/wan/z85230.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/wan/z85230.c	Tue Mar  4 19:30:04 2003
@@ -1634,7 +1634,7 @@
 			write_zsreg(c, R0, RES_Rx_CRC);
 		}
 		else
-			/* Can't occur as we dont reenable the DMA irq until
+			/* Can't occur as we don't reenable the DMA irq until
 			   after the flip is done */
 			printk(KERN_WARNING "%s: DMA flip overrun!\n", c->netdevice->name);
 			
diff -Nru a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
--- a/drivers/net/wireless/Kconfig	Tue Mar  4 19:30:05 2003
+++ b/drivers/net/wireless/Kconfig	Tue Mar  4 19:30:05 2003
@@ -6,13 +6,13 @@
 	depends on NETDEVICES
 
 config NET_RADIO
-	bool "Wireless LAN (non-hamradio)"
+	bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions"
 	---help---
 	  Support for wireless LANs and everything having to do with radio,
 	  but not with amateur radio or FM broadcasting.
 
 	  Saying Y here also enables the Wireless Extensions (creates
-	  /proc/net/wireless and enables ifconfig access). The Wireless
+	  /proc/net/wireless and enables iwconfig access). The Wireless
 	  Extension is a generic API allowing a driver to expose to the user
 	  space configuration and statistics specific to common Wireless LANs.
 	  The beauty of it is that a single set of tool can support all the
@@ -28,6 +28,11 @@
 	  special kernel support are available from
 	  <ftp://shadow.cabi.net/pub/Linux/>.
 
+# Note : the cards are obsolete (can't buy them anymore), but the drivers
+# are not, as people are still using them...
+comment "Obsolete Wireless cards support (pre-802.11)"
+	depends on NET_RADIO && (INET || ISA || PCMCIA)
+
 config STRIP
 	tristate "STRIP (Metricom starmode radio IP)"
 	depends on NET_RADIO && INET
@@ -68,10 +73,6 @@
 	  On some computers the card ends up in non-valid state after some
 	  time. Use a ping-reset script to clear it.
 
-comment "Wireless ISA/PCI cards support"
-	depends on NET_RADIO && (ISA || PCI || ALL_PPC || PCMCIA)
-
-# Good old obsolete Wavelan.
 config WAVELAN
 	tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support"
 	depends on NET_RADIO && ISA
@@ -102,7 +103,54 @@
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
-# 802.11b cards
+config PCMCIA_WAVELAN
+	tristate "AT&T/Lucent old WaveLAN Pcmcia wireless support"
+	depends on NET_RADIO && PCMCIA
+	help
+	  Say Y here if you intend to attach an AT&T/Lucent Wavelan PCMCIA
+	  (PC-card) wireless Ethernet networking card to your computer.  This
+	  driver is for the non-IEEE-802.11 Wavelan cards.
+
+	  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 wavelan_cs.  If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+	  If unsure, say N.
+
+config PCMCIA_NETWAVE
+	tristate "Xircom Netwave AirSurfer Pcmcia wireless support"
+	depends on NET_RADIO && PCMCIA
+	help
+	  Say Y here if you intend to attach this type of PCMCIA (PC-card)
+	  wireless Ethernet networking card to your computer.
+
+	  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 netwave_cs.  If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+	  If unsure, say N.
+
+comment "Wireless 802.11 Frequency Hopping cards support"
+	depends on NET_RADIO && PCMCIA
+
+config PCMCIA_RAYCS
+	tristate "Aviator/Raytheon 2.4MHz wireless support"
+	depends on NET_RADIO && PCMCIA
+	---help---
+	  Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
+	  (PC-card) wireless Ethernet networking card to your computer.
+	  Please read the file <file:Documentation/networking/ray_cs.txt> for
+	  details.
+
+	  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 ray_cs.  If you want to compile it as a
+	  module, say M here and read <file:Documentation/modules.txt>.  If
+	  unsure, say N.
+
+comment "Wireless 802.11b ISA/PCI cards support"
+	depends on NET_RADIO && (ISA || PCI || ALL_PPC || PCMCIA)
+
 config AIRO
 	tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
 	depends on NET_RADIO && (ISA || PCI)
@@ -175,41 +223,12 @@
 	  this variety.
 
 # If Pcmcia is compiled in, offer Pcmcia cards...
-comment "Wireless Pcmcia/Cardbus cards support"
-	depends on NET_RADIO && PCMCIA
-
-# Obsolete cards
-config PCMCIA_NETWAVE
-	tristate "Xircom Netwave AirSurfer Pcmcia wireless support"
-	depends on NET_RADIO && PCMCIA
-	help
-	  Say Y here if you intend to attach this type of PCMCIA (PC-card)
-	  wireless Ethernet networking card to your computer.
-
-	  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 netwave_cs.  If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-	  If unsure, say N.
-
-config PCMCIA_WAVELAN
-	tristate "AT&T/Lucent old Wavelan Pcmcia wireless support"
+comment "Wireless 802.11b Pcmcia/Cardbus cards support"
 	depends on NET_RADIO && PCMCIA
-	help
-	  Say Y here if you intend to attach an AT&T/Lucent Wavelan PCMCIA
-	  (PC-card) wireless Ethernet networking card to your computer.  This
-	  driver is for the non-IEEE-802.11 Wavelan cards.
 
-	  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 wavelan_cs.  If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-	  If unsure, say N.
-
-# 802.11b cards
 config PCMCIA_HERMES
 	tristate "Hermes PCMCIA card support"
-	depends on PCMCIA!=n && HERMES
+	depends on NET_RADIO && PCMCIA && HERMES
 	---help---
 	  A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
 	  as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -248,34 +267,6 @@
 	  Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
 	  for location).  You also want to check out the PCMCIA-HOWTO,
 	  available from <http://www.linuxdoc.org/docs.html#howto>.
-
-config NET_PCMCIA_RADIO
-	bool "PCMCIA Wireless LAN"
-	depends on NET_PCMCIA
-	help
-	  Say Y here if you would like to use a PCMCIA (PC-card) device to
-	  connect to a wireless local area network. Then say Y to the driver
-	  for your particular card below.
-
-	  To use your PC-cards, you will need supporting software from David
-	  Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
-	  for location). You also want to check out the PCMCIA-HOWTO,
-	  available from <http://www.linuxdoc.org/docs.html#howto>.
-
-config PCMCIA_RAYCS
-	tristate "Aviator/Raytheon 2.4MHz wireless support"
-	depends on NET_PCMCIA_RADIO && PCMCIA
-	---help---
-	  Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
-	  (PC-card) wireless Ethernet networking card to your computer.
-	  Please read the file <file:Documentation/networking/ray_cs.txt> for
-	  details.
-
-	  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 ray_cs.  If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt>.  If
-	  unsure, say N.
 
 # yes, this works even when no drivers are selected
 config NET_WIRELESS
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/net/wireless/airo.c	Tue Mar  4 19:30:04 2003
@@ -970,7 +970,7 @@
 	int open;
 	struct net_device             *dev;
 	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
-	   use the high bit to mark wether it is in use. */
+	   use the high bit to mark whether it is in use. */
 #define MAX_FIDS 6
 	int                           fids[MAX_FIDS];
 	int registered;
@@ -2213,7 +2213,7 @@
 	/* Enable the interrupts */
 	OUT4500( ai, EVINTEN, STATUS_INTS );
 	/* Note there is a race condition between the last two lines that
-	   I dont know how to get rid of right now... */
+	   I don't know how to get rid of right now... */
 }
 
 static void disable_interrupts( struct airo_info *ai ) {
@@ -5126,7 +5126,7 @@
 	Resp rsp;
 
 	/* Note : you may have realised that, as this is a SET operation,
-	 * this is priviledged and therefore a normal user can't
+	 * this is privileged and therefore a normal user can't
 	 * perform scanning.
 	 * This is not an error, while the device perform scanning,
 	 * traffic doesn't flow, so it's a perfect DoS...
@@ -5816,7 +5816,7 @@
 			break;
 		}
 
-		/* Seperate R/W functions bracket legality here
+		/* Separate R/W functions bracket legality here
 		 */
 		if ( com.command <= AIROGMICSTATS )
 			rc = readrids(dev,&com);
diff -Nru a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c
--- a/drivers/net/wireless/arlan-proc.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/net/wireless/arlan-proc.c	Tue Mar  4 19:30:09 2003
@@ -79,7 +79,7 @@
 		case 0xFB:
 			return "ERROR BackBone failure ";
 		case 0xFA:
-			return "ERROR tranceiver not found ";
+			return "ERROR transceiver not found ";
 		case 0xF9:
 			return "ERROR no more address space ";
 		case 0xF8:
diff -Nru a/drivers/net/wireless/arlan.c b/drivers/net/wireless/arlan.c
--- a/drivers/net/wireless/arlan.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/net/wireless/arlan.c	Tue Mar  4 19:30:10 2003
@@ -567,7 +567,7 @@
 				break;
 			times++;
 		}
-		/* if long command, we wont repeat trying */ ;
+		/* if long command, we won't repeat trying */ ;
 		if (priv->card_polling_interval > 1)
 			break;
 		times++;
diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/net/wireless/orinoco.c	Tue Mar  4 19:30:14 2003
@@ -117,7 +117,7 @@
  *	o Init of priv->tx_rate_ctrl in firmware specific section.
  *	o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
  *	o Spectrum card always need cor_reset (for every reset)
- *	o Fix cor_reset to not loose bit 7 in the register
+ *	o Fix cor_reset to not lose bit 7 in the register
  *	o flush_stale_links to remove zombie Pcmcia instances
  *	o Ack previous hermes event before reset
  *		Me (with my little hands)
@@ -4166,7 +4166,7 @@
 	e = create_proc_read_entry("buf", S_IFREG | S_IRUGO,
 					       priv->dir_dev, orinoco_proc_get_hermes_buf, priv);
 	if (! e) {
-		printk(KERN_ERR "Unable to intialize /proc/hermes/%s/buf\n", dev->name);
+		printk(KERN_ERR "Unable to initialize /proc/hermes/%s/buf\n", dev->name);
 		goto fail;
 	}
 
diff -Nru a/drivers/net/wireless/todo.txt b/drivers/net/wireless/todo.txt
--- a/drivers/net/wireless/todo.txt	Tue Mar  4 19:30:11 2003
+++ b/drivers/net/wireless/todo.txt	Tue Mar  4 19:30:11 2003
@@ -2,28 +2,14 @@
 	-------------
 
 1) Bring other kernel Wireless LAN drivers here
-	Already done :
-	 o hermes.c/orinoco.c	-> Wavelan IEEE driver + Airport driver
-	 o airo.c/airo_cs.c	-> Ben's Aironet driver
-	 o wavelan.c		-> old Wavelan ISA driver
-	 o wavelan_cs.c		-> old Wavelan Pcmcia driver
-	 o netwave_cs.c		-> Netwave Pcmcia driver
-	Drivers likely to go :
-	 o ray_cs.c		-> Raytheon/Aviator driver (maintainer MIA)
-	Drivers I have absolutely no control over :
-	 o arlan.c		-> old Aironet Arlan 655 (need to ask Elmer)
-	 o aironet4500_xxx.c	-> Elmer's Aironet driver (need to ask Elmer)
-	 o strip.c		-> Metricom's stuff. Not a wlan. Hum...
-
-	ETA : Kernel 2.5.X
+	Completed
 
 2) Bring new Wireless LAN driver not yet in the kernel there
 	See my web page for details
+	In particular : HostAP
 
 3) Misc
 	o Mark wavelan, wavelan_cs, netwave_cs drivers as obsolete
 	o Maybe arlan.c, ray_cs.c and strip.c also deserve to be obsolete
-	o Use new Probe/module stuff in wavelan.c
-	o New Wireless Extension API (pending)
 
 	Jean II
diff -Nru a/drivers/net/wireless/wavelan_cs.h b/drivers/net/wireless/wavelan_cs.h
--- a/drivers/net/wireless/wavelan_cs.h	Tue Mar  4 19:30:10 2003
+++ b/drivers/net/wireless/wavelan_cs.h	Tue Mar  4 19:30:10 2003
@@ -60,7 +60,7 @@
 /* The detection of the wavelan card is made by reading the MAC address
  * from the card and checking it. If you have a non AT&T product (OEM,
  * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this
- * part to accomodate your hardware...
+ * part to accommodate your hardware...
  */
 const unsigned char	MAC_ADDRESSES[][3] =
 {
diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
--- a/drivers/parisc/ccio-dma.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/parisc/ccio-dma.c	Tue Mar  4 19:30:05 2003
@@ -924,7 +924,7 @@
 			** can't change. And we need the offset from the first
 			** chunk - not the last one. Ergo Successive chunks
 			** must start on page boundaries and dove tail
-			** with it's predecessor.
+			** with its predecessor.
 			*/
 			sg_dma_len(vcontig_sg) = vcontig_len;
 
diff -Nru a/drivers/parisc/dino.c b/drivers/parisc/dino.c
--- a/drivers/parisc/dino.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/parisc/dino.c	Tue Mar  4 19:30:04 2003
@@ -755,7 +755,7 @@
 
 	/*
 	** This enables DINO to generate interrupts when it sees
-	** any of it's inputs *change*. Just asserting an IRQ
+	** any of its inputs *change*. Just asserting an IRQ
 	** before it's enabled (ie unmasked) isn't good enough.
 	*/
 	gsc_writel(eim, dino_dev->hba.base_addr+DINO_IAR0);
diff -Nru a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
--- a/drivers/parisc/sba_iommu.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/parisc/sba_iommu.c	Tue Mar  4 19:30:12 2003
@@ -1114,7 +1114,7 @@
 
 /*
 ** Two address ranges are DMA contiguous *iff* "end of prev" and
-** "start of next" are both on a page boundry.
+** "start of next" are both on a page boundary.
 **
 ** (shift left is a quick trick to mask off upper bits)
 */
@@ -1219,7 +1219,7 @@
 			** can't change. And we need the offset from the first
 			** chunk - not the last one. Ergo Successive chunks
 			** must start on page boundaries and dove tail
-			** with it's predecessor.
+			** with its predecessor.
 			*/
 			sg_dma_len(vcontig_sg) = vcontig_len;
 
diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
--- a/drivers/parport/parport_pc.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/parport/parport_pc.c	Tue Mar  4 19:30:14 2003
@@ -35,7 +35,7 @@
  * All registers are 8 bits wide and read/write.  If your hardware differs
  * only in register addresses (eg because your registers are on 32-bit
  * word boundaries) then you can alter the constants in parport_pc.h to
- * accomodate this.
+ * accommodate this.
  *
  * Note that the ECP registers may not start at offset 0x400 for PCI cards,
  * but rather will start at port->base_hi.
@@ -422,7 +422,7 @@
 			status = inb (STATUS (port));
 			if (status & 0x01) {
 				/* EPP timeout should never occur... */
-				printk (KERN_DEBUG "%s: EPP timeout occured while talking to "
+				printk (KERN_DEBUG "%s: EPP timeout occurred while talking to "
 					"w91284pic (should not have done)\n", port->name);
 				clear_epp_timeout (port);
 			}
diff -Nru a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
--- a/drivers/pci/hotplug.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/pci/hotplug.c	Tue Mar  4 19:30:13 2003
@@ -10,6 +10,7 @@
 #define DBG(x...)
 #endif
 
+static void pci_free_resources(struct pci_dev *dev);
 
 #ifdef CONFIG_HOTPLUG
 int pci_hotplug (struct device *dev, char **envp, int num_envp,
@@ -185,7 +186,13 @@
 {
 	if (pci_dev_driver(dev))
 		return -EBUSY;
-	pci_remove_device(dev);
+	device_unregister(&dev->dev);
+	list_del(&dev->bus_list);
+	list_del(&dev->global_list);
+	pci_free_resources(dev);
+#ifdef CONFIG_PROC_FS
+	pci_proc_detach_device(dev);
+#endif
 	return 0;
 }
 EXPORT_SYMBOL(pci_remove_device_safe);
@@ -233,15 +240,33 @@
 }
 
 /**
- * pci_remove_device - remove a pci device
+ * pci_remove_bus_device - remove a PCI device and any children
  * @dev: the device to remove
  *
- * Delete the device structure from the device lists,
- * remove the /proc entry, and notify userspace (/sbin/hotplug).
+ * Remove a PCI device from the device lists, informing the drivers
+ * that the device has been removed.  We also remove any subordinate
+ * buses and children in a depth-first manner.
+ *
+ * For each device we remove, delete the device structure from the
+ * device lists, remove the /proc entry, and notify userspace
+ * (/sbin/hotplug).
  */
-void
-pci_remove_device(struct pci_dev *dev)
+void pci_remove_bus_device(struct pci_dev *dev)
 {
+	if (dev->subordinate) {
+		struct pci_bus *b = dev->subordinate;
+
+		pci_remove_behind_bridge(dev);
+
+#ifdef CONFIG_PROC_FS
+		pci_proc_detach_bus(b);
+#endif
+
+		list_del(&b->node);
+		kfree(b);
+		dev->subordinate = NULL;
+	}
+
 	device_unregister(&dev->dev);
 	list_del(&dev->bus_list);
 	list_del(&dev->global_list);
@@ -249,9 +274,33 @@
 #ifdef CONFIG_PROC_FS
 	pci_proc_detach_device(dev);
 #endif
+
+	kfree(dev);
+}
+
+/**
+ * pci_remove_behind_bridge - remove all devices behind a PCI bridge
+ * @dev: PCI bridge device
+ *
+ * Remove all devices on the bus, except for the parent bridge.
+ * This also removes any child buses, and any devices they may
+ * contain in a depth-first manner.
+ */
+void pci_remove_behind_bridge(struct pci_dev *dev)
+{
+	struct list_head *l, *n;
+
+	if (dev->subordinate) {
+		list_for_each_safe(l, n, &dev->subordinate->devices) {
+			struct pci_dev *dev = pci_dev_b(l);
+
+			pci_remove_bus_device(dev);
+		}
+	}
 }
 
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pci_insert_device);
-EXPORT_SYMBOL(pci_remove_device);
+EXPORT_SYMBOL(pci_remove_bus_device);
+EXPORT_SYMBOL(pci_remove_behind_bridge);
 #endif
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/pci/probe.c	Tue Mar  4 19:30:11 2003
@@ -609,6 +609,7 @@
 	}
 	return b;
 }
+EXPORT_SYMBOL(pci_scan_bus_parented);
 
 EXPORT_SYMBOL(pci_devices);
 EXPORT_SYMBOL(pci_root_buses);
diff -Nru a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
--- a/drivers/pcmcia/cardbus.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/pcmcia/cardbus.c	Tue Mar  4 19:30:05 2003
@@ -90,7 +90,7 @@
 #define PCDATA_INDICATOR	0x0015
 
 typedef struct cb_config_t {
-	struct pci_dev dev;
+	struct pci_dev *dev[8];
 } cb_config_t;
 
 /*=====================================================================
@@ -178,7 +178,7 @@
 	if (!s->cb_config)
 		goto fail;
 
-	dev = &s->cb_config[0].dev;
+	dev = s->cb_config->dev[0];
 
 	/* Config space? */
 	if (space == 0) {
@@ -248,14 +248,25 @@
 	}
 	s->functions = fn;
 
-	c = kmalloc(fn * sizeof(struct cb_config_t), GFP_ATOMIC);
+	c = kmalloc(sizeof(struct cb_config_t), GFP_ATOMIC);
 	if (!c)
 		return CS_OUT_OF_RESOURCE;
-	memset(c, 0, fn * sizeof(struct cb_config_t));
+ 	memset(c, 0, sizeof(struct cb_config_t));
+
+	for (i = 0; i < fn; i++) {
+		c->dev[i] = kmalloc(sizeof(struct pci_dev), GFP_ATOMIC);
+		if (!c->dev[i]) {
+			for (; i--; )
+				kfree(c->dev[i]);
+			kfree(c);
+			return CS_OUT_OF_RESOURCE;
+		}
+		memset(c->dev[i], 0, sizeof(struct pci_dev));
+	}
 
 	irq = s->cap.pci_irq;
 	for (i = 0; i < fn; i++) {
-		struct pci_dev *dev = &c[i].dev;
+		struct pci_dev *dev = c->dev[i];
 		u8 irq_pin;
 		int r;
 
@@ -309,11 +320,8 @@
 	cb_config_t *c = s->cb_config;
 
 	if (c) {
-		int i;
-
 		s->cb_config = NULL;
-		for (i = 0 ; i < s->functions ; i++)
-			pci_remove_device(&c[i].dev);
+		pci_remove_behind_bridge(s->cap.cb_dev);
 
 		kfree(c);
 		printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
@@ -347,7 +355,7 @@
 
 	/* Set up PCI interrupt and command registers */
 	for (i = 0; i < s->functions; i++) {
-		dev = &s->cb_config[i].dev;
+		dev = s->cb_config->dev[i];
 		pci_write_config_byte(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
 				      PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
@@ -356,7 +364,7 @@
 
 	if (s->irq.AssignedIRQ) {
 		for (i = 0; i < s->functions; i++) {
-			dev = &s->cb_config[i].dev;
+			dev = s->cb_config->dev[i];
 			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
 					      s->irq.AssignedIRQ);
 		}
diff -Nru a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
--- a/drivers/pcmcia/i82365.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/pcmcia/i82365.c	Tue Mar  4 19:30:13 2003
@@ -846,7 +846,7 @@
 	
 	    printk("PNP ");
 	    
-	    if (pnp_activate_dev(dev, NULL) < 0) {
+	    if (pnp_activate_dev(dev) < 0) {
 		printk("activate failed\n");
 		pnp_device_detach(dev);
 		break;
diff -Nru a/drivers/pcmcia/sa1100.h b/drivers/pcmcia/sa1100.h
--- a/drivers/pcmcia/sa1100.h	Tue Mar  4 19:30:10 2003
+++ b/drivers/pcmcia/sa1100.h	Tue Mar  4 19:30:10 2003
@@ -150,6 +150,7 @@
  */
 #define SA1100_PCMCIA_POLL_PERIOD    (2*HZ)
 
+struct pcmcia_low_level;
 
 /* This structure encapsulates per-socket state which we might need to
  * use when responding to a Card Services query of some kind.
@@ -158,6 +159,8 @@
   /*
    * Core PCMCIA state
    */
+  int			nr;
+  struct resource	res;
   socket_state_t        cs_state;
   pccard_io_map         io_map[MAX_IO_WIN];
   pccard_mem_map        pc_mem_map[MAX_WIN];
@@ -173,6 +176,9 @@
    * Info from low level handler
    */
   unsigned int          irq;
+  unsigned int		irq_state;
+
+  struct pcmcia_low_level *ops;
 };
 
 
@@ -189,61 +195,55 @@
 /*
  * Declaration for all machine specific init/exit functions.
  */
-extern int pcmcia_adsbitsy_init(void);
-extern void pcmcia_adsbitsy_exit(void);
-
-extern int pcmcia_assabet_init(void);
-extern void pcmcia_assabet_exit(void);
-
-extern int pcmcia_badge4_init(void);
-extern void pcmcia_badge4_exit(void);
+extern int pcmcia_adsbitsy_init(struct device *);
+extern void pcmcia_adsbitsy_exit(struct device *);
 
-extern int pcmcia_cerf_init(void);
-extern void pcmcia_cerf_exit(void);
+extern int pcmcia_assabet_init(struct device *);
+extern void pcmcia_assabet_exit(struct device *);
 
-extern int pcmcia_flexanet_init(void);
-extern void pcmcia_flexanet_exit(void);
+extern int pcmcia_badge4_init(struct device *);
+extern void pcmcia_badge4_exit(struct device *);
 
-extern int pcmcia_freebird_init(void);
-extern void pcmcia_freebird_exit(void);
+extern int pcmcia_cerf_init(struct device *);
+extern void pcmcia_cerf_exit(struct device *);
 
-extern int pcmcia_gcplus_init(void);
-extern void pcmcia_gcplus_exit(void);
+extern int pcmcia_flexanet_init(struct device *);
+extern void pcmcia_flexanet_exit(struct device *);
 
-extern int pcmcia_graphicsmaster_init(void);
-extern void pcmcia_graphicsmaster_exit(void);
+extern int pcmcia_freebird_init(struct device *);
+extern void pcmcia_freebird_exit(struct device *);
 
-extern int pcmcia_jornada720_init(void);
-extern void pcmcia_jornada720_exit(void);
+extern int pcmcia_gcplus_init(struct device *);
+extern void pcmcia_gcplus_exit(struct device *);
 
-extern int pcmcia_neponset_init(void);
-extern void pcmcia_neponset_exit(void);
+extern int pcmcia_graphicsmaster_init(struct device *);
+extern void pcmcia_graphicsmaster_exit(struct device *);
 
-extern int pcmcia_pangolin_init(void);
-extern void pcmcia_pangolin_exit(void);
+extern int pcmcia_pangolin_init(struct device *);
+extern void pcmcia_pangolin_exit(struct device *);
 
-extern int pcmcia_pfs168_init(void);
-extern void pcmcia_pfs168_exit(void);
+extern int pcmcia_pfs168_init(struct device *);
+extern void pcmcia_pfs168_exit(struct device *);
 
-extern int pcmcia_shannon_init(void);
-extern void pcmcia_shannon_exit(void);
+extern int pcmcia_shannon_init(struct device *);
+extern void pcmcia_shannon_exit(struct device *);
 
-extern int pcmcia_simpad_init(void);
-extern void pcmcia_simpad_exit(void);
+extern int pcmcia_simpad_init(struct device *);
+extern void pcmcia_simpad_exit(struct device *);
 
-extern int pcmcia_stork_init(void);
-extern void pcmcia_stork_exit(void);
+extern int pcmcia_stork_init(struct device *);
+extern void pcmcia_stork_exit(struct device *);
 
-extern int pcmcia_system3_init(void);
-extern void pcmcia_system3_exit(void);
+extern int pcmcia_system3_init(struct device *);
+extern void pcmcia_system3_exit(struct device *);
 
-extern int pcmcia_trizeps_init(void);
-extern void pcmcia_trizeps_exit(void);
+extern int pcmcia_trizeps_init(struct device *);
+extern void pcmcia_trizeps_exit(struct device *);
 
-extern int pcmcia_xp860_init(void);
-extern void pcmcia_xp860_exit(void);
+extern int pcmcia_xp860_init(struct device *);
+extern void pcmcia_xp860_exit(struct device *);
 
-extern int pcmcia_yopy_init(void);
-extern void pcmcia_yopy_exit(void);
+extern int pcmcia_yopy_init(struct device *);
+extern void pcmcia_yopy_exit(struct device *);
 
 #endif  /* !defined(_PCMCIA_SA1100_H) */
diff -Nru a/drivers/pcmcia/sa1100_adsbitsy.c b/drivers/pcmcia/sa1100_adsbitsy.c
--- a/drivers/pcmcia/sa1100_adsbitsy.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/pcmcia/sa1100_adsbitsy.c	Tue Mar  4 19:30:14 2003
@@ -9,8 +9,10 @@
  * 7/5/01 Woojung Huh <whuh@applieddata.net>
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -34,12 +36,12 @@
 }
 
 static int
-adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+adsbitsy_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int pa_dwr_mask, pa_dwr_set;
   int ret;
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
 
@@ -71,7 +73,7 @@
     return -1;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -84,25 +86,25 @@
 }
 
 static struct pcmcia_low_level adsbitsy_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= adsbitsy_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= adsbitsy_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_adsbitsy_init(void)
+int __init pcmcia_adsbitsy_init(struct device *dev)
 {
 	int ret = -ENODEV;
 	if (machine_is_adsbitsy())
-		ret = sa1100_register_pcmcia(&adsbitsy_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&adsbitsy_pcmcia_ops, dev);
 	return ret;
 }
 
-void __exit pcmcia_adsbitsy_exit(void)
+void __exit pcmcia_adsbitsy_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&adsbitsy_pcmcia_ops);
+	sa1100_unregister_pcmcia(&adsbitsy_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
--- a/drivers/pcmcia/sa1100_assabet.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/pcmcia/sa1100_assabet.c	Tue Mar  4 19:30:12 2003
@@ -5,9 +5,11 @@
  *
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -31,18 +33,18 @@
 {
 	int i, res;
 
-	/* Set transition detect */
-	set_irq_type(ASSABET_IRQ_GPIO_CF_IRQ, IRQT_FALLING);
-
 	/* Register interrupts */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			goto irq_err;
+		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
 	}
 
+	init->socket_irq[0] = NO_IRQ;
+	init->socket_irq[1] = ASSABET_IRQ_GPIO_CF_IRQ;
+
 	/* There's only one slot, but it's "Slot 1": */
 	return 2;
 
@@ -69,47 +71,31 @@
 	return 0;
 }
 
-static int
-assabet_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+static void
+assabet_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long levels;
+	unsigned long levels = GPLR;
 
-	if (state_array->size < 2)
-		return -1;
-
-	levels = GPLR;
-
-	state_array->state[1].detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
-	state_array->state[1].ready  = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
-	state_array->state[1].bvd1   = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
-	state_array->state[1].bvd2   = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
-	state_array->state[1].wrprot = 0; /* Not available on Assabet. */
-	state_array->state[1].vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
-	state_array->state[1].vs_Xv  = 0;
-
-	return 1;
-}
-
-static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-	if (info->sock > 1)
-		return -1;
-
-	if (info->sock == 1)
-		info->irq = ASSABET_IRQ_GPIO_CF_IRQ;
-
-	return 0;
+	if (sock == 1) {
+		state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
+		state->ready  = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
+		state->bvd1   = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
+		state->bvd2   = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
+		state->wrprot = 0; /* Not available on Assabet. */
+		state->vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
+		state->vs_Xv  = 0;
+	}
 }
 
 static int
-assabet_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+assabet_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
 	unsigned int mask;
 
-	if (configure->sock > 1)
+	if (sock > 1)
 		return -1;
 
-	if (configure->sock == 0)
+	if (sock == 0)
 		return 0;
 
 	switch (configure->vcc) {
@@ -138,15 +124,6 @@
 
 	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask);
 
-	/*
-	 * Handle suspend mode properly.  This prevents a
-	 * flood of IRQs from the CF device.
-	 */
-	if (configure->irq)
-		enable_irq(ASSABET_IRQ_GPIO_CF_IRQ);
-	else
-		disable_irq(ASSABET_IRQ_GPIO_CF_IRQ);
-
 	return 0;
 }
 
@@ -194,23 +171,23 @@
 }
 
 static struct pcmcia_low_level assabet_pcmcia_ops = { 
+	.owner			= THIS_MODULE,
 	.init			= assabet_pcmcia_init,
 	.shutdown		= assabet_pcmcia_shutdown,
 	.socket_state		= assabet_pcmcia_socket_state,
-	.get_irq_info		= assabet_pcmcia_get_irq_info,
 	.configure_socket	= assabet_pcmcia_configure_socket,
 
 	.socket_init		= assabet_pcmcia_socket_init,
 	.socket_suspend		= assabet_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_assabet_init(void)
+int __init pcmcia_assabet_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_assabet()) {
 		if (!machine_has_neponset())
-			ret = sa1100_register_pcmcia(&assabet_pcmcia_ops);
+			ret = sa1100_register_pcmcia(&assabet_pcmcia_ops, dev);
 #ifndef CONFIG_ASSABET_NEPONSET
 		else
 			printk(KERN_ERR "Card Services disabled: missing "
@@ -220,8 +197,8 @@
 	return ret;
 }
 
-void __exit pcmcia_assabet_exit(void)
+void __exit pcmcia_assabet_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&assabet_pcmcia_ops);
+	sa1100_unregister_pcmcia(&assabet_pcmcia_ops, dev);
 }
 
diff -Nru a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1100_badge4.c
--- a/drivers/pcmcia/sa1100_badge4.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/pcmcia/sa1100_badge4.c	Tue Mar  4 19:30:05 2003
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/device.h>
@@ -96,11 +97,11 @@
 }
 
 static int
-badge4_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+badge4_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
 	int ret;
 
-	switch (conf->sock) {
+	switch (sock) {
 	case 0:
 		if ((conf->vcc != 0) &&
 		    (conf->vcc != badge4_pcmvcc)) {
@@ -130,7 +131,7 @@
 		return -1;
 	}
 
-	ret = sa1111_pcmcia_configure_socket(conf);
+	ret = sa1111_pcmcia_configure_socket(sock, conf);
 	if (ret == 0) {
 		unsigned long flags;
 		int need5V;
@@ -148,29 +149,29 @@
 }
 
 static struct pcmcia_low_level badge4_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= badge4_pcmcia_init,
 	.shutdown		= badge4_pcmcia_shutdown,
 	.socket_state		= sa1111_pcmcia_socket_state,
-	.get_irq_info		= sa1111_pcmcia_get_irq_info,
 	.configure_socket	= badge4_pcmcia_configure_socket,
 
 	.socket_init		= sa1111_pcmcia_socket_init,
 	.socket_suspend		= sa1111_pcmcia_socket_suspend,
 };
 
-int pcmcia_badge4_init(void)
+int pcmcia_badge4_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_badge4())
-		ret = sa1100_register_pcmcia(&badge4_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&badge4_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __devexit pcmcia_badge4_exit(void)
+void __devexit pcmcia_badge4_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&badge4_pcmcia_ops);
+	sa1100_unregister_pcmcia(&badge4_pcmcia_ops, dev);
 }
 
 static int __init pcmv_setup(char *s)
diff -Nru a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
--- a/drivers/pcmcia/sa1100_cerf.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/pcmcia/sa1100_cerf.c	Tue Mar  4 19:30:13 2003
@@ -6,8 +6,10 @@
  *
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -34,16 +36,16 @@
 {
   int i, res;
 
-  set_irq_type(IRQ_GPIO_CF_IRQ, IRQT_FALLING);
-
   for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-    res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+    res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt, SA_INTERRUPT,
 		      irqs[i].str, NULL);
     if (res)
       goto irq_err;
+    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
   }
 
+  init->socket_irq[CERF_SOCKET] = IRQ_GPIO_CF_IRQ;
+
   return 2;
 
  irq_err:
@@ -66,43 +68,28 @@
   return 0;
 }
 
-static int cerf_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-  int i = CERF_SOCKET;
-
-  if(state_array->size<2) return -1;
-
-  levels=GPLR;
-
-  state_array->state[i].detect=((levels & GPIO_CF_CD)==0)?1:0;
-  state_array->state[i].ready=(levels & GPIO_CF_IRQ)?1:0;
-  state_array->state[i].bvd1=(levels & GPIO_CF_BVD1)?1:0;
-  state_array->state[i].bvd2=(levels & GPIO_CF_BVD2)?1:0;
-  state_array->state[i].wrprot=0;
-  state_array->state[i].vs_3v=1;
-  state_array->state[i].vs_Xv=0;
-
-  return 1;
-}
-
-static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  if(info->sock>1) return -1;
-
-  if (info->sock == CERF_SOCKET)
-    info->irq=IRQ_GPIO_CF_IRQ;
+static void cerf_pcmcia_socket_state(int sock, struct pcmcia_state *state)
+{
+  unsigned long levels=GPLR;
 
-  return 0;
+  if (sock == CERF_SOCKET) {
+    state->detect=((levels & GPIO_CF_CD)==0)?1:0;
+    state->ready=(levels & GPIO_CF_IRQ)?1:0;
+    state->bvd1=(levels & GPIO_CF_BVD1)?1:0;
+    state->bvd2=(levels & GPIO_CF_BVD2)?1:0;
+    state->wrprot=0;
+    state->vs_3v=1;
+    state->vs_Xv=0;
+  }
 }
 
-static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
+static int cerf_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
-  if(configure->sock>1)
+  if (sock>1)
     return -1;
 
-  if (configure->sock != CERF_SOCKET)
+  if (sock != CERF_SOCKET)
     return 0;
 
   switch(configure->vcc){
@@ -161,27 +148,27 @@
 }
 
 static struct pcmcia_low_level cerf_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= cerf_pcmcia_init,
   .shutdown		= cerf_pcmcia_shutdown,
   .socket_state		= cerf_pcmcia_socket_state,
-  .get_irq_info		= cerf_pcmcia_get_irq_info,
   .configure_socket	= cerf_pcmcia_configure_socket,
 
   .socket_init		= cerf_pcmcia_socket_init,
   .socket_suspend	= cerf_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_cerf_init(void)
+int __init pcmcia_cerf_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_cerf())
-		ret = sa1100_register_pcmcia(&cerf_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&cerf_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_cerf_exit(void)
+void __exit pcmcia_cerf_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&cerf_pcmcia_ops);
+	sa1100_unregister_pcmcia(&cerf_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_flexanet.c b/drivers/pcmcia/sa1100_flexanet.c
--- a/drivers/pcmcia/sa1100_flexanet.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/pcmcia/sa1100_flexanet.c	Tue Mar  4 19:30:08 2003
@@ -5,9 +5,10 @@
  * by Jordi Colomer, 09/05/2001
  *
  */
-
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -40,19 +41,18 @@
   GPDR &= ~(GPIO_CF1_NCD | GPIO_CF1_BVD1 | GPIO_CF1_IRQ |
             GPIO_CF2_NCD | GPIO_CF2_BVD1 | GPIO_CF2_IRQ );
 
-  /* Set IRQ edge */
-  set_irq_type(IRQ_GPIO_CF1_IRQ, IRQT_FALLING);
-  set_irq_type(IRQ_GPIO_CF2_IRQ, IRQT_FALLING);
-
   /* Register the socket interrupts (not the card interrupts) */
   for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-    res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+    res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt, SA_INTERRUPT,
 		      irqs[i].name, NULL);
     if (res < 0)
       break;
+    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
   }
 
+  init->socket_irq[0] = IRQ_GPIO_CF1_IRQ;
+  init->socket_irq[1] = IRQ_GPIO_CF2_IRQ;
+
   /* If we failed, then free all interrupts requested thus far. */
   if (res < 0) {
     printk(KERN_ERR "%s: request for IRQ%d failed: %d\n",
@@ -88,67 +88,43 @@
  *  Sockets in Flexanet are 3.3V only, without BVD2.
  *
  */
-static int flexanet_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if (state_array->size < 2)
-    return -1;
-
-  /* Sense the GPIOs, asynchronously */
-  levels = GPLR;
-
-  /* Socket 0 */
-  state_array->state[0].detect = ((levels & GPIO_CF1_NCD)==0)?1:0;
-  state_array->state[0].ready  = (levels & GPIO_CF1_IRQ)?1:0;
-  state_array->state[0].bvd1   = (levels & GPIO_CF1_BVD1)?1:0;
-  state_array->state[0].bvd2   = 1;
-  state_array->state[0].wrprot = 0;
-  state_array->state[0].vs_3v  = 1;
-  state_array->state[0].vs_Xv  = 0;
-
-  /* Socket 1 */
-  state_array->state[1].detect = ((levels & GPIO_CF2_NCD)==0)?1:0;
-  state_array->state[1].ready  = (levels & GPIO_CF2_IRQ)?1:0;
-  state_array->state[1].bvd1   = (levels & GPIO_CF2_BVD1)?1:0;
-  state_array->state[1].bvd2   = 1;
-  state_array->state[1].wrprot = 0;
-  state_array->state[1].vs_3v  = 1;
-  state_array->state[1].vs_Xv  = 0;
-
-  return 1;
-}
-
-
-/*
- * Return the IRQ information for a given socket number (the IRQ number)
- *
- */
-static int flexanet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  /* check the socket index */
-  if (info->sock > 1)
-    return -1;
+static void flexanet_pcmcia_socket_state(int sock, struct pcmcia_state *state)
+{
+  unsigned long levels = GPLR; /* Sense the GPIOs, asynchronously */
 
-  if (info->sock == 0)
-    info->irq = IRQ_GPIO_CF1_IRQ;
-  else if (info->sock == 1)
-    info->irq = IRQ_GPIO_CF2_IRQ;
+  switch (sock) {
+  case 0: /* Socket 0 */
+    state->detect = ((levels & GPIO_CF1_NCD)==0)?1:0;
+    state->ready  = (levels & GPIO_CF1_IRQ)?1:0;
+    state->bvd1   = (levels & GPIO_CF1_BVD1)?1:0;
+    state->bvd2   = 1;
+    state->wrprot = 0;
+    state->vs_3v  = 1;
+    state->vs_Xv  = 0;
+    break;
 
-  return 0;
+  case 1: /* Socket 1 */
+    state->detect = ((levels & GPIO_CF2_NCD)==0)?1:0;
+    state->ready  = (levels & GPIO_CF2_IRQ)?1:0;
+    state->bvd1   = (levels & GPIO_CF2_BVD1)?1:0;
+    state->bvd2   = 1;
+    state->wrprot = 0;
+    state->vs_3v  = 1;
+    state->vs_Xv  = 0;
+    break;
+  }
 }
 
 
 /*
  *
  */
-static int flexanet_pcmcia_configure_socket(const struct pcmcia_configure
+static int flexanet_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long value, flags, mask;
 
-
-  if (configure->sock > 1)
+  if (sock > 1)
     return -1;
 
   /* Ignore the VCC level since it is 3.3V and always on */
@@ -174,7 +150,7 @@
   /* Reset the slot(s) using the controls in the BCR */
   mask = 0;
 
-  switch (configure->sock)
+  switch (sock)
   {
     case 0 : mask = FHH_BCR_CF1_RST; break;
     case 1 : mask = FHH_BCR_CF2_RST; break;
@@ -222,28 +198,28 @@
  *
  */
 static struct pcmcia_low_level flexanet_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= flexanet_pcmcia_init,
   .shutdown		= flexanet_pcmcia_shutdown,
   .socket_state		= flexanet_pcmcia_socket_state,
-  .get_irq_info		= flexanet_pcmcia_get_irq_info,
   .configure_socket	= flexanet_pcmcia_configure_socket,
 
   .socket_init		= flexanet_pcmcia_socket_init,
   .socket_suspend	= flexanet_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_flexanet_init(void)
+int __init pcmcia_flexanet_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_flexanet())
-		ret = sa1100_register_pcmcia(&flexanet_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&flexanet_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_flexanet_exit(void)
+void __exit pcmcia_flexanet_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&flexanet_pcmcia_ops);
+	sa1100_unregister_pcmcia(&flexanet_pcmcia_ops, dev);
 }
 
diff -Nru a/drivers/pcmcia/sa1100_freebird.c b/drivers/pcmcia/sa1100_freebird.c
--- a/drivers/pcmcia/sa1100_freebird.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/pcmcia/sa1100_freebird.c	Tue Mar  4 19:30:04 2003
@@ -4,8 +4,10 @@
  * Created by Eric Peng <ericpeng@coventive.com>
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -35,18 +37,17 @@
   mdelay(100);
   LINKUP_PRC = 0xc0;
 
-  /* Set transition detect */
-  set_irq_type(IRQ_GPIO_FREEBIRD_CF_IRQ, IRQT_FALLING);
-
   /* Register interrupts */
   for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-    res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+    res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt, SA_INTERRUPT,
     		      irqs[i].str, NULL);
     if (res)
       goto irq_err;
+    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
   }
 
+  init->socket_irq[0] = IRQ_GPIO_FREEBIRD_CF_IRQ;
+
   /* There's only one slot, but it's "Slot 1": */
   return 2;
 
@@ -75,54 +76,30 @@
   return 0;
 }
 
-static int freebird_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0,
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels = LINKUP_PRS;
+static void freebird_pcmcia_socket_state(int sock, struct pcmcia_state *state)
+{
+  unsigned long levels = LINKUP_PRS;
 //printk("LINKUP_PRS=%x\n",levels);
 
-  state_array->state[0].detect=
-    ((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0;
-
-  state_array->state[0].ready=(levels & LINKUP_RDY)?1:0;
-
-  state_array->state[0].bvd1=(levels & LINKUP_BVD1)?1:0;
-
-  state_array->state[0].bvd2=(levels & LINKUP_BVD2)?1:0;
-
-  state_array->state[0].wrprot=0; /* Not available on Assabet. */
-
-  state_array->state[0].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
-
-  state_array->state[0].vs_Xv=0;
-
-  return 1;
-}
-
-static int freebird_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  if(info->sock>1) return -1;
-
-  if(info->sock==0)
-    info->irq=IRQ_GPIO_FREEBIRD_CF_IRQ;
-
-  return 0;
+  if (sock == 0) {
+    state->detect = ((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0;
+    state->ready  = (levels & LINKUP_RDY)?1:0;
+    state->bvd1   = (levels & LINKUP_BVD1)?1:0;
+    state->bvd2   = (levels & LINKUP_BVD2)?1:0;
+    state->wrprot = 0; /* Not available on Assabet. */
+    state->vs_3v  = 1;  /* Can only apply 3.3V on Assabet. */
+    state->vs_Xv  = 0;
+  }
 }
 
-static int freebird_pcmcia_configure_socket(const struct pcmcia_configure
+static int freebird_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long value, flags;
 
-  if(configure->sock>1) return -1;
+  if(sock>1) return -1;
 
-  if(configure->sock==1) return 0;
+  if(sock==1) return 0;
 
   local_irq_save(flags);
 
@@ -179,27 +156,27 @@
 }
 
 static struct pcmcia_low_level freebird_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= freebird_pcmcia_init,
   .shutdown		= freebird_pcmcia_shutdown,
   .socket_state		= freebird_pcmcia_socket_state,
-  .get_irq_info		= freebird_pcmcia_get_irq_info,
   .configure_socket	= freebird_pcmcia_configure_socket,
 
   .socket_init		= freebird_pcmcia_socket_init,
   .socket_suspend	= freebird_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_freebird_init(void)
+int __init pcmcia_freebird_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_freebird())
-		ret = sa1100_register_pcmcia(&freebird_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&freebird_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_freebird_exit(void)
+void __exit pcmcia_freebird_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&freebird_pcmcia_ops);
+	sa1100_unregister_pcmcia(&freebird_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
--- a/drivers/pcmcia/sa1100_generic.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/pcmcia/sa1100_generic.c	Tue Mar  4 19:30:10 2003
@@ -110,59 +110,74 @@
  * Call board specific BS value calculation to allow boards
  * to tweak the BS values.
  */
-static int sa1100_pcmcia_set_mecr(int sock, unsigned int cpu_clock)
+static int
+sa1100_pcmcia_set_mecr(struct sa1100_pcmcia_socket *skt, unsigned int cpu_clock)
 {
-	struct sa1100_pcmcia_socket *skt;
 	u32 mecr;
 	unsigned long flags;
 	unsigned int bs;
 
-	if (sock < 0 || sock > SA1100_PCMCIA_MAX_SOCK)
-		return -1;
-
-	skt = PCMCIA_SOCKET(sock);
-
 	local_irq_save(flags);
 
-	bs = pcmcia_low_level->socket_get_timing(sock, cpu_clock, skt->speed_io);
+	bs = skt->ops->socket_get_timing(skt->nr, cpu_clock, skt->speed_io);
 
 	mecr = MECR;
-	MECR_FAST_SET(mecr, sock, 0);
-	MECR_BSIO_SET(mecr, sock, bs );
-	MECR_BSA_SET(mecr, sock, bs );
-	MECR_BSM_SET(mecr, sock, bs );
+	MECR_FAST_SET(mecr, skt->nr, 0);
+	MECR_BSIO_SET(mecr, skt->nr, bs );
+	MECR_BSA_SET(mecr, skt->nr, bs );
+	MECR_BSM_SET(mecr, skt->nr, bs );
 	MECR = mecr;
 
 	local_irq_restore(flags);
 
-	DEBUG(4, "%s(): FAST%u %X  BSM%u %X  BSA%u %X  BSIO%u %X\n",
-	      __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
-	      MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
-	      sock, MECR_BSIO_GET(mecr, sock));
+	DEBUG(4, "%s(): sock %u FAST %X  BSM %X  BSA %X  BSIO %X\n",
+	      __FUNCTION__, skt->nr, MECR_FAST_GET(mecr, skt->nr),
+	      MECR_BSM_GET(mecr, skt->nr), MECR_BSA_GET(mecr, skt->nr),
+	      MECR_BSIO_GET(mecr, skt->nr));
 
 	return 0;
 }
 
 /*
- * sa1100_pcmcia_state_to_config
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * sa1100_pcmcia_config_skt
+ * ^^^^^^^^^^^^^^^^^^^^^^^^
  *
  * Convert PCMCIA socket state to our socket configure structure.
  */
-static struct pcmcia_configure
-sa1100_pcmcia_state_to_config(unsigned int sock, socket_state_t *state)
+static int
+sa1100_pcmcia_config_skt(struct sa1100_pcmcia_socket *skt, socket_state_t *state)
 {
-  struct pcmcia_configure conf;
+	struct pcmcia_configure conf;
+	int ret;
+
+	conf.vcc     = state->Vcc;
+	conf.vpp     = state->Vpp;
+	conf.output  = state->flags & SS_OUTPUT_ENA ? 1 : 0;
+	conf.speaker = state->flags & SS_SPKR_ENA ? 1 : 0;
+	conf.reset   = state->flags & SS_RESET ? 1 : 0;
+
+	ret = skt->ops->configure_socket(skt->nr, &conf);
+	if (ret == 0) {
+		/*
+		 * This really needs a better solution.  The IRQ
+		 * may or may not be claimed by the driver.
+		 */
+		if (skt->irq_state != 1 && state->io_irq) {
+			skt->irq_state = 1;
+			set_irq_type(skt->irq, IRQT_FALLING);
+		} else if (skt->irq_state == 1 && state->io_irq == 0) {
+		  	skt->irq_state = 0;
+			set_irq_type(skt->irq, IRQT_NOEDGE);
+		}
+
+		skt->cs_state = *state;
+	}
 
-  conf.sock    = sock;
-  conf.vcc     = state->Vcc;
-  conf.vpp     = state->Vpp;
-  conf.output  = state->flags & SS_OUTPUT_ENA ? 1 : 0;
-  conf.speaker = state->flags & SS_SPKR_ENA ? 1 : 0;
-  conf.reset   = state->flags & SS_RESET ? 1 : 0;
-  conf.irq     = state->io_irq != 0;
+	if (ret < 0)
+		printk(KERN_ERR "sa1100_pcmcia: unable to configure "
+		       "socket %d\n", skt->nr);
 
-  return conf;
+	return ret;
 }
 
 /* sa1100_pcmcia_sock_init()
@@ -177,17 +192,12 @@
 static int sa1100_pcmcia_sock_init(unsigned int sock)
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
-  struct pcmcia_configure conf;
 
   DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, sock);
 
-  skt->cs_state = dead_socket;
-
-  conf = sa1100_pcmcia_state_to_config(sock, &dead_socket);
-
-  pcmcia_low_level->configure_socket(&conf);
+  sa1100_pcmcia_config_skt(skt, &dead_socket);
 
-  return pcmcia_low_level->socket_init(sock);
+  return skt->ops->socket_init(skt->nr);
 }
 
 
@@ -203,19 +213,14 @@
 static int sa1100_pcmcia_suspend(unsigned int sock)
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
-  struct pcmcia_configure conf;
   int ret;
 
-  DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, skt->nr);
 
-  conf = sa1100_pcmcia_state_to_config(sock, &dead_socket);
+  ret = sa1100_pcmcia_config_skt(skt, &dead_socket);
 
-  ret = pcmcia_low_level->configure_socket(&conf);
-
-  if (ret == 0) {
-    skt->cs_state = dead_socket;
-    ret = pcmcia_low_level->socket_suspend(sock);
-  }
+  if (ret == 0)
+    ret = skt->ops->socket_suspend(skt->nr);
 
   return ret;
 }
@@ -286,40 +291,33 @@
  */
 static void sa1100_pcmcia_task_handler(void *data)
 {
-  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
-  struct pcmcia_state_array state_array;
+  struct pcmcia_state state;
   unsigned int all_events;
 
   DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
 
-  state_array.size = sa1100_pcmcia_socket_count;
-  state_array.state = state;
-
   do {
     unsigned int events;
-    int ret, i;
-
-    memset(state, 0, sizeof(state));
+    int i;
 
     DEBUG(4, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
 
-    ret = pcmcia_low_level->socket_state(&state_array);
-    if (ret < 0) {
-      printk(KERN_ERR "sa1100_pcmcia: unable to read socket status\n");
-      break;
-    }
-
     all_events = 0;
 
-    for (i = 0; i < state_array.size; i++, all_events |= events) {
+    for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
       struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
 
-      events = sa1100_pcmcia_events(&state[i], &skt->k_state,
+      memset(&state, 0, sizeof(state));
+
+      skt->ops->socket_state(skt->nr, &state);
+
+      events = sa1100_pcmcia_events(&state, &skt->k_state,
 				    skt->cs_state.csc_mask,
 				    skt->cs_state.flags);
 
-      if (events && sa1100_pcmcia_socket[i].handler != NULL)
+      if (events && skt->handler != NULL)
 	skt->handler(skt->handler_info, events);
+      all_events |= events;
     }
   } while(all_events);
 }  /* sa1100_pcmcia_task_handler() */
@@ -351,7 +349,7 @@
  * handling code performs scheduling operations which cannot be
  * executed from within an interrupt context.
  */
-static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
+void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
   DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
   schedule_work(&sa1100_pcmcia_task);
@@ -378,12 +376,16 @@
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
 
+  if (handler && !try_module_get(skt->ops->owner))
+  	return -ENODEV;
   if (handler == NULL) {
     skt->handler = NULL;
   } else {
     skt->handler_info = info;
     skt->handler = handler;
   }
+  if (!handler)
+  	module_put(skt->ops->owner);
 
   return 0;
 }
@@ -427,7 +429,7 @@
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   int ret = -1;
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   if (sock < sa1100_pcmcia_socket_count) {
     cap->features  = SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
@@ -463,28 +465,20 @@
 sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status)
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
-  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
-  struct pcmcia_state_array state_array;
+  struct pcmcia_state state;
   unsigned int stat;
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
-
-  state_array.size = sa1100_pcmcia_socket_count;
-  state_array.state = state;
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
-  memset(state, 0, sizeof(state));
+  memset(&state, 0, sizeof(state));
 
-  if ((pcmcia_low_level->socket_state(&state_array)) < 0) {
-    printk(KERN_ERR "sa1100_pcmcia: unable to get socket status\n");
-    return -1;
-  }
-
-  skt->k_state = state[sock];
+  skt->ops->socket_state(skt->nr, &state);
+  skt->k_state = state;
 
-  stat = state[sock].detect ? SS_DETECT : 0;
-  stat |= state[sock].ready ? SS_READY  : 0;
-  stat |= state[sock].vs_3v ? SS_3VCARD : 0;
-  stat |= state[sock].vs_Xv ? SS_XVCARD : 0;
+  stat = state.detect ? SS_DETECT : 0;
+  stat |= state.ready ? SS_READY  : 0;
+  stat |= state.vs_3v ? SS_3VCARD : 0;
+  stat |= state.vs_Xv ? SS_XVCARD : 0;
 
   /* The power status of individual sockets is not available
    * explicitly from the hardware, so we just remember the state
@@ -493,11 +487,11 @@
   stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
 
   if (skt->cs_state.flags & SS_IOCARD)
-    stat |= state[sock].bvd1 ? SS_STSCHG : 0;
+    stat |= state.bvd1 ? SS_STSCHG : 0;
   else {
-    if (state[sock].bvd1 == 0)
+    if (state.bvd1 == 0)
       stat |= SS_BATDEAD;
-    else if (state[sock].bvd2 == 0)
+    else if (state.bvd2 == 0)
       stat |= SS_BATWARN;
   }
 
@@ -530,7 +524,7 @@
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   *state = skt->cs_state;
 
@@ -551,9 +545,8 @@
 sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
-  struct pcmcia_configure conf;
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   DEBUG(3, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n",
 	(state->csc_mask==0)?"<NONE>":"",
@@ -571,16 +564,7 @@
   DEBUG(3, "\tVcc %d  Vpp %d  irq %d\n",
 	state->Vcc, state->Vpp, state->io_irq);
 
-  conf = sa1100_pcmcia_state_to_config(sock, state);
-
-  if (pcmcia_low_level->configure_socket(&conf) < 0) {
-    printk(KERN_ERR "sa1100_pcmcia: unable to configure socket %d\n", sock);
-    return -1;
-  }
-
-  skt->cs_state = *state;
-  
-  return 0;
+  return sa1100_pcmcia_config_skt(skt, state);
 }  /* sa1100_pcmcia_set_socket() */
 
 
@@ -623,7 +607,7 @@
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   DEBUG(3, "\tmap %u  speed %u\n\tstart 0x%08x  stop 0x%08x\n",
 	map->map, map->speed, map->start, map->stop);
@@ -647,7 +631,7 @@
     if ( map->speed == 0)
        map->speed = SA1100_PCMCIA_IO_ACCESS;
 
-	sa1100_pcmcia_set_mecr(sock, cpufreq_get(0));
+	sa1100_pcmcia_set_mecr(skt, cpufreq_get(0));
   }
 
   if (map->stop == 1)
@@ -704,7 +688,7 @@
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   unsigned long start;
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   DEBUG(3, "\tmap %u speed %u sys_start %08lx sys_stop %08lx card_start %08x\n",
 	map->map, map->speed, map->sys_start, map->sys_stop, map->card_start);
@@ -736,18 +720,17 @@
 			  map->speed = SA1100_PCMCIA_5V_MEM_ACCESS;
 	  }
 
-	  sa1100_pcmcia_set_mecr(sock, cpufreq_get(0));
+	  sa1100_pcmcia_set_mecr(skt, cpufreq_get(0));
 
   }
 
-  start = (map->flags & MAP_ATTRIB) ? skt->phys_attr : skt->phys_mem;
-
   if (map->sys_stop == 0)
     map->sys_stop = PAGE_SIZE-1;
 
+  start = (map->flags & MAP_ATTRIB) ? skt->phys_attr : skt->phys_mem;
   map->sys_stop -= map->sys_start;
-  map->sys_stop += start;
-  map->sys_start = start;
+  map->sys_stop += start + map->card_start;
+  map->sys_start = start + map->card_start;
 
   skt->pc_mem_map[map->map] = *map;
 
@@ -767,9 +750,8 @@
 sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
 			  int count, int *eof, void *data)
 {
-  unsigned int sock = (unsigned int)data;
+  struct sa1100_pcmcia_socket *skt = data;
   unsigned int clock = cpufreq_get(0);
-  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   unsigned long mecr = MECR;
   char *p = buf;
 
@@ -815,13 +797,13 @@
   p+=sprintf(p, "IRQ      : %d\n", skt->cs_state.io_irq);
 
   p+=sprintf(p, "I/O      : %u (%u)\n", skt->speed_io,
-	     sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, sock)));
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, skt->nr)));
 
   p+=sprintf(p, "attribute: %u (%u)\n", skt->speed_attr,
-	     sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, sock)));
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, skt->nr)));
 
   p+=sprintf(p, "common   : %u (%u)\n", skt->speed_mem,
-	     sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, sock)));
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, skt->nr)));
 
   return p-buf;
 }
@@ -846,7 +828,7 @@
   }
 
   entry->read_proc = sa1100_pcmcia_proc_status;
-  entry->data = (void *)sock;
+  entry->data = PCMCIA_SOCKET(sock);
 }
 
 #endif  /* defined(CONFIG_PROC_FS) */
@@ -881,8 +863,10 @@
 {
 	unsigned int sock;
 
-	for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock)
-		sa1100_pcmcia_set_mecr(sock, clock);
+	for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock) {
+		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+		sa1100_pcmcia_set_mecr(skt, clock);
+	}
 }
 
 /* sa1100_pcmcia_notifier()
@@ -936,11 +920,10 @@
  *
  * Register an SA1100 PCMCIA low level driver with the SA1100 core.
  */
-int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
+int sa1100_register_pcmcia(struct pcmcia_low_level *ops, struct device *dev)
 {
 	struct pcmcia_init pcmcia_init;
-	struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
-	struct pcmcia_state_array state_array;
+	struct pcmcia_socket_class_data *cls;
 	unsigned int i, cpu_clock;
 	int ret;
 
@@ -956,54 +939,46 @@
 	 * set default MECR calculation if the board specific
 	 * code did not specify one...
 	 */
-	if (!pcmcia_low_level->socket_get_timing)
-		pcmcia_low_level->socket_get_timing = sa1100_pcmcia_default_mecr_timing;
+	if (!ops->socket_get_timing)
+		ops->socket_get_timing = sa1100_pcmcia_default_mecr_timing;
 
-	pcmcia_init.handler = sa1100_pcmcia_interrupt;
+	pcmcia_init.socket_irq[0] = NO_IRQ;
+	pcmcia_init.socket_irq[1] = NO_IRQ;
 	ret = ops->init(&pcmcia_init);
 	if (ret < 0) {
 		printk(KERN_ERR "Unable to initialize kernel PCMCIA service (%d).\n", ret);
-		if (ret == -1)
-			ret = -EIO;
 		goto out;
 	}
 
 	sa1100_pcmcia_socket_count = ret;
 
-	state_array.size  = ret;
-	state_array.state = state;
-
-	memset(state, 0, sizeof(state));
+	cpu_clock = cpufreq_get(0);
 
-	if (ops->socket_state(&state_array) < 0) {
-		printk(KERN_ERR "Unable to get PCMCIA status driver.\n");
-		ret = -EIO;
-		goto shutdown;
+	for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
+		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+		memset(skt, 0, sizeof(*skt));
 	}
 
-	cpu_clock = cpufreq_get(0);
-
 	/*
 	 * We initialize the MECR to default values here, because we are
 	 * not guaranteed to see a SetIOMap operation at runtime.
 	 */
 	for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
 		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
-		struct pcmcia_irq_info irq_info;
 
-		if (!request_mem_region(_PCMCIA(i), PCMCIASp, "PCMCIA")) {
-			ret = -EBUSY;
-			goto out_err;
-		}
+		skt->res.start	= _PCMCIA(i);
+		skt->res.end	= _PCMCIA(i) + PCMCIASp - 1;
+		skt->res.name	= "PCMCIA";
+		skt->res.flags	= IORESOURCE_MEM;
 
-		irq_info.sock = i;
-		irq_info.irq  = -1;
-		ret = ops->get_irq_info(&irq_info);
-		if (ret < 0)
-			printk(KERN_ERR "Unable to get IRQ for socket %u (%d)\n", i, ret);
+		ret = request_resource(&iomem_resource, &skt->res);
+		if (ret)
+			goto out_err;
 
-		skt->irq        = irq_info.irq;
-		skt->k_state    = state[i];
+		skt->nr		= i;
+		skt->ops	= ops;
+		skt->irq	= pcmcia_init.socket_irq[i];
+		skt->irq_state	= 0;
 		skt->speed_io   = SA1100_PCMCIA_IO_ACCESS;
 		skt->speed_attr = SA1100_PCMCIA_5V_MEM_ACCESS;
 		skt->speed_mem  = SA1100_PCMCIA_5V_MEM_ACCESS;
@@ -1016,18 +991,22 @@
 			goto out_err;
 		}
 
-		sa1100_pcmcia_set_mecr(i, cpu_clock);
+		ops->socket_state(skt->nr, &skt->k_state);
+		sa1100_pcmcia_set_mecr(skt, cpu_clock);
 	}
 
-
-	/* Only advertise as many sockets as we can detect */
-	ret = register_ss_entry(sa1100_pcmcia_socket_count,
-				&sa1100_pcmcia_operations);
-	if (ret < 0) {
-		printk(KERN_ERR "Unable to register sockets\n");
+	cls = kmalloc(sizeof(struct pcmcia_socket_class_data), GFP_KERNEL);
+	if (!cls) {
+		ret = -ENOMEM;
 		goto out_err;
 	}
 
+	memset(cls, 0, sizeof(struct pcmcia_socket_class_data));
+
+	cls->ops	= &sa1100_pcmcia_operations;
+	cls->nsock	= sa1100_pcmcia_socket_count;
+	dev->class_data = cls;
+
 	/*
 	 * Start the event poll timer.  It will reschedule by itself afterwards.
 	 */
@@ -1039,10 +1018,10 @@
 		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
 		iounmap(skt->virt_io);
 		skt->virt_io = NULL;
-		release_mem_region(_PCMCIA(i), PCMCIASp);
+		if (skt->res.start)
+			release_resource(&skt->res);
 	}
 
- shutdown:
 	ops->shutdown();
 
  out:
@@ -1056,7 +1035,7 @@
  *
  * Unregister a previously registered pcmcia driver
  */
-void sa1100_unregister_pcmcia(struct pcmcia_low_level *ops)
+void sa1100_unregister_pcmcia(struct pcmcia_low_level *ops, struct device *dev)
 {
 	int i;
 
@@ -1072,25 +1051,84 @@
 
 	del_timer_sync(&poll_timer);
 
-	unregister_ss_entry(&sa1100_pcmcia_operations);
-
 	for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
 		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
 
 		iounmap(skt->virt_io);
 		skt->virt_io = NULL;
 		
-		release_mem_region(_PCMCIA(i), PCMCIASp);
+		release_resource(&skt->res);
 	}
 
 	ops->shutdown();
 
 	flush_scheduled_work();
 
+	kfree(dev->class_data);
+	dev->class_data = NULL;
+
 	pcmcia_low_level = NULL;
 }
 EXPORT_SYMBOL(sa1100_unregister_pcmcia);
 
+static struct device_driver sa1100_pcmcia_driver = {
+	.name		= "sa11x0-pcmcia",
+	.bus		= &platform_bus_type,
+	.devclass	= &pcmcia_socket_class,
+};
+
+static struct platform_device sa1100_pcmcia_device = {
+	.name		= "sa11x0-pcmcia",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA11x0 [PCMCIA]",
+	},
+};
+
+struct ll_fns {
+	int (*init)(struct device *dev);
+	void (*exit)(struct device *dev);
+};
+
+static struct ll_fns sa1100_ll_fns[] = {
+#ifdef CONFIG_SA1100_ASSABET
+	{ .init = pcmcia_assabet_init,	.exit = pcmcia_assabet_exit,	},
+#endif
+#ifdef CONFIG_SA1100_CERF
+	{ .init = pcmcia_cerf_init,	.exit = pcmcia_cerf_exit,	},
+#endif
+#ifdef CONFIG_SA1100_FLEXANET
+	{ .init = pcmcia_flexanet_init,	.exit = pcmcia_flexanet_exit,	},
+#endif
+#ifdef CONFIG_SA1100_FREEBIRD
+	{ .init = pcmcia_freebird_init,	.exit = pcmcia_freebird_exit,	},
+#endif
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+	{ .init = pcmcia_gcplus_init,	.exit = pcmcia_gcplus_exit,	},
+#endif
+#ifdef CONFIG_SA1100_H3600
+	{ .init = pcmcia_h3600_init,	.exit = pcmcia_h3600_exit,	},
+#endif
+#ifdef CONFIG_SA1100_PANGOLIN
+	{ .init = pcmcia_pangolin_init,	.exit = pcmcia_pangolin_exit,	},
+#endif
+#ifdef CONFIG_SA1100_SHANNON
+	{ .init = pcmcia_shannon_init,	.exit = pcmcia_shannon_exit,	},
+#endif
+#ifdef CONFIG_SA1100_SIMPAD
+	{ .init = pcmcia_simpad_init,	.exit = pcmcia_simpad_exit,	},
+#endif
+#ifdef CONFIG_SA1100_STORK
+	{ .init = pcmcia_stork_init,	.exit = pcmcia_stork_exit,	},
+#endif
+#ifdef CONFIG_SA1100_TRIZEPS
+	{ .init = pcmcia_trizeps_init,	.exit = pcmcia_trizeps_exit,	},
+#endif
+#ifdef CONFIG_SA1100_YOPY
+	{ .init = pcmcia_yopy_init,	.exit = pcmcia_yopy_exit,	},
+#endif
+};
+
 /* sa1100_pcmcia_init()
  * ^^^^^^^^^^^^^^^^^^^^
  *
@@ -1115,61 +1153,34 @@
 		return -EINVAL;
 	}
 
-	for (i = 0; i < SA1100_PCMCIA_MAX_SOCK; i++) {
-		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
-
-		skt->speed_io   = SA1100_PCMCIA_IO_ACCESS;
-		skt->speed_attr = SA1100_PCMCIA_5V_MEM_ACCESS;
-		skt->speed_mem  = SA1100_PCMCIA_5V_MEM_ACCESS;
-	}
-
 #ifdef CONFIG_CPU_FREQ
 	ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block,
 					CPUFREQ_TRANSITION_NOTIFIER);
 	if (ret < 0) {
 		printk(KERN_ERR "Unable to register CPU frequency change "
 			"notifier (%d)\n", ret);
+		driver_unregister(&sa1100_pcmcia_driver);
 		return ret;
 	}
 #endif
 
-#ifdef CONFIG_SA1100_ASSABET
-	pcmcia_assabet_init();
-#endif
-#ifdef CONFIG_SA1100_CERF
-	pcmcia_cerf_init();
-#endif
-#ifdef CONFIG_SA1100_FLEXANET
-	pcmcia_flexanet_init();
-#endif
-#ifdef CONFIG_SA1100_FREEBIRD
-	pcmcia_freebird_init();
-#endif
-#ifdef CONFIG_SA1100_GRAPHICSCLIENT
-	pcmcia_gcplus_init();
-#endif
-#ifdef CONFIG_SA1100_H3600
-	pcmcia_h3600_init();
-#endif
-#ifdef CONFIG_SA1100_PANGOLIN
-	pcmcia_pangolin_init();
-#endif
-#ifdef CONFIG_SA1100_SHANNON
-	pcmcia_shannon_init();
-#endif
-#ifdef CONFIG_SA1100_SIMPAD
-	pcmcia_simpad_init();
-#endif
-#ifdef CONFIG_SA1100_STORK
-	pcmcia_stork_init();
-#endif
-#ifdef CONFIG_SA1100_TRIZEPS
-	pcmcia_trizeps_init();
-#endif
-#ifdef CONFIG_SA1100_YOPY
-	pcmcia_yopy_init();
-#endif
+	driver_register(&sa1100_pcmcia_driver);
+
+	/*
+	 * Initialise any "on-board" PCMCIA sockets.
+	 */
+	for (i = 0; i < ARRAY_SIZE(sa1100_ll_fns); i++) {
+		ret = sa1100_ll_fns[i].init(&sa1100_pcmcia_device.dev);
+		if (ret == 0)
+			break;
+	}
 
+	if (ret == 0)
+		platform_device_register(&sa1100_pcmcia_device);
+
+	/*
+	 * Don't fail if we don't find any on-board sockets.
+	 */
 	return 0;
 }
 
@@ -1180,48 +1191,14 @@
  */
 static void __exit sa1100_pcmcia_exit(void)
 {
-#ifdef CONFIG_SA1100_ASSABET
-	pcmcia_assabet_exit();
-#endif
-#ifdef CONFIG_SA1100_CERF
-	pcmcia_cerf_exit();
-#endif
-#ifdef CONFIG_SA1100_FLEXANET
-	pcmcia_flexanet_exit();
-#endif
-#ifdef CONFIG_SA1100_FREEBIRD
-	pcmcia_freebird_exit();
-#endif
-#ifdef CONFIG_SA1100_GRAPHICSCLIENT
-	pcmcia_gcplus_exit();
-#endif
-#ifdef CONFIG_SA1100_H3600
-	pcmcia_h3600_exit();
-#endif
-#ifdef CONFIG_SA1100_PANGOLIN
-	pcmcia_pangolin_exit();
-#endif
-#ifdef CONFIG_SA1100_SHANNON
-	pcmcia_shannon_exit();
-#endif
-#ifdef CONFIG_SA1100_SIMPAD
-	pcmcia_simpad_exit();
-#endif
-#ifdef CONFIG_SA1100_STORK
-	pcmcia_stork_exit();
-#endif
-#ifdef CONFIG_SA1100_YOPY
-	pcmcia_yopy_exit();
-#endif
+	platform_device_unregister(&sa1100_pcmcia_device);
 
-	if (pcmcia_low_level) {
-		printk(KERN_ERR "PCMCIA: low level driver still registered\n");
-		sa1100_unregister_pcmcia(pcmcia_low_level);
-	}
 
 #ifdef CONFIG_CPU_FREQ
 	cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 #endif
+
+	driver_unregister(&sa1100_pcmcia_driver);
 }
 
 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
diff -Nru a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h
--- a/drivers/pcmcia/sa1100_generic.h	Tue Mar  4 19:30:10 2003
+++ b/drivers/pcmcia/sa1100_generic.h	Tue Mar  4 19:30:10 2003
@@ -18,7 +18,7 @@
 #define SA1100_PCMCIA_MAX_SOCK   (2)
 
 struct pcmcia_init {
-  void (*handler)(int irq, void *dev, struct pt_regs *regs);
+	int	socket_irq[SA1100_PCMCIA_MAX_SOCK];
 };
 
 struct pcmcia_state {
@@ -31,14 +31,8 @@
             vs_Xv: 1;
 };
 
-struct pcmcia_state_array {
-  unsigned int size;
-  struct pcmcia_state *state;
-};
-
 struct pcmcia_configure {
-  unsigned sock: 8,
-            vcc: 8,
+  unsigned  vcc: 8,
             vpp: 8,
          output: 1,
         speaker: 1,
@@ -46,17 +40,13 @@
             irq: 1;
 };
 
-struct pcmcia_irq_info {
-  unsigned int sock;
-  unsigned int irq;
-};
-
 struct pcmcia_low_level {
+  struct module *owner;
+
   int (*init)(struct pcmcia_init *);
   int (*shutdown)(void);
-  int (*socket_state)(struct pcmcia_state_array *);
-  int (*get_irq_info)(struct pcmcia_irq_info *);
-  int (*configure_socket)(const struct pcmcia_configure *);
+  void (*socket_state)(int sock, struct pcmcia_state *);
+  int (*configure_socket)(int sock, const struct pcmcia_configure *);
 
   /*
    * Enable card status IRQs on (re-)initialisation.  This can
@@ -77,7 +67,8 @@
 		unsigned int cpu_speed, unsigned int cmd_time);
 };
 
-extern int sa1100_register_pcmcia(struct pcmcia_low_level *);
-extern void sa1100_unregister_pcmcia(struct pcmcia_low_level *);
+extern int sa1100_register_pcmcia(struct pcmcia_low_level *, struct device *);
+extern void sa1100_unregister_pcmcia(struct pcmcia_low_level *, struct device *);
+extern void sa1100_pcmcia_interrupt(int, void *, struct pt_regs *);
 
 #endif
diff -Nru a/drivers/pcmcia/sa1100_graphicsclient.c b/drivers/pcmcia/sa1100_graphicsclient.c
--- a/drivers/pcmcia/sa1100_graphicsclient.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/pcmcia/sa1100_graphicsclient.c	Tue Mar  4 19:30:03 2003
@@ -11,9 +11,11 @@
  *    Fix
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -49,13 +51,15 @@
 
   /* Register interrupts */
   irq = S0_CD_IRQ;
-  res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA 0 CD", NULL);
+  res = request_irq(irq, sa1100_pcmcia_interrupt, SA_INTERRUPT, "PCMCIA 0 CD", NULL);
   if (res < 0) {
     printk(KERN_ERR "%s: request for IRQ%d failed (%d)\n",
 	   __FUNCTION__, irq, res);
     return res;
   }
 
+  init->socket_irq[0] = S0_STS_IRQ;
+
   return 1;			// 1 PCMCIA Slot
 }
 
@@ -71,45 +75,27 @@
   return 0;
 }
 
-static int gcplus_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if(state_array->size<1) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels=*PCMCIA_Status;
-
-  state_array->state[0].detect=(levels & ADS_CS_ST_A_CD)?1:0;
-  state_array->state[0].ready=(levels & ADS_CS_ST_A_READY)?1:0;
-  state_array->state[0].bvd1= 0;
-  state_array->state[0].bvd2= 0;
-  state_array->state[0].wrprot=0;
-  state_array->state[0].vs_3v=0;
-  state_array->state[0].vs_Xv=0;
-
-  return 1;
-}
-
-static int gcplus_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+static void gcplus_pcmcia_socket_state(int sock, struct pcmcia_state *state_array)
 {
-	if (info->sock > 1)
-		return -1;
+  unsigned long levels = *PCMCIA_Status;
 
-	if (info->sock == 0)
-		info->irq = S0_STS_IRQ;
-
-  	return 0;
+  if (sock == 0) {
+    state->detect=(levels & ADS_CS_ST_A_CD)?1:0;
+    state->ready=(levels & ADS_CS_ST_A_READY)?1:0;
+    state->bvd1= 0;
+    state->bvd2= 0;
+    state->wrprot=0;
+    state->vs_3v=0;
+    state->vs_Xv=0;
+  }
 }
 
-static int gcplus_pcmcia_configure_socket(const struct pcmcia_configure
+static int gcplus_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long flags;
 
-  if(configure->sock>1) return -1;
+  if(sock>1) return -1;
 
   local_irq_save(flags);
 
@@ -160,28 +146,28 @@
 }
 
 static struct pcmcia_low_level gcplus_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= gcplus_pcmcia_init,
   .shutdown		= gcplus_pcmcia_shutdown,
   .socket_state		= gcplus_pcmcia_socket_state,
-  .get_irq_info		= gcplus_pcmcia_get_irq_info,
   .configure_socket	= gcplus_pcmcia_configure_socket,
 
   .socket_init		= gcplus_pcmcia_socket_init,
   .socket_suspend	= gcplus_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_gcplus_init(void)
+int __init pcmcia_gcplus_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_gcplus())
-		ret = sa1100_register_pcmcia(&gcplus_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&gcplus_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_gcplus_exit(void)
+void __exit pcmcia_gcplus_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&gcplus_pcmcia_ops);
+	sa1100_unregister_pcmcia(&gcplus_pcmcia_ops, dev);
 }
 
diff -Nru a/drivers/pcmcia/sa1100_graphicsmaster.c b/drivers/pcmcia/sa1100_graphicsmaster.c
--- a/drivers/pcmcia/sa1100_graphicsmaster.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/pcmcia/sa1100_graphicsmaster.c	Tue Mar  4 19:30:11 2003
@@ -8,8 +8,10 @@
  * 7/5/01 Woojung Huh <whuh@applieddata.net>
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -35,12 +37,12 @@
 }
 
 static int
-graphicsmaster_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+graphicsmaster_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int pa_dwr_mask, pa_dwr_set;
   int ret;
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
 
@@ -69,7 +71,7 @@
     return -1;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -82,28 +84,28 @@
 }
 
 static struct pcmcia_low_level graphicsmaster_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= graphicsmaster_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= graphicsmaster_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_graphicsmaster_init(void)
+int __init pcmcia_graphicsmaster_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_graphicsmaster())
-		ret = sa1100_register_pcmcia(&graphicsmaster_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&graphicsmaster_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_graphicsmaster_exit(void)
+void __exit pcmcia_graphicsmaster_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&graphicsmaster_pcmcia_ops);
+	sa1100_unregister_pcmcia(&graphicsmaster_pcmcia_ops, dev);
 }
 
diff -Nru a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
--- a/drivers/pcmcia/sa1100_h3600.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/pcmcia/sa1100_h3600.c	Tue Mar  4 19:30:11 2003
@@ -4,8 +4,10 @@
  * PCMCIA implementation routines for H3600
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -28,17 +30,11 @@
 	int i, res;
 
 	/*
-	 * Set transition detect
-	 */
-	set_irq_type(IRQ_GPIO_H3600_PCMCIA_IRQ0, IRQT_FALLING);
-	set_irq_type(IRQ_GPIO_H3600_PCMCIA_IRQ1, IRQT_FALLING);
-
-	/*
 	 * Register interrupts
 	 */
 	for (i = res = 0; i < ARRAY_SIZE(irqs); i++) {
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			break;
 	}
@@ -51,6 +47,9 @@
 			free_irq(irqs[i].irq, NULL);
 	}
 
+	init->socket_irq[0] = IRQ_GPIO_H3600_PCMCIA_IRQ0;
+	init->socket_irq[1] = IRQ_GPIO_H3600_PCMCIA_IRQ1;
+
 	return res ? res : 2;
 }
 
@@ -72,54 +71,37 @@
 	return 0;
 }
 
-static int
-h3600_pcmcia_socket_state(struct pcmcia_state_array *state)
+static void h3600_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long levels;
-
-	if (state->size < 2)
-		return -1;
-
-	levels = GPLR;
+	unsigned long levels = GPLR;
 
-	state->state[0].detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
-	state->state[0].ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
-	state->state[0].bvd1 = 0;
-	state->state[0].bvd2 = 0;
-	state->state[0].wrprot = 0; /* Not available on H3600. */
-	state->state[0].vs_3v = 0;
-	state->state[0].vs_Xv = 0;
-
-	state->state[1].detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
-	state->state[1].ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
-	state->state[1].bvd1 = 0;
-	state->state[1].bvd2 = 0;
-	state->state[1].wrprot = 0; /* Not available on H3600. */
-	state->state[1].vs_3v = 0;
-	state->state[1].vs_Xv = 0;
-
-	return 1;
-}
-
-static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-	switch (info->sock) {
+	switch (sock) {
 	case 0:
-		info->irq = IRQ_GPIO_H3600_PCMCIA_IRQ0;
+		state->detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
+		state->ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
+		state->bvd1 = 0;
+		state->bvd2 = 0;
+		state->wrprot = 0; /* Not available on H3600. */
+		state->vs_3v = 0;
+		state->vs_Xv = 0;
 		break;
+
 	case 1:
-		info->irq = IRQ_GPIO_H3600_PCMCIA_IRQ1;
+		state->detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
+		state->ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
+		state->bvd1 = 0;
+		state->bvd2 = 0;
+		state->wrprot = 0; /* Not available on H3600. */
+		state->vs_3v = 0;
+		state->vs_Xv = 0;
 		break;
-	default:
-		return -1;
 	}
-	return 0;
 }
 
 static int
-h3600_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+h3600_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
-	if (conf->sock > 1)
+	if (sock > 1)
 		return -1;
 
 	if (conf->vcc != 0 && conf->vcc != 33 && conf->vcc != 50) {
@@ -188,27 +170,27 @@
 }
 
 struct pcmcia_low_level h3600_pcmcia_ops = { 
+	.owner			= THIS_MODULE,
 	.init			= h3600_pcmcia_init,
 	.shutdown		= h3600_pcmcia_shutdown,
 	.socket_state		= h3600_pcmcia_socket_state,
-	.get_irq_info		= h3600_pcmcia_get_irq_info,
 	.configure_socket	= h3600_pcmcia_configure_socket,
 
 	.socket_init		= h3600_pcmcia_socket_init,
 	.socket_suspend		= h3600_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_h3600_init(void)
+int __init pcmcia_h3600_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_h3600())
-		ret = sa1100_register_pcmcia(&h3600_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&h3600_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_h3600_exit(void)
+void __exit pcmcia_h3600_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&h3600_pcmcia_ops);
+	sa1100_unregister_pcmcia(&h3600_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
--- a/drivers/pcmcia/sa1100_jornada720.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/pcmcia/sa1100_jornada720.c	Tue Mar  4 19:30:08 2003
@@ -4,6 +4,7 @@
  * Jornada720 PCMCIA specific routines
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/device.h>
@@ -49,15 +50,15 @@
 }
 
 static int
-jornada720_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+jornada720_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int pa_dwr_mask, pa_dwr_set;
   int ret;
 
 printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
-	       conf->sock, conf->vcc, conf->vpp);
+	       sock, conf->vcc, conf->vpp);
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
 
@@ -90,7 +91,7 @@
     return -1;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -103,27 +104,27 @@
 }
 
 static struct pcmcia_low_level jornada720_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= jornada720_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= jornada720_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_jornada720_init(void)
+int __init pcmcia_jornada720_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_jornada720())
-		ret = sa1100_register_pcmcia(&jornada720_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&jornada720_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __devexit pcmcia_jornada720_exit(void)
+void __devexit pcmcia_jornada720_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&jornada720_pcmcia_ops);
+	sa1100_unregister_pcmcia(&jornada720_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
--- a/drivers/pcmcia/sa1100_neponset.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/pcmcia/sa1100_neponset.c	Tue Mar  4 19:30:13 2003
@@ -3,6 +3,7 @@
  *
  * Neponset PCMCIA specific routines
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/device.h>
@@ -58,13 +59,13 @@
 }
 
 static int
-neponset_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+neponset_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
 	unsigned int ncr_mask, pa_dwr_mask;
 	unsigned int ncr_set, pa_dwr_set;
 	int ret;
 
-	switch (conf->sock) {
+	switch (sock) {
 	case 0:
 		pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
 		ncr_mask = NCR_A0VPP | NCR_A1VPP;
@@ -113,7 +114,7 @@
 		return -1;
 	}
 
-	ret = sa1111_pcmcia_configure_socket(conf);
+	ret = sa1111_pcmcia_configure_socket(sock, conf);
 	if (ret == 0) {
 		unsigned long flags;
 
@@ -127,27 +128,27 @@
 }
 
 static struct pcmcia_low_level neponset_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= neponset_pcmcia_init,
 	.shutdown		= sa1111_pcmcia_shutdown,
 	.socket_state		= sa1111_pcmcia_socket_state,
-	.get_irq_info		= sa1111_pcmcia_get_irq_info,
 	.configure_socket	= neponset_pcmcia_configure_socket,
 
 	.socket_init		= sa1111_pcmcia_socket_init,
 	.socket_suspend		= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_neponset_init(void)
+int __init pcmcia_neponset_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_assabet())
-		ret = sa1100_register_pcmcia(&neponset_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&neponset_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __devexit pcmcia_neponset_exit(void)
+void __devexit pcmcia_neponset_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&neponset_pcmcia_ops);
+	sa1100_unregister_pcmcia(&neponset_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_pangolin.c b/drivers/pcmcia/sa1100_pangolin.c
--- a/drivers/pcmcia/sa1100_pangolin.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/pcmcia/sa1100_pangolin.c	Tue Mar  4 19:30:04 2003
@@ -5,8 +5,10 @@
  *
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -14,6 +16,12 @@
 #include <asm/irq.h>
 #include "sa1100_generic.h"
 
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+#define PANGOLIN_SOCK	1
+#else
+#define PANGOLIN_SOCK	0
+#endif
+
 static int pangolin_pcmcia_init(struct pcmcia_init *init){
   int res;
 
@@ -22,12 +30,14 @@
   GPCR = GPIO_PCMCIA_BUS_ON;
 #endif
 
+  init->socket_irq[PANGOLIN_SOCK] = IRQ_PCMCIA_IRQ;
+
   /* Set transition detect */
   set_irq_type(IRQ_PCMCIA_CD, IRQT_NOEDGE);
   set_irq_type(IRQ_PCMCIA_IRQ, IRQT_FALLING);
 
   /* Register interrupts */
-  res = request_irq(IRQ_PCMCIA_CD, init->handler, SA_INTERRUPT,
+  res = request_irq(IRQ_PCMCIA_CD, sa1100_pcmcia_interrupt, SA_INTERRUPT,
 		    "PCMCIA_CD", NULL);
   if (res >= 0)
     /* There's only one slot, but it's "Slot 1": */
@@ -51,57 +61,29 @@
   return 0;
 }
 
-static int pangolin_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels=GPLR;
-#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
-  state_array->state[1].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
-  state_array->state[1].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
-  state_array->state[1].bvd1=1; /* Not available on Pangolin. */
-  state_array->state[1].bvd2=1; /* Not available on Pangolin. */
-  state_array->state[1].wrprot=0; /* Not available on Pangolin. */
-  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Pangolin. */
-  state_array->state[1].vs_Xv=0;
-#else
-  state_array->state[0].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
-  state_array->state[0].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
-  state_array->state[0].bvd1=1; /* Not available on Pangolin. */
-  state_array->state[0].bvd2=1; /* Not available on Pangolin. */
-  state_array->state[0].wrprot=0; /* Not available on Pangolin. */
-  state_array->state[0].vs_3v=0;  /* voltage level is determined by jumper setting */
-  state_array->state[0].vs_Xv=0;
-#endif
-  return 1;
-}
-
-static int pangolin_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+static void pangolin_pcmcia_socket_state(int sock, struct pcmcia_state *state)
+{
+  unsigned long levels = GPLR;;
 
-  if(info->sock>1) return -1;
-#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
-  if(info->sock==1)
-	info->irq=IRQ_PCMCIA_IRQ;
-#else
-  if(info->sock==0)
-        info->irq=IRQ_PCMCIA_IRQ;
-#endif
-  return 0;
+  if (sock == PANGOLIN_SOCK) {
+    state->detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
+    state->ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
+    state->bvd1=1; /* Not available on Pangolin. */
+    state->bvd2=1; /* Not available on Pangolin. */
+    state->wrprot=0; /* Not available on Pangolin. */
+    state->vs_3v=1;  /* Can only apply 3.3V on Pangolin. */
+    state->vs_Xv=0;
+  }
 }
 
-static int pangolin_pcmcia_configure_socket(const struct pcmcia_configure
+static int pangolin_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long value, flags;
 
-  if(configure->sock>1) return -1;
+  if(sock>1) return -1;
 #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
-  if(configure->sock==0) return 0;
+  if(sock==0) return 0;
 #endif
   local_irq_save(flags);
 
@@ -132,7 +114,7 @@
   }
 #ifdef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
   /* reset & unreset request */
-  if(configure->sock==0) {
+  if(sock==0) {
 	if(configure->reset) {
 		GPSR |= GPIO_PCMCIA_RESET;
 	} else {
@@ -148,40 +130,40 @@
 static int pangolin_pcmcia_socket_init(int sock)
 {
   if (sock == 1)
-    set_irq_type(IRQ_PCmCIA_CD, IRQT_BOTHEDGE);
+    set_irq_type(IRQ_PCMCIA_CD, IRQT_BOTHEDGE);
   return 0;
 }
 
 static int pangolin_pcmcia_socket_suspend(int sock)
 {
   if (sock == 1)
-    set_irq_type(IRQ_PCmCIA_CD, IRQT_NOEDGE);
+    set_irq_type(IRQ_PCMCIA_CD, IRQT_NOEDGE);
   return 0;
 }
 
 static struct pcmcia_low_level pangolin_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= pangolin_pcmcia_init,
   .shutdown		= pangolin_pcmcia_shutdown,
   .socket_state		= pangolin_pcmcia_socket_state,
-  .get_irq_info		= pangolin_pcmcia_get_irq_info,
   .configure_socket	= pangolin_pcmcia_configure_socket,
 
   .socket_init		= pangolin_pcmcia_socket_init,
-  socket_suspend,	pangolin_pcmcia_socket_suspend,
+  .socket_suspend	= pangolin_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_pangolin_init(void)
+int __init pcmcia_pangolin_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_pangolin())
-		ret = sa1100_register_pcmcia(&pangolin_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&pangolin_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_pangolin_exit(void)
+void __exit pcmcia_pangolin_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&pangolin_pcmcia_ops);
+	sa1100_unregister_pcmcia(&pangolin_pcmcia_ops, dev);
 }
 
diff -Nru a/drivers/pcmcia/sa1100_pfs168.c b/drivers/pcmcia/sa1100_pfs168.c
--- a/drivers/pcmcia/sa1100_pfs168.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/pcmcia/sa1100_pfs168.c	Tue Mar  4 19:30:07 2003
@@ -5,9 +5,11 @@
  * PFS168 PCMCIA specific routines
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -29,7 +31,7 @@
 }
 
 static int
-pfs168_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+pfs168_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int pa_dwr_mask = 0, pa_dwr_set = 0;
   int ret;
@@ -46,7 +48,7 @@
    *
    */
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
 
@@ -106,7 +108,7 @@
     break;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -119,27 +121,27 @@
 }
 
 static struct pcmcia_low_level pfs168_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= pfs168_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= pfs168_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_pfs168_init(void)
+int __init pcmcia_pfs168_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_pfs168())
-		ret = sa1100_register_pcmcia(&pfs168_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&pfs168_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_pfs168_exit(void)
+void __exit pcmcia_pfs168_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&pfs168_pcmcia_ops);
+	sa1100_unregister_pcmcia(&pfs168_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
--- a/drivers/pcmcia/sa1100_shannon.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/pcmcia/sa1100_shannon.c	Tue Mar  4 19:30:13 2003
@@ -4,8 +4,10 @@
  * PCMCIA implementation routines for Shannon
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -32,17 +34,16 @@
 	GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
 		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
 
-	/* Set transition detect */
-	set_irq_type(SHANNON_IRQ_GPIO_RDY_0, IRQT_FALLING);
-	set_irq_type(SHANNON_IRQ_GPIO_RDY_1, IRQT_FALLING);
+	init->socket_irq[0] = SHANNON_IRQ_GPIO_RDY_0;
+	init->socket_irq[1] = SHANNON_IRQ_GPIO_RDY_1;
 
 	/* Register interrupts */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			goto irq_err;
+		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
 	}
 
 	return 2;
@@ -68,48 +69,35 @@
 	return 0;
 }
 
-static int shannon_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+static void shannon_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long levels;
-
-	memset(state_array->state, 0,
-	       state_array->size * sizeof(struct pcmcia_state));
-
-	levels = GPLR;
+	unsigned long levels = GPLR;
 
-	state_array->state[0].detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
-	state_array->state[0].ready  = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
-	state_array->state[0].wrprot = 0; /* Not available on Shannon. */
-	state_array->state[0].bvd1 = 1; 
-	state_array->state[0].bvd2 = 1; 
-	state_array->state[0].vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
-	state_array->state[0].vs_Xv  = 0;
-
-	state_array->state[1].detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
-	state_array->state[1].ready  = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
-	state_array->state[1].wrprot = 0; /* Not available on Shannon. */
-	state_array->state[1].bvd1 = 1; 
-	state_array->state[1].bvd2 = 1; 
-	state_array->state[1].vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
-	state_array->state[1].vs_Xv  = 0;
-
-	return 1;
-}
+	switch (sock) {
+	case 0:
+		state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
+		state->ready  = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
+		state->wrprot = 0; /* Not available on Shannon. */
+		state->bvd1   = 1; 
+		state->bvd2   = 1; 
+		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
+		state->vs_Xv  = 0;
+		break;
 
-static int shannon_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-	if (info->sock == 0)
-		info->irq = SHANNON_IRQ_GPIO_RDY_0;
-	else if (info->sock == 1)
-		info->irq = SHANNON_IRQ_GPIO_RDY_1;
-	else return -1;
-	
-	return 0;
+	case 1:
+		state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
+		state->ready  = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
+		state->wrprot = 0; /* Not available on Shannon. */
+		state->bvd1   = 1; 
+		state->bvd2   = 1; 
+		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
+		state->vs_Xv  = 0;
+		break;
+	}
 }
 
-static int shannon_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int shannon_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
-
 	switch (configure->vcc) {
 	case 0:	/* power off */
 		printk(KERN_WARNING __FUNCTION__"(): CS asked for 0V, still applying 3.3V..\n");
@@ -152,27 +140,27 @@
 }
 
 static struct pcmcia_low_level shannon_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= shannon_pcmcia_init,
 	.shutdown		= shannon_pcmcia_shutdown,
 	.socket_state		= shannon_pcmcia_socket_state,
-	.get_irq_info		= shannon_pcmcia_get_irq_info,
 	.configure_socket	= shannon_pcmcia_configure_socket,
 
 	.socket_init		= shannon_pcmcia_socket_init,
 	.socket_suspend		= shannon_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_shannon_init(void)
+int __init pcmcia_shannon_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_shannon())
-		ret = sa1100_register_pcmcia(&shannon_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&shannon_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_shannon_exit(void)
+void __exit pcmcia_shannon_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&shannon_pcmcia_ops);
+	sa1100_unregister_pcmcia(&shannon_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
--- a/drivers/pcmcia/sa1100_simpad.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/pcmcia/sa1100_simpad.c	Tue Mar  4 19:30:14 2003
@@ -4,8 +4,10 @@
  * PCMCIA implementation routines for simpad
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -27,15 +29,16 @@
 
   clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
-  /* Set transition detect */
-  set_irq_type( IRQ_GPIO_CF_CD, IRQT_NOEDGE );
-  set_irq_type( IRQ_GPIO_CF_IRQ, IRQT_FALLING );
+  init->socket_irq[1] = IRQ_GPIO_CF_IRQ;
 
   /* Register interrupts */
   irq = IRQ_GPIO_CF_CD;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  res = request_irq(irq, sa1100_pcmcia_interrupt, SA_INTERRUPT,
+		    "CF_CD", NULL );
   if( res < 0 ) goto irq_err;
 
+  set_irq_type( IRQ_GPIO_CF_CD, IRQT_NOEDGE );
+
   /* There's only one slot, but it's "Slot 1": */
   return 2;
 
@@ -58,59 +61,36 @@
   return 0;
 }
 
-static int simpad_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array)
+static void simpad_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-  unsigned long levels;
-  unsigned long *cs3reg = CS3_BASE;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels=GPLR;
-
-  state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
-
-  state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
-
-  state_array->state[1].bvd1=1; /* Not available on Simpad. */
-
-  state_array->state[1].bvd2=1; /* Not available on Simpad. */
-
-  state_array->state[1].wrprot=0; /* Not available on Simpad. */
-
+  if (sock == 1) {
+    unsigned long levels = GPLR;
+    unsigned long *cs3reg = CS3_BASE;
+
+    state->detect=((levels & GPIO_CF_CD)==0)?1:0;
+    state->ready=(levels & GPIO_CF_IRQ)?1:0;
+    state->bvd1=1; /* Not available on Simpad. */
+    state->bvd2=1; /* Not available on Simpad. */
+    state->wrprot=0; /* Not available on Simpad. */
   
-  if((*cs3reg & 0x0c) == 0x0c) {
-    state_array->state[1].vs_3v=0;
-    state_array->state[1].vs_Xv=0;
-  } else
-  {
-    state_array->state[1].vs_3v=1;
-    state_array->state[1].vs_Xv=0;
+    if((*cs3reg & 0x0c) == 0x0c) {
+      state->vs_3v=0;
+      state->vs_Xv=0;
+    } else {
+      state->vs_3v=1;
+      state->vs_Xv=0;
+    }
   }
-  return 1;
-}
-
-static int simpad_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  if(info->sock>1) return -1;
-
-  if(info->sock==1)
-    info->irq=IRQ_GPIO_CF_IRQ;
-
-  return 0;
 }
 
-static int simpad_pcmcia_configure_socket(const struct pcmcia_configure
+static int simpad_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long value, flags;
 
-  if(configure->sock>1) return -1;
+  if(sock>1) return -1;
 
-  if(configure->sock==0) return 0;
+  if(sock==0) return 0;
 
   local_irq_save(flags);
 
@@ -159,27 +139,27 @@
 }
 
 static struct pcmcia_low_level simpad_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= simpad_pcmcia_init,
   .shutdown		= simpad_pcmcia_shutdown,
   .socket_state		= simpad_pcmcia_socket_state,
-  .get_irq_info		= simpad_pcmcia_get_irq_info,
   .configure_socket	= simpad_pcmcia_configure_socket,
 
   .socket_init		= simpad_pcmcia_socket_init,
   .socket_suspend	= simpad_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_simpad_init(void)
+int __init pcmcia_simpad_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_simpad())
-		ret = sa1100_register_pcmcia(&simpad_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&simpad_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_simpad_exit(void)
+void __exit pcmcia_simpad_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&simpad_pcmcia_ops);
+	sa1100_unregister_pcmcia(&simpad_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_stork.c b/drivers/pcmcia/sa1100_stork.c
--- a/drivers/pcmcia/sa1100_stork.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/pcmcia/sa1100_stork.c	Tue Mar  4 19:30:09 2003
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/i2c.h>
 
 #include <asm/hardware.h>
@@ -45,17 +46,16 @@
 
 	printk("in stork_pcmcia_init\n");
 
-	/* Set transition detect */
-	set_irq_type(IRQ_GPIO_STORK_PCMCIA_A_RDY, IRQT_FALLING);
-	set_irq_type(IRQ_GPIO_STORK_PCMCIA_B_RDY, IRQT_FALLING);
+	init->socket_irq[0] = IRQ_GPIO_STORK_PCMCIA_A_RDY;
+	init->socket_irq[1] = IRQ_GPIO_STORK_PCMCIA_B_RDY;
 
 	/* Register interrupts */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			goto irq_err;
+		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
 	}
 
         return 2;
@@ -87,69 +87,51 @@
         return 0;
 }
 
-static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+static void stork_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-        unsigned long levels;
-
-        if(state_array->size<2) return -1;
+        unsigned long levels = GPLR;
 
-        memset(state_array->state, 0, 
-               (state_array->size)*sizeof(struct pcmcia_state));
+	if (debug > 1)
+		printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", levels,
+			(levels & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
 
-        levels=GPLR;
+	switch (sock) {
+	case 0:
+		state->detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
+		state->ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
+		state->bvd1= 1;
+		state->bvd2= 1;
+		state->wrprot=0;
+		state->vs_3v=1;
+		state->vs_Xv=0;
+		break;
 
-	if (debug > 1)
-		printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
-	state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
-	state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
-	state_array->state[0].bvd1= 1;
-	state_array->state[0].bvd2= 1;
-	state_array->state[0].wrprot=0;
-	state_array->state[0].vs_3v=1;
-	state_array->state[0].vs_Xv=0;
-
-	state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
-	state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
-	state_array->state[1].bvd1=1;
-	state_array->state[1].bvd2=1;
-	state_array->state[1].wrprot=0;
-	state_array->state[1].vs_3v=1;
-	state_array->state[1].vs_Xv=0;
-
-        return 1;
-}
-
-static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-
-        switch (info->sock) {
-        case 0:
-                info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
-                break;
-        case 1:
-                info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
-                break;
-        default:
-                return -1;
-        }
-        return 0;
+	case 1:
+		state->detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
+		state->ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
+		state->bvd1=1;
+		state->bvd2=1;
+		state->wrprot=0;
+		state->vs_3v=1;
+		state->vs_Xv=0;
+		break;
+	}
 }
 
-static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int stork_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
-        int card = configure->sock;
 	unsigned long flags;
 
         int DETECT, RDY, POWER, RESET;
 
-        if (card > 1) return -1;
+        if (sock > 1) return -1;
 
 	printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%d\n", 
-                       card, configure->vcc, configure->vpp, configure->reset);
+                       sock, configure->vcc, configure->vpp, configure->reset);
 
 	local_irq_save(flags);
 
-        if (card == 0) {
+        if (sock == 0) {
     	    DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
     	    RDY = GPIO_STORK_PCMCIA_A_RDY;
     	    POWER = STORK_PCMCIA_A_POWER_ON;
@@ -228,28 +210,28 @@
 }
 
 static struct pcmcia_low_level stork_pcmcia_ops = { 
+	.owner			= THIS_MODULE,
 	.init			= stork_pcmcia_init,
 	.shutdown		= stork_pcmcia_shutdown,
 	.socket_state		= stork_pcmcia_socket_state,
-	.get_irq_info		= stork_pcmcia_get_irq_info,
 	.configure_socket	= stork_pcmcia_configure_socket,
 
 	.socket_init		= stork_pcmcia_socket_init,
 	.socket_suspend		= stork_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_stork_init(void)
+int __init pcmcia_stork_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_stork())
-		ret = sa1100_register_pcmcia(&stork_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&stork_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_stork_exit(void)
+void __exit pcmcia_stork_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&stork_pcmcia_ops);
+	sa1100_unregister_pcmcia(&stork_pcmcia_ops, dev);
 }
 
diff -Nru a/drivers/pcmcia/sa1100_system3.c b/drivers/pcmcia/sa1100_system3.c
--- a/drivers/pcmcia/sa1100_system3.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/pcmcia/sa1100_system3.c	Tue Mar  4 19:30:14 2003
@@ -25,9 +25,11 @@
  *
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/device.h>
 #include <linux/ioport.h>
 
 #include <asm/hardware.h>
@@ -48,6 +50,9 @@
 
 int system3_pcmcia_init(struct pcmcia_init *init)
 {
+	init->socket_irq[0] = IRQ_S0_READY_NINT;
+	init->socket_irq[1] = IRQ_S1_READY_NINT;
+
 	/* Don't need no CD and BVD* interrupts */
 	return 2;
 }
@@ -57,76 +62,69 @@
 	return 0;
 }
 
-int system3_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+int system3_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
-	if (!conf)
-		return -1;
-
 	/* only CF ATM */
-	if (conf->sock == 0)
+	if (sock == 0)
 		return -1;
 
-	return sa1111_pcmcia_configure_socket( conf );
+	return sa1111_pcmcia_configure_socket(sock, conf);
 }
 
-static int system3_pcmcia_socket_state(struct pcmcia_state_array
-		*state)
+static void system3_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long	status		= 0;
-
-	if(state->size<2) return -1;
-
-	memset(state->state, 0,
-			(state->size)*sizeof(struct pcmcia_state));
-
-	status=PCSR;
+	unsigned long status = PCSR;
 
+	switch (sock) {
 #if 0 /* PCMCIA socket not yet connected */
-	state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
-	state->state[0].ready  = status & PCSR_S0_READY  ? 1 : 0;
-	state->state[0].bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
-	state->state[0].bvd2   = 1;
-	state->state[0].wrprot = status & PCSR_S0_WP     ? 1 : 0;
-	state->state[0].vs_3v  = 1;
-	state->state[0].vs_Xv  = 0;
+	case 0:
+		state->detect = status & PCSR_S0_DETECT ? 0 : 1;
+		state->ready  = status & PCSR_S0_READY  ? 1 : 0;
+		state->bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
+		state->bvd2   = 1;
+		state->wrprot = status & PCSR_S0_WP     ? 1 : 0;
+		state->vs_3v  = 1;
+		state->vs_Xv  = 0;
+		break;
 #endif
 
-	state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1;
-	state->state[1].ready  = status & PCSR_S1_READY  ? 1 : 0;
-	state->state[1].bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
-	state->state[1].bvd2   = 1;
-	state->state[1].wrprot = status & PCSR_S1_WP     ? 1 : 0;
-	state->state[1].vs_3v  = 1;
-	state->state[1].vs_Xv  = 0;
-
-	DPRINTK( "PCSR=0x%08lx, S1_RDY_nIREQ=%d\n", status,
-			state->state[1].ready );
+	case 1:
+		state->detect = status & PCSR_S1_DETECT ? 0 : 1;
+		state->ready  = status & PCSR_S1_READY  ? 1 : 0;
+		state->bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
+		state->bvd2   = 1;
+		state->wrprot = status & PCSR_S1_WP     ? 1 : 0;
+		state->vs_3v  = 1;
+		state->vs_Xv  = 0;
+		break;
+	}
 
-	return 1;
+	DPRINTK("Sock %d PCSR=0x%08lx, Sx_RDY_nIREQ=%d\n",
+		sock, status, state->ready);
 }
 
 struct pcmcia_low_level system3_pcmcia_ops = {
-	.init				= system3_pcmcia_init,
-	.shutdown			= system3_pcmcia_shutdown,
+	.owner			= THIS_MODULE,
+	.init			= system3_pcmcia_init,
+	.shutdown		= system3_pcmcia_shutdown,
 	.socket_state		= system3_pcmcia_socket_state,
-	.get_irq_info		= sa1111_pcmcia_get_irq_info,
 	.configure_socket	= system3_pcmcia_configure_socket,
 
 	.socket_init		= sa1111_pcmcia_socket_init,
 	.socket_suspend		= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_system3_init(void)
+int __init pcmcia_system3_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_pt_system3())
-		ret = sa1100_register_pcmcia(&system3_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&system3_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_system3_exit(void)
+void __exit pcmcia_system3_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&system3_pcmcia_ops);
+	sa1100_unregister_pcmcia(&system3_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_trizeps.c b/drivers/pcmcia/sa1100_trizeps.c
--- a/drivers/pcmcia/sa1100_trizeps.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/pcmcia/sa1100_trizeps.c	Tue Mar  4 19:30:10 2003
@@ -9,8 +9,10 @@
  * Guennadi Liakhovetski <gl@dsa-ac.de>
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -29,6 +31,8 @@
 {
 	int res;
 
+	init->socket_irq[0] = TRIZEPS_IRQ_PCMCIA_IRQ0;
+
 	/* Enable CF bus: */
 	TRIZEPS_BCR_clear(TRIZEPS_BCR1, TRIZEPS_nPCM_ENA_REG);
 
@@ -36,15 +40,12 @@
 	GPDR &= ~((GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0))
 		    | (GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)));
 
-	/* Set transition detect */
-//	set_irq_type(SA1100_GPIO_TO_IRQ(GPIO_TRIZEPS_PCMCIA_CD0), IRQT_BOTHEDGE);
-	set_irq_type(TRIZEPS_IRQ_PCMCIA_IRQ0, IRQT_FALLING);
-
 	/* Register SOCKET interrupts */
 	/* WHY? */
-	set_irq_type(TRIZEPS_IRQ_PCMCIA_CD0, IRQT_NOEDGE);
-	res = request_irq( TRIZEPS_IRQ_PCMCIA_CD0, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
+	res = request_irq(TRIZEPS_IRQ_PCMCIA_CD0, sa1100_pcmcia_interrupt,
+			  SA_INTERRUPT, "PCMCIA_CD0", NULL );
 	if( res < 0 ) goto irq_err;
+	set_irq_type(TRIZEPS_IRQ_PCMCIA_CD0, IRQT_NOEDGE);
 
 	//MECR = 0x00060006; // Initialised on trizeps init
 
@@ -79,55 +80,30 @@
  *
 
  ******************************************************/
-static int trizeps_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-	unsigned long levels;
-
-	if (state_array->size < NUMBER_OF_TRIZEPS_PCMCIA_SLOTS) return -1;
-
-	memset(state_array->state, 0,
-	       (state_array->size)*sizeof(struct pcmcia_state));
-
-	levels = GPLR;
-
-	state_array->state[0].detect = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0)) == 0) ? 1 : 0;
-	state_array->state[0].ready  = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)) != 0) ? 1 : 0;
-	state_array->state[0].bvd1   = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD1) !=0 ) ? 1 : 0;
-	state_array->state[0].bvd2   = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD2) != 0) ? 1 : 0;
-	state_array->state[0].wrprot = 0; // not write protected
-	state_array->state[0].vs_3v  = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS1) == 0) ? 1 : 0; //VS1=0 -> vs_3v=1
-	state_array->state[0].vs_Xv  = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS2) == 0) ? 1 : 0; //VS2=0 -> vs_Xv=1
-
-	return 1;  // success
-}
-
-/**
- *
- *
- ******************************************************/
-static int trizeps_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+static void trizeps_pcmcia_socket_state(int sock, struct pcmcia_state *state_array)
+{
+	unsigned long levels = GPLR;
 
-	switch (info->sock) {
-	case 0:
-		info->irq=TRIZEPS_IRQ_PCMCIA_IRQ0;
-		break;
-	case 1:
-		// MFTB2 use only one Slot
-	default:
-		return -1;
+	if (sock == 0) {
+		state->detect = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0)) == 0) ? 1 : 0;
+		state->ready  = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)) != 0) ? 1 : 0;
+		state->bvd1   = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD1) !=0 ) ? 1 : 0;
+		state->bvd2   = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD2) != 0) ? 1 : 0;
+		state->wrprot = 0; // not write protected
+		state->vs_3v  = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS1) == 0) ? 1 : 0; //VS1=0 -> vs_3v=1
+		state->vs_Xv  = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS2) == 0) ? 1 : 0; //VS2=0 -> vs_Xv=1
 	}
-	return 0;
 }
 
 /**
  *
  *
  ******************************************************/
-static int trizeps_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int trizeps_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
 	unsigned long flags;
 
-	if(configure->sock>1) return -1;
+	if(sock>1) return -1;
 
 	local_irq_save(flags);
 
@@ -167,24 +143,18 @@
 	*/
 	local_irq_restore(flags);
 
-	if (configure->irq) {
-		enable_irq(TRIZEPS_IRQ_PCMCIA_CD0);
-		enable_irq(TRIZEPS_IRQ_PCMCIA_IRQ0);
-	} else {
-		disable_irq(TRIZEPS_IRQ_PCMCIA_IRQ0);
-		disable_irq(TRIZEPS_IRQ_PCMCIA_CD0);
-	}
-
 	return 0;
 }
 
 static int trizeps_pcmcia_socket_init(int sock)
 {
+	set_irq_type(TRIZEPS_IRQ_PCMCIA_CD0, IRQT_BOTHEDGE);
 	return 0;
 }
 
 static int trizeps_pcmcia_socket_suspend(int sock)
 {
+	set_irq_type(TRIZEPS_IRQ_PCMCIA_CD0, IRQT_NOEDGE);
 	return 0;
 }
 
@@ -193,24 +163,24 @@
  *
  ******************************************************/
 struct pcmcia_low_level trizeps_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= trizeps_pcmcia_init,
 	.shutdown		= trizeps_pcmcia_shutdown,
 	.socket_state		= trizeps_pcmcia_socket_state,
-	.get_irq_info		= trizeps_pcmcia_get_irq_info,
 	.configure_socket	= trizeps_pcmcia_configure_socket,
 	.socket_init		= trizeps_pcmcia_socket_init,
 	.socket_suspend		= trizeps_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_trizeps_init(void)
+int __init pcmcia_trizeps_init(struct device *dev)
 {
 	if (machine_is_trizeps()) {
-		return sa1100_register_pcmcia(&trizeps_pcmcia_ops);
+		return sa1100_register_pcmcia(&trizeps_pcmcia_ops, dev);
 	}
 	return -ENODEV;
 }
 
-void __exit pcmcia_trizeps_exit(void)
+void __exit pcmcia_trizeps_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&trizeps_pcmcia_ops);
+	sa1100_unregister_pcmcia(&trizeps_pcmcia_ops, dev);
 }
diff -Nru a/drivers/pcmcia/sa1100_xp860.c b/drivers/pcmcia/sa1100_xp860.c
--- a/drivers/pcmcia/sa1100_xp860.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/pcmcia/sa1100_xp860.c	Tue Mar  4 19:30:07 2003
@@ -4,9 +4,11 @@
  * XP860 PCMCIA specific routines
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -40,7 +42,7 @@
 }
 
 static int
-xp860_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+xp860_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int gpio_mask, pa_dwr_mask;
   unsigned int gpio_set, pa_dwr_set;
@@ -70,7 +72,7 @@
    * the corresponding truth table.
    */
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
     gpio_mask = NCR_A0VPP | NCR_A1VPP;
@@ -117,7 +119,7 @@
     break;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -132,28 +134,28 @@
 }
 
 static struct pcmcia_low_level xp860_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= xp860_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= xp860_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_xp860_init(void)
+int __init pcmcia_xp860_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_xp860())
-		ret = sa1100_register_pcmcia(&xp860_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&xp860_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_xp860_exit(void)
+void __exit pcmcia_xp860_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&xp860_pcmcia_ops);
+	sa1100_unregister_pcmcia(&xp860_pcmcia_ops, dev);
 }
 
diff -Nru a/drivers/pcmcia/sa1100_yopy.c b/drivers/pcmcia/sa1100_yopy.c
--- a/drivers/pcmcia/sa1100_yopy.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/pcmcia/sa1100_yopy.c	Tue Mar  4 19:30:12 2003
@@ -4,8 +4,10 @@
  * PCMCIA implementation routines for Yopy
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -38,19 +40,18 @@
 {
 	int i, res;
 
+	init->socket_irq[0] = IRQ_CF_IREQ;
+
 	pcmcia_power(0);
 	pcmcia_reset(1);
 
-	/* Set transition detect */
-	set_irq_type(IRQ_CF_IREQ, IRQT_FALLING);
-
 	/* Register interrupts */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			goto irq_err;
+		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
 	}
 
 	return 1;
@@ -80,42 +81,24 @@
 	return 0;
 }
 
-static int yopy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
-{
-	unsigned long levels;
-
-	if (state_array->size != 1)
-		return -1;
-
-	memset(state_array->state, 0,
-	       state_array->size * sizeof(struct pcmcia_state));
-
-	levels = GPLR;
-
-	state_array->state[0].detect = (levels & GPIO_CF_CD)    ? 0 : 1;
-	state_array->state[0].ready  = (levels & GPIO_CF_READY) ? 1 : 0;
-	state_array->state[0].bvd1   = (levels & GPIO_CF_BVD1)  ? 1 : 0;
-	state_array->state[0].bvd2   = (levels & GPIO_CF_BVD2)  ? 1 : 0;
-	state_array->state[0].wrprot = 0; /* Not available on Yopy. */
-	state_array->state[0].vs_3v  = 0; /* FIXME Can only apply 3.3V on Yopy. */
-	state_array->state[0].vs_Xv  = 0;
-
-	return 1;
-}
-
-static int yopy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+static void yopy_pcmcia_socket_state(int sock, struct pcmcia_state_array *state)
 {
-	if (info->sock != 0)
-		return -1;
-
-	info->irq = IRQ_CF_IREQ;
+	unsigned long levels = GPLR;
 
-	return 0;
+	if (sock == 0) {
+		state->detect = (levels & GPIO_CF_CD)    ? 0 : 1;
+		state->ready  = (levels & GPIO_CF_READY) ? 1 : 0;
+		state->bvd1   = (levels & GPIO_CF_BVD1)  ? 1 : 0;
+		state->bvd2   = (levels & GPIO_CF_BVD2)  ? 1 : 0;
+		state->wrprot = 0; /* Not available on Yopy. */
+		state->vs_3v  = 0; /* FIXME Can only apply 3.3V on Yopy. */
+		state->vs_Xv  = 0;
+	}
 }
 
-static int yopy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int yopy_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
-	if (configure->sock != 0)
+	if (sock != 0)
 		return -1;
 
 	switch (configure->vcc) {
@@ -161,28 +144,28 @@
 }
 
 static struct pcmcia_low_level yopy_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= yopy_pcmcia_init,
 	.shutdown		= yopy_pcmcia_shutdown,
 	.socket_state		= yopy_pcmcia_socket_state,
-	.get_irq_info		= yopy_pcmcia_get_irq_info,
 	.configure_socket	= yopy_pcmcia_configure_socket,
 
 	.socket_init		= yopy_pcmcia_socket_init,
 	.socket_suspend		= yopy_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_yopy_init(void)
+int __init pcmcia_yopy_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_yopy())
-		ret = sa1100_register_pcmcia(&yopy_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&yopy_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_yopy_exit(void)
+void __exit pcmcia_yopy_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&yopy_pcmcia_ops);
+	sa1100_unregister_pcmcia(&yopy_pcmcia_ops, dev);
 }
 
diff -Nru a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
--- a/drivers/pcmcia/sa1111_generic.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/pcmcia/sa1111_generic.c	Tue Mar  4 19:30:05 2003
@@ -12,6 +12,9 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
+#include <linux/proc_fs.h>
+#include <pcmcia/ss.h>
+
 #include <asm/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/irq.h>
@@ -35,9 +38,14 @@
 {
 	int i, ret;
 
+	if (init->socket_irq[0] == NO_IRQ)
+		init->socket_irq[0] = IRQ_S0_READY_NINT;
+	if (init->socket_irq[1] == NO_IRQ)
+		init->socket_irq[1] = IRQ_S1_READY_NINT;
+
 	for (i = ret = 0; i < ARRAY_SIZE(irqs); i++) {
-		ret = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		ret = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (ret)
 			break;
 		set_irq_type(irqs[i].irq, IRQT_FALLING);
@@ -63,53 +71,39 @@
 	return 0;
 }
 
-int sa1111_pcmcia_socket_state(struct pcmcia_state_array *state)
+void sa1111_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long status;
-
-	if (state->size < 2)
-		return -1;
-
-	status = sa1111_readl(pcmcia->mapbase + SA1111_PCSR);
-
-	state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
-	state->state[0].ready  = status & PCSR_S0_READY  ? 1 : 0;
-	state->state[0].bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
-	state->state[0].bvd2   = status & PCSR_S0_BVD2   ? 1 : 0;
-	state->state[0].wrprot = status & PCSR_S0_WP     ? 1 : 0;
-	state->state[0].vs_3v  = status & PCSR_S0_VS1    ? 0 : 1;
-	state->state[0].vs_Xv  = status & PCSR_S0_VS2    ? 0 : 1;
-
-	state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1;
-	state->state[1].ready  = status & PCSR_S1_READY  ? 1 : 0;
-	state->state[1].bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
-	state->state[1].bvd2   = status & PCSR_S1_BVD2   ? 1 : 0;
-	state->state[1].wrprot = status & PCSR_S1_WP     ? 1 : 0;
-	state->state[1].vs_3v  = status & PCSR_S1_VS1    ? 0 : 1;
-	state->state[1].vs_Xv  = status & PCSR_S1_VS2    ? 0 : 1;
-
-	return 1;
-}
+	unsigned long status = sa1111_readl(pcmcia->mapbase + SA1111_PCSR);
 
-int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-	int ret = 0;
+	switch (sock) {
+	case 0:
+		state->detect = status & PCSR_S0_DETECT ? 0 : 1;
+		state->ready  = status & PCSR_S0_READY  ? 1 : 0;
+		state->bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
+		state->bvd2   = status & PCSR_S0_BVD2   ? 1 : 0;
+		state->wrprot = status & PCSR_S0_WP     ? 1 : 0;
+		state->vs_3v  = status & PCSR_S0_VS1    ? 0 : 1;
+		state->vs_Xv  = status & PCSR_S0_VS2    ? 0 : 1;
+		break;
 
-	switch (info->sock) {
-	case 0:	info->irq = IRQ_S0_READY_NINT;	break;
-	case 1: info->irq = IRQ_S1_READY_NINT;	break;
-	default: ret = 1;
+	case 1:
+		state->detect = status & PCSR_S1_DETECT ? 0 : 1;
+		state->ready  = status & PCSR_S1_READY  ? 1 : 0;
+		state->bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
+		state->bvd2   = status & PCSR_S1_BVD2   ? 1 : 0;
+		state->wrprot = status & PCSR_S1_WP     ? 1 : 0;
+		state->vs_3v  = status & PCSR_S1_VS1    ? 0 : 1;
+		state->vs_Xv  = status & PCSR_S1_VS2    ? 0 : 1;
+		break;
 	}
-
-	return ret;
 }
 
-int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+int sa1111_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
 	unsigned int rst, flt, wait, pse, irq, pccr_mask, val;
 	unsigned long flags;
 
-	switch (conf->sock) {
+	switch (sock) {
 	case 0:
 		rst = PCCR_S0_RST;
 		flt = PCCR_S0_FLT;
@@ -161,11 +155,6 @@
 	sa1111_writel(val, pcmcia->mapbase + SA1111_PCCR);
 	local_irq_restore(flags);
 
-	if (conf->irq)
-		enable_irq(irq);
-	else
-		disable_irq(irq);
-
 	return 0;
 }
 
@@ -207,28 +196,28 @@
 	sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR);
 
 #ifdef CONFIG_SA1100_ADSBITSY
-	pcmcia_adsbitsy_init();
+	pcmcia_adsbitsy_init(dev);
 #endif
 #ifdef CONFIG_SA1100_BADGE4
-	pcmcia_badge4_init();
+	pcmcia_badge4_init(dev);
 #endif
 #ifdef CONFIG_SA1100_GRAPHICSMASTER
-	pcmcia_graphicsmaster_init();
+	pcmcia_graphicsmaster_init(dev);
 #endif
 #ifdef CONFIG_SA1100_JORNADA720
-	pcmcia_jornada720_init();
+	pcmcia_jornada720_init(dev);
 #endif
 #ifdef CONFIG_ASSABET_NEPONSET
-	pcmcia_neponset_init();
+	pcmcia_neponset_init(dev);
 #endif
 #ifdef CONFIG_SA1100_PFS168
-	pcmcia_pfs_init();
+	pcmcia_pfs_init(dev);
 #endif
 #ifdef CONFIG_SA1100_PT_SYSTEM3
-	pcmcia_system3_init();
+	pcmcia_system3_init(dev);
 #endif
 #ifdef CONFIG_SA1100_XP860
-	pcmcia_xp860_init();
+	pcmcia_xp860_init(dev);
 #endif
 	return 0;
 }
@@ -238,28 +227,28 @@
 	struct sa1111_dev *sadev = SA1111_DEV(dev);
 
 #ifdef CONFIG_SA1100_ADSBITSY
-	pcmcia_adsbitsy_exit();
+	pcmcia_adsbitsy_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_BADGE4
-	pcmcia_badge4_exit();
+	pcmcia_badge4_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_GRAPHICSMASTER
-	pcmcia_graphicsmaster_exit();
+	pcmcia_graphicsmaster_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_JORNADA720
-	pcmcia_jornada720_exit();
+	pcmcia_jornada720_exit(dev);
 #endif
 #ifdef CONFIG_ASSABET_NEPONSET
-	pcmcia_neponset_exit();
+	pcmcia_neponset_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_PFS168
-	pcmcia_pfs_exit();
+	pcmcia_pfs_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_PT_SYSTEM3
-	pcmcia_system3_exit();
+	pcmcia_system3_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_XP860
-	pcmcia_xp860_exit();
+	pcmcia_xp860_exit(dev);
 #endif
 
 	release_mem_region(sadev->res.start, 512);
@@ -282,6 +271,7 @@
 	.drv = {
 		.name		= "sa1111-pcmcia",
 		.bus		= &sa1111_bus_type,
+		.devclass	= &pcmcia_socket_class,
 		.probe		= pcmcia_probe,
 		.remove		= __devexit_p(pcmcia_remove),
 		.suspend	= pcmcia_suspend,
diff -Nru a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h
--- a/drivers/pcmcia/sa1111_generic.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/pcmcia/sa1111_generic.h	Tue Mar  4 19:30:13 2003
@@ -1,7 +1,14 @@
 extern int sa1111_pcmcia_init(struct pcmcia_init *);
 extern int sa1111_pcmcia_shutdown(void);
-extern int sa1111_pcmcia_socket_state(struct pcmcia_state_array *);
-extern int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *);
-extern int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *);
+extern void sa1111_pcmcia_socket_state(int sock, struct pcmcia_state *);
+extern int sa1111_pcmcia_configure_socket(int sock, const struct pcmcia_configure *);
 extern int sa1111_pcmcia_socket_init(int);
 extern int sa1111_pcmcia_socket_suspend(int);
+
+
+extern int pcmcia_jornada720_init(struct device *);
+extern void pcmcia_jornada720_exit(struct device *);
+
+extern int pcmcia_neponset_init(struct device *);
+extern void pcmcia_neponset_exit(struct device *);
+
diff -Nru a/drivers/pnp/interface.c b/drivers/pnp/interface.c
--- a/drivers/pnp/interface.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/pnp/interface.c	Tue Mar  4 19:30:04 2003
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/stat.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 #include "base.h"
diff -Nru a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
--- a/drivers/s390/block/dasd.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/s390/block/dasd.c	Tue Mar  4 19:30:08 2003
@@ -1582,7 +1582,7 @@
 
 /*
  * Cancels a request that was started with dasd_sleep_on_req.
- * This is usefull to timeout requests. The request will be
+ * This is useful to timeout requests. The request will be
  * terminated if it is currently in i/o.
  * Returns 1 if the request has been terminated.
  */
diff -Nru a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
--- a/drivers/s390/block/dasd_3990_erp.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/s390/block/dasd_3990_erp.c	Tue Mar  4 19:30:13 2003
@@ -197,7 +197,7 @@
  * DASD_3990_ERP_CLEANUP 
  *
  * DESCRIPTION
- *   Removes the already build but not neccessary ERP request and sets
+ *   Removes the already build but not necessary ERP request and sets
  *   the status of the original cqr / erp to the given (final) status
  *
  *  PARAMETER
diff -Nru a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
--- a/drivers/s390/block/dasd_diag.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/s390/block/dasd_diag.c	Tue Mar  4 19:30:04 2003
@@ -467,7 +467,7 @@
  * the diag_bio_t for each block has 16 bytes. 
  * That makes:
  * (8192 - 96 - 8) / 16 = 505.5 blocks at maximum.
- * We want to fit two into the available memory so that we can immediatly
+ * We want to fit two into the available memory so that we can immediately
  * start the next request if one finishes off. That makes 252.75 blocks
  * for one request. Give a little safety and the result is 240.
  */
diff -Nru a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
--- a/drivers/s390/block/dasd_eckd.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/s390/block/dasd_eckd.c	Tue Mar  4 19:30:03 2003
@@ -19,7 +19,7 @@
  * 10/04/00 changed RW-CCWS to R/W Key and Data
  * 10/10/00 reverted last change according to ESS exploitation
  * 10/10/00 now dequeuing init_cqr before freeing *ouch*
- * 26/10/00 fixed ITPM20144ASC (problems when accesing a device formatted by VIF)
+ * 26/10/00 fixed ITPM20144ASC (problems when accessing a device formatted by VIF)
  * 01/23/01 fixed kmalloc statement in dump_sense to be GFP_ATOMIC
  *	    fixed partition handling and HDIO_GETGEO
  * 2002/01/04 Created 2.4-2.5 compatibility mode
@@ -1427,7 +1427,7 @@
  * addition we have one define extent ccw + 16 bytes of data and one
  * locate record ccw + 16 bytes of data. That makes:
  * (8192 - 24 - 136 - 8 - 16 - 8 - 16) / 16 = 499 blocks at maximum.
- * We want to fit two into the available memory so that we can immediatly
+ * We want to fit two into the available memory so that we can immediately
  * start the next request if one finishes off. That makes 249.5 blocks
  * for one request. Give a little safety and the result is 240.
  */
diff -Nru a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
--- a/drivers/s390/block/dasd_fba.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/s390/block/dasd_fba.c	Tue Mar  4 19:30:11 2003
@@ -389,7 +389,7 @@
  * locate record ccw for each block (stupid devices!) + 16 bytes of data.
  * That makes:
  * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum.
- * We want to fit two into the available memory so that we can immediatly
+ * We want to fit two into the available memory so that we can immediately
  * start the next request if one finishes off. That makes 100.1 blocks
  * for one request. Give a little safety and the result is 96.
  */
diff -Nru a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
--- a/drivers/s390/char/con3215.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/s390/char/con3215.c	Tue Mar  4 19:30:11 2003
@@ -312,10 +312,10 @@
 }
 
 /*
- * Function to conditionally start an IO. A read is started immediatly,
- * a write is only started immediatly if the flush flag is on or the
+ * Function to conditionally start an IO. A read is started immediately,
+ * a write is only started immediately if the flush flag is on or the
  * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not
- * done immediatly a timer is started with a delay of RAW3215_TIMEOUT.
+ * done immediately a timer is started with a delay of RAW3215_TIMEOUT.
  */
 static inline void
 raw3215_try_io(struct raw3215_info *raw)
diff -Nru a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
--- a/drivers/s390/char/sclp.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/s390/char/sclp.c	Tue Mar  4 19:30:10 2003
@@ -26,7 +26,7 @@
 #define SCLP_CORE_PRINT_HEADER "sclp low level driver: "
 
 /*
- * decides wether we make use of the macro MACHINE_IS_VM to
+ * decides whether we make use of the macro MACHINE_IS_VM to
  * configure the driver for VM at run time (a little bit
  * different behaviour); otherwise we use the default
  * settings in sclp_data.init_ioctls
@@ -481,8 +481,7 @@
 do_machine_quiesce(void)
 {
 	cpu_quiesce_map = cpu_online_map;
-	smp_call_function(do_load_quiesce_psw, NULL, 0, 0);
-	do_load_quiesce_psw(NULL);
+	on_each_cpu(do_load_quiesce_psw, NULL, 0, 0);
 }
 #else
 static void
diff -Nru a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
--- a/drivers/s390/char/sclp_rw.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/s390/char/sclp_rw.c	Tue Mar  4 19:30:08 2003
@@ -192,7 +192,7 @@
 	 * under VM (Why does VM interpret \n but the native machine doesn't ?)
 	 *
 	 * Depending on i/o-control setting the message is always written
-	 * immediatly or we wait for a final new line maybe coming with the
+	 * immediately or we wait for a final new line maybe coming with the
 	 * next message. Besides we avoid a buffer overrun by writing its
 	 * content.
 	 *
diff -Nru a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
--- a/drivers/s390/cio/device_fsm.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/s390/cio/device_fsm.c	Tue Mar  4 19:30:09 2003
@@ -288,7 +288,7 @@
 	}
 	/* Is Set Path Group supported? */
 	if (!cdev->private->flags.pgid_supp) {
-		/* No, set state online immediatly. */
+		/* No, set state online immediately. */
 		ccw_device_done(cdev, DEV_STATE_ONLINE);
 		return 0;
 	}
@@ -333,7 +333,7 @@
 		return -EBUSY;
 	/* Is Set Path Group supported? */
 	if (!cdev->private->flags.pgid_supp) {
-		/* No, set state offline immediatly. */
+		/* No, set state offline immediately. */
 		ccw_device_done(cdev, DEV_STATE_OFFLINE);
 		return 0;
 	}
diff -Nru a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
--- a/drivers/s390/cio/qdio.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/s390/cio/qdio.h	Tue Mar  4 19:30:05 2003
@@ -27,7 +27,7 @@
 #define IQDIO_DELAY_TARGET 0
 #define QDIO_BUSY_BIT_PATIENCE 2000 /* in microsecs */
 #define IQDIO_GLOBAL_LAPS 2 /* GLOBAL_LAPS are not used as we */
-#define IQDIO_GLOBAL_LAPS_INT 1 /* dont global summary */
+#define IQDIO_GLOBAL_LAPS_INT 1 /* don't global summary */
 #define IQDIO_LOCAL_LAPS 4
 #define IQDIO_LOCAL_LAPS_INT 1
 #define IQDIO_GLOBAL_SUMMARY_CC_MASK 2
diff -Nru a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h
--- a/drivers/s390/net/iucv.h	Tue Mar  4 19:30:14 2003
+++ b/drivers/s390/net/iucv.h	Tue Mar  4 19:30:14 2003
@@ -214,7 +214,7 @@
  *        pgm_data- application data passed to interrupt handlers 
  * Output: NA                                                     
  * Return: address of handler                                     
- *         (0) - Error occured, registration not completed.
+ *         (0) - Error occurred, registration not completed.
  * NOTE: Exact cause of failure will be recorded in syslog.                        
 */
 iucv_handle_t iucv_register_program (uchar pgmname[16],
diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
--- a/drivers/s390/net/lcs.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/s390/net/lcs.c	Tue Mar  4 19:30:04 2003
@@ -1206,7 +1206,7 @@
 	card->stats.tx_packets++;
 	dev_kfree_skb(skb);
 	if (card->tx_emitted <= 0)
-		/* If this is the first tx buffer emit it immediatly. */
+		/* If this is the first tx buffer emit it immediately. */
 		__lcs_emit_txbuffer(card);
 	return 0;
 }
diff -Nru a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
--- a/drivers/sbus/char/envctrl.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/sbus/char/envctrl.c	Tue Mar  4 19:30:05 2003
@@ -810,7 +810,7 @@
 		pchild->fan_mask |= chnls_mask[(pchild->chnl_array[i]).chnl_no];
 
 	/* We only need to know if this child has fan status monitored.
-	 * We dont care which channels since we have the mask already.
+	 * We don't care which channels since we have the mask already.
 	 */
 	pchild->mon_type[0] = ENVCTRL_FANSTAT_MON;
 }
@@ -842,7 +842,7 @@
 	}
 
 	/* We only need to know if this child has global addressing 
-	 * line monitored.  We dont care which channels since we know 
+	 * line monitored.  We don't care which channels since we know 
 	 * the mask already (ENVCTRL_GLOBALADDR_ADDR_MASK).
 	 */
 	pchild->mon_type[0] = ENVCTRL_GLOBALADDR_MON;
@@ -858,7 +858,7 @@
 		pchild->voltage_mask |= chnls_mask[(pchild->chnl_array[i]).chnl_no];
 
 	/* We only need to know if this child has voltage status monitored.
-	 * We dont care which channels since we have the mask already.
+	 * We don't care which channels since we have the mask already.
 	 */
 	pchild->mon_type[0] = ENVCTRL_VOLTAGESTAT_MON;
 }
@@ -1115,7 +1115,7 @@
 		       envctrl_dev.minor);
 	}
 
-	/* Note above traversal routine post-incremented 'i' to accomodate 
+	/* Note above traversal routine post-incremented 'i' to accommodate 
 	 * a next child device, so we decrement before reverse-traversal of
 	 * child devices.
 	 */
diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c
--- a/drivers/scsi/AM53C974.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/scsi/AM53C974.c	Tue Mar  4 19:30:08 2003
@@ -2091,7 +2091,7 @@
 		goto EXIT_ABORT;
 	}
 	msg[0] = AM53C974_read_8(FFREG);
-	if (!msg[0] & 0x80) {
+	if (!(msg[0] & 0x80)) {
 		printk("scsi%d: error: expecting IDENTIFY message, got ", instance->host_no);
 		print_msg(msg);
 		hostdata->aborted = 1;
diff -Nru a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
--- a/drivers/scsi/FlashPoint.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/FlashPoint.c	Tue Mar  4 19:30:05 2003
@@ -3846,7 +3846,7 @@
 	}
 	else
 	{
-		if(!currTar_Info->TarEEValue & EE_WIDE_SCSI)
+		if(!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
 		{
 			return(0);
 		}
@@ -7529,7 +7529,7 @@
  *
  *   $Workfile:   phase.c  $
  *
- *   Description:  Functions to intially handle the SCSI bus phase when
+ *   Description:  Functions to initially handle the SCSI bus phase when
  *                 the target asserts request (and the automation is not
  *                 enabled to handle the situation).
  *
@@ -10866,7 +10866,7 @@
  * Function: DiagEEPROM
  *
  * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
- *              neccessary.
+ *              necessary.
  *
  *---------------------------------------------------------------------*/
 
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	Tue Mar  4 19:30:13 2003
+++ b/drivers/scsi/Kconfig	Tue Mar  4 19:30:13 2003
@@ -1325,9 +1325,9 @@
 	bool "Include loadable firmware in driver"
 	depends on SCSI_QLOGIC_FC
   	help
-	  Say Y to include ISP2100 Fabric Initiator/Target Firmware, with
+	  Say Y to include ISP2X00 Fabric Initiator/Target Firmware, with
 	  expanded LUN addressing and FcTape (FCP-2) support, in the
-	  Qlogic QLA 1280 driver. This is required on some platforms.
+	  qlogicfc driver. This is required on some platforms.
 
 config SCSI_QLOGIC_1280
 	tristate "Qlogic QLA 1280 SCSI support"
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile	Tue Mar  4 19:30:12 2003
+++ b/drivers/scsi/Makefile	Tue Mar  4 19:30:12 2003
@@ -120,13 +120,11 @@
 obj-$(CONFIG_BLK_DEV_SR)	+= sr_mod.o
 obj-$(CONFIG_CHR_DEV_SG)	+= sg.o
 
-scsi_mod-objs	:= scsi.o hosts.o scsi_ioctl.o constants.o scsicam.o \
-		   scsi_error.o scsi_lib.o scsi_scan.o scsi_syms.o \
-		   scsi_sysfs.o
-
-ifdef CONFIG_PROC_FS
-scsi_mod-objs	+= scsi_proc.o
-endif
+scsi_mod-y			+= scsi.o hosts.o scsi_ioctl.o constants.o \
+				   scsicam.o scsi_error.o scsi_lib.o \
+				   scsi_scan.o scsi_syms.o scsi_sysfs.o
+scsi_mod-$(CONFIG_PROC_FS)	+= scsi_proc.o
+scsi_mod-$(CONFIG_X86_PC9800)	+= scsi_pc98.o
 			
 sd_mod-objs	:= sd.o
 sr_mod-objs	:= sr.o sr_ioctl.o sr_vendor.o
diff -Nru a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
--- a/drivers/scsi/NCR5380.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/NCR5380.c	Tue Mar  4 19:30:05 2003
@@ -2750,7 +2750,7 @@
 	phase = PHASE_MSGIN;
 	NCR5380_transfer_pio(instance, &phase, &len, &data);
 
-	if (!msg[0] & 0x80) {
+	if (!(msg[0] & 0x80)) {
 		printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no);
 		print_msg(msg);
 		abort = 1;
diff -Nru a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
--- a/drivers/scsi/NCR53C9x.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/NCR53C9x.c	Tue Mar  4 19:30:05 2003
@@ -2942,7 +2942,7 @@
 /* Target negotiates for synchronous transfers before we do, this
  * is legal although very strange.  What is even funnier is that
  * the SCSI2 standard specifically recommends against targets doing
- * this because so many initiators cannot cope with this occuring.
+ * this because so many initiators cannot cope with this occurring.
  */
 static int target_with_ants_in_pants(struct NCR_ESP *esp,
 				     Scsi_Cmnd *SCptr,
diff -Nru a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
--- a/drivers/scsi/NCR53c406a.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/scsi/NCR53c406a.c	Tue Mar  4 19:30:08 2003
@@ -472,7 +472,7 @@
 		return 0;
 	}
 
-	DEB(printk("NCR53c406a BIOS found at %X\n", (unsigned int) bios_base);
+	DEB(printk("NCR53c406a BIOS found at 0x%x\n", (unsigned int) bios_base);
 	    );
 #endif				/* USE_BIOS */
 
@@ -487,14 +487,14 @@
 	} else {
 		for (i = 0; i < PORT_COUNT && !port_base; i++) {
 			if (!request_region(ports[i], 0x10, "NCR53c406a")) {
-				DEB(printk("NCR53c406a: port %x in use\n", ports[i]));
+				DEB(printk("NCR53c406a: port 0x%x in use\n", ports[i]));
 			} else {
-				VDEB(printk("NCR53c406a: port %x available\n", ports[i]));
+				VDEB(printk("NCR53c406a: port 0x%x available\n", ports[i]));
 				outb(C5_IMG, ports[i] + 0x0d);	/* reg set 1 */
 				if ((inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7 && (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7 && (inb(ports[i] + 0x0e) & 0xf8) == 0x58) {
 					port_base = ports[i];
 					VDEB(printk("NCR53c406a: Sig register valid\n"));
-					VDEB(printk("port_base=%x\n", port_base));
+					VDEB(printk("port_base=0x%x\n", port_base));
 					break;
 				}
 				release_region(ports[i], 0x10);
@@ -523,7 +523,7 @@
 	}
 #endif
 
-	DEB(printk("NCR53c406a: using port_base %x\n", port_base));
+	DEB(printk("NCR53c406a: using port_base 0x%x\n", port_base));
 
 	tpnt->present = 1;
 	tpnt->proc_name = "NCR53c406a";
@@ -611,11 +611,11 @@
 	for (i = 0; i < PORT_COUNT && !port_base; i++)
 		if (ports[i] == ints[1]) {
 			port_base = ints[1];
-			DEB(printk("NCR53c406a: Specified port_base 0x%X\n", port_base);
+			DEB(printk("NCR53c406a: Specified port_base 0x%x\n", port_base);
 			    )
 		}
 	if (!port_base) {
-		printk("NCR53c406a: Invalid PORTBASE 0x%X specified\n", ints[1]);
+		printk("NCR53c406a: Invalid PORTBASE 0x%x specified\n", ints[1]);
 		return;
 	}
 
@@ -638,7 +638,7 @@
 	if (ints[0] > 2)
 		fast_pio = ints[3];
 
-	DEB(printk("NCR53c406a: port_base=0x%X, irq=%d, fast_pio=%d\n", port_base, irq_level, fast_pio);)
+	DEB(printk("NCR53c406a: port_base=0x%x, irq=%d, fast_pio=%d\n", port_base, irq_level, fast_pio);)
 }
 
 __setup("ncr53c406a=", NCR53c406a_setup);
diff -Nru a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
--- a/drivers/scsi/aacraid/comminit.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/aacraid/comminit.c	Tue Mar  4 19:30:04 2003
@@ -210,7 +210,7 @@
 
 /**
  *	aac_comm_init	-	Initialise FSA data structures
- *	@dev:	Adapter to intialise
+ *	@dev:	Adapter to initialise
  *
  *	Initializes the data structures that are required for the FSA commuication
  *	interface to operate. 
diff -Nru a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
--- a/drivers/scsi/aacraid/commsup.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/scsi/aacraid/commsup.c	Tue Mar  4 19:30:11 2003
@@ -79,7 +79,7 @@
  *	fib_setup	-	setup the fibs
  *	@dev: Adapter to set up
  *
- *	Allocate the PCI space for the fibs, map it and then intialise the
+ *	Allocate the PCI space for the fibs, map it and then initialise the
  *	fib area, the unmapped fib data and also the free list
  */
 
diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
--- a/drivers/scsi/aacraid/linit.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/scsi/aacraid/linit.c	Tue Mar  4 19:30:07 2003
@@ -60,7 +60,7 @@
 #define AAC_DRIVERNAME	"aacraid"
 
 MODULE_AUTHOR("Red Hat Inc and Adaptec");
-MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, Adaptec 2120S, 2200S, 5400S, and HP NetRAID-4M devices. http://domsch.com/linux/ or http://linux.adaptec.com");
+MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, PERC 320/DC, Adaptec 2120S, 2200S, 5400S, and HP NetRAID-4M devices. http://domsch.com/linux/ or http://linux.adaptec.com");
 MODULE_LICENSE("GPL");
 MODULE_PARM(nondasd, "i");
 MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
@@ -96,6 +96,7 @@
 	{ 0x9005, 0x0285, 0x9005, 0x0286, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2120S   ", 1 }, /* Adaptec 2120S (Crusader)*/
 	{ 0x9005, 0x0285, 0x9005, 0x0285, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2 }, /* Adaptec 2200S (Vulcan)*/
 	{ 0x9005, 0x0285, 0x9005, 0x0287, aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2 }, /* Adaptec 2200S (Vulcan-2m)*/
+	{ 0x9005, 0x0285, 0x1028, 0x0287, aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2 }, /* Dell PERC 320/DC */
 	{ 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4 }, /* Adaptec 5400S (Mustang)*/
 	{ 0x1011, 0x0046, 0x9005, 0x0364, aac_sa_init, "aacraid",  "ADAPTEC ", "AAC-364         ", 4 }, /* Adaptec 5400S (Mustang)*/
 	{ 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL    ", "PERCRAID        ", 4 }, /* Dell PERC2 "Quad Channel" */
@@ -110,10 +111,10 @@
 static int aac_cfg_release(struct inode * inode,struct file * file);
 
 static struct file_operations aac_cfg_fops = {
-	owner: THIS_MODULE,
-	ioctl: aac_cfg_ioctl,
-	open: aac_cfg_open,
-	release: aac_cfg_release
+	.owner		= THIS_MODULE,
+	.ioctl		= aac_cfg_ioctl,
+	.open		= aac_cfg_open,
+	.release	= aac_cfg_release
 };
 
 static int aac_detect(Scsi_Host_Template *);
diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/aha152x.c	Tue Mar  4 19:30:04 2003
@@ -1131,7 +1131,7 @@
 	while ( setup_count<ARRAY_SIZE(setup) && (dev=pnp_find_dev(NULL, ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), dev)) ) {
 		if (pnp_device_attach(dev) < 0)
 			continue;
-		if (pnp_activate_dev(dev, NULL) < 0) {
+		if (pnp_activate_dev(dev) < 0) {
 			pnp_device_detach(dev);
 			continue;
 		}
@@ -2663,7 +2663,7 @@
 		 * STCNT to trigger ENSWRAP interrupt, instead of
 		 * polling for DFIFOFULL
 		 */
-		the_time=jiffies + 10*HZ;
+		the_time=jiffies + 100*HZ;
 		while(TESTLO(DMASTAT, DFIFOFULL|INTSTAT) && time_before(jiffies,the_time))
 			barrier();
 
@@ -2676,7 +2676,7 @@
 		if(TESTHI(DMASTAT, DFIFOFULL)) {
 			fifodata = 128;
 		} else {
-			the_time=jiffies + 10*HZ;
+			the_time=jiffies + 100*HZ;
 			while(TESTLO(SSTAT2, SEMPTY) && time_before(jiffies,the_time))
 				barrier();
 
@@ -2832,7 +2832,7 @@
 			CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
 		}
 
-		the_time=jiffies + 10*HZ;
+		the_time=jiffies + 100*HZ;
 		while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT) && time_before(jiffies,the_time))
 			barrier();
 
diff -Nru a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/scsi/aha1542.c	Tue Mar  4 19:30:09 2003
@@ -1161,7 +1161,7 @@
 			if(pnp_device_attach(pdev)<0)
 				continue;
 			
-			if(pnp_activate_dev(pdev, NULL)<0) {
+			if(pnp_activate_dev(pdev)<0) {
 				pnp_device_detach(pdev);
 				continue;
 			}
diff -Nru a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
--- a/drivers/scsi/aic7xxx/aic79xx.h	Tue Mar  4 19:30:11 2003
+++ b/drivers/scsi/aic7xxx/aic79xx.h	Tue Mar  4 19:30:11 2003
@@ -180,7 +180,7 @@
 
 /*
  * Define the size of our QIN and QOUT FIFOs.  They must be a power of 2
- * in size and accomodate as many transactions as can be queued concurrently.
+ * in size and accommodate as many transactions as can be queued concurrently.
  */
 #define	AHD_QIN_SIZE	AHD_MAX_QUEUE
 #define	AHD_QOUT_SIZE	AHD_MAX_QUEUE
@@ -365,7 +365,7 @@
 
 /*
  * The driver keeps up to MAX_SCB scb structures per card in memory.  The SCB
- * consists of a "hardware SCB" mirroring the fields availible on the card
+ * consists of a "hardware SCB" mirroring the fields available on the card
  * and additional information the kernel stores for each transaction.
  *
  * To minimize space utilization, a portion of the hardware scb stores
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
--- a/drivers/scsi/aic7xxx/aic79xx_core.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c	Tue Mar  4 19:30:03 2003
@@ -516,7 +516,7 @@
 	ahd_dump_card_state(ahd);
 	panic("BRKADRINT");
 
-	/* Tell everyone that this HBA is no longer availible */
+	/* Tell everyone that this HBA is no longer available */
 	ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
 		       CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
 		       CAM_NO_HBA);
@@ -3755,9 +3755,9 @@
 				    devinfo->target, &tstate);
 
 	/*
-	 * Parse as much of the message as is availible,
+	 * Parse as much of the message as is available,
 	 * rejecting it if we don't support it.  When
-	 * the entire message is availible and has been
+	 * the entire message is available and has been
 	 * handled, return MSGLOOP_MSGCOMPLETE, indicating
 	 * that we have parsed an entire message.
 	 *
@@ -6016,7 +6016,7 @@
 	 * Now that termination is set, wait for up
 	 * to 500ms for our transceivers to settle.  If
 	 * the adapter does not have a cable attached,
-	 * the tranceivers may never settle, so don't
+	 * the transceivers may never settle, so don't
 	 * complain if we fail here.
 	 */
 	for (wait = 10000;
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c	Tue Mar  4 19:30:09 2003
@@ -801,7 +801,6 @@
 
 /************************  Host template entry points *************************/
 static int	   ahd_linux_detect(Scsi_Host_Template *);
-static int	   ahd_linux_release(struct Scsi_Host *);
 static const char *ahd_linux_info(struct Scsi_Host *);
 static int	   ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
@@ -811,6 +810,7 @@
 static int	   ahd_linux_biosparam(struct scsi_device*,
 				       struct block_device*, sector_t, int[]);
 #else
+static int	   ahd_linux_release(struct Scsi_Host *);
 static void	   ahd_linux_select_queue_depth(struct Scsi_Host *host,
 						Scsi_Device *scsi_devs);
 static int	   ahd_linux_biosparam(Disk *, kdev_t, int[]);
@@ -874,7 +874,7 @@
 	ahd_list_lockinit();
 
 #ifdef CONFIG_PCI
-	ahd_linux_pci_probe(template);
+	ahd_linux_pci_init();
 #endif
 
 	/*
@@ -894,6 +894,7 @@
 	return (found);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 /*
  * Free the passed in Scsi_Host memory structures prior to unloading the
  * module.
@@ -925,6 +926,7 @@
 	ahd_list_unlock(&l);
 	return (0);
 }
+#endif
 
 /*
  * Return a string describing the driver.
@@ -1664,9 +1666,9 @@
 }
 
 Scsi_Host_Template aic79xx_driver_template = {
+	.module			= THIS_MODULE,
+	.name			= "aic79xx",
 	.proc_info		= ahd_linux_proc_info,
-	.detect			= ahd_linux_detect,
-	.release		= ahd_linux_release,
 	.info			= ahd_linux_info,
 	.queuecommand		= ahd_linux_queue,
 	.eh_abort_handler	= ahd_linux_abort,
@@ -1698,18 +1700,17 @@
 #endif
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	.name			= "aic79xx",
 	.slave_alloc		= ahd_linux_slave_alloc,
 	.slave_configure	= ahd_linux_slave_configure,
 	.slave_destroy		= ahd_linux_slave_destroy,
 #else
+	.detect			= ahd_linux_detect,
+	.release		= ahd_linux_release,
 	.select_queue_depths	= ahd_linux_select_queue_depth,
 	.use_new_eh_code	= 1,
 #endif
 };
 
-#define driver_template aic79xx_driver_template
-#include "scsi_module.c"
 /**************************** Tasklet Handler *********************************/
 
 static void
@@ -2381,9 +2382,8 @@
 		ahd_set_name(ahd, new_name);
 	}
 	host->unique_id = ahd->unit;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	scsi_set_device(host, &ahd->dev_softc->dev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) && \
+    LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
 	scsi_set_pci_device(host, ahd->dev_softc);
 #endif
 	ahd_linux_initialize_scsi_bus(ahd);
@@ -2410,6 +2410,10 @@
 	ahd_intr_enable(ahd, TRUE);
 	ahd_linux_start_dv(ahd);
 	ahd_unlock(ahd, &s);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	scsi_add_host(host, &ahd->dev_softc->dev);
+#endif
 	return (0);
 }
 
@@ -2556,8 +2560,12 @@
 					 __WCLONE) == -ERESTARTSYS);
 		}
 		ahd_teardown_runq_tasklet(ahd);
-		if (ahd->platform_data->host != NULL)
+		if (ahd->platform_data->host != NULL) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+			scsi_remove_host(ahd->platform_data->host);
+#endif
 			scsi_unregister(ahd->platform_data->host);
+		}
 
 		/* destroy all of the device and target objects */
 		for (i = 0; i < AHD_NUM_TARGETS; i++) {
@@ -2595,21 +2603,17 @@
 					   0x1000);
 #endif
 		}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		/* XXX Need an instance detach in the PCI code */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && \
+    LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+    		/*
+		 * In 2.4 we detach from the scsi midlayer before the PCI
+		 * layer invokes our remove callback.
+		 */
 		if (ahd->dev_softc != NULL)
 			ahd->dev_softc->driver = NULL;
 #endif
 		free(ahd->platform_data, M_DEVBUF);
 	}
-	if (TAILQ_EMPTY(&ahd_tailq)) {
-		unregister_reboot_notifier(&ahd_linux_notifier);
-#ifdef CONFIG_PCI
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		pci_unregister_driver(&aic79xx_pci_driver);
-#endif
-#endif
-	}
 }
 
 void
@@ -5315,3 +5319,30 @@
 		}
 	}
 }
+
+static int __init ahd_linux_init(void)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+       return (ahd_linux_detect(&aic79xx_driver_template) ? 0 : -ENODEV);
+#else
+	scsi_register_module(MODULE_SCSI_HA, &aic79xx_driver_template);
+	if (!driver_template.present) {
+		scsi_unregister_module(MODULE_SCSI_HA,
+				       &aic79xx_driver_template);
+		return (-ENODEV);
+	}
+
+	return (0);
+#endif
+}
+
+static void __exit ahd_linux_exit(void)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	scsi_unregister_module(MODULE_SCSI_HA, &aic79xx_driver_template);
+#endif
+	ahd_linux_pci_exit();
+}
+
+module_init(ahd_linux_init);
+module_exit(ahd_linux_exit);
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h	Tue Mar  4 19:30:10 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h	Tue Mar  4 19:30:10 2003
@@ -952,7 +952,8 @@
 #include <linux/bios32.h>
 #endif
 
-int			 ahd_linux_pci_probe(Scsi_Host_Template *);
+int			 ahd_linux_pci_init(void);
+void			 ahd_linux_pci_exit(void);
 int			 ahd_pci_map_registers(struct ahd_softc *ahd);
 int			 ahd_pci_map_int(struct ahd_softc *ahd);
 
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c	Tue Mar  4 19:30:05 2003
@@ -183,14 +183,21 @@
 	}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	pci_set_drvdata(pdev, ahd);
-	if (aic79xx_detect_complete)
+	if (aic79xx_detect_complete) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 		ahd_linux_register_host(ahd, &aic79xx_driver_template);
+#else
+		printf("aic79xx: ignoring PCI device found after "
+		       "initialization\n");
+		return (-ENODEV);
+#endif
+	}
 #endif
 	return (0);
 }
 
 int
-ahd_linux_pci_probe(Scsi_Host_Template *template)
+ahd_linux_pci_init(void)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	return (pci_module_init(&aic79xx_pci_driver));
@@ -217,6 +224,12 @@
 	}
 	return (found);
 #endif
+}
+
+void
+ahd_linux_pci_exit(void)
+{
+	pci_unregister_driver(&aic79xx_pci_driver);
 }
 
 static int
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h
--- a/drivers/scsi/aic7xxx/aic7xxx.h	Tue Mar  4 19:30:09 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx.h	Tue Mar  4 19:30:09 2003
@@ -372,7 +372,7 @@
 
 /*
  * The driver keeps up to MAX_SCB scb structures per card in memory.  The SCB
- * consists of a "hardware SCB" mirroring the fields availible on the card
+ * consists of a "hardware SCB" mirroring the fields available on the card
  * and additional information the kernel stores for each transaction.
  *
  * To minimize space utilization, a portion of the hardware scb stores
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c	Tue Mar  4 19:30:08 2003
@@ -389,7 +389,7 @@
 
 	ahc_dump_card_state(ahc);
 
-	/* Tell everyone that this HBA is no longer availible */
+	/* Tell everyone that this HBA is no longer available */
 	ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
 		       CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
 		       CAM_NO_HBA);
@@ -2988,9 +2988,9 @@
 	targ_scsirate = tinfo->scsirate;
 
 	/*
-	 * Parse as much of the message as is availible,
+	 * Parse as much of the message as is available,
 	 * rejecting it if we don't support it.  When
-	 * the entire message is availible and has been
+	 * the entire message is available and has been
 	 * handled, return MSGLOOP_MSGCOMPLETE, indicating
 	 * that we have parsed an entire message.
 	 *
@@ -4999,7 +4999,7 @@
 		/*
 		 * Wait for up to 500ms for our transceivers
 		 * to settle.  If the adapter does not have
-		 * a cable attached, the tranceivers may
+		 * a cable attached, the transceivers may
 		 * never settle, so don't complain if we
 		 * fail here.
 		 */
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c	Tue Mar  4 19:30:04 2003
@@ -108,7 +108,7 @@
  * but are not limited to:
  *
  *  1: Import of the latest FreeBSD sequencer code for this driver
- *  2: Modification of kernel code to accomodate different sequencer semantics
+ *  2: Modification of kernel code to accommodate different sequencer semantics
  *  3: Extensive changes throughout kernel portion of driver to improve
  *     abort/reset processing and error hanndling
  *  4: Other work contributed by various people on the Internet
@@ -875,7 +875,7 @@
 	ahc_list_lockinit();
 
 #ifdef CONFIG_PCI
-	ahc_linux_pci_probe(template);
+	ahc_linux_pci_init();
 #endif
 
 	if (aic7xxx_no_probe == 0)
@@ -1266,9 +1266,9 @@
 }
 
 Scsi_Host_Template aic7xxx_driver_template = {
+	.module			= THIS_MODULE,
+	.name			= "aic7xxx",
 	.proc_info		= ahc_linux_proc_info,
-	.detect			= ahc_linux_detect,
-	.release		= ahc_linux_release,
 	.info			= ahc_linux_info,
 	.queuecommand		= ahc_linux_queue,
 	.eh_abort_handler	= ahc_linux_abort,
@@ -1300,19 +1300,17 @@
 #endif
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	.name			= "aic7xxx",
 	.slave_alloc		= ahc_linux_slave_alloc,
 	.slave_configure	= ahc_linux_slave_configure,
 	.slave_destroy		= ahc_linux_slave_destroy,
 #else
+	.detect			= ahc_linux_detect,
+	.release		= ahc_linux_release,
 	.select_queue_depths	= ahc_linux_select_queue_depth,
 	.use_new_eh_code	= 1,
 #endif
 };
 
-#define driver_template aic7xxx_driver_template
-#include "scsi_module.c"
-
 /**************************** Tasklet Handler *********************************/
 
 static void
@@ -1861,9 +1859,8 @@
 		ahc_set_name(ahc, new_name);
 	}
 	host->unique_id = ahc->unit;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	scsi_set_device(host, &ahc->dev_softc->dev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) && \
+    LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
 	scsi_set_pci_device(host, ahc->dev_softc);
 #endif
 	ahc_linux_initialize_scsi_bus(ahc);
@@ -1897,6 +1894,10 @@
 	ahc_intr_enable(ahc, TRUE);
 	ahc_linux_start_dv(ahc);
 	ahc_unlock(ahc, &s);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL));
+#endif
 	return (0);
 }
 
@@ -2075,8 +2076,12 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 		tasklet_kill(&ahc->platform_data->runq_tasklet);
 #endif
-		if (ahc->platform_data->host != NULL)
+		if (ahc->platform_data->host != NULL) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+			scsi_remove_host(ahc->platform_data->host);
+#endif
 			scsi_unregister(ahc->platform_data->host);
+		}
 
 		/* destroy all of the device and target objects */
 		for (i = 0; i < AHC_NUM_TARGETS; i++) {
@@ -2112,19 +2117,16 @@
 #endif
 		}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		/* XXX Need an instance detach in the PCI code */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+		/*
+		 * In 2.4 we detach from the scsi midlayer before the PCI
+		 * layer invokes our remove callback.
+		 */
 		if (ahc->dev_softc != NULL)
 			ahc->dev_softc->driver = NULL;
 #endif
-		free(ahc->platform_data, M_DEVBUF);
-	}
-	if (TAILQ_EMPTY(&ahc_tailq)) {
-		unregister_reboot_notifier(&ahc_linux_notifier);
-#ifdef CONFIG_PCI
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		pci_unregister_driver(&aic7xxx_pci_driver);
-#endif
 #endif
+		free(ahc->platform_data, M_DEVBUF);
 	}
 }
 
@@ -5182,3 +5184,51 @@
 		}
 	}
 }
+
+static int __init ahc_linux_init(void)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	return (ahc_linux_detect(&aic7xxx_driver_template) ? 0 : -ENODEV);
+#else
+	scsi_register_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
+	if (!driver_template.present) {
+		scsi_unregister_module(MODULE_SCSI_HA,
+				       &aic7xxx_driver_template);
+		return (-ENODEV);
+	}
+
+	return (0);
+#endif
+}
+
+static void __exit ahc_linux_exit(void)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	struct	ahc_softc *ahc;
+
+	ahc_linux_pci_exit();
+
+	/*
+	 * Get rid of the non-pci devices.  
+	 *
+	 * XXX(hch): switch over eisa support to new LDM-based API
+	 */
+	TAILQ_FOREACH(ahc, &ahc_tailq, links)
+		ahc_linux_release(ahc->platform_data->host);
+#else
+	scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
+
+	/*
+	 * In 2.4 we have to unregister from the PCI core _after_
+	 * unregistering from the scsi midlayer to avoid danling references.
+	 *
+	 * The 2.4 scsi midlayer is so f***ed..
+	 */
+	ahc_linux_pci_exit();
+#endif
+
+	unregister_reboot_notifier(&ahc_linux_notifier);
+}
+
+module_init(ahc_linux_init);
+module_exit(ahc_linux_exit);
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h	Tue Mar  4 19:30:07 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h	Tue Mar  4 19:30:07 2003
@@ -912,7 +912,8 @@
 #include <linux/bios32.h>
 #endif
 
-int			 ahc_linux_pci_probe(Scsi_Host_Template *);
+int			 ahc_linux_pci_init(void);
+void			 ahc_linux_pci_exit(void);
 int			 ahc_pci_map_registers(struct ahc_softc *ahc);
 int			 ahc_pci_map_int(struct ahc_softc *ahc);
 
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	Tue Mar  4 19:30:05 2003
@@ -179,14 +179,21 @@
 	}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	pci_set_drvdata(pdev, ahc);
-	if (aic7xxx_detect_complete)
+	if (aic7xxx_detect_complete) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 		ahc_linux_register_host(ahc, &aic7xxx_driver_template);
+#else
+		printf("aic7xxx: ignoring PCI device found after "
+		       "initialization\n");
+		return (-ENODEV);
+#endif
+	}
 #endif
 	return (0);
 }
 
 int
-ahc_linux_pci_probe(Scsi_Host_Template *template)
+ahc_linux_pci_init(void)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	return (pci_module_init(&aic7xxx_pci_driver));
@@ -213,6 +220,12 @@
 	}
 	return (found);
 #endif
+}
+
+void
+ahc_linux_pci_exit(void)
+{
+	pci_unregister_driver(&aic7xxx_pci_driver);
 }
 
 static int
diff -Nru a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
--- a/drivers/scsi/aic7xxx_old.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/scsi/aic7xxx_old.c	Tue Mar  4 19:30:08 2003
@@ -111,7 +111,7 @@
  * but are not limited to:
  *
  *  1: Import of the latest FreeBSD sequencer code for this driver
- *  2: Modification of kernel code to accomodate different sequencer semantics
+ *  2: Modification of kernel code to accommodate different sequencer semantics
  *  3: Extensive changes throughout kernel portion of driver to improve
  *     abort/reset processing and error hanndling
  *  4: Other work contributed by various people on the Internet
@@ -4609,8 +4609,8 @@
          * handler do the rest.  We don't want to unpause the sequencer yet
          * though so we'll return early.  We also have to make sure that
          * we clear the SEQINT *BEFORE* we set the REQINIT handler active
-         * or else it's possible on VLB cards to loose the first REQINIT
-         * interrupt.  Edge triggered EISA cards could also loose this
+         * or else it's possible on VLB cards to lose the first REQINIT
+         * interrupt.  Edge triggered EISA cards could also lose this
          * interrupt, although PCI and level triggered cards should not
          * have this problem since they continually interrupt the kernel
          * until we take care of the situation.
@@ -4945,9 +4945,9 @@
   target_mask = (0x01 << tindex);
 
   /*
-   * Parse as much of the message as is availible,
+   * Parse as much of the message as is available,
    * rejecting it if we don't support it.  When
-   * the entire message is availible and has been
+   * the entire message is available and has been
    * handled, return TRUE indicating that we have
    * parsed an entire message.
    */
@@ -10392,7 +10392,7 @@
   aic7xxx_done_cmds_complete(p);
   /* If the command was already complete or just completed, then we didn't
    * do a reset, return FAILED */
-  if(!scb->flags & SCB_ACTIVE)
+  if(!(scb->flags & SCB_ACTIVE))
     return FAILED;
 
   pause_sequencer(p);
@@ -10615,7 +10615,7 @@
   aic7xxx_done_cmds_complete(p);
   /* If the command was already complete or just completed, then we didn't
    * do a reset, return FAILED */
-  if(!scb->flags & SCB_ACTIVE)
+  if(!(scb->flags & SCB_ACTIVE))
     return FAILED;
 
   pause_sequencer(p);
diff -Nru a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
--- a/drivers/scsi/atari_NCR5380.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/scsi/atari_NCR5380.c	Tue Mar  4 19:30:10 2003
@@ -2543,7 +2543,7 @@
     phase = PHASE_MSGIN;
     NCR5380_transfer_pio(instance, &phase, &len, &data);
 
-    if (!msg[0] & 0x80) {
+    if (!(msg[0] & 0x80)) {
 	printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
 	print_msg(msg);
 	do_abort(instance);
@@ -2953,7 +2953,7 @@
      * on any queue, so they won't be retried ...
      *
      * Conclusion: either scsi.c disables timeout for all resetted commands
-     * immediately, or we loose!  As of linux-2.0.20 it doesn't.
+     * immediately, or we lose!  As of linux-2.0.20 it doesn't.
      */
 
     /* After the reset, there are no more connected or disconnected commands
diff -Nru a/drivers/scsi/cpqfcTScontrol.c b/drivers/scsi/cpqfcTScontrol.c
--- a/drivers/scsi/cpqfcTScontrol.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/cpqfcTScontrol.c	Tue Mar  4 19:30:04 2003
@@ -586,7 +586,7 @@
 
 
 
-// This "look ahead" function examines the IMQ for occurence of
+// This "look ahead" function examines the IMQ for occurrence of
 // "type".  Returns 1 if found, 0 if not.
 static int PeekIMQEntry( PTACHYON fcChip, ULONG type)
 {
diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
--- a/drivers/scsi/cpqfcTSinit.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/cpqfcTSinit.c	Tue Mar  4 19:30:04 2003
@@ -1514,7 +1514,7 @@
       Exchanges->fcExchange[i].timeOut = 10; // seconds default (changed later)
 
       // Since we need to immediately return the aborted Cmnd to Scsi 
-      // upper layers, we can't make future reference to any of it's 
+      // upper layers, we can't make future reference to any of its 
       // fields (e.g the Nexus).
 
       cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &i);
diff -Nru a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c
--- a/drivers/scsi/cpqfcTSworker.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/scsi/cpqfcTSworker.c	Tue Mar  4 19:30:12 2003
@@ -79,7 +79,7 @@
 // synchronously (i.e. each of the 30k I/O had to be started one at a
 // time by sending a starting frame via Tachyon's outbound que).  
 
-// To accomodate kernel "module" build, this driver limits the exchanges
+// To accommodate kernel "module" build, this driver limits the exchanges
 // to 256, because of the contiguous physical memory limitation of 128M.
 
 // Typical FC Exchanges are opened presuming the FC frames start without errors,
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/scsi/dpt_i2o.c	Tue Mar  4 19:30:13 2003
@@ -86,7 +86,7 @@
 #elif defined(__alpha__)
 	PROC_ALPHA ,
 #else
-	(-1),
+	(-1),(-1)
 #endif
 	 FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
 	ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
@@ -1135,7 +1135,8 @@
        // to support async LCT get
 	wait_data->next = adpt_post_wait_queue;
 	adpt_post_wait_queue = wait_data;
-	adpt_post_wait_id = (++adpt_post_wait_id & 0x7fff);
+	adpt_post_wait_id++;
+	adpt_post_wait_id &= 0x7fff;
 	wait_data->id =  adpt_post_wait_id;
 	spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
 
@@ -1252,7 +1253,7 @@
 		}
 	}
 	spin_unlock(&adpt_post_wait_lock);
-        // If this happens we loose commands that probably really completed
+        // If this happens we lose commands that probably really completed
 	printk(KERN_DEBUG"dpti: Could Not find task %d in wait queue\n",context);
 	printk(KERN_DEBUG"      Tasks in wait queue:\n");
 	for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c
--- a/drivers/scsi/esp.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/scsi/esp.c	Tue Mar  4 19:30:14 2003
@@ -3567,7 +3567,7 @@
 /* Target negotiates for synchronous transfers before we do, this
  * is legal although very strange.  What is even funnier is that
  * the SCSI2 standard specifically recommends against targets doing
- * this because so many initiators cannot cope with this occuring.
+ * this because so many initiators cannot cope with this occurring.
  */
 static int target_with_ants_in_pants(struct esp *esp,
 				     Scsi_Cmnd *SCptr,
diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
--- a/drivers/scsi/fdomain.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/scsi/fdomain.c	Tue Mar  4 19:30:11 2003
@@ -725,13 +725,13 @@
       switch (Quantum) {
       case 2:			/* ISA_200S */
       case 3:			/* ISA_250MG */
-	 base = readb(bios_base + 0x1fa2) + (readb(bios_base + 0x1fa3) << 8);
+	 base = isa_readb(bios_base + 0x1fa2) + (isa_readb(bios_base + 0x1fa3) << 8);
 	 break;
       case 4:			/* ISA_200S (another one) */
-	 base = readb(bios_base + 0x1fa3) + (readb(bios_base + 0x1fa4) << 8);
+	 base = isa_readb(bios_base + 0x1fa3) + (isa_readb(bios_base + 0x1fa4) << 8);
 	 break;
       default:
-	 base = readb(bios_base + 0x1fcc) + (readb(bios_base + 0x1fcd) << 8);
+	 base = isa_readb(bios_base + 0x1fcc) + (isa_readb(bios_base + 0x1fcd) << 8);
 	 break;
       }
    
@@ -1777,7 +1777,7 @@
 	 offset = bios_base + 0x1f31 + drive * 25;
 	 break;
       }
-      memcpy_fromio( &i, offset, sizeof( struct drive_info ) );
+      isa_memcpy_fromio( &i, offset, sizeof( struct drive_info ) );
       info_array[0] = i.heads;
       info_array[1] = i.sectors;
       info_array[2] = i.cylinders;
diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
--- a/drivers/scsi/g_NCR5380.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/g_NCR5380.c	Tue Mar  4 19:30:05 2003
@@ -323,7 +323,7 @@
 				printk(KERN_ERR "dtc436e probe: attach failed\n");
 				continue;
 			}
-			if (pnp_activate_dev(dev, NULL) < 0) {
+			if (pnp_activate_dev(dev) < 0) {
 				printk(KERN_ERR "dtc436e probe: activate failed\n");
 				pnp_device_detach(dev);
 				continue;
diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
--- a/drivers/scsi/gdth.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/scsi/gdth.c	Tue Mar  4 19:30:10 2003
@@ -28,7 +28,7 @@
  *                                                                      *
  * $Log: gdth.c,v $
  * Revision 1.61  2002/10/03 09:35:22  boji
- * Fixed SCREENSERVICE intialisation in SMP cases.
+ * Fixed SCREENSERVICE initialisation in SMP cases.
  * Added checks for gdth_polling before GDTH_HA_LOCK
  *
  * Revision 1.60  2002/02/05 09:35:22  achim
diff -Nru a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
--- a/drivers/scsi/gdth.h	Tue Mar  4 19:30:07 2003
+++ b/drivers/scsi/gdth.h	Tue Mar  4 19:30:07 2003
@@ -915,7 +915,7 @@
         unchar          ldr_no;                 /* log. drive no. */
         unchar          rw_attribs;             /* r/w attributes */
         unchar          cluster_type;           /* cluster properties */
-        unchar          media_changed;          /* Flag:MOUNT/UNMOUNT occured */
+        unchar          media_changed;          /* Flag:MOUNT/UNMOUNT occurred*/
         ulong32         start_sec;              /* start sector */
     } hdr[MAX_LDRIVES];                         /* host drives */
     struct {
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/hosts.c	Tue Mar  4 19:30:04 2003
@@ -270,21 +270,6 @@
 		if (scsi_check_device_busy(sdev))
 			return 1;
 
-	/*
-	 * Next we detach the high level drivers from the Scsi_Device
-	 * structures
-	 */
-	list_for_each_entry(sdev, &shost->my_devices, siblings) {
-		scsi_detach_device(sdev);
-
-		/* If something still attached, punt */
-		if (sdev->attached) {
-			printk(KERN_ERR "Attached usage count = %d\n",
-			       sdev->attached);
-			return 1;
-		}
-	}
-
 	scsi_forget_host(shost);
 	return 0;
 }
diff -Nru a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
--- a/drivers/scsi/ibmmca.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/ibmmca.c	Tue Mar  4 19:30:04 2003
@@ -1157,7 +1157,7 @@
 	if (adaptertype == IBM_SCSI2_FW) {	/* F/W SCSI adapter: */
 		/* F/W adapter PUN-space extension evaluation: */
 		if (num_bus) {
-			printk(KERN_INFO "IBM MCA SCSI: Seperate bus mode (wide-addressing enabled)\n");
+			printk(KERN_INFO "IBM MCA SCSI: Separate bus mode (wide-addressing enabled)\n");
 			subsystem_maxid(host_index) = 16;
 		} else {
 			printk(KERN_INFO "IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n");
diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c
--- a/drivers/scsi/ips.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/scsi/ips.c	Tue Mar  4 19:30:03 2003
@@ -1801,7 +1801,7 @@
 /*                                                                          */
 /* Routine Description:                                                     */
 /*   Fill in a single scb sg_list element from an address                   */
-/*   return a -1 if a breakup occured                                       */
+/*   return a -1 if a breakup occurred                                      */
 /****************************************************************************/
 static inline int ips_fill_scb_sg_single(ips_ha_t *ha, dma_addr_t busaddr,
                             ips_scb_t *scb, int indx, unsigned int e_len)
@@ -2737,7 +2737,7 @@
 
       scb->dcdb.cmd_attribute = ips_command_direction[scb->scsi_cmd->cmnd[0]];
 
-      if (!scb->dcdb.cmd_attribute & 0x3)
+      if (!(scb->dcdb.cmd_attribute & 0x3))
          scb->dcdb.transfer_length = 0;
 
       if (scb->data_len >= IPS_MAX_XFER) {
@@ -3315,7 +3315,7 @@
          scb->dcdb.transfer_length = scb->data_len;
          scb->dcdb.cmd_attribute |= ips_command_direction[scb->scsi_cmd->cmnd[0]];
 
-         if (!scb->dcdb.cmd_attribute & 0x3)
+         if (!(scb->dcdb.cmd_attribute & 0x3))
             scb->dcdb.transfer_length = 0;
 
          if (scb->data_len >= IPS_MAX_XFER) {
diff -Nru a/drivers/scsi/mac_NCR5380.c b/drivers/scsi/mac_NCR5380.c
--- a/drivers/scsi/mac_NCR5380.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/scsi/mac_NCR5380.c	Tue Mar  4 19:30:12 2003
@@ -2694,7 +2694,7 @@
     phase = PHASE_MSGIN;
     NCR5380_transfer_pio(instance, &phase, &len, &data);
 
-    if (!msg[0] & 0x80) {
+    if (!(msg[0] & 0x80)) {
 	printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
 	print_msg(msg);
 	do_abort(instance);
@@ -3082,7 +3082,7 @@
      * on any queue, so they won't be retried ...
      *
      * Conclusion: either scsi.c disables timeout for all resetted commands
-     * immediately, or we loose!  As of linux-2.0.20 it doesn't.
+     * immediately, or we lose!  As of linux-2.0.20 it doesn't.
      */
 
     /* After the reset, there are no more connected or disconnected commands
diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/scsi/megaraid.c	Tue Mar  4 19:30:03 2003
@@ -309,7 +309,7 @@
  *	Thu Mar 15 18:38:11 EST 2001 - AM
  *
  *	Firmware version check removed if subsysid==0x1111 and
- *	subsysvid==0x1111, since its not yet initialized.
+ *	subsysvid==0x1111, since it's not yet initialized.
  *
  *	changes made to correctly calculate the base in mega_findCard.
  *
@@ -1714,7 +1714,7 @@
 	unsigned char *data = (unsigned char *) SCpnt->request_buffer;
 	mega_driver_info driver_info;
 
-	/* If this is not our command dont do anything */
+	/* If this is not our command don't do anything */
 	if (SCpnt->cmnd[0] != M_RD_DRIVER_IOCTL_INTERFACE)
 		return 0;
 
@@ -2879,7 +2879,7 @@
 #endif
 		}
 
-		/* Hmmm...Should we not make this more modularized so that in future we dont add
+		/* Hmmm...Should we not make this more modularized so that in future we don't add
 		   for each firmware */
 
 		if (flag & BOARD_QUARTZ) {
@@ -2906,7 +2906,7 @@
 			 * pci_vendor_id not subsysvid - AM
 			 */
 
-			/* If we dont detect this valid subsystem vendor id's 
+			/* If we don't detect this valid subsystem vendor id's 
 			   we refuse to load the driver 
 			   PART of PC200X compliance
 			 */
diff -Nru a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
--- a/drivers/scsi/ncr53c8xx.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/ncr53c8xx.c	Tue Mar  4 19:30:05 2003
@@ -1536,7 +1536,7 @@
 	/*
 	**	Now there are 4 possibilities:
 	**
-	**	(1) The ncr looses arbitration.
+	**	(1) The ncr loses arbitration.
 	**	This is ok, because it will try again,
 	**	when the bus becomes idle.
 	**	(But beware of the timeout function!)
@@ -3090,7 +3090,7 @@
 		case 0x8:
 			/*
 			**	JUMP / CALL
-			**	dont't relocate if relative :-)
+			**	don't relocate if relative :-)
 			*/
 			if (opcode & 0x00800000)
 				relocs = 0;
@@ -5852,7 +5852,7 @@
 	/*
 	**	Why not to try the immediate lower divisor and to choose 
 	**	the one that allows the fastest output speed ?
-	**	We dont want input speed too much greater than output speed.
+	**	We don't want input speed too much greater than output speed.
 	*/
 	if (div >= 1 && fak < 8) {
 		u_long fak2, per2;
diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
--- a/drivers/scsi/nsp32.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/scsi/nsp32.c	Tue Mar  4 19:30:07 2003
@@ -939,7 +939,7 @@
 	/*
 	 * If reselected New ID:LUN is not existed
 	 * or current nexus is not existed, unexpected
-	 * reselection is occured. Send reject message.
+	 * reselection is occurred. Send reject message.
 	 */
 	if (newid >= MAX_TARGET || newlun >= MAX_LUN) {
 		nsp32_msg(KERN_WARNING, "unknown id/lun");
@@ -1333,7 +1333,7 @@
 
 	/*
 	 * AutoSCSI Interrupt.
-	 * Note: This interrupt is occured when AutoSCSI is finished.  Then
+	 * Note: This interrupt is occurred when AutoSCSI is finished.  Then
 	 * check SCSIEXECUTEPHASE, and do appropriate action.  Each phases are
 	 * recorded when AutoSCSI sequencer has been processed.
 	 */
@@ -1345,7 +1345,7 @@
 		/* Selection Timeout, go busfree phase. */
 		if (auto_stat & SELECTION_TIMEOUT) {
 			nsp32_dbg(NSP32_DEBUG_INTR,
-				  "selection timeout occured");
+				  "selection timeout occurred");
 
 			SCpnt->result = DID_TIME_OUT << 16;
 			nsp32_scsi_done(data, SCpnt);
@@ -1357,7 +1357,7 @@
 			 * MsgOut phase was processed.
 			 * If MSG_IN_OCCUER is not set, then MsgOut phase is
 			 * completed. Thus, msgoutlen must reset.  Otherwise,
-			 * nothing to do here. If MSG_OUT_OCCUER is occured,
+			 * nothing to do here. If MSG_OUT_OCCUER is occurred,
 			 * then we will encounter the condition and check.
 			 */
 			if (!(auto_stat & MSG_IN_OCCUER) &&
@@ -1515,7 +1515,7 @@
 
 	/* PCI_IRQ */
 	if (irq_stat & IRQSTATUS_PCI_IRQ) {
-		nsp32_dbg(NSP32_DEBUG_INTR, "PCI IRQ occured");
+		nsp32_dbg(NSP32_DEBUG_INTR, "PCI IRQ occurred");
 		/* Do nothing */
 	}
 
@@ -1524,7 +1524,7 @@
 		nsp32_msg(KERN_ERR, "Received unexpected BMCNTERR IRQ! ");
 		/*
 		 * TODO: To be implemented improving bus master
-		 * transfer reliablity when BMCNTERR is occured in
+		 * transfer reliablity when BMCNTERR is occurred in
 		 * AutoSCSI phase described in specification.
 		 */
 	}
@@ -2300,7 +2300,7 @@
 		} else {
 			/*
 			 * On the contrary, if unexpected bus free is
-			 * occured, then negotiation is failed. Fall
+			 * occurred, then negotiation is failed. Fall
 			 * back to ASYNC mode.
 			 */
 			nsp32_set_async(data, data->curtarget);
@@ -2338,7 +2338,7 @@
 		return (TRUE);
 	} else {
 		/* Unexpected bus free */
-		nsp32_msg(KERN_WARNING, "unexpected bus free occured");
+		nsp32_msg(KERN_WARNING, "unexpected bus free occurred");
 
 		/* DID_ERROR? */
 		//SCpnt->result   = (DID_OK << 16) | (SCpnt->SCp.Message << 8) | (SCpnt->SCp.Status << 0);
@@ -2426,7 +2426,7 @@
 		  "enter: msgoutlen: 0x%x", data->msgoutlen);
 
 	/*
-	 * If MsgOut phase is occured without having any
+	 * If MsgOut phase is occurred without having any
 	 * message, then No_Operation is sent (SCSI-2).
 	 */
 	if (data->msgoutlen == 0) {
@@ -2614,7 +2614,7 @@
 	case COMMAND_COMPLETE:
 	case DISCONNECT:
 		/*
-		 * These messages should not be occured.
+		 * These messages should not be occurred.
 		 * They should be processed on AutoSCSI sequencer.
 		 */
 		nsp32_msg(KERN_WARNING, 
@@ -2654,7 +2654,7 @@
 
 	case SAVE_POINTERS:
 		/*
-		 * These messages should not be occured.
+		 * These messages should not be occurred.
 		 * They should be processed on AutoSCSI sequencer.
 		 */
 		nsp32_msg (KERN_WARNING, 
diff -Nru a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
--- a/drivers/scsi/oktagon_esp.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/oktagon_esp.c	Tue Mar  4 19:30:04 2003
@@ -245,7 +245,7 @@
   if((code == SYS_DOWN || code == SYS_HALT) && (esp = current_esp))
    {
     esp_bootup_reset(esp,esp->eregs);
-    udelay(500); /* Settle time. Maybe unneccessary. */
+    udelay(500); /* Settle time. Maybe unnecessary. */
    }
   return NOTIFY_DONE;
 }
diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
--- a/drivers/scsi/pcmcia/fdomain_stub.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/scsi/pcmcia/fdomain_stub.c	Tue Mar  4 19:30:10 2003
@@ -2,7 +2,7 @@
 
     A driver for Future Domain-compatible PCMCIA SCSI cards
 
-    fdomain_cs.c 1.43 2000/06/12 21:27:25
+    fdomain_cs.c 1.47 2001/10/13 00:08:52
 
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
@@ -19,8 +19,8 @@
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
     Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in which
-    case the provisions of the GPL are applicable instead of the
+    terms of the GNU General Public License version 2 (the "GPL"), in
+    which case the provisions of the GPL are applicable instead of the
     above.  If you wish to allow the use of your version of this file
     only under the terms of the GPL and not to allow others to use
     your version of this file under the MPL, indicate your decision
@@ -53,27 +53,30 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"fdomain_cs.c 1.43 2000/06/12 21:27:25 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
+/* Module parameters */
+
+MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
+MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
+MODULE_LICENSE("Dual MPL/GPL");
+
+#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
 
 /* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
+INT_MODULE_PARM(irq_mask, 0xdeb8);
 static int irq_list[4] = { -1 };
-
-MODULE_PARM(irq_mask, "i");
 MODULE_PARM(irq_list, "1-4i");
 
+#ifdef PCMCIA_DEBUG
+INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version =
+"fdomain_cs.c 1.47 2001/10/13 00:08:52 (David Hinds)";
+#else
+#define DEBUG(n, args...)
+#endif
+
 /*====================================================================*/
 
 typedef struct scsi_info_t {
@@ -213,6 +216,7 @@
     u_char tuple_data[64];
     Scsi_Device *dev;
     dev_node_t *node, **tail;
+    char str[16];
     struct Scsi_Host *host;
 
     DEBUG(0, "fdomain_config(0x%p)\n", link);
@@ -253,7 +257,8 @@
     ints[0] = 2;
     ints[1] = link->io.BasePort1;
     ints[2] = link->irq.AssignedIRQ;
-    fdomain_setup("PCMCIA setup", ints);
+    sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ);
+    fdomain_setup(str, ints);
     
     scsi_register_host(&driver_template);
 
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/scsi/pcmcia/nsp_cs.c	Tue Mar  4 19:30:14 2003
@@ -128,7 +128,7 @@
 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
 
 /* /usr/src/linux/drivers/scsi/hosts.h */
-static Scsi_Host_Template driver_template = {
+static Scsi_Host_Template nsp_driver_template = {
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
 	.proc_name	         = "nsp_cs",      /* kernel 2.4 */
 #else
@@ -136,8 +136,10 @@
 #endif
 	.proc_info		 = nsp_proc_info,
 	.name			 = "WorkBit NinjaSCSI-3/32Bi(16bit)",
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 	.detect			 = nsp_detect,
 	.release		 = nsp_release,
+#endif
 	.info			 = nsp_info,
 	.queuecommand		 = nsp_queuecommand,
 /*	.eh_strategy_handler	 = nsp_eh_strategy,*/
@@ -1215,7 +1217,7 @@
 /*----------------------------------------------------------------*/
 /* look for ninja3 card and init if found			  */
 /*----------------------------------------------------------------*/
-static int nsp_detect(Scsi_Host_Template *sht)
+static struct Scsi_Host *__nsp_detect(Scsi_Host_Template *sht)
 {
 	struct Scsi_Host *host;	/* registered host structure */
 	nsp_hw_data *data = &nsp_data;
@@ -1225,7 +1227,7 @@
 	request_region(data->BaseAddress, data->NumAddress, "nsp_cs");
 	host		  = scsi_register(sht, 0);
 	if(host == NULL)
-		return 0;
+		return NULL;
 
 	host->unique_id	  = data->BaseAddress;
 	host->io_port	  = data->BaseAddress;
@@ -1252,7 +1254,13 @@
 
 	//MOD_INC_USE_COUNT;
 
-	return 1; /* detect done. */
+	return host;
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static int nsp_detect(Scsi_Host_Template *sht)
+{
+	return (__nsp_detect(sht) != NULL);
 }
 
 static int nsp_release(struct Scsi_Host *shpnt)
@@ -1271,6 +1279,7 @@
 
 	return 0;
 }
+#endif
 
 /*----------------------------------------------------------------*/
 /* return info string						  */
@@ -1763,55 +1772,53 @@
 	}
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
-	scsi_register_host(&driver_template);
+	host = __nsp_detect(&nsp_driver_template);
 #else
-	scsi_register_module(MODULE_SCSI_HA, &driver_template);
+	scsi_register_module(MODULE_SCSI_HA, &nsp_driver_template);
+	for (host = scsi_hostlist; host != NULL; host = host->next) {
+		if (host->hostt == &nsp_driver_template)
+			break;
 #endif
 
+	if (!host)
+		goto cs_failed;
+
 	DEBUG(0, "GET_SCSI_INFO\n");
 	tail = &link->dev;
 	info->ndev = 0;
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45))
-	for (host = scsi_host_get_next(NULL); host;
-	     host = scsi_host_get_next(host)) {
-#else
-	for (host = scsi_hostlist; host != NULL; host = host->next) {
-#endif
-		if (host->hostt == &driver_template) {
-	    		list_for_each_entry (dev, &host->my_devices, siblings) {
-				u_long arg[2], id;
-				kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
-				id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
-					((arg[0]>>8)&0xf00) + ((arg[0]>>12)&0xf000);
-				node = &info->node[info->ndev];
-				node->minor = 0;
-				switch (dev->type) {
-				case TYPE_TAPE:
-					node->major = SCSI_TAPE_MAJOR;
-					sprintf(node->dev_name, "st#%04lx", id);
-					break;
-				case TYPE_DISK:
-				case TYPE_MOD:
-					node->major = SCSI_DISK0_MAJOR;
-					sprintf(node->dev_name, "sd#%04lx", id);
-					break;
-				case TYPE_ROM:
-				case TYPE_WORM:
-					node->major = SCSI_CDROM_MAJOR;
-					sprintf(node->dev_name, "sr#%04lx", id);
-					break;
-				default:
-					node->major = SCSI_GENERIC_MAJOR;
-					sprintf(node->dev_name, "sg#%04lx", id);
-					break;
-				}
-				*tail = node; tail = &node->next;
-				info->ndev++;
-				info->host = dev->host;
-			}
+	list_for_each_entry (dev, &host->my_devices, siblings) {
+		u_long arg[2], id;
+		kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
+		id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
+			((arg[0]>>8)&0xf00) + ((arg[0]>>12)&0xf000);
+		node = &info->node[info->ndev];
+		node->minor = 0;
+		switch (dev->type) {
+		case TYPE_TAPE:
+			node->major = SCSI_TAPE_MAJOR;
+			sprintf(node->dev_name, "st#%04lx", id);
+			break;
+		case TYPE_DISK:
+		case TYPE_MOD:
+			node->major = SCSI_DISK0_MAJOR;
+			sprintf(node->dev_name, "sd#%04lx", id);
+			break;
+		case TYPE_ROM:
+		case TYPE_WORM:
+			node->major = SCSI_CDROM_MAJOR;
+			sprintf(node->dev_name, "sr#%04lx", id);
+			break;
+		default:
+			node->major = SCSI_GENERIC_MAJOR;
+			sprintf(node->dev_name, "sg#%04lx", id);
+			break;
 		}
+		*tail = node; tail = &node->next;
+		info->ndev++;
+		info->host = dev->host;
 	}
+
 	*tail = NULL;
 	if (info->ndev == 0) {
 		printk(KERN_INFO "nsp_cs: no SCSI devices found\n");
@@ -1839,6 +1846,10 @@
 		       req.Base+req.Size-1);
 	printk("\n");
 
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+	scsi_add_host(host, NULL);
+#endif
+
 	link->state &= ~DEV_CONFIG_PENDING;
 	return;
 
@@ -1859,6 +1870,7 @@
 static void nsp_cs_release(u_long arg)
 {
 	dev_link_t *link = (dev_link_t *)arg;
+	scsi_info_t *info = link->priv;
 
 	DEBUG(0, "%s(0x%p)\n", __FUNCTION__, link);
 
@@ -1874,10 +1886,11 @@
 	}
 
 	/* Unlink the device chain */
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
-	scsi_unregister_host(&driver_template);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,2))
+	scsi_unregister_module(MODULE_SCSI_HA, &nsp_driver_template);
 #else
-	scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
+	scsi_remove_host(info->host);
+	scsi_unregister(info->host);
 #endif
 	link->dev = NULL;
 
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
--- a/drivers/scsi/pcmcia/nsp_cs.h	Tue Mar  4 19:30:07 2003
+++ b/drivers/scsi/pcmcia/nsp_cs.h	Tue Mar  4 19:30:07 2003
@@ -183,7 +183,7 @@
 #define S_ATN		0x80	/**/
 #define S_SELECT	0x40	/**/
 #define S_REQUEST	0x20    /* Request line from SCSI bus*/
-#define S_ACK		0x10    /* Acknowlege line from SCSI bus*/
+#define S_ACK		0x10    /* Acknowledge line from SCSI bus*/
 #define S_BUSY		0x08    /* Busy line from SCSI bus*/
 #define S_CD		0x04    /* Command/Data line from SCSI bus*/
 #define S_IO		0x02    /* Input/Output line from SCSI bus*/
@@ -280,8 +280,6 @@
 static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
 static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time);
 
-static int nsp_detect(Scsi_Host_Template * );
-static int nsp_release(struct Scsi_Host *shpnt);
 static const char *nsp_info(struct Scsi_Host *shpnt);
 static int nsp_proc_info(char *buffer, char **start, off_t offset,
 			 int length, int hostno, int inout);
diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
--- a/drivers/scsi/qlogicfc.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/scsi/qlogicfc.c	Tue Mar  4 19:30:11 2003
@@ -1563,7 +1563,7 @@
 				/* 
 				 * if any of the following are true we do not
 				 * call scsi_done.  if the status is CS_ABORTED
-				 * we dont have to call done because the upper
+				 * we don't have to call done because the upper
 				 * level should already know its aborted.
 				 */
 				if (hostdata->handle_serials[le_hand] != Cmnd->serial_number 
diff -Nru a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
--- a/drivers/scsi/qlogicpti.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/scsi/qlogicpti.c	Tue Mar  4 19:30:11 2003
@@ -776,7 +776,7 @@
 }
 
 /* The request and response queues must each be aligned
- * on a page boundry.
+ * on a page boundary.
  */
 static int __init qpti_map_queues(struct qlogicpti *qpti)
 {
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/scsi/scsi.c	Tue Mar  4 19:30:09 2003
@@ -1308,7 +1308,8 @@
 void scsi_set_device_offline(struct scsi_device *sdev)
 {
 	struct scsi_cmnd *scmd;
-	int	cmds_active = 0;
+	LIST_HEAD(active_list);
+	struct list_head *lh, *lh_sf;
 	unsigned long flags;
 
 	sdev->online = FALSE;
@@ -1324,15 +1325,17 @@
 			if (!scsi_delete_timer(scmd)) {
 				continue;
 			}
-
-			++cmds_active;
-
-			scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD);
+			list_add_tail(&scmd->eh_entry, &active_list);
 		}
 	}
 	spin_unlock_irqrestore(&sdev->list_lock, flags);
 
-	if (!cmds_active) {
+	if (!list_empty(&active_list)) {
+		list_for_each_safe(lh, lh_sf, &active_list) {
+			scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
+			scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD);
+		}
+	} else {
 		/* FIXME: Send online state change hotplug event */
 	}
 }
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/scsi.h	Tue Mar  4 19:30:05 2003
@@ -503,8 +503,9 @@
 /*
  * Prototypes for functions in scsi_scan.c
  */
-extern int scsi_add_single_device(uint, uint, uint, uint);
-extern int scsi_remove_single_device(uint, uint, uint, uint);
+extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
+		uint, uint, uint);
+extern int scsi_remove_device(struct scsi_device *);
 extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
 
 /*
diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
--- a/drivers/scsi/scsi_ioctl.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/scsi/scsi_ioctl.c	Tue Mar  4 19:30:14 2003
@@ -194,7 +194,7 @@
  *      of the given command. There is no way to override this.
  *   -  Data transfers are limited to PAGE_SIZE (4K on i386, 8K on alpha).
  *   -  The length (x + y) must be at least OMAX_SB_LEN bytes long to
- *      accomodate the sense buffer when an error occurs.
+ *      accommodate the sense buffer when an error occurs.
  *      The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that
  *      old code will not be surprised.
  *   -  If a Unix error occurs (e.g. ENOMEM) then the user will receive
diff -Nru a/drivers/scsi/scsi_pc98.c b/drivers/scsi/scsi_pc98.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/scsi/scsi_pc98.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2003  Osamu Tomita <tomita@cinet.co.jp>
+ *
+ *  PC9801 BIOS geometry handling.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/genhd.h>
+#include <linux/blk.h>
+#include <asm/pc9800.h>
+
+#include "scsi.h"
+#include "hosts.h"
+
+
+/* XXX - For now, we assume the first (i.e. having the least host_no)
+   real (i.e. non-emulated) host adapter shall be BIOS-controlled one.
+   We *SHOULD* invent another way.  */
+static inline struct Scsi_Host *first_real_host(void)
+{
+	struct Scsi_Host *shost = NULL;
+
+	while ((shost = scsi_host_get_next(shost))) {
+		if (!shost->hostt->emulated)
+			break;
+	}
+
+	return shost;
+}
+
+static int pc98_first_bios_param(struct scsi_device *sdev, int *ip)
+{
+	const u8 *p = (&__PC9800SCA(u8, PC9800SCA_SCSI_PARAMS) + sdev->id * 4);
+
+	ip[0] = p[1];   /* # of heads */
+	ip[1] = p[0];   /* # of sectors/track */
+	ip[2] = *(u16 *)&p[2] & 0x0fff; /* # of cylinders */
+	if (p[3] & (1 << 6)) { /* #-of-cylinders is 16-bit */
+		ip[2] |= (ip[0] & 0xf0) << 8;
+		ip[0] &= 0x0f;
+	}
+
+	return 0;
+}
+
+int pc98_bios_param(struct scsi_device *sdev, struct block_device *bdev,
+			sector_t capacity, int *ip)
+{
+	static struct Scsi_Host *first_real = first_real_host();
+
+	if (sdev->host == first_real && sdev->id < 7 &&
+	    __PC9800SCA_TEST_BIT(PC9800SCA_DISK_EQUIPS, sdev->id))
+	    	return pc98_first_bios_param(sdev, ip);
+
+	/* Assume PC-9801-92 compatible parameters for HAs without BIOS.  */
+	ip[0] = 8;
+	ip[1] = 32;
+	ip[2] = capacity / (8 * 32);
+	if (ip[2] > 65535) {    /* if capacity >= 8GB */
+		/* Recent on-board adapters seem to use this parameter. */
+		ip[1] = 128;
+		ip[2] = capacity / (8 * 128);
+		if (ip[2] > 65535) { /* if capacity >= 32GB  */
+			/* Clip the number of cylinders.  Currently
+			   this is the limit that we deal with.  */
+			ip[2] = 65535;
+		}
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pc98_bios_param);
diff -Nru a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
--- a/drivers/scsi/scsi_proc.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/scsi_proc.c	Tue Mar  4 19:30:04 2003
@@ -398,6 +398,50 @@
 }
 #endif	/* CONFIG_SCSI_LOGGING */ 
 
+static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
+{
+	struct Scsi_Host *shost;
+	struct scsi_device *sdev;
+	int error = -ENODEV;
+
+	shost = scsi_host_hn_get(host);
+	if (!shost)
+		return -ENODEV;
+
+	if (!scsi_find_device(shost, channel, id, lun)) {
+		sdev = scsi_add_device(shost, channel, id, lun);
+		if (IS_ERR(sdev))
+			error = PTR_ERR(sdev);
+		else
+			error = 0;
+	}
+
+	scsi_host_put(shost);
+	return error;
+}
+
+static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
+{
+	struct scsi_device *sdev;
+	struct Scsi_Host *shost;
+	int error = -ENODEV;
+
+	shost = scsi_host_hn_get(host);
+	if (!shost)
+		return -ENODEV;
+	sdev = scsi_find_device(shost, channel, id, lun);
+	if (!sdev)
+		goto out;
+	if (sdev->access_count)
+		goto out;
+
+	error = scsi_remove_device(sdev);
+out:
+	scsi_host_put(shost);
+	return error;
+}
+
+
 static int proc_scsi_gen_write(struct file * file, const char * buf,
                               unsigned long length, void *data)
 {
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/scsi/scsi_scan.c	Tue Mar  4 19:30:12 2003
@@ -189,6 +189,8 @@
 	{"HITACHI", "DF500", "*", BLIST_SPARSELUN},
 	{"HITACHI", "DF600", "*", BLIST_SPARSELUN},
 	{"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"SUN", "T300", "*", BLIST_SPARSELUN},
+	{"SUN", "T4", "*", BLIST_SPARSELUN},
 	{ NULL, NULL, NULL, 0 },
 };
 
@@ -1259,14 +1261,6 @@
 	return SCSI_SCAN_LUN_PRESENT;
 }
 
-static void scsi_remove_lun(struct scsi_device *sdev)
-{
-	devfs_unregister(sdev->de);
-	scsi_device_unregister(sdev);
-
-	scsi_free_sdev(sdev);
-}
-
 /**
  * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
  * @sdevscan:	probe the LUN corresponding to this Scsi_Device
@@ -1284,90 +1278,77 @@
  *     SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized
  **/
 static int scsi_probe_and_add_lun(struct Scsi_Host *host,
-		struct request_queue **q, uint channel, uint id,
-	       	uint lun, int *bflagsp)
+		struct request_queue **q, uint channel, uint id, uint lun,
+		int *bflagsp, struct scsi_device **sdevp)
 {
-	Scsi_Device *sdev = NULL;
-	Scsi_Request *sreq = NULL;
-	unsigned char *scsi_result = NULL;
-	int bflags;
-	int res;
+	struct scsi_device *sdev;
+	struct scsi_request *sreq;
+	unsigned char *result;
+	int bflags, res = SCSI_SCAN_NO_RESPONSE;
 
 	sdev = scsi_alloc_sdev(host, q, channel, id, lun);
-	if (sdev == NULL)
-		return SCSI_SCAN_NO_RESPONSE;
+	if (!sdev)
+		goto out;
 	sreq = scsi_allocate_request(sdev);
-	if (sreq == NULL) {
-		printk(ALLOC_FAILURE_MSG, __FUNCTION__);
-		res = SCSI_SCAN_NO_RESPONSE;
-		goto bail_out;
-	}
-	/*
-	 * The sreq is for use only with sdevscan.
-	 */
+	if (!sreq)
+		goto out_free_sdev;
+	result = kmalloc(256, GFP_ATOMIC |
+			(host->unchecked_isa_dma) ? __GFP_DMA : 0);
+	if (!result)
+		goto out_free_sreq;
 
-	scsi_result = kmalloc(256, GFP_ATOMIC |
-			      (host->unchecked_isa_dma) ?
-			      GFP_DMA : 0);
-	if (scsi_result == NULL) {
-		printk(ALLOC_FAILURE_MSG, __FUNCTION__);
-		res = SCSI_SCAN_NO_RESPONSE;
-		goto bail_out;
-	}
-
-	scsi_probe_lun(sreq, scsi_result, &bflags);
+	scsi_probe_lun(sreq, result, &bflags);
 	if (sreq->sr_result)
-		res = SCSI_SCAN_NO_RESPONSE;
-	else {
+		goto out_free_result;
+
+	/*
+	 * result contains valid SCSI INQUIRY data.
+	 */
+	if ((result[0] >> 5) == 3) {
 		/*
-		 * scsi_result contains valid SCSI INQUIRY data.
+		 * For a Peripheral qualifier 3 (011b), the SCSI
+		 * spec says: The device server is not capable of
+		 * supporting a physical device on this logical
+		 * unit.
+		 *
+		 * For disks, this implies that there is no
+		 * logical disk configured at sdev->lun, but there
+		 * is a target id responding.
 		 */
-		if ((scsi_result[0] >> 5) == 3) {
-			/*
-			 * For a Peripheral qualifier 3 (011b), the SCSI
-			 * spec says: The device server is not capable of
-			 * supporting a physical device on this logical
-			 * unit.
-			 *
-			 * For disks, this implies that there is no
-			 * logical disk configured at sdev->lun, but there
-			 * is a target id responding.
-			 */
-			SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
+		SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
 					"scsi scan: peripheral qualifier of 3,"
 					" no device added\n"));
-			res = SCSI_SCAN_TARGET_PRESENT;
-		} else {
-			res = scsi_add_lun(sdev, sreq, scsi_result, &bflags);
-			if (res == SCSI_SCAN_LUN_PRESENT) {
-				if ((bflags & BLIST_KEY) != 0) {
-					sdev->lockable = 0;
-					scsi_unlock_floptical(sreq,
-							      scsi_result);
-					/*
-					 * scsi_result no longer contains
-					 * the INQUIRY data.
-					 */
-				}
-				if (bflagsp != NULL)
-					*bflagsp = bflags;
-			}
+		res = SCSI_SCAN_TARGET_PRESENT;
+		goto out_free_result;
+	}
+
+	res = scsi_add_lun(sdev, sreq, result, &bflags);
+	if (res == SCSI_SCAN_LUN_PRESENT) {
+		if (bflags & BLIST_KEY) {
+			sdev->lockable = 0;
+			scsi_unlock_floptical(sreq, result);
 		}
+		if (bflagsp)
+			*bflagsp = bflags;
 	}
-bail_out:
-	if (scsi_result != NULL)
-		kfree(scsi_result);
-	if (sreq != NULL)
-		scsi_release_request(sreq);
-	if (res != SCSI_SCAN_LUN_PRESENT) {
-		if(q) {
+
+ out_free_result:
+	kfree(result);
+ out_free_sreq:
+	scsi_release_request(sreq);
+ out_free_sdev:
+	if (res == SCSI_SCAN_LUN_PRESENT) {
+		if (sdevp)
+			*sdevp = sdev;
+	} else {
+		if (q) {
 			*q = sdev->request_queue;
 			sdev->request_queue = NULL;
 		}
 		scsi_free_sdev(sdev);
 	}
+ out:
 	return res;
-
 }
 
 /**
@@ -1453,8 +1434,8 @@
 	 * sparse_lun.
 	 */
 	for (lun = 1; lun < max_dev_lun; ++lun)
-		if ((scsi_probe_and_add_lun(shost, q, channel, id, lun, NULL)
-		     != SCSI_SCAN_LUN_PRESENT) && !sparse_lun)
+		if ((scsi_probe_and_add_lun(shost, q, channel, id, lun,
+		      NULL, NULL) != SCSI_SCAN_LUN_PRESENT) && !sparse_lun)
 			return;
 }
 
@@ -1669,7 +1650,7 @@
 			int res;
 
 			res = scsi_probe_and_add_lun(sdev->host, q,
-				       	sdev->channel, sdev->id, lun, NULL);
+				sdev->channel, sdev->id, lun, NULL, NULL);
 			if (res == SCSI_SCAN_NO_RESPONSE) {
 				/*
 				 * Got some results, but now none, abort.
@@ -1691,55 +1672,33 @@
 
 }
 
-int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
+struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
+				    uint channel, uint id, uint lun)
 {
-	struct Scsi_Host *shost;
-	int error = -ENODEV;
 	struct scsi_device *sdev;
+	int error = -ENODEV, res;
 
-	shost = scsi_host_hn_get(host);
-	if (!shost)
-		return -ENODEV;
-	if(scsi_find_device(shost, channel, id, lun) != NULL)
-		goto out;
+	res = scsi_probe_and_add_lun(shost, NULL, channel, id, lun,
+			NULL, &sdev);
+	if (res == SCSI_SCAN_LUN_PRESENT)
+		error = scsi_attach_device(sdev);
 
-	if (scsi_probe_and_add_lun(shost, NULL, channel, id, lun, NULL) ==
-			SCSI_SCAN_LUN_PRESENT) {
-		error = 0;
-		sdev = scsi_find_device(shost, channel, id, lun);
-		scsi_attach_device(sdev);
-	}
-out:
-	scsi_host_put(shost);
-	return error;
+	if (error)
+		sdev = ERR_PTR(error);
+	return sdev;
 }
 
-int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
+int scsi_remove_device(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev;
-	struct Scsi_Host *shost;
-	int error = -ENODEV;
-
-	shost = scsi_host_hn_get(host);
-	if (!shost)
-		return -ENODEV;
-	sdev = scsi_find_device(shost, channel, id, lun);
-	if (!sdev)
-		goto out;
-
-	error = -EBUSY;
-	if (sdev->access_count)
-		goto out;
 	scsi_detach_device(sdev);
 	if (sdev->attached)
-		goto out;
+		return -EINVAL;
 
-	scsi_remove_lun(sdev);
-	error = 0;
+	devfs_unregister(sdev->de);
+	scsi_device_unregister(sdev);
 
-out:
-	scsi_host_put(shost);
-	return error;
+	scsi_free_sdev(sdev);
+	return 0;
 }
 
 /**
@@ -1778,9 +1737,8 @@
 	 * Scan LUN 0, if there is some response, scan further. Ideally, we
 	 * would not configure LUN 0 until all LUNs are scanned.
 	 */
-	res = scsi_probe_and_add_lun(shost, q, channel, id, 0, &bflags);
+	res = scsi_probe_and_add_lun(shost, q, channel, id, 0, &bflags, &sdev);
 	if (res == SCSI_SCAN_LUN_PRESENT) {
-		sdev = scsi_find_device(shost, channel, id, 0);
 		if (scsi_report_lun_scan(sdev, q, bflags) != 0)
 			/*
 			 * The REPORT LUN did not scan the target,
@@ -1846,9 +1804,13 @@
 void scsi_forget_host(struct Scsi_Host *shost)
 {
 	struct list_head *le, *lh;
+	struct scsi_device *sdev;
 
-	list_for_each_safe(le, lh, &shost->my_devices)
-		scsi_remove_lun(list_entry(le, struct scsi_device, siblings));
+	list_for_each_safe(le, lh, &shost->my_devices) {
+		sdev = list_entry(le, struct scsi_device, siblings);
+		
+		scsi_remove_device(sdev);
+	}
 }
 
 /*
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/scsi/scsi_syms.c	Tue Mar  4 19:30:08 2003
@@ -78,6 +78,8 @@
 EXPORT_SYMBOL(scsi_slave_detach);
 EXPORT_SYMBOL(scsi_device_get);
 EXPORT_SYMBOL(scsi_device_put);
+EXPORT_SYMBOL(scsi_add_device);
+EXPORT_SYMBOL(scsi_remove_device);
 EXPORT_SYMBOL(scsi_set_device_offline);
 
 /*
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/scsi/sd.c	Tue Mar  4 19:30:12 2003
@@ -678,7 +678,7 @@
 	 */
 
 	/* An error occurred */
-	if (driver_byte(result) != 0 && 	/* An error occured */
+	if (driver_byte(result) != 0 && 	/* An error occurred */
 	    SCpnt->sense_buffer[0] == 0xF0) {	/* Sense data is valid */
 		switch (SCpnt->sense_buffer[2]) {
 		case MEDIUM_ERROR:
@@ -719,7 +719,7 @@
 
 		case RECOVERED_ERROR:
 			/*
-			 * An error occured, but it recovered.  Inform the
+			 * An error occurred, but it recovered.  Inform the
 			 * user, but make sure that it's not treated as a
 			 * hard error.
 			 */
diff -Nru a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
--- a/drivers/scsi/seagate.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/scsi/seagate.c	Tue Mar  4 19:30:08 2003
@@ -493,7 +493,7 @@
 
 	/*
 	 *	At all times, we will use IRQ 5.  Should also check for IRQ3
-	 *	if we loose our first interrupt.
+	 *	if we lose our first interrupt.
 	 */
 	instance = scsi_register (tpnt, 0);
 	if (instance == NULL)
diff -Nru a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
--- a/drivers/scsi/sgiwd93.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/scsi/sgiwd93.c	Tue Mar  4 19:30:13 2003
@@ -4,10 +4,13 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  *		 1999 Andrew R. Baker (andrewb@uab.edu)
  *		      - Support for 2nd SCSI controller on Indigo2
+ *		 2001 Florian Lohoff (flo@rfc822.org)
+ *		      - Delete HPC scatter gather (Read corruption on 
+ *		        multiple disks)
+ *		      - Cleanup wback cache handling
  * 
  * (In all truth, Jed Schimmel wrote all this code.)
  *
- * $Id: sgiwd93.c,v 1.19 2000/02/04 07:40:47 ralf Exp $
  */
 #include <linux/init.h>
 #include <linux/types.h>
@@ -36,32 +39,13 @@
 
 struct hpc_chunk {
 	struct hpc_dma_desc desc;
-	unsigned long padding;
+	u32 _padding;	/* align to quadword boundary */
 };
 
 struct Scsi_Host *sgiwd93_host = NULL;
 struct Scsi_Host *sgiwd93_host1 = NULL;
 
 /* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */
-static inline void write_wd33c93_count(const wd33c93_regs regs,
-				       unsigned long value)
-{
-	*regs.SASR = WD_TRANSFER_COUNT_MSB;
-	*regs.SCMD = ((value >> 16) & 0xff);
-	*regs.SCMD = ((value >>  8) & 0xff);
-	*regs.SCMD = ((value >>  0) & 0xff);
-}
-
-static inline unsigned long read_wd33c93_count(const wd33c93_regs regs)
-{
-	unsigned long value;
-
-	*regs.SASR = WD_TRANSFER_COUNT_MSB;
-	value =  (*regs.SCMD << 16);
-	value |= (*regs.SCMD <<  8);
-	value |= (*regs.SCMD <<  0);
-	return value;
-}
 
 /* XXX woof! */
 static void sgiwd93_intr(int irq, void *dev_id, struct pt_regs *regs)
@@ -82,7 +66,6 @@
 	unsigned long physaddr;
 	unsigned long count;
 	
-	dma_cache_wback_inv((unsigned long)addr,len);
 	physaddr = PHYSADDR(addr);
 	while (len) {
 		/*
@@ -101,7 +84,6 @@
 static int dma_setup(Scsi_Cmnd *cmd, int datainp)
 {
 	struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
-	const wd33c93_regs regs = hdata->regs;
 	struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->host->base;
 	struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->dma_bounce_buffer;
 
@@ -112,46 +94,17 @@
 
 	hdata->dma_dir = datainp;
 
-	if(cmd->SCp.buffers_residual) {
-		struct scatterlist *slp = cmd->SCp.buffer;
-		int i, totlen = 0;
+	/*
+	 * wd33c93 shouldn't pass us bogus dma_setups, but
+	 * it does:-( The other wd33c93 drivers deal with
+	 * it the same way (which isn't that obvious).
+	 * IMHO a better fix would be, not to do these
+	 * dma setups in the first place
+	 */
+	if (cmd->SCp.ptr == NULL)
+		return 1;
 
-#ifdef DEBUG_DMA
-		printk("SCLIST<");
-#endif
-		for(i = 0; i <= cmd->SCp.buffers_residual; i++) {
-#ifdef DEBUG_DMA
-			printk("[%p,%d]",
-			       page_address(slp[i].page) + slp[i].offset,
-			       slp[i].length);
-#endif
-			fill_hpc_entries (&hcp,
-					  page_address(slp[i].page) + slp[i].offset,
-					  slp[i].length);
-			totlen += slp[i].length;
-		}
-#ifdef DEBUG_DMA
-		printk(">tlen<%d>", totlen);
-#endif
-		hdata->dma_bounce_len = totlen; /* a trick... */
-		write_wd33c93_count(regs, totlen);
-	} else {
-		/* Non-scattered dma. */
-#ifdef DEBUG_DMA
-		printk("ONEBUF<%p,%d>", cmd->SCp.ptr, cmd->SCp.this_residual);
-#endif
-		/*
-		 * wd33c93 shouldn't pass us bogus dma_setups, but
-		 * it does:-( The other wd33c93 drivers deal with
-		 * it the same way (which isn't that obvious).
-		 * IMHO a better fix would be, not to do these
-		 * dma setups in the first place
-		 */
-		if (cmd->SCp.ptr == NULL)
-			return 1;
-		fill_hpc_entries (&hcp, cmd->SCp.ptr,cmd->SCp.this_residual);
-		write_wd33c93_count(regs, cmd->SCp.this_residual);
-	}
+	fill_hpc_entries (&hcp, cmd->SCp.ptr,cmd->SCp.this_residual);
 
 	/* To make sure, if we trip an HPC bug, that we transfer
 	 * every single byte, we tag on an extra zero length dma
@@ -166,10 +119,14 @@
 
 	/* Start up the HPC. */
 	hregs->ndptr = PHYSADDR(hdata->dma_bounce_buffer);
-	if(datainp)
+	if(datainp) {
+		dma_cache_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual);
 		hregs->ctrl = (HPC3_SCTRL_ACTIVE);
-	else
+	} else {
+		dma_cache_wback_inv((unsigned long) cmd->SCp.ptr, cmd->SCp.this_residual);
 		hregs->ctrl = (HPC3_SCTRL_ACTIVE | HPC3_SCTRL_DIR);
+	}
+
 	return 0;
 }
 
@@ -177,7 +134,6 @@
 		     int status)
 {
 	struct WD33C93_hostdata *hdata = (struct WD33C93_hostdata *)instance->hostdata;
-	const wd33c93_regs regs = hdata->regs;
 	struct hpc3_scsiregs *hregs;
 
 	if (!SCpnt)
@@ -197,44 +153,6 @@
 	}
 	hregs->ctrl = 0;
 
-	/* See how far we got and update scatterlist state if necessary. */
-	if(SCpnt->SCp.buffers_residual) {
-		struct scatterlist *slp = SCpnt->SCp.buffer;
-		int totlen, wd93_residual, transferred, i;
-
-		/* Yep, we were doing the scatterlist thang. */
-		totlen = hdata->dma_bounce_len;
-		wd93_residual = read_wd33c93_count(regs);
-		transferred = totlen - wd93_residual;
-
-#ifdef DEBUG_DMA
-		printk("tlen<%d>resid<%d>transf<%d> ",
-		       totlen, wd93_residual, transferred);
-#endif
-
-		/* Avoid long winded partial-transfer search for common case. */
-		if(transferred != totlen) {
-			/* This is the nut case. */
-#ifdef DEBUG_DMA
-			printk("Jed was here...");
-#endif
-			for(i = 0; i <= SCpnt->SCp.buffers_residual; i++) {
-				if(slp[i].length >= transferred)
-					break;
-				transferred -= slp[i].length;
-			}
-		} else {
-			/* This is the common case. */
-#ifdef DEBUG_DMA
-			printk("did it all...");
-#endif
-			i = SCpnt->SCp.buffers_residual;
-		}
-		SCpnt->SCp.buffer = &slp[i];
-		SCpnt->SCp.buffers_residual = SCpnt->SCp.buffers_residual - i;
-		SCpnt->SCp.ptr = (char *) page_address(slp[i].page) + slp[i].offset;
-		SCpnt->SCp.this_residual = slp[i].length;
-	}
 #ifdef DEBUG_DMA
 	printk("\n");
 #endif
@@ -264,6 +182,9 @@
 	};
 	hcp--;
 	hcp->desc.pnext = PHYSADDR(buf);
+
+	/* Force flush to memory */
+	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
 }
 
 int __init sgiwd93_detect(Scsi_Host_Template *SGIblows)
@@ -273,8 +194,8 @@
 	struct hpc3_scsiregs *hregs1 = &hpc3c0->scsi_chan1;
 	struct WD33C93_hostdata *hdata;
 	struct WD33C93_hostdata *hdata1;
-	uchar *buf;
 	wd33c93_regs regs;
+	uchar *buf;
 	
 	if(called)
 		return 0; /* Should bitch on the console about this... */
@@ -294,10 +215,10 @@
 		return 0;
 	}
 	init_hpc_chain(buf);
-	dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
+	
 	/* HPC_SCSI_REG0 | 0x03 | KSEG1 */
-	regs.SASR = (volatile unsigned char *)KSEG1ADDR (0x1fbc0003);
-	regs.SCMD = (volatile unsigned char *)KSEG1ADDR (0x1fbc0007);
+	regs.SASR = (unsigned char*) KSEG1ADDR (0x1fbc0003);
+	regs.SCMD = (unsigned char*) KSEG1ADDR (0x1fbc0007);
 	wd33c93_init(sgiwd93_host, regs, dma_setup, dma_stop, WD33C93_FS_16_20);
 
 	hdata = (struct WD33C93_hostdata *)sgiwd93_host->hostdata;
@@ -329,17 +250,16 @@
 				return 1; /* We registered host0 so return success*/
 			}
 			init_hpc_chain(buf);
-			dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
+
 			/* HPC_SCSI_REG1 | 0x03 | KSEG1 */
-			regs.SASR = (volatile unsigned char *)KSEG1ADDR (0x1fbc8003);
-			regs.SCMD = (volatile unsigned char *)KSEG1ADDR (0x1fbc8007);
+			regs.SASR = (unsigned char*) KSEG1ADDR(0x1fbc8003);
+			regs.SCMD = (unsigned char*) KSEG1ADDR(0x1fbc8007);
 			wd33c93_init(sgiwd93_host1, regs, dma_setup, dma_stop,
-				     WD33C93_FS_16_20);
+			             WD33C93_FS_16_20);
 	
 			hdata1 = (struct WD33C93_hostdata *)sgiwd93_host1->hostdata;
 			hdata1->no_sync = 0;
 			hdata1->dma_bounce_buffer = (uchar *) (KSEG1ADDR(buf));
-			dma_cache_wback_inv((unsigned long) buf, PAGE_SIZE);
 	
 			if (request_irq(SGI_WD93_1_IRQ, sgiwd93_intr, 0, "SGI WD93", (void *) sgiwd93_host1)) {
 				printk(KERN_WARNING "sgiwd93: Could not allocate irq %d (for host1).\n", SGI_WD93_1_IRQ);
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/scsi/sr.c	Tue Mar  4 19:30:05 2003
@@ -26,7 +26,7 @@
  *	Modified by Richard Gooch <rgooch@atnf.csiro.au> to support devfs
  *
  *	Modified by Jens Axboe <axboe@suse.de> - support DVD-RAM
- *	transparently and loose the GHOST hack
+ *	transparently and lose the GHOST hack
  *
  *	Modified by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *	check resource allocation in sr_init and some cleanups
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/scsi/st.c	Tue Mar  4 19:30:11 2003
@@ -2963,7 +2963,7 @@
    set the size of partition 1. There is no size field for the default partition.
    Michael Schaefer's Sony SDT-7000 returns two descriptors and the second is
    used to set the size of partition 1 (this is what the SCSI-3 standard specifies).
-   The following algorithm is used to accomodate both drives: if the number of
+   The following algorithm is used to accommodate both drives: if the number of
    partition size fields is greater than the maximum number of additional partitions
    in the mode page, the second field is used. Otherwise the first field is used.
 
diff -Nru a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
--- a/drivers/scsi/sun3_NCR5380.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/sun3_NCR5380.c	Tue Mar  4 19:30:04 2003
@@ -2564,7 +2564,7 @@
     msg[0] = NCR5380_read(CURRENT_SCSI_DATA_REG);
 #endif
 
-    if (!msg[0] & 0x80) {
+    if (!(msg[0] & 0x80)) {
 	printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
 	print_msg(msg);
 	do_abort(instance);
@@ -2970,7 +2970,7 @@
      * on any queue, so they won't be retried ...
      *
      * Conclusion: either scsi.c disables timeout for all resetted commands
-     * immediately, or we loose!  As of linux-2.0.20 it doesn't.
+     * immediately, or we lose!  As of linux-2.0.20 it doesn't.
      */
 
     /* After the reset, there are no more connected or disconnected commands
diff -Nru a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
--- a/drivers/scsi/sun3_scsi.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/sun3_scsi.c	Tue Mar  4 19:30:04 2003
@@ -543,7 +543,7 @@
 #if 1
 	// check to empty the fifo on a read
 	if(!write_flag) {
-		int tmo = 200000; /* 2 sec */
+		int tmo = 20000; /* .2 sec */
 		
 		while(1) {
 			if(dregs->csr & CSR_FIFO_EMPTY)
diff -Nru a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
--- a/drivers/scsi/sym53c416.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/scsi/sym53c416.c	Tue Mar  4 19:30:04 2003
@@ -679,7 +679,7 @@
 				printk(KERN_WARNING "sym53c416: unable to attach PnP device.\n");
 				continue;
 			}
-			if(pnp_activate_dev(idev, NULL)<0)
+			if(pnp_activate_dev(idev) < 0)
 			{
 				printk(KERN_WARNING "sym53c416: unable to activate PnP device.\n");
 				pnp_device_detach(idev);
diff -Nru a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
--- a/drivers/scsi/sym53c8xx.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/scsi/sym53c8xx.c	Tue Mar  4 19:30:11 2003
@@ -2677,7 +2677,7 @@
 	/*
 	**	Now there are 4 possibilities:
 	**
-	**	(1) The ncr looses arbitration.
+	**	(1) The ncr loses arbitration.
 	**	This is ok, because it will try again,
 	**	when the bus becomes idle.
 	**	(But beware of the timeout function!)
@@ -3653,7 +3653,7 @@
 	**	some target to reset or some disconnected 
 	**	job to abort. Since error recovery is a serious 
 	**	busyness, we will really reset the SCSI BUS, if 
-	**	case of a SCSI interrupt occuring in this path.
+	**	case of a SCSI interrupt occurring in this path.
 	*/
 
 	/*
@@ -4631,7 +4631,7 @@
 		case 0x8:
 			/*
 			**	JUMP / CALL
-			**	dont't relocate if relative :-)
+			**	don't relocate if relative :-)
 			*/
 			if (opcode & 0x00800000)
 				relocs = 0;
@@ -6984,7 +6984,7 @@
 			INW (nc_sist);
 		}
 		else if (istat & DIP) {
-			if (INB (nc_dstat) & ABRT);
+			if (INB (nc_dstat) & ABRT)
 				break;
 		}
 		UDELAY(5);
@@ -7953,7 +7953,7 @@
 	/*
 	**	Why not to try the immediate lower divisor and to choose 
 	**	the one that allows the fastest output speed ?
-	**	We dont want input speed too much greater than output speed.
+	**	We don't want input speed too much greater than output speed.
 	*/
 	if (div >= 1 && fak < 8) {
 		u_long fak2, per2;
@@ -9092,7 +9092,7 @@
 	ccb_p   cp  = ncr_ccb_from_dsa(np, dsa);
 
 	/*
-	 * Fix Up. Some disks respond to a PPR negotation with
+	 * Fix Up. Some disks respond to a PPR negotiation with
 	 * a bus free instead of a message reject. 
 	 * Disable ppr negotiation if this is first time
 	 * tried ppr negotiation.
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_conf.h b/drivers/scsi/sym53c8xx_2/sym_conf.h
--- a/drivers/scsi/sym53c8xx_2/sym_conf.h	Tue Mar  4 19:30:12 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_conf.h	Tue Mar  4 19:30:12 2003
@@ -244,7 +244,7 @@
  *  But for HVD/SE only capable chips (825a, 875, 885), 
  *  the driver uses some heuristic to probe against HVD. 
  *  Normally, the chip senses the DIFFSENS signal and 
- *  should switch its BUS tranceivers to high impedance 
+ *  should switch its BUS transceivers to high impedance 
  *  in situation of the driver having been wrong about 
  *  the actual BUS mode. May-be, the BUS mode probing of 
  *  the driver is safe, but, given that it may be partially 
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c
--- a/drivers/scsi/sym53c8xx_2/sym_fw.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_fw.c	Tue Mar  4 19:30:14 2003
@@ -539,7 +539,7 @@
 		case 0x8:
 			/*
 			 *  JUMP / CALL
-			 *  dont't relocate if relative :-)
+			 *  don't relocate if relative :-)
 			 */
 			if (opcode & 0x00800000)
 				relocs = 0;
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_fw1.h b/drivers/scsi/sym53c8xx_2/sym_fw1.h
--- a/drivers/scsi/sym53c8xx_2/sym_fw1.h	Tue Mar  4 19:30:12 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_fw1.h	Tue Mar  4 19:30:12 2003
@@ -340,7 +340,7 @@
 	/*
 	 *  Now there are 4 possibilities:
 	 *
-	 *  (1) The chip looses arbitration.
+	 *  (1) The chip loses arbitration.
 	 *  This is ok, because it will try again,
 	 *  when the bus becomes idle.
 	 *  (But beware of the timeout function!)
@@ -1361,7 +1361,7 @@
 	 *  some target to reset or some disconnected 
 	 *  job to abort. Since error recovery is a serious 
 	 *  busyness, we will really reset the SCSI BUS, if 
-	 *  case of a SCSI interrupt occuring in this path.
+	 *  case of a SCSI interrupt occurring in this path.
 	 */
 
 #ifdef SYM_CONF_TARGET_ROLE_SUPPORT
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_fw2.h b/drivers/scsi/sym53c8xx_2/sym_fw2.h
--- a/drivers/scsi/sym53c8xx_2/sym_fw2.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_fw2.h	Tue Mar  4 19:30:13 2003
@@ -320,7 +320,7 @@
 	/*
 	 *  Now there are 4 possibilities:
 	 *
-	 *  (1) The chip looses arbitration.
+	 *  (1) The chip loses arbitration.
 	 *  This is ok, because it will try again,
 	 *  when the bus becomes idle.
 	 *  (But beware of the timeout function!)
@@ -1246,7 +1246,7 @@
 	 *  some target to reset or some disconnected 
 	 *  job to abort. Since error recovery is a serious 
 	 *  busyness, we will really reset the SCSI BUS, if 
-	 *  case of a SCSI interrupt occuring in this path.
+	 *  case of a SCSI interrupt occurring in this path.
 	 */
 #ifdef SYM_CONF_TARGET_ROLE_SUPPORT
 	/*
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c	Tue Mar  4 19:30:14 2003
@@ -125,7 +125,7 @@
  *
  *  The whole SCSI sub-system under Linux is basically single-threaded.
  *  Everything, including low-level driver interrupt routine, happens 
- *  whith the `io_request_lock' held.
+ *  with the `io_request_lock' held.
  *  The sym53c8xx-1.x drivers series ran their interrupt code using a 
  *  spin mutex per controller. This added complexity without improving 
  *  scalability significantly. the sym-2 driver still use a spinlock 
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c	Tue Mar  4 19:30:03 2003
@@ -234,7 +234,7 @@
 			INW (nc_sist);
 		}
 		else if (istat & DIP) {
-			if (INB (nc_dstat) & ABRT);
+			if (INB (nc_dstat) & ABRT)
 				break;
 		}
 		UDELAY(5);
diff -Nru a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
--- a/drivers/scsi/wd33c93.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/scsi/wd33c93.c	Tue Mar  4 19:30:11 2003
@@ -1,7 +1,4 @@
 /*
- *    wd33c93.c - Linux-68k device driver for the Commodore
- *                Amiga A2091/590 SCSI controller card
- *
  * Copyright (c) 1996 John Shifflett, GeoLog Consulting
  *    john@geolog.com
  *    jshiffle@netcom.com
@@ -15,8 +12,9 @@
  * 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.
- *
- *
+ */
+
+/*
  * Drew Eckhardt's excellent 'Generic NCR5380' sources from Linux-PC
  * provided much of the inspiration and some of the code for this
  * driver. Everything I know about Amiga DMA was gleaned from careful
@@ -76,38 +74,26 @@
 #include <linux/config.h>
 #include <linux/module.h>
 
-#include <asm/system.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/version.h>
 #include <linux/init.h>
-#include <asm/irq.h>
 #include <linux/blk.h>
+#include <asm/irq.h>
 
 #include "scsi.h"
 #include "hosts.h"
 
-
-#define WD33C93_VERSION    "1.25"
-#define WD33C93_DATE       "09/Jul/1997"
-/* NOTE: 1.25 for m68k is related to in2000-1.31 for x86 */
-
-/*
- * Note - the following defines have been moved to 'wd33c93.h':
- *
- *    PROC_INTERFACE
- *    PROC_STATISTICS
- *    SYNC_DEBUG
- *    DEBUGGING_ON
- *    DEBUG_DEFAULTS
- *
- */
-
-
 #include "wd33c93.h"
 
 
+#define WD33C93_VERSION    "1.26"
+#define WD33C93_DATE       "22/Feb/2003"
+
+MODULE_AUTHOR("John Shifflett");
+MODULE_DESCRIPTION("Generic WD33C93 SCSI driver");
+MODULE_LICENSE("GPL");
 
 /*
  * 'setup_strings' is a single string used to pass operating parameters and
@@ -163,172 +149,223 @@
  */
 
 /* Normally, no defaults are specified */
-static char *setup_args[] =
-      {"","","","","","","","",""};
-
-/* filled in by 'insmod' */
-static char *setup_strings = 0;
+static char *setup_args[] = { "", "", "", "", "", "", "", "", "" };
 
-#ifdef MODULE_PARM
+static char *setup_strings;
 MODULE_PARM(setup_strings, "s");
-#endif
-
 
+static void wd33c93_execute(struct Scsi_Host *instance);
 
-static inline uchar read_wd33c93(const wd33c93_regs regs, uchar reg_num)
+#ifdef CONFIG_WD33C93_PIO
+static inline uchar
+read_wd33c93(const wd33c93_regs regs, uchar reg_num)
 {
-   *regs.SASR = reg_num;
-   mb();
-   return(*regs.SCMD);
+	uchar data;
+
+	outb(reg_num, *regs.SASR);
+	data = inb(*regs.SCMD);
+	return data;
 }
 
+static inline unsigned long
+read_wd33c93_count(const wd33c93_regs regs)
+{
+	unsigned long value;
 
-#define READ_AUX_STAT() (*regs.SASR)
+	outb(WD_TRANSFER_COUNT_MSB, *regs.SASR);
+	value = inb(*regs.SCMD) << 16;
+	value |= inb(*regs.SCMD) << 8;
+	value |= inb(*regs.SCMD);
+	return value;
+}
 
+static inline uchar
+read_aux_stat(const wd33c93_regs regs)
+{
+	return inb(*regs.SASR);
+}
+
+static inline void
+write_wd33c93(const wd33c93_regs regs, uchar reg_num, uchar value)
+{
+      outb(reg_num, *regs.SASR);
+      outb(value, *regs.SCMD);
+}
 
-static inline void write_wd33c93(const wd33c93_regs regs, uchar reg_num,
-				 uchar value)
+static inline void
+write_wd33c93_count(const wd33c93_regs regs, unsigned long value)
 {
-   *regs.SASR = reg_num;
-   mb();
-   *regs.SCMD = value;
-   mb();
+	outb(WD_TRANSFER_COUNT_MSB, *regs.SASR);
+	outb((value >> 16) & 0xff, *regs.SCMD);
+	outb((value >> 8) & 0xff, *regs.SCMD);
+	outb( value & 0xff, *regs.SCMD);
 }
 
+#define write_wd33c93_cmd(regs, cmd) \
+	write_wd33c93((regs), WD_COMMAND, (cmd))
 
-static inline void write_wd33c93_cmd(const wd33c93_regs regs, uchar cmd)
+static inline void
+write_wd33c93_cdb(const wd33c93_regs regs, uint len, uchar cmnd[])
 {
-   *regs.SASR = WD_COMMAND;
-   mb();
-   *regs.SCMD = cmd;
-   mb();
+	int i;
+
+	outb(WD_CDB_1, *regs.SASR);
+	for (i=0; i<len; i++)
+		outb(cmnd[i], *regs.SCMD);
 }
 
+#else /* CONFIG_WD33C93_PIO */
+static inline uchar
+read_wd33c93(const wd33c93_regs regs, uchar reg_num)
+{
+	*regs.SASR = reg_num;
+	mb();
+	return (*regs.SCMD);
+}
 
-static inline uchar read_1_byte(const wd33c93_regs regs)
+static unsigned long
+read_wd33c93_count(const wd33c93_regs regs)
 {
-uchar asr;
-uchar x = 0;
+	unsigned long value;
 
-   write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
-   write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO|0x80);
-   do {
-      asr = READ_AUX_STAT();
-      if (asr & ASR_DBR)
-         x = read_wd33c93(regs, WD_DATA);
-      } while (!(asr & ASR_INT));
-   return x;
+	*regs.SASR = WD_TRANSFER_COUNT_MSB;
+	mb();
+	value = *regs.SCMD << 16;
+	value |= *regs.SCMD << 8;
+	value |= *regs.SCMD;
+	mb();
+	return value;
 }
 
+static inline uchar
+read_aux_stat(const wd33c93_regs regs)
+{
+	return *regs.SASR;
+}
 
-static void write_wd33c93_count(const wd33c93_regs regs, unsigned long value)
+static inline void
+write_wd33c93(const wd33c93_regs regs, uchar reg_num, uchar value)
 {
-   *regs.SASR = WD_TRANSFER_COUNT_MSB;
-   mb();
-   *regs.SCMD = value >> 16;
-   *regs.SCMD = value >> 8;
-   *regs.SCMD = value;
-   mb();
+	*regs.SASR = reg_num;
+	mb();
+	*regs.SCMD = value;
+	mb();
 }
 
+static void
+write_wd33c93_count(const wd33c93_regs regs, unsigned long value)
+{
+	*regs.SASR = WD_TRANSFER_COUNT_MSB;
+	mb();
+	*regs.SCMD = value >> 16;
+	*regs.SCMD = value >> 8;
+	*regs.SCMD = value;
+	mb();
+}
 
-static unsigned long read_wd33c93_count(const wd33c93_regs regs)
+static inline void
+write_wd33c93_cmd(const wd33c93_regs regs, uchar cmd)
 {
-unsigned long value;
+	*regs.SASR = WD_COMMAND;
+	mb();
+	*regs.SCMD = cmd;
+	mb();
+}
+
+static inline void
+write_wd33c93_cdb(const wd33c93_regs regs, uint len, uchar cmnd[])
+{
+	int i;
 
-   *regs.SASR = WD_TRANSFER_COUNT_MSB;
-   mb();
-   value = *regs.SCMD << 16;
-   value |= *regs.SCMD << 8;
-   value |= *regs.SCMD;
-   mb();
-   return value;
+	*regs.SASR = WD_CDB_1;
+	for (i = 0; i < len; i++)
+		*regs.SCMD = cmnd[i];
 }
+#endif /* CONFIG_WD33C93_PIO */
 
+static inline uchar
+read_1_byte(const wd33c93_regs regs)
+{
+	uchar asr;
+	uchar x = 0;
+
+	write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
+	write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO | 0x80);
+	do {
+		asr = read_aux_stat(regs);
+		if (asr & ASR_DBR)
+			x = read_wd33c93(regs, WD_DATA);
+	} while (!(asr & ASR_INT));
+	return x;
+}
 
 /* The 33c93 needs to be told which direction a command transfers its
  * data; we use this function to figure it out. Returns true if there
  * will be a DATA_OUT phase with this command, false otherwise.
  * (Thanks to Joerg Dorchain for the research and suggestion.)
  */
-static int is_dir_out(Scsi_Cmnd *cmd)
+static inline int
+is_dir_out(Scsi_Cmnd * cmd)
 {
-   switch (cmd->cmnd[0]) {
-      case WRITE_6:           case WRITE_10:          case WRITE_12:
-      case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:
-      case WRITE_VERIFY:      case WRITE_VERIFY_12:      
-      case COMPARE:           case COPY:              case COPY_VERIFY:
-      case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:
-      case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:      
-      case FORMAT_UNIT:       case REASSIGN_BLOCKS:   case RESERVE:
-      case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:
-      case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:
-      case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:
-      case 0xea:
-         return 1;
-      default:
-         return 0;
-      }
+	return cmd->sc_data_direction == SCSI_DATA_WRITE;
 }
 
+static struct sx_period sx_table[] = {
+	{1, 0x20},
+	{252, 0x20},
+	{376, 0x30},
+	{500, 0x40},
+	{624, 0x50},
+	{752, 0x60},
+	{876, 0x70},
+	{1000, 0x00},
+	{0, 0}
+};
 
+static int
+round_period(unsigned int period)
+{
+	int x;
 
-static struct sx_period sx_table[] = {
-   {  1, 0x20},
-   {252, 0x20},
-   {376, 0x30},
-   {500, 0x40},
-   {624, 0x50},
-   {752, 0x60},
-   {876, 0x70},
-   {1000,0x00},
-   {0,   0} };
-
-static int round_period(unsigned int period)
-{
-int x;
-
-   for (x=1; sx_table[x].period_ns; x++) {
-      if ((period <= sx_table[x-0].period_ns) &&
-          (period >  sx_table[x-1].period_ns)) {
-         return x;
-         }
-      }
-   return 7;
-}
-
-static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
-{
-uchar result;
-
-   period *= 4;   /* convert SDTR code to ns */
-   result = sx_table[round_period(period)].reg_value;
-   result |= (offset < OPTIMUM_SX_OFF)?offset:OPTIMUM_SX_OFF;
-   return result;
+	for (x = 1; sx_table[x].period_ns; x++) {
+		if ((period <= sx_table[x - 0].period_ns) &&
+		    (period > sx_table[x - 1].period_ns)) {
+			return x;
+		}
+	}
+	return 7;
 }
 
+static uchar
+calc_sync_xfer(unsigned int period, unsigned int offset)
+{
+	uchar result;
 
+	period *= 4;		/* convert SDTR code to ns */
+	result = sx_table[round_period(period)].reg_value;
+	result |= (offset < OPTIMUM_SX_OFF) ? offset : OPTIMUM_SX_OFF;
+	return result;
+}
 
-static void wd33c93_execute(struct Scsi_Host *instance);
-
-int wd33c93_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+int
+wd33c93_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
-   struct WD33C93_hostdata *hostdata;
-   Scsi_Cmnd *tmp;
+	struct WD33C93_hostdata *hostdata;
+	Scsi_Cmnd *tmp;
 
-   hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
+	hostdata = (struct WD33C93_hostdata *) cmd->device->host->hostdata;
 
-DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld( ",cmd->target,cmd->cmnd[0],cmd->pid))
+	DB(DB_QUEUE_COMMAND,
+	   printk("Q-%d-%02x-%ld( ", cmd->device->id, cmd->cmnd[0], cmd->pid))
 
 /* Set up a few fields in the Scsi_Cmnd structure for our own use:
  *  - host_scribble is the pointer to the next cmd in the input queue
  *  - scsi_done points to the routine we call when a cmd is finished
  *  - result is what you'd expect
  */
-
-   cmd->host_scribble = NULL;
-   cmd->scsi_done = done;
-   cmd->result = 0;
+	cmd->host_scribble = NULL;
+	cmd->scsi_done = done;
+	cmd->result = 0;
 
 /* We use the Scsi_Pointer structure that's included with each command
  * as a scratchpad (as it's intended to be used!). The handy thing about
@@ -345,19 +382,18 @@
  *  - SCp.phase records this command's SRCID_ER bit setting
  */
 
-   if (cmd->use_sg) {
-      cmd->SCp.buffer = (struct scatterlist *)cmd->buffer;
-      cmd->SCp.buffers_residual = cmd->use_sg - 1;
-      cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
-		     cmd->SCp.buffer->offset;
-      cmd->SCp.this_residual = cmd->SCp.buffer->length;
-      }
-   else {
-      cmd->SCp.buffer = NULL;
-      cmd->SCp.buffers_residual = 0;
-      cmd->SCp.ptr = (char *)cmd->request_buffer;
-      cmd->SCp.this_residual = cmd->request_bufflen;
-      }
+	if (cmd->use_sg) {
+		cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
+		cmd->SCp.buffers_residual = cmd->use_sg - 1;
+		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
+		    cmd->SCp.buffer->offset;
+		cmd->SCp.this_residual = cmd->SCp.buffer->length;
+	} else {
+		cmd->SCp.buffer = NULL;
+		cmd->SCp.buffers_residual = 0;
+		cmd->SCp.ptr = (char *) cmd->request_buffer;
+		cmd->SCp.this_residual = cmd->request_bufflen;
+	}
 
 /* WD docs state that at the conclusion of a "LEVEL2" command, the
  * status byte can be retrieved from the LUN register. Apparently,
@@ -376,41 +412,37 @@
  * status byte is stored.
  */
 
-   cmd->SCp.Status = ILLEGAL_STATUS_BYTE;
+	cmd->SCp.Status = ILLEGAL_STATUS_BYTE;
 
-   /*
-    * Add the cmd to the end of 'input_Q'. Note that REQUEST SENSE
-    * commands are added to the head of the queue so that the desired
-    * sense data is not lost before REQUEST_SENSE executes.
-    */
-
-   spin_lock_irq(&hostdata->lock);
-
-   if (!(hostdata->input_Q) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-      cmd->host_scribble = (uchar *)hostdata->input_Q;
-      hostdata->input_Q = cmd;
-      }
-   else {   /* find the end of the queue */
-      for (tmp=(Scsi_Cmnd *)hostdata->input_Q; tmp->host_scribble;
-            tmp=(Scsi_Cmnd *)tmp->host_scribble)
-         ;
-      tmp->host_scribble = (uchar *)cmd;
-      }
+	/*
+	 * Add the cmd to the end of 'input_Q'. Note that REQUEST SENSE
+	 * commands are added to the head of the queue so that the desired
+	 * sense data is not lost before REQUEST_SENSE executes.
+	 */
+
+	spin_lock_irq(&hostdata->lock);
+
+	if (!(hostdata->input_Q) || (cmd->cmnd[0] == REQUEST_SENSE)) {
+		cmd->host_scribble = (uchar *) hostdata->input_Q;
+		hostdata->input_Q = cmd;
+	} else {		/* find the end of the queue */
+		for (tmp = (Scsi_Cmnd *) hostdata->input_Q; tmp->host_scribble;
+		     tmp = (Scsi_Cmnd *) tmp->host_scribble) ;
+		tmp->host_scribble = (uchar *) cmd;
+	}
 
 /* We know that there's at least one command in 'input_Q' now.
  * Go see if any of them are runnable!
  */
 
-   wd33c93_execute(cmd->host);
+	wd33c93_execute(cmd->device->host);
 
-DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
+	DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid))
 
-   spin_unlock_irq(&hostdata->lock);
-   return 0;
+	spin_unlock_irq(&hostdata->lock);
+	return 0;
 }
 
-
-
 /*
  * This routine attempts to start a scsi command. If the host_card is
  * already connected, we give up immediately. Otherwise, look through
@@ -421,64 +453,60 @@
  * the wd33c93_intr itself, which means that a wd33c93 interrupt
  * cannot occur while we are in here.
  */
-static void wd33c93_execute (struct Scsi_Host *instance)
+static void
+wd33c93_execute(struct Scsi_Host *instance)
 {
-struct WD33C93_hostdata *hostdata = (struct WD33C93_hostdata *)instance->hostdata;
-const wd33c93_regs regs = hostdata->regs;
-Scsi_Cmnd *cmd, *prev;
-int i;
-
-DB(DB_EXECUTE,printk("EX("))
-
-   if (hostdata->selecting || hostdata->connected) {
-
-DB(DB_EXECUTE,printk(")EX-0 "))
-
-      return;
-      }
-
-    /*
-     * Search through the input_Q for a command destined
-     * for an idle target/lun.
-     */
-
-   cmd = (Scsi_Cmnd *)hostdata->input_Q;
-   prev = 0;
-   while (cmd) {
-      if (!(hostdata->busy[cmd->target] & (1 << cmd->lun)))
-         break;
-      prev = cmd;
-      cmd = (Scsi_Cmnd *)cmd->host_scribble;
-      }
-
-   /* quit if queue empty or all possible targets are busy */
-
-   if (!cmd) {
-
-DB(DB_EXECUTE,printk(")EX-1 "))
-
-      return;
-      }
-
-   /*  remove command from queue */
-   
-   if (prev)
-      prev->host_scribble = cmd->host_scribble;
-   else
-      hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble;
+	struct WD33C93_hostdata *hostdata =
+	    (struct WD33C93_hostdata *) instance->hostdata;
+	const wd33c93_regs regs = hostdata->regs;
+	Scsi_Cmnd *cmd, *prev;
+
+	DB(DB_EXECUTE, printk("EX("))
+	if (hostdata->selecting || hostdata->connected) {
+		DB(DB_EXECUTE, printk(")EX-0 "))
+		return;
+	}
+
+	/*
+	 * Search through the input_Q for a command destined
+	 * for an idle target/lun.
+	 */
+
+	cmd = (Scsi_Cmnd *) hostdata->input_Q;
+	prev = 0;
+	while (cmd) {
+		if (!(hostdata->busy[cmd->device->id] & (1 << cmd->device->lun)))
+			break;
+		prev = cmd;
+		cmd = (Scsi_Cmnd *) cmd->host_scribble;
+	}
+
+	/* quit if queue empty or all possible targets are busy */
+
+	if (!cmd) {
+		DB(DB_EXECUTE, printk(")EX-1 "))
+		return;
+	}
+
+	/*  remove command from queue */
+
+	if (prev)
+		prev->host_scribble = cmd->host_scribble;
+	else
+		hostdata->input_Q = (Scsi_Cmnd *) cmd->host_scribble;
 
 #ifdef PROC_STATISTICS
-   hostdata->cmd_cnt[cmd->target]++;
+	hostdata->cmd_cnt[cmd->device->id]++;
 #endif
 
-   /*
-    * Start the selection process
-    */
-
-   if (is_dir_out(cmd))
-      write_wd33c93(regs, WD_DESTINATION_ID, cmd->target);
-   else
-      write_wd33c93(regs, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
+	/*
+	 * Start the selection process
+	 */
+
+	if (is_dir_out(cmd))
+		write_wd33c93(regs, WD_DESTINATION_ID, cmd->device->id);
+	else
+		write_wd33c93(regs, WD_DESTINATION_ID, cmd->device->id | DSTID_DPD);
 
 /* Now we need to figure out whether or not this command is a good
  * candidate for disconnect/reselect. We guess to the best of our
@@ -503,55 +531,58 @@
  * to change around and experiment with for now.
  */
 
-   cmd->SCp.phase = 0;  /* assume no disconnect */
-   if (hostdata->disconnect == DIS_NEVER)
-      goto no;
-   if (hostdata->disconnect == DIS_ALWAYS)
-      goto yes;
-   if (cmd->device->type == 1)   /* tape drive? */
-      goto yes;
-   if (hostdata->disconnected_Q) /* other commands disconnected? */
-      goto yes;
-   if (!(hostdata->input_Q))     /* input_Q empty? */
-      goto no;
-   for (prev=(Scsi_Cmnd *)hostdata->input_Q; prev;
-         prev=(Scsi_Cmnd *)prev->host_scribble) {
-      if ((prev->target != cmd->target) || (prev->lun != cmd->lun)) {
-         for (prev=(Scsi_Cmnd *)hostdata->input_Q; prev;
-               prev=(Scsi_Cmnd *)prev->host_scribble)
-            prev->SCp.phase = 1;
-         goto yes;
-         }
-      }
-   goto no;
+	cmd->SCp.phase = 0;	/* assume no disconnect */
+	if (hostdata->disconnect == DIS_NEVER)
+		goto no;
+	if (hostdata->disconnect == DIS_ALWAYS)
+		goto yes;
+	if (cmd->device->type == 1)	/* tape drive? */
+		goto yes;
+	if (hostdata->disconnected_Q)	/* other commands disconnected? */
+		goto yes;
+	if (!(hostdata->input_Q))	/* input_Q empty? */
+		goto no;
+	for (prev = (Scsi_Cmnd *) hostdata->input_Q; prev;
+	     prev = (Scsi_Cmnd *) prev->host_scribble) {
+		if ((prev->device->id != cmd->device->id) ||
+		    (prev->device->lun != cmd->device->lun)) {
+			for (prev = (Scsi_Cmnd *) hostdata->input_Q; prev;
+			     prev = (Scsi_Cmnd *) prev->host_scribble)
+				prev->SCp.phase = 1;
+			goto yes;
+		}
+	}
 
-yes:
-   cmd->SCp.phase = 1;
+	goto no;
+
+ yes:
+	cmd->SCp.phase = 1;
 
 #ifdef PROC_STATISTICS
-   hostdata->disc_allowed_cnt[cmd->target]++;
+	hostdata->disc_allowed_cnt[cmd->device->id]++;
 #endif
 
-no:
+ no:
 
-   write_wd33c93(regs, WD_SOURCE_ID, ((cmd->SCp.phase)?SRCID_ER:0));
+	write_wd33c93(regs, WD_SOURCE_ID, ((cmd->SCp.phase) ? SRCID_ER : 0));
 
-   write_wd33c93(regs, WD_TARGET_LUN, cmd->lun);
-   write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
-   hostdata->busy[cmd->target] |= (1 << cmd->lun);
-
-   if ((hostdata->level2 == L2_NONE) ||
-       (hostdata->sync_stat[cmd->target] == SS_UNSET)) {
-
-         /*
-          * Do a 'Select-With-ATN' command. This will end with
-          * one of the following interrupts:
-          *    CSR_RESEL_AM:  failure - can try again later.
-          *    CSR_TIMEOUT:   failure - give up.
-          *    CSR_SELECT:    success - proceed.
-          */
+	write_wd33c93(regs, WD_TARGET_LUN, cmd->device->lun);
+	write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,
+		      hostdata->sync_xfer[cmd->device->id]);
+	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+
+	if ((hostdata->level2 == L2_NONE) ||
+	    (hostdata->sync_stat[cmd->device->id] == SS_UNSET)) {
+
+		/*
+		 * Do a 'Select-With-ATN' command. This will end with
+		 * one of the following interrupts:
+		 *    CSR_RESEL_AM:  failure - can try again later.
+		 *    CSR_TIMEOUT:   failure - give up.
+		 *    CSR_SELECT:    success - proceed.
+		 */
 
-      hostdata->selecting = cmd;
+		hostdata->selecting = cmd;
 
 /* Every target has its own synchronous transfer setting, kept in the
  * sync_xfer array, and a corresponding status byte in sync_stat[].
@@ -565,119 +596,115 @@
  * later, but at that time we'll negotiate for async by specifying a
  * sync fifo depth of 0.
  */
-      if (hostdata->sync_stat[cmd->target] == SS_UNSET)
-            hostdata->sync_stat[cmd->target] = SS_FIRST;
-      hostdata->state = S_SELECTING;
-      write_wd33c93_count(regs, 0); /* guarantee a DATA_PHASE interrupt */
-      write_wd33c93_cmd(regs, WD_CMD_SEL_ATN);
-      }
-
-   else {
-
-         /*
-          * Do a 'Select-With-ATN-Xfer' command. This will end with
-          * one of the following interrupts:
-          *    CSR_RESEL_AM:  failure - can try again later.
-          *    CSR_TIMEOUT:   failure - give up.
-          *    anything else: success - proceed.
-          */
-
-      hostdata->connected = cmd;
-      write_wd33c93(regs, WD_COMMAND_PHASE, 0);
-
-   /* copy command_descriptor_block into WD chip
-    * (take advantage of auto-incrementing)
-    */
-
-      *regs.SASR = WD_CDB_1;
-      for (i=0; i<cmd->cmd_len; i++)
-         *regs.SCMD = cmd->cmnd[i];
-
-   /* The wd33c93 only knows about Group 0, 1, and 5 commands when
-    * it's doing a 'select-and-transfer'. To be safe, we write the
-    * size of the CDB into the OWN_ID register for every case. This
-    * way there won't be problems with vendor-unique, audio, etc.
-    */
-
-      write_wd33c93(regs, WD_OWN_ID, cmd->cmd_len);
-
-   /* When doing a non-disconnect command with DMA, we can save
-    * ourselves a DATA phase interrupt later by setting everything
-    * up ahead of time.
-    */
-
-      if ((cmd->SCp.phase == 0) && (hostdata->no_dma == 0)) {
-         if (hostdata->dma_setup(cmd,
-                     (is_dir_out(cmd))?DATA_OUT_DIR:DATA_IN_DIR))
-            write_wd33c93_count(regs, 0); /* guarantee a DATA_PHASE interrupt */
-         else {
-            write_wd33c93_count(regs, cmd->SCp.this_residual);
-            write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_DMA);
-            hostdata->dma = D_DMA_RUNNING;
-            }
-         }
-      else
-         write_wd33c93_count(regs, 0); /* guarantee a DATA_PHASE interrupt */
-
-      hostdata->state = S_RUNNING_LEVEL2;
-      write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
-      }
-
-   /*
-    * Since the SCSI bus can handle only 1 connection at a time,
-    * we get out of here now. If the selection fails, or when
-    * the command disconnects, we'll come back to this routine
-    * to search the input_Q again...
-    */
-      
-DB(DB_EXECUTE,printk("%s%ld)EX-2 ",(cmd->SCp.phase)?"d:":"",cmd->pid))
-}
-
-
-
-static void transfer_pio(const wd33c93_regs regs, uchar *buf, int cnt,
-			 int data_in_dir, struct WD33C93_hostdata *hostdata)
-{
-uchar asr;
-
-DB(DB_TRANSFER,printk("(%p,%d,%s:",buf,cnt,data_in_dir?"in":"out"))
-
-   write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
-   write_wd33c93_count(regs, cnt);
-   write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO);
-   if (data_in_dir) {
-      do {
-         asr = READ_AUX_STAT();
-         if (asr & ASR_DBR)
-            *buf++ = read_wd33c93(regs, WD_DATA);
-         } while (!(asr & ASR_INT));
-      }
-   else {
-      do {
-         asr = READ_AUX_STAT();
-         if (asr & ASR_DBR)
-            write_wd33c93(regs, WD_DATA, *buf++);
-         } while (!(asr & ASR_INT));
-      }
-
-   /* Note: we are returning with the interrupt UN-cleared.
-   * Since (presumably) an entire I/O operation has
-   * completed, the bus phase is probably different, and
-   * the interrupt routine will discover this when it
-   * responds to the uncleared int.
-   */
+		if (hostdata->sync_stat[cmd->device->id] == SS_UNSET)
+			hostdata->sync_stat[cmd->device->id] = SS_FIRST;
+		hostdata->state = S_SELECTING;
+		write_wd33c93_count(regs, 0);	/* guarantee a DATA_PHASE interrupt */
+		write_wd33c93_cmd(regs, WD_CMD_SEL_ATN);
+	} else {
+
+		/*
+		 * Do a 'Select-With-ATN-Xfer' command. This will end with
+		 * one of the following interrupts:
+		 *    CSR_RESEL_AM:  failure - can try again later.
+		 *    CSR_TIMEOUT:   failure - give up.
+		 *    anything else: success - proceed.
+		 */
+
+		hostdata->connected = cmd;
+		write_wd33c93(regs, WD_COMMAND_PHASE, 0);
+
+		/* copy command_descriptor_block into WD chip
+		 * (take advantage of auto-incrementing)
+		 */
+
+		write_wd33c93_cdb(regs, cmd->cmd_len, cmd->cmnd);
+
+		/* The wd33c93 only knows about Group 0, 1, and 5 commands when
+		 * it's doing a 'select-and-transfer'. To be safe, we write the
+		 * size of the CDB into the OWN_ID register for every case. This
+		 * way there won't be problems with vendor-unique, audio, etc.
+		 */
+
+		write_wd33c93(regs, WD_OWN_ID, cmd->cmd_len);
+
+		/* When doing a non-disconnect command with DMA, we can save
+		 * ourselves a DATA phase interrupt later by setting everything
+		 * up ahead of time.
+		 */
+
+		if ((cmd->SCp.phase == 0) && (hostdata->no_dma == 0)) {
+			if (hostdata->dma_setup(cmd,
+						(is_dir_out(cmd)) ? DATA_OUT_DIR
+						: DATA_IN_DIR))
+				write_wd33c93_count(regs, 0);	/* guarantee a DATA_PHASE interrupt */
+			else {
+				write_wd33c93_count(regs,
+						    cmd->SCp.this_residual);
+				write_wd33c93(regs, WD_CONTROL,
+					      CTRL_IDI | CTRL_EDI | CTRL_DMA);
+				hostdata->dma = D_DMA_RUNNING;
+			}
+		} else
+			write_wd33c93_count(regs, 0);	/* guarantee a DATA_PHASE interrupt */
+
+		hostdata->state = S_RUNNING_LEVEL2;
+		write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
+	}
+
+	/*
+	 * Since the SCSI bus can handle only 1 connection at a time,
+	 * we get out of here now. If the selection fails, or when
+	 * the command disconnects, we'll come back to this routine
+	 * to search the input_Q again...
+	 */
+
+	DB(DB_EXECUTE,
+	   printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->pid))
+}
+
+static void
+transfer_pio(const wd33c93_regs regs, uchar * buf, int cnt,
+	     int data_in_dir, struct WD33C93_hostdata *hostdata)
+{
+	uchar asr;
+
+	DB(DB_TRANSFER,
+	   printk("(%p,%d,%s:", buf, cnt, data_in_dir ? "in" : "out"))
+
+	write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
+	write_wd33c93_count(regs, cnt);
+	write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO);
+	if (data_in_dir) {
+		do {
+			asr = read_aux_stat(regs);
+			if (asr & ASR_DBR)
+				*buf++ = read_wd33c93(regs, WD_DATA);
+		} while (!(asr & ASR_INT));
+	} else {
+		do {
+			asr = read_aux_stat(regs);
+			if (asr & ASR_DBR)
+				write_wd33c93(regs, WD_DATA, *buf++);
+		} while (!(asr & ASR_INT));
+	}
+
+	/* Note: we are returning with the interrupt UN-cleared.
+	 * Since (presumably) an entire I/O operation has
+	 * completed, the bus phase is probably different, and
+	 * the interrupt routine will discover this when it
+	 * responds to the uncleared int.
+	 */
 
 }
 
-
-
-static void transfer_bytes(const wd33c93_regs regs, Scsi_Cmnd *cmd,
-			   int data_in_dir)
+static void
+transfer_bytes(const wd33c93_regs regs, Scsi_Cmnd * cmd, int data_in_dir)
 {
-struct WD33C93_hostdata *hostdata;
-unsigned long length;
+	struct WD33C93_hostdata *hostdata;
+	unsigned long length;
 
-   hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
+	hostdata = (struct WD33C93_hostdata *) cmd->device->host->hostdata;
 
 /* Normally, you'd expect 'this_residual' to be non-zero here.
  * In a series of scatter-gather transfers, however, this
@@ -687,38 +714,31 @@
  * now we need to setup the next scatter-gather buffer as the
  * source or destination for THIS transfer.
  */
-   if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
-      ++cmd->SCp.buffer;
-      --cmd->SCp.buffers_residual;
-      cmd->SCp.this_residual = cmd->SCp.buffer->length;
-      cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
-		     cmd->SCp.buffer->offset;
-      }
+	if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
+		++cmd->SCp.buffer;
+		--cmd->SCp.buffers_residual;
+		cmd->SCp.this_residual = cmd->SCp.buffer->length;
+		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
+		    cmd->SCp.buffer->offset;
+	}
 
-   write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
+	write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,
+		      hostdata->sync_xfer[cmd->device->id]);
 
 /* 'hostdata->no_dma' is TRUE if we don't even want to try DMA.
  * Update 'this_residual' and 'ptr' after 'transfer_pio()' returns.
  */
 
-   if (hostdata->no_dma)
-      goto use_transfer_pio;
-
-/* 'dma_setup()' will return TRUE if we can't do DMA.
- * Update 'this_residual' and 'ptr' after 'transfer_pio()' returns.
- */
-
-   else if (hostdata->dma_setup(cmd, data_in_dir)) {
-use_transfer_pio:
+	if (hostdata->no_dma || hostdata->dma_setup(cmd, data_in_dir)) {
 #ifdef PROC_STATISTICS
-      hostdata->pio_cnt++;
+		hostdata->pio_cnt++;
 #endif
-      transfer_pio(regs, (uchar *)cmd->SCp.ptr, cmd->SCp.this_residual,
-                         data_in_dir, hostdata);
-      length = cmd->SCp.this_residual;
-      cmd->SCp.this_residual = read_wd33c93_count(regs);
-      cmd->SCp.ptr += (length - cmd->SCp.this_residual);
-      }
+		transfer_pio(regs, (uchar *) cmd->SCp.ptr,
+			     cmd->SCp.this_residual, data_in_dir, hostdata);
+		length = cmd->SCp.this_residual;
+		cmd->SCp.this_residual = read_wd33c93_count(regs);
+		cmd->SCp.ptr += (length - cmd->SCp.this_residual);
+	}
 
 /* We are able to do DMA (in fact, the Amiga hardware is
  * already going!), so start up the wd33c93 in DMA mode.
@@ -729,51 +749,50 @@
  * until then.
  */
 
-   else {
+	else {
 #ifdef PROC_STATISTICS
-      hostdata->dma_cnt++;
+		hostdata->dma_cnt++;
 #endif
-      write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_DMA);
-      write_wd33c93_count(regs, cmd->SCp.this_residual);
-
-      if ((hostdata->level2 >= L2_DATA) ||
-          (hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
-         write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
-         write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
-         hostdata->state = S_RUNNING_LEVEL2;
-         }
-      else
-         write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO);
+		write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_DMA);
+		write_wd33c93_count(regs, cmd->SCp.this_residual);
 
-      hostdata->dma = D_DMA_RUNNING;
-      }
-}
+		if ((hostdata->level2 >= L2_DATA) ||
+		    (hostdata->level2 == L2_BASIC && cmd->SCp.phase == 0)) {
+			write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
+			write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
+			hostdata->state = S_RUNNING_LEVEL2;
+		} else
+			write_wd33c93_cmd(regs, WD_CMD_TRANS_INFO);
+
+		hostdata->dma = D_DMA_RUNNING;
+	}
+}
+
+void
+wd33c93_intr(struct Scsi_Host *instance)
+{
+	struct WD33C93_hostdata *hostdata =
+	    (struct WD33C93_hostdata *) instance->hostdata;
+	const wd33c93_regs regs = hostdata->regs;
+	Scsi_Cmnd *patch, *cmd;
+	uchar asr, sr, phs, id, lun, *ucp, msg;
+	unsigned long length, flags;
+
+	asr = read_aux_stat(regs);
+	if (!(asr & ASR_INT) || (asr & ASR_BSY))
+		return;
 
-
-
-void wd33c93_intr (struct Scsi_Host *instance)
-{
-struct WD33C93_hostdata *hostdata = (struct WD33C93_hostdata *)instance->hostdata;
-const wd33c93_regs regs = hostdata->regs;
-Scsi_Cmnd *patch, *cmd;
-uchar asr, sr, phs, id, lun, *ucp, msg;
-unsigned long length, flags;
-
-   asr = READ_AUX_STAT();
-   if (!(asr & ASR_INT) || (asr & ASR_BSY))
-      return;
-
-   spin_lock_irqsave(&hostdata->lock, flags);
+	spin_lock_irqsave(&hostdata->lock, flags);
 
 #ifdef PROC_STATISTICS
-   hostdata->int_cnt++;
+	hostdata->int_cnt++;
 #endif
 
-   cmd = (Scsi_Cmnd *)hostdata->connected;   /* assume we're connected */
-   sr = read_wd33c93(regs, WD_SCSI_STATUS);  /* clear the interrupt */
-   phs = read_wd33c93(regs, WD_COMMAND_PHASE);
+	cmd = (Scsi_Cmnd *) hostdata->connected;	/* assume we're connected */
+	sr = read_wd33c93(regs, WD_SCSI_STATUS);	/* clear the interrupt */
+	phs = read_wd33c93(regs, WD_COMMAND_PHASE);
 
-DB(DB_INTR,printk("{%02x:%02x-",asr,sr))
+	DB(DB_INTR, printk("{%02x:%02x-", asr, sr))
 
 /* After starting a DMA transfer, the next interrupt
  * is guaranteed to be in response to completion of
@@ -789,76 +808,74 @@
  * whatever is needed, we go on and service the WD3393
  * interrupt normally.
  */
-
-   if (hostdata->dma == D_DMA_RUNNING) {
-DB(DB_TRANSFER,printk("[%p/%d:",cmd->SCp.ptr,cmd->SCp.this_residual))
-      hostdata->dma_stop(cmd->host, cmd, 1);
-      hostdata->dma = D_DMA_OFF;
-      length = cmd->SCp.this_residual;
-      cmd->SCp.this_residual = read_wd33c93_count(regs);
-      cmd->SCp.ptr += (length - cmd->SCp.this_residual);
-DB(DB_TRANSFER,printk("%p/%d]",cmd->SCp.ptr,cmd->SCp.this_residual))
-      }
+	    if (hostdata->dma == D_DMA_RUNNING) {
+		DB(DB_TRANSFER,
+		   printk("[%p/%d:", cmd->SCp.ptr, cmd->SCp.this_residual))
+		    hostdata->dma_stop(cmd->device->host, cmd, 1);
+		hostdata->dma = D_DMA_OFF;
+		length = cmd->SCp.this_residual;
+		cmd->SCp.this_residual = read_wd33c93_count(regs);
+		cmd->SCp.ptr += (length - cmd->SCp.this_residual);
+		DB(DB_TRANSFER,
+		   printk("%p/%d]", cmd->SCp.ptr, cmd->SCp.this_residual))
+	}
 
 /* Respond to the specific WD3393 interrupt - there are quite a few! */
+	switch (sr) {
+	case CSR_TIMEOUT:
+		DB(DB_INTR, printk("TIMEOUT"))
+
+		    if (hostdata->state == S_RUNNING_LEVEL2)
+			hostdata->connected = NULL;
+		else {
+			cmd = (Scsi_Cmnd *) hostdata->selecting;	/* get a valid cmd */
+			hostdata->selecting = NULL;
+		}
+
+		cmd->result = DID_NO_CONNECT << 16;
+		hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+		hostdata->state = S_UNCONNECTED;
+		cmd->scsi_done(cmd);
+
+		/* From esp.c:
+		 * There is a window of time within the scsi_done() path
+		 * of execution where interrupts are turned back on full
+		 * blast and left that way.  During that time we could
+		 * reconnect to a disconnected command, then we'd bomb
+		 * out below.  We could also end up executing two commands
+		 * at _once_.  ...just so you know why the restore_flags()
+		 * is here...
+		 */
 
-   switch (sr) {
-
-      case CSR_TIMEOUT:
-DB(DB_INTR,printk("TIMEOUT"))
-
-         if (hostdata->state == S_RUNNING_LEVEL2)
-            hostdata->connected = NULL;
-         else {
-            cmd = (Scsi_Cmnd *)hostdata->selecting;   /* get a valid cmd */
-            hostdata->selecting = NULL;
-            }
-
-         cmd->result = DID_NO_CONNECT << 16;
-         hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-         hostdata->state = S_UNCONNECTED;
-         cmd->scsi_done(cmd);
-
-    /* From esp.c:
-     * There is a window of time within the scsi_done() path
-     * of execution where interrupts are turned back on full
-     * blast and left that way.  During that time we could
-     * reconnect to a disconnected command, then we'd bomb
-     * out below.  We could also end up executing two commands
-     * at _once_.  ...just so you know why the restore_flags()
-     * is here...
-     */
-
-         spin_unlock_irqrestore(&hostdata->lock, flags);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
 
 /* We are not connected to a target - check to see if there
  * are commands waiting to be executed.
  */
 
-         wd33c93_execute(instance);
-         break;
-
+		wd33c93_execute(instance);
+		break;
 
 /* Note: this interrupt should not occur in a LEVEL2 command */
 
-      case CSR_SELECT:
-
-DB(DB_INTR,printk("SELECT"))
-         hostdata->connected = cmd = (Scsi_Cmnd *)hostdata->selecting;
-         hostdata->selecting = NULL;
+	case CSR_SELECT:
+		DB(DB_INTR, printk("SELECT"))
+		    hostdata->connected = cmd =
+		    (Scsi_Cmnd *) hostdata->selecting;
+		hostdata->selecting = NULL;
+
+		/* construct an IDENTIFY message with correct disconnect bit */
+
+		hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->device->lun);
+		if (cmd->SCp.phase)
+			hostdata->outgoing_msg[0] |= 0x40;
 
-      /* construct an IDENTIFY message with correct disconnect bit */
-
-         hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->lun);
-         if (cmd->SCp.phase)
-            hostdata->outgoing_msg[0] |= 0x40;
-
-         if (hostdata->sync_stat[cmd->target] == SS_FIRST) {
+		if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) {
 #ifdef SYNC_DEBUG
-printk(" sending SDTR ");
+			printk(" sending SDTR ");
 #endif
 
-            hostdata->sync_stat[cmd->target] = SS_WAITING;
+			hostdata->sync_stat[cmd->device->id] = SS_WAITING;
 
 /* Tack on a 2nd message to ask about synchronous transfers. If we've
  * been asked to do only asynchronous transfers on this device, we
@@ -866,158 +883,155 @@
  * solve the problems some people have had with GVP's Guru ROM.
  */
 
-            hostdata->outgoing_msg[1] = EXTENDED_MESSAGE;
-            hostdata->outgoing_msg[2] = 3;
-            hostdata->outgoing_msg[3] = EXTENDED_SDTR;
-            if (hostdata->no_sync & (1 << cmd->target)) {
-               hostdata->outgoing_msg[4] = hostdata->default_sx_per/4;
-               hostdata->outgoing_msg[5] = 0;
-               }
-            else {
-            hostdata->outgoing_msg[4] = OPTIMUM_SX_PER/4;
-            hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF;
-               }
-            hostdata->outgoing_len = 6;
-            }
-         else
-            hostdata->outgoing_len = 1;
-
-         hostdata->state = S_CONNECTED;
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-	 break;
-
-
-      case CSR_XFER_DONE|PHS_DATA_IN:
-      case CSR_UNEXP    |PHS_DATA_IN:
-      case CSR_SRV_REQ  |PHS_DATA_IN:
-DB(DB_INTR,printk("IN-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
-         transfer_bytes(regs, cmd, DATA_IN_DIR);
-         if (hostdata->state != S_RUNNING_LEVEL2)
-            hostdata->state = S_CONNECTED;
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-	 break;
-
-
-      case CSR_XFER_DONE|PHS_DATA_OUT:
-      case CSR_UNEXP    |PHS_DATA_OUT:
-      case CSR_SRV_REQ  |PHS_DATA_OUT:
-DB(DB_INTR,printk("OUT-%d.%d",cmd->SCp.this_residual,cmd->SCp.buffers_residual))
-         transfer_bytes(regs, cmd, DATA_OUT_DIR);
-         if (hostdata->state != S_RUNNING_LEVEL2)
-            hostdata->state = S_CONNECTED;
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-	 break;
-
+			hostdata->outgoing_msg[1] = EXTENDED_MESSAGE;
+			hostdata->outgoing_msg[2] = 3;
+			hostdata->outgoing_msg[3] = EXTENDED_SDTR;
+			if (hostdata->no_sync & (1 << cmd->device->id)) {
+				hostdata->outgoing_msg[4] =
+				    hostdata->default_sx_per / 4;
+				hostdata->outgoing_msg[5] = 0;
+			} else {
+				hostdata->outgoing_msg[4] = OPTIMUM_SX_PER / 4;
+				hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF;
+			}
+			hostdata->outgoing_len = 6;
+		} else
+			hostdata->outgoing_len = 1;
+
+		hostdata->state = S_CONNECTED;
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
+
+	case CSR_XFER_DONE | PHS_DATA_IN:
+	case CSR_UNEXP | PHS_DATA_IN:
+	case CSR_SRV_REQ | PHS_DATA_IN:
+		DB(DB_INTR,
+		   printk("IN-%d.%d", cmd->SCp.this_residual,
+			  cmd->SCp.buffers_residual))
+		    transfer_bytes(regs, cmd, DATA_IN_DIR);
+		if (hostdata->state != S_RUNNING_LEVEL2)
+			hostdata->state = S_CONNECTED;
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
+
+	case CSR_XFER_DONE | PHS_DATA_OUT:
+	case CSR_UNEXP | PHS_DATA_OUT:
+	case CSR_SRV_REQ | PHS_DATA_OUT:
+		DB(DB_INTR,
+		   printk("OUT-%d.%d", cmd->SCp.this_residual,
+			  cmd->SCp.buffers_residual))
+		    transfer_bytes(regs, cmd, DATA_OUT_DIR);
+		if (hostdata->state != S_RUNNING_LEVEL2)
+			hostdata->state = S_CONNECTED;
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
 
 /* Note: this interrupt should not occur in a LEVEL2 command */
 
-      case CSR_XFER_DONE|PHS_COMMAND:
-      case CSR_UNEXP    |PHS_COMMAND:
-      case CSR_SRV_REQ  |PHS_COMMAND:
-DB(DB_INTR,printk("CMND-%02x,%ld",cmd->cmnd[0],cmd->pid))
-         transfer_pio(regs, cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata);
-         hostdata->state = S_CONNECTED;
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-	 break;
-
-
-      case CSR_XFER_DONE|PHS_STATUS:
-      case CSR_UNEXP    |PHS_STATUS:
-      case CSR_SRV_REQ  |PHS_STATUS:
-DB(DB_INTR,printk("STATUS="))
-
-         cmd->SCp.Status = read_1_byte(regs);
-DB(DB_INTR,printk("%02x",cmd->SCp.Status))
-         if (hostdata->level2 >= L2_BASIC) {
-            sr = read_wd33c93(regs, WD_SCSI_STATUS);  /* clear interrupt */
-            hostdata->state = S_RUNNING_LEVEL2;
-            write_wd33c93(regs, WD_COMMAND_PHASE, 0x50);
-            write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
-            }
-         else {
-            hostdata->state = S_CONNECTED;
-            }
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-	 break;
-
-
-      case CSR_XFER_DONE|PHS_MESS_IN:
-      case CSR_UNEXP    |PHS_MESS_IN:
-      case CSR_SRV_REQ  |PHS_MESS_IN:
-DB(DB_INTR,printk("MSG_IN="))
-
-         msg = read_1_byte(regs);
-         sr = read_wd33c93(regs, WD_SCSI_STATUS);  /* clear interrupt */
-
-         hostdata->incoming_msg[hostdata->incoming_ptr] = msg;
-         if (hostdata->incoming_msg[0] == EXTENDED_MESSAGE)
-            msg = EXTENDED_MESSAGE;
-         else
-            hostdata->incoming_ptr = 0;
-
-         cmd->SCp.Message = msg;
-         switch (msg) {
-
-            case COMMAND_COMPLETE:
-DB(DB_INTR,printk("CCMP-%ld",cmd->pid))
-               write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-               hostdata->state = S_PRE_CMP_DISC;
-               break;
-
-            case SAVE_POINTERS:
-DB(DB_INTR,printk("SDP"))
-               write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-               hostdata->state = S_CONNECTED;
-               break;
-
-            case RESTORE_POINTERS:
-DB(DB_INTR,printk("RDP"))
-               if (hostdata->level2 >= L2_BASIC) {
-                  write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
-                  write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
-                  hostdata->state = S_RUNNING_LEVEL2;
-                  }
-               else {
-                  write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-                  hostdata->state = S_CONNECTED;
-                  }
-               break;
-
-            case DISCONNECT:
-DB(DB_INTR,printk("DIS"))
-               cmd->device->disconnect = 1;
-               write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-               hostdata->state = S_PRE_TMP_DISC;
-               break;
+	case CSR_XFER_DONE | PHS_COMMAND:
+	case CSR_UNEXP | PHS_COMMAND:
+	case CSR_SRV_REQ | PHS_COMMAND:
+		DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->pid))
+		    transfer_pio(regs, cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR,
+				 hostdata);
+		hostdata->state = S_CONNECTED;
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
+
+	case CSR_XFER_DONE | PHS_STATUS:
+	case CSR_UNEXP | PHS_STATUS:
+	case CSR_SRV_REQ | PHS_STATUS:
+		DB(DB_INTR, printk("STATUS="))
+		cmd->SCp.Status = read_1_byte(regs);
+		DB(DB_INTR, printk("%02x", cmd->SCp.Status))
+		    if (hostdata->level2 >= L2_BASIC) {
+			sr = read_wd33c93(regs, WD_SCSI_STATUS);	/* clear interrupt */
+			hostdata->state = S_RUNNING_LEVEL2;
+			write_wd33c93(regs, WD_COMMAND_PHASE, 0x50);
+			write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
+		} else {
+			hostdata->state = S_CONNECTED;
+		}
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
+
+	case CSR_XFER_DONE | PHS_MESS_IN:
+	case CSR_UNEXP | PHS_MESS_IN:
+	case CSR_SRV_REQ | PHS_MESS_IN:
+		DB(DB_INTR, printk("MSG_IN="))
+
+		msg = read_1_byte(regs);
+		sr = read_wd33c93(regs, WD_SCSI_STATUS);	/* clear interrupt */
+
+		hostdata->incoming_msg[hostdata->incoming_ptr] = msg;
+		if (hostdata->incoming_msg[0] == EXTENDED_MESSAGE)
+			msg = EXTENDED_MESSAGE;
+		else
+			hostdata->incoming_ptr = 0;
+
+		cmd->SCp.Message = msg;
+		switch (msg) {
+
+		case COMMAND_COMPLETE:
+			DB(DB_INTR, printk("CCMP-%ld", cmd->pid))
+			    write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
+			hostdata->state = S_PRE_CMP_DISC;
+			break;
+
+		case SAVE_POINTERS:
+			DB(DB_INTR, printk("SDP"))
+			    write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
+			hostdata->state = S_CONNECTED;
+			break;
+
+		case RESTORE_POINTERS:
+			DB(DB_INTR, printk("RDP"))
+			    if (hostdata->level2 >= L2_BASIC) {
+				write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
+				write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
+				hostdata->state = S_RUNNING_LEVEL2;
+			} else {
+				write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
+				hostdata->state = S_CONNECTED;
+			}
+			break;
+
+		case DISCONNECT:
+			DB(DB_INTR, printk("DIS"))
+			    cmd->device->disconnect = 1;
+			write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
+			hostdata->state = S_PRE_TMP_DISC;
+			break;
 
-            case MESSAGE_REJECT:
-DB(DB_INTR,printk("REJ"))
+		case MESSAGE_REJECT:
+			DB(DB_INTR, printk("REJ"))
 #ifdef SYNC_DEBUG
-printk("-REJ-");
+			    printk("-REJ-");
 #endif
-               if (hostdata->sync_stat[cmd->target] == SS_WAITING)
-                  hostdata->sync_stat[cmd->target] = SS_SET;
-               write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-               hostdata->state = S_CONNECTED;
-               break;
+			if (hostdata->sync_stat[cmd->device->id] == SS_WAITING)
+				hostdata->sync_stat[cmd->device->id] = SS_SET;
+			write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
+			hostdata->state = S_CONNECTED;
+			break;
 
-            case EXTENDED_MESSAGE:
-DB(DB_INTR,printk("EXT"))
+		case EXTENDED_MESSAGE:
+			DB(DB_INTR, printk("EXT"))
 
-               ucp = hostdata->incoming_msg;
+			    ucp = hostdata->incoming_msg;
 
 #ifdef SYNC_DEBUG
-printk("%02x",ucp[hostdata->incoming_ptr]);
+			printk("%02x", ucp[hostdata->incoming_ptr]);
 #endif
-         /* Is this the last byte of the extended message? */
+			/* Is this the last byte of the extended message? */
 
-               if ((hostdata->incoming_ptr >= 2) &&
-                   (hostdata->incoming_ptr == (ucp[1] + 1))) {
+			if ((hostdata->incoming_ptr >= 2) &&
+			    (hostdata->incoming_ptr == (ucp[1] + 1))) {
 
-                  switch (ucp[2]) {   /* what's the EXTENDED code? */
-                     case EXTENDED_SDTR:
-                        id = calc_sync_xfer(ucp[3],ucp[4]);
-                        if (hostdata->sync_stat[cmd->target] != SS_WAITING) {
+				switch (ucp[2]) {	/* what's the EXTENDED code? */
+				case EXTENDED_SDTR:
+					id = calc_sync_xfer(ucp[3], ucp[4]);
+					if (hostdata->sync_stat[cmd->device->id] !=
+					    SS_WAITING) {
 
 /* A device has sent an unsolicited SDTR message; rather than go
  * through the effort of decoding it and then figuring out what
@@ -1028,123 +1042,140 @@
  * specifically ask for sync transfers, we won't do any.
  */
 
-                           write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
-                           hostdata->outgoing_msg[0] = EXTENDED_MESSAGE;
-                           hostdata->outgoing_msg[1] = 3;
-                           hostdata->outgoing_msg[2] = EXTENDED_SDTR;
-                           hostdata->outgoing_msg[3] = hostdata->default_sx_per/4;
-                           hostdata->outgoing_msg[4] = 0;
-                           hostdata->outgoing_len = 5;
-                           hostdata->sync_xfer[cmd->target] =
-                                       calc_sync_xfer(hostdata->default_sx_per/4,0);
-                           }
-                        else {
-                           hostdata->sync_xfer[cmd->target] = id;
-                           }
+						write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN);	/* want MESS_OUT */
+						hostdata->outgoing_msg[0] =
+						    EXTENDED_MESSAGE;
+						hostdata->outgoing_msg[1] = 3;
+						hostdata->outgoing_msg[2] =
+						    EXTENDED_SDTR;
+						hostdata->outgoing_msg[3] =
+						    hostdata->default_sx_per /
+						    4;
+						hostdata->outgoing_msg[4] = 0;
+						hostdata->outgoing_len = 5;
+						hostdata->sync_xfer[cmd->device->id] =
+						    calc_sync_xfer(hostdata->
+								   default_sx_per
+								   / 4, 0);
+					} else {
+						hostdata->sync_xfer[cmd->device->id] = id;
+					}
 #ifdef SYNC_DEBUG
-printk("sync_xfer=%02x",hostdata->sync_xfer[cmd->target]);
+					printk("sync_xfer=%02x",
+					       hostdata->sync_xfer[cmd->device->id]);
 #endif
-                        hostdata->sync_stat[cmd->target] = SS_SET;
-                        write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-                        hostdata->state = S_CONNECTED;
-                        break;
-                     case EXTENDED_WDTR:
-                        write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
-                        printk("sending WDTR ");
-                        hostdata->outgoing_msg[0] = EXTENDED_MESSAGE;
-                        hostdata->outgoing_msg[1] = 2;
-                        hostdata->outgoing_msg[2] = EXTENDED_WDTR;
-                        hostdata->outgoing_msg[3] = 0;   /* 8 bit transfer width */
-                        hostdata->outgoing_len = 4;
-                        write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-                        hostdata->state = S_CONNECTED;
-                        break;
-                     default:
-                        write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
-                        printk("Rejecting Unknown Extended Message(%02x). ",ucp[2]);
-                        hostdata->outgoing_msg[0] = MESSAGE_REJECT;
-                        hostdata->outgoing_len = 1;
-                        write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-                        hostdata->state = S_CONNECTED;
-                        break;
-                     }
-                  hostdata->incoming_ptr = 0;
-                  }
-
-         /* We need to read more MESS_IN bytes for the extended message */
-
-               else {
-                  hostdata->incoming_ptr++;
-                  write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-                  hostdata->state = S_CONNECTED;
-                  }
-               break;
-
-            default:
-               printk("Rejecting Unknown Message(%02x) ",msg);
-               write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN); /* want MESS_OUT */
-               hostdata->outgoing_msg[0] = MESSAGE_REJECT;
-               hostdata->outgoing_len = 1;
-               write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-               hostdata->state = S_CONNECTED;
-            }
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-         break;
-
+					hostdata->sync_stat[cmd->device->id] =
+					    SS_SET;
+					write_wd33c93_cmd(regs,
+							  WD_CMD_NEGATE_ACK);
+					hostdata->state = S_CONNECTED;
+					break;
+				case EXTENDED_WDTR:
+					write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN);	/* want MESS_OUT */
+					printk("sending WDTR ");
+					hostdata->outgoing_msg[0] =
+					    EXTENDED_MESSAGE;
+					hostdata->outgoing_msg[1] = 2;
+					hostdata->outgoing_msg[2] =
+					    EXTENDED_WDTR;
+					hostdata->outgoing_msg[3] = 0;	/* 8 bit transfer width */
+					hostdata->outgoing_len = 4;
+					write_wd33c93_cmd(regs,
+							  WD_CMD_NEGATE_ACK);
+					hostdata->state = S_CONNECTED;
+					break;
+				default:
+					write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN);	/* want MESS_OUT */
+					printk
+					    ("Rejecting Unknown Extended Message(%02x). ",
+					     ucp[2]);
+					hostdata->outgoing_msg[0] =
+					    MESSAGE_REJECT;
+					hostdata->outgoing_len = 1;
+					write_wd33c93_cmd(regs,
+							  WD_CMD_NEGATE_ACK);
+					hostdata->state = S_CONNECTED;
+					break;
+				}
+				hostdata->incoming_ptr = 0;
+			}
+
+			/* We need to read more MESS_IN bytes for the extended message */
+
+			else {
+				hostdata->incoming_ptr++;
+				write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
+				hostdata->state = S_CONNECTED;
+			}
+			break;
+
+		default:
+			printk("Rejecting Unknown Message(%02x) ", msg);
+			write_wd33c93_cmd(regs, WD_CMD_ASSERT_ATN);	/* want MESS_OUT */
+			hostdata->outgoing_msg[0] = MESSAGE_REJECT;
+			hostdata->outgoing_len = 1;
+			write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
+			hostdata->state = S_CONNECTED;
+		}
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
 
 /* Note: this interrupt will occur only after a LEVEL2 command */
 
-      case CSR_SEL_XFER_DONE:
+	case CSR_SEL_XFER_DONE:
 
 /* Make sure that reselection is enabled at this point - it may
  * have been turned off for the command that just completed.
  */
 
-         write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
-         if (phs == 0x60) {
-DB(DB_INTR,printk("SX-DONE-%ld",cmd->pid))
-            cmd->SCp.Message = COMMAND_COMPLETE;
-            lun = read_wd33c93(regs, WD_TARGET_LUN);
-DB(DB_INTR,printk(":%d.%d",cmd->SCp.Status,lun))
-            hostdata->connected = NULL;
-            hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-            hostdata->state = S_UNCONNECTED;
-            if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE)
-               cmd->SCp.Status = lun;
-            if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
-               cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-            else
-               cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-            cmd->scsi_done(cmd);
+		write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
+		if (phs == 0x60) {
+			DB(DB_INTR, printk("SX-DONE-%ld", cmd->pid))
+			    cmd->SCp.Message = COMMAND_COMPLETE;
+			lun = read_wd33c93(regs, WD_TARGET_LUN);
+			DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun))
+			    hostdata->connected = NULL;
+			hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+			hostdata->state = S_UNCONNECTED;
+			if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE)
+				cmd->SCp.Status = lun;
+			if (cmd->cmnd[0] == REQUEST_SENSE
+			    && cmd->SCp.Status != GOOD)
+				cmd->result =
+				    (cmd->
+				     result & 0x00ffff) | (DID_ERROR << 16);
+			else
+				cmd->result =
+				    cmd->SCp.Status | (cmd->SCp.Message << 8);
+			cmd->scsi_done(cmd);
 
 /* We are no longer  connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-            spin_unlock_irqrestore(&hostdata->lock, flags);
-            wd33c93_execute(instance);
-            }
-         else {
-            printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---",asr,sr,phs,cmd->pid);
-            spin_unlock_irqrestore(&hostdata->lock, flags);
-	 }
-         break;
-
+			spin_unlock_irqrestore(&hostdata->lock, flags);
+			wd33c93_execute(instance);
+		} else {
+			printk
+			    ("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---",
+			     asr, sr, phs, cmd->pid);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
+		}
+		break;
 
 /* Note: this interrupt will occur only after a LEVEL2 command */
 
-      case CSR_SDP:
-DB(DB_INTR,printk("SDP"))
-            hostdata->state = S_RUNNING_LEVEL2;
-            write_wd33c93(regs, WD_COMMAND_PHASE, 0x41);
-            write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-	 break;
-
-
-      case CSR_XFER_DONE|PHS_MESS_OUT:
-      case CSR_UNEXP    |PHS_MESS_OUT:
-      case CSR_SRV_REQ  |PHS_MESS_OUT:
-DB(DB_INTR,printk("MSG_OUT="))
+	case CSR_SDP:
+		DB(DB_INTR, printk("SDP"))
+		    hostdata->state = S_RUNNING_LEVEL2;
+		write_wd33c93(regs, WD_COMMAND_PHASE, 0x41);
+		write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
+
+	case CSR_XFER_DONE | PHS_MESS_OUT:
+	case CSR_UNEXP | PHS_MESS_OUT:
+	case CSR_SRV_REQ | PHS_MESS_OUT:
+		DB(DB_INTR, printk("MSG_OUT="))
 
 /* To get here, we've probably requested MESSAGE_OUT and have
  * already put the correct bytes in outgoing_msg[] and filled
@@ -1158,21 +1189,19 @@
  * NOP messages in these situations results in no harm and
  * makes everyone happy.
  */
+		    if (hostdata->outgoing_len == 0) {
+			hostdata->outgoing_len = 1;
+			hostdata->outgoing_msg[0] = NOP;
+		}
+		transfer_pio(regs, hostdata->outgoing_msg,
+			     hostdata->outgoing_len, DATA_OUT_DIR, hostdata);
+		DB(DB_INTR, printk("%02x", hostdata->outgoing_msg[0]))
+		    hostdata->outgoing_len = 0;
+		hostdata->state = S_CONNECTED;
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
 
-         if (hostdata->outgoing_len == 0) {
-            hostdata->outgoing_len = 1;
-            hostdata->outgoing_msg[0] = NOP;
-            }
-         transfer_pio(regs, hostdata->outgoing_msg, hostdata->outgoing_len,
-                            DATA_OUT_DIR, hostdata);
-DB(DB_INTR,printk("%02x",hostdata->outgoing_msg[0]))
-         hostdata->outgoing_len = 0;
-         hostdata->state = S_CONNECTED;
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-	 break;
-
-
-      case CSR_UNEXP_DISC:
+	case CSR_UNEXP_DISC:
 
 /* I think I've seen this after a request-sense that was in response
  * to an error condition, but not sure. We certainly need to do
@@ -1186,353 +1215,387 @@
  * have been turned off for the command that just completed.
  */
 
-         write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
-         if (cmd == NULL) {
-            printk(" - Already disconnected! ");
-            hostdata->state = S_UNCONNECTED;
-            spin_unlock_irqrestore(&hostdata->lock, flags);
-	    return;
-            }
-DB(DB_INTR,printk("UNEXP_DISC-%ld",cmd->pid))
-         hostdata->connected = NULL;
-         hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-         hostdata->state = S_UNCONNECTED;
-         if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
-            cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-         else
-            cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-         cmd->scsi_done(cmd);
+		write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
+		if (cmd == NULL) {
+			printk(" - Already disconnected! ");
+			hostdata->state = S_UNCONNECTED;
+			spin_unlock_irqrestore(&hostdata->lock, flags);
+			return;
+		}
+		DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid))
+		    hostdata->connected = NULL;
+		hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+		hostdata->state = S_UNCONNECTED;
+		if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
+			cmd->result =
+			    (cmd->result & 0x00ffff) | (DID_ERROR << 16);
+		else
+			cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
+		cmd->scsi_done(cmd);
 
 /* We are no longer connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-    /* look above for comments on scsi_done() */
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-         wd33c93_execute(instance);
-         break;
+		/* look above for comments on scsi_done() */
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		wd33c93_execute(instance);
+		break;
 
-
-      case CSR_DISC:
+	case CSR_DISC:
 
 /* Make sure that reselection is enabled at this point - it may
  * have been turned off for the command that just completed.
  */
 
-         write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
-DB(DB_INTR,printk("DISC-%ld",cmd->pid))
-         if (cmd == NULL) {
-            printk(" - Already disconnected! ");
-            hostdata->state = S_UNCONNECTED;
-            }
-         switch (hostdata->state) {
-            case S_PRE_CMP_DISC:
-               hostdata->connected = NULL;
-               hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-               hostdata->state = S_UNCONNECTED;
-DB(DB_INTR,printk(":%d",cmd->SCp.Status))
-               if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
-                  cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-               else
-                  cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-               cmd->scsi_done(cmd);
-               break;
-            case S_PRE_TMP_DISC:
-            case S_RUNNING_LEVEL2:
-               cmd->host_scribble = (uchar *)hostdata->disconnected_Q;
-               hostdata->disconnected_Q = cmd;
-               hostdata->connected = NULL;
-               hostdata->state = S_UNCONNECTED;
+		write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
+		DB(DB_INTR, printk("DISC-%ld", cmd->pid))
+		    if (cmd == NULL) {
+			printk(" - Already disconnected! ");
+			hostdata->state = S_UNCONNECTED;
+		}
+		switch (hostdata->state) {
+		case S_PRE_CMP_DISC:
+			hostdata->connected = NULL;
+			hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+			hostdata->state = S_UNCONNECTED;
+			DB(DB_INTR, printk(":%d", cmd->SCp.Status))
+			    if (cmd->cmnd[0] == REQUEST_SENSE
+				&& cmd->SCp.Status != GOOD)
+				cmd->result =
+				    (cmd->
+				     result & 0x00ffff) | (DID_ERROR << 16);
+			else
+				cmd->result =
+				    cmd->SCp.Status | (cmd->SCp.Message << 8);
+			cmd->scsi_done(cmd);
+			break;
+		case S_PRE_TMP_DISC:
+		case S_RUNNING_LEVEL2:
+			cmd->host_scribble = (uchar *) hostdata->disconnected_Q;
+			hostdata->disconnected_Q = cmd;
+			hostdata->connected = NULL;
+			hostdata->state = S_UNCONNECTED;
 
 #ifdef PROC_STATISTICS
-               hostdata->disc_done_cnt[cmd->target]++;
+			hostdata->disc_done_cnt[cmd->device->id]++;
 #endif
 
-               break;
-            default:
-               printk("*** Unexpected DISCONNECT interrupt! ***");
-               hostdata->state = S_UNCONNECTED;
-            }
+			break;
+		default:
+			printk("*** Unexpected DISCONNECT interrupt! ***");
+			hostdata->state = S_UNCONNECTED;
+		}
 
 /* We are no longer connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-         wd33c93_execute(instance);
-         break;
-
-
-      case CSR_RESEL_AM:
-      case CSR_RESEL:
-DB(DB_INTR,printk("RESEL%s", sr == CSR_RESEL_AM ? "_AM" : ""))
-
-   /* Old chips (pre -A ???) don't have advanced features and will
-    * generate CSR_RESEL.  In that case we have to extract the LUN the
-    * hard way (see below).
-    * First we have to make sure this reselection didn't
-    * happen during Arbitration/Selection of some other device.
-    * If yes, put losing command back on top of input_Q.
-    */
-
-         if (hostdata->level2 <= L2_NONE) {
-
-            if (hostdata->selecting) {
-               cmd = (Scsi_Cmnd *)hostdata->selecting;
-               hostdata->selecting = NULL;
-               hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-               cmd->host_scribble = (uchar *)hostdata->input_Q;
-               hostdata->input_Q = cmd;
-               }
-            }
-
-         else {
-
-            if (cmd) {
-               if (phs == 0x00) {
-                  hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-                  cmd->host_scribble = (uchar *)hostdata->input_Q;
-                  hostdata->input_Q = cmd;
-                  }
-               else {
-                  printk("---%02x:%02x:%02x-TROUBLE: Intrusive ReSelect!---",asr,sr,phs);
-                  while (1)
-                     printk("\r");
-                  }
-               }
-
-            }
-
-   /* OK - find out which device reselected us. */
-
-         id = read_wd33c93(regs, WD_SOURCE_ID);
-         id &= SRCID_MASK;
-
-   /* and extract the lun from the ID message. (Note that we don't
-    * bother to check for a valid message here - I guess this is
-    * not the right way to go, but...)
-    */
-
-         if (sr == CSR_RESEL_AM) {
-            lun = read_wd33c93(regs, WD_DATA);
-            if (hostdata->level2 < L2_RESELECT)
-               write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-            lun &= 7;
-         }
-         else {
-            /* Old chip; wait for msgin phase to pick up the LUN. */
-            for (lun = 255; lun; lun--) {
-               if ((asr = READ_AUX_STAT()) & ASR_INT)
-                  break;
-               udelay(10);
-            }
-            if (!(asr & ASR_INT)) {
-               printk("wd33c93: Reselected without IDENTIFY\n");
-               lun = 0;
-            }
-            else {
-               /* Verify this is a change to MSG_IN and read the message */
-               sr = read_wd33c93(regs, WD_SCSI_STATUS);
-               if (sr == (CSR_ABORT   | PHS_MESS_IN) ||
-                   sr == (CSR_UNEXP   | PHS_MESS_IN) ||
-                   sr == (CSR_SRV_REQ | PHS_MESS_IN)) {
-                  /* Got MSG_IN, grab target LUN */
-                  lun = read_1_byte(regs);
-                  /* Now we expect a 'paused with ACK asserted' int.. */
-                  asr = READ_AUX_STAT();
-                  if (!(asr & ASR_INT)) {
-                     udelay(10);
-                     asr = READ_AUX_STAT();
-                     if (!(asr & ASR_INT))
-                        printk("wd33c93: No int after LUN on RESEL (%02x)\n",
-                              asr);
-                  }
-                  sr = read_wd33c93(regs, WD_SCSI_STATUS);
-                  if (sr != CSR_MSGIN)
-                     printk("wd33c93: Not paused with ACK on RESEL (%02x)\n",
-                           sr);
-                  lun &= 7;
-                  write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
-               }
-               else {
-                  printk("wd33c93: Not MSG_IN on reselect (%02x)\n", sr);
-                  lun = 0;
-               }
-            }
-         }
-
-   /* Now we look for the command that's reconnecting. */
-
-         cmd = (Scsi_Cmnd *)hostdata->disconnected_Q;
-         patch = NULL;
-         while (cmd) {
-            if (id == cmd->target && lun == cmd->lun)
-               break;
-            patch = cmd;
-            cmd = (Scsi_Cmnd *)cmd->host_scribble;
-            }
-
-   /* Hmm. Couldn't find a valid command.... What to do? */
-
-         if (!cmd) {
-            printk("---TROUBLE: target %d.%d not in disconnect queue---",id,lun);
-            spin_unlock_irqrestore(&hostdata->lock, flags);
-	    return;
-            }
-
-   /* Ok, found the command - now start it up again. */
-
-         if (patch)
-            patch->host_scribble = cmd->host_scribble;
-         else
-            hostdata->disconnected_Q = (Scsi_Cmnd *)cmd->host_scribble;
-         hostdata->connected = cmd;
-
-   /* We don't need to worry about 'initialize_SCp()' or 'hostdata->busy[]'
-    * because these things are preserved over a disconnect.
-    * But we DO need to fix the DPD bit so it's correct for this command.
-    */
-
-         if (is_dir_out(cmd))
-            write_wd33c93(regs, WD_DESTINATION_ID, cmd->target);
-         else
-            write_wd33c93(regs, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
-         if (hostdata->level2 >= L2_RESELECT) {
-            write_wd33c93_count(regs, 0);  /* we want a DATA_PHASE interrupt */
-            write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
-            write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
-            hostdata->state = S_RUNNING_LEVEL2;
-            }
-         else
-            hostdata->state = S_CONNECTED;
-
-DB(DB_INTR,printk("-%ld",cmd->pid))
-         spin_unlock_irqrestore(&hostdata->lock, flags);
- break;
-         
-      default:
-         printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--",asr,sr,phs);
-         spin_unlock_irqrestore(&hostdata->lock, flags);
-      }
-
-DB(DB_INTR,printk("} "))
-
-}
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+		wd33c93_execute(instance);
+		break;
+
+	case CSR_RESEL_AM:
+	case CSR_RESEL:
+		DB(DB_INTR, printk("RESEL%s", sr == CSR_RESEL_AM ? "_AM" : ""))
+
+		    /* Old chips (pre -A ???) don't have advanced features and will
+		     * generate CSR_RESEL.  In that case we have to extract the LUN the
+		     * hard way (see below).
+		     * First we have to make sure this reselection didn't
+		     * happen during Arbitration/Selection of some other device.
+		     * If yes, put losing command back on top of input_Q.
+		     */
+		    if (hostdata->level2 <= L2_NONE) {
+
+			if (hostdata->selecting) {
+				cmd = (Scsi_Cmnd *) hostdata->selecting;
+				hostdata->selecting = NULL;
+				hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+				cmd->host_scribble =
+				    (uchar *) hostdata->input_Q;
+				hostdata->input_Q = cmd;
+			}
+		}
+
+		else {
+
+			if (cmd) {
+				if (phs == 0x00) {
+					hostdata->busy[cmd->device->id] &=
+					    ~(1 << cmd->device->lun);
+					cmd->host_scribble =
+					    (uchar *) hostdata->input_Q;
+					hostdata->input_Q = cmd;
+				} else {
+					printk
+					    ("---%02x:%02x:%02x-TROUBLE: Intrusive ReSelect!---",
+					     asr, sr, phs);
+					while (1)
+						printk("\r");
+				}
+			}
+
+		}
+
+		/* OK - find out which device reselected us. */
+
+		id = read_wd33c93(regs, WD_SOURCE_ID);
+		id &= SRCID_MASK;
+
+		/* and extract the lun from the ID message. (Note that we don't
+		 * bother to check for a valid message here - I guess this is
+		 * not the right way to go, but...)
+		 */
+
+		if (sr == CSR_RESEL_AM) {
+			lun = read_wd33c93(regs, WD_DATA);
+			if (hostdata->level2 < L2_RESELECT)
+				write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
+			lun &= 7;
+		} else {
+			/* Old chip; wait for msgin phase to pick up the LUN. */
+			for (lun = 255; lun; lun--) {
+				if ((asr = read_aux_stat(regs)) & ASR_INT)
+					break;
+				udelay(10);
+			}
+			if (!(asr & ASR_INT)) {
+				printk
+				    ("wd33c93: Reselected without IDENTIFY\n");
+				lun = 0;
+			} else {
+				/* Verify this is a change to MSG_IN and read the message */
+				sr = read_wd33c93(regs, WD_SCSI_STATUS);
+				if (sr == (CSR_ABORT | PHS_MESS_IN) ||
+				    sr == (CSR_UNEXP | PHS_MESS_IN) ||
+				    sr == (CSR_SRV_REQ | PHS_MESS_IN)) {
+					/* Got MSG_IN, grab target LUN */
+					lun = read_1_byte(regs);
+					/* Now we expect a 'paused with ACK asserted' int.. */
+					asr = read_aux_stat(regs);
+					if (!(asr & ASR_INT)) {
+						udelay(10);
+						asr = read_aux_stat(regs);
+						if (!(asr & ASR_INT))
+							printk
+							    ("wd33c93: No int after LUN on RESEL (%02x)\n",
+							     asr);
+					}
+					sr = read_wd33c93(regs, WD_SCSI_STATUS);
+					if (sr != CSR_MSGIN)
+						printk
+						    ("wd33c93: Not paused with ACK on RESEL (%02x)\n",
+						     sr);
+					lun &= 7;
+					write_wd33c93_cmd(regs,
+							  WD_CMD_NEGATE_ACK);
+				} else {
+					printk
+					    ("wd33c93: Not MSG_IN on reselect (%02x)\n",
+					     sr);
+					lun = 0;
+				}
+			}
+		}
+
+		/* Now we look for the command that's reconnecting. */
+
+		cmd = (Scsi_Cmnd *) hostdata->disconnected_Q;
+		patch = NULL;
+		while (cmd) {
+			if (id == cmd->device->id && lun == cmd->device->lun)
+				break;
+			patch = cmd;
+			cmd = (Scsi_Cmnd *) cmd->host_scribble;
+		}
+
+		/* Hmm. Couldn't find a valid command.... What to do? */
+
+		if (!cmd) {
+			printk
+			    ("---TROUBLE: target %d.%d not in disconnect queue---",
+			     id, lun);
+			spin_unlock_irqrestore(&hostdata->lock, flags);
+			return;
+		}
+
+		/* Ok, found the command - now start it up again. */
+
+		if (patch)
+			patch->host_scribble = cmd->host_scribble;
+		else
+			hostdata->disconnected_Q =
+			    (Scsi_Cmnd *) cmd->host_scribble;
+		hostdata->connected = cmd;
+
+		/* We don't need to worry about 'initialize_SCp()' or 'hostdata->busy[]'
+		 * because these things are preserved over a disconnect.
+		 * But we DO need to fix the DPD bit so it's correct for this command.
+		 */
+
+		if (is_dir_out(cmd))
+			write_wd33c93(regs, WD_DESTINATION_ID, cmd->device->id);
+		else
+			write_wd33c93(regs, WD_DESTINATION_ID,
+				      cmd->device->id | DSTID_DPD);
+		if (hostdata->level2 >= L2_RESELECT) {
+			write_wd33c93_count(regs, 0);	/* we want a DATA_PHASE interrupt */
+			write_wd33c93(regs, WD_COMMAND_PHASE, 0x45);
+			write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
+			hostdata->state = S_RUNNING_LEVEL2;
+		} else
+			hostdata->state = S_CONNECTED;
+
+		DB(DB_INTR, printk("-%ld", cmd->pid))
+		    spin_unlock_irqrestore(&hostdata->lock, flags);
+		break;
+
+	default:
+		printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--", asr, sr, phs);
+		spin_unlock_irqrestore(&hostdata->lock, flags);
+	}
+
+	DB(DB_INTR, printk("} "))
+
+}
+
+static void
+reset_wd33c93(struct Scsi_Host *instance)
+{
+	struct WD33C93_hostdata *hostdata =
+	    (struct WD33C93_hostdata *) instance->hostdata;
+	const wd33c93_regs regs = hostdata->regs;
+	uchar sr;
+
+#ifdef CONFIG_SGI_IP22
+	{
+		int busycount = 0;
+		extern void sgiwd93_reset(unsigned long);
+		/* wait 'til the chip gets some time for us */
+		while ((READ_AUX_STAT() & ASR_BSY) && busycount++ < 100)
+			udelay (10);
+	/*
+ 	 * there are scsi devices out there, which manage to lock up
+	 * the wd33c93 in a busy condition. In this state it won't
+	 * accept the reset command. The only way to solve this is to
+ 	 * give the chip a hardware reset (if possible). The code below
+	 * does this for the SGI Indy, where this is possible
+	 */
+	/* still busy ? */
+	if (READ_AUX_STAT() & ASR_BSY)
+		sgiwd93_reset(instance->base); /* yeah, give it the hard one */
+	}
+#endif
 
+	write_wd33c93(regs, WD_OWN_ID, OWNID_EAF | OWNID_RAF |
+		      instance->this_id | hostdata->clock_freq);
+	write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
+	write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,
+		      calc_sync_xfer(hostdata->default_sx_per / 4,
+				     DEFAULT_SX_OFF));
+	write_wd33c93(regs, WD_COMMAND, WD_CMD_RESET);
 
 
-static void reset_wd33c93(struct Scsi_Host *instance)
-{
-struct WD33C93_hostdata *hostdata = (struct WD33C93_hostdata *)instance->hostdata;
-const wd33c93_regs regs = hostdata->regs;
-uchar sr;
-
-   write_wd33c93(regs, WD_OWN_ID, OWNID_EAF | OWNID_RAF |
-                 instance->this_id | hostdata->clock_freq);
-   write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
-   write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,
-                 calc_sync_xfer(hostdata->default_sx_per/4,DEFAULT_SX_OFF));
-   write_wd33c93(regs, WD_COMMAND, WD_CMD_RESET);
 #ifdef CONFIG_MVME147_SCSI
-   udelay(25); /* The old wd33c93 on MVME147 needs this, at least */
+	udelay(25);		/* The old wd33c93 on MVME147 needs this, at least */
 #endif
 
-   while (!(READ_AUX_STAT() & ASR_INT))
-      ;
-   sr = read_wd33c93(regs, WD_SCSI_STATUS);
-
-   hostdata->microcode = read_wd33c93(regs, WD_CDB_1);
-   if (sr == 0x00)
-      hostdata->chip = C_WD33C93;
-   else if (sr == 0x01) {
-      write_wd33c93(regs, WD_QUEUE_TAG, 0xa5);  /* any random number */
-      sr = read_wd33c93(regs, WD_QUEUE_TAG);
-      if (sr == 0xa5) {
-         hostdata->chip = C_WD33C93B;
-         write_wd33c93(regs, WD_QUEUE_TAG, 0);
-         }
-      else
-         hostdata->chip = C_WD33C93A;
-      }
-   else
-      hostdata->chip = C_UNKNOWN_CHIP;
-
-   write_wd33c93(regs, WD_TIMEOUT_PERIOD, TIMEOUT_PERIOD_VALUE);
-   write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
-}
-
-
-
-int wd33c93_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
-{
-struct Scsi_Host *instance;
-struct WD33C93_hostdata *hostdata;
-int i;
-
-   instance = SCpnt->host;
-   hostdata = (struct WD33C93_hostdata *)instance->hostdata;
-
-   printk("scsi%d: reset. ", instance->host_no);
-   disable_irq(instance->irq);
-
-   ((struct WD33C93_hostdata *)instance->hostdata)->dma_stop(instance,NULL,0);
-   for (i = 0; i < 8; i++) {
-      hostdata->busy[i] = 0;
-      hostdata->sync_xfer[i] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
-      hostdata->sync_stat[i] = SS_UNSET;  /* using default sync values */
-      }
-   hostdata->input_Q = NULL;
-   hostdata->selecting = NULL;
-   hostdata->connected = NULL;
-   hostdata->disconnected_Q = NULL;
-   hostdata->state = S_UNCONNECTED;
-   hostdata->dma = D_DMA_OFF;
-   hostdata->incoming_ptr = 0;
-   hostdata->outgoing_len = 0;
-
-   reset_wd33c93(instance);
-   SCpnt->result = DID_RESET << 16;
-   enable_irq(instance->irq);
-   return 0;
-}
-
-
-
-int wd33c93_abort (Scsi_Cmnd *cmd)
-{
-struct Scsi_Host *instance;
-struct WD33C93_hostdata *hostdata;
-wd33c93_regs regs;
-Scsi_Cmnd *tmp, *prev;
-
-   disable_irq(cmd->host->irq);
-
-   instance = cmd->host;
-   hostdata = (struct WD33C93_hostdata *)instance->hostdata;
-   regs = hostdata->regs;
+	while (!(read_aux_stat(regs) & ASR_INT))
+		;
+	sr = read_wd33c93(regs, WD_SCSI_STATUS);
+
+	hostdata->microcode = read_wd33c93(regs, WD_CDB_1);
+	if (sr == 0x00)
+		hostdata->chip = C_WD33C93;
+	else if (sr == 0x01) {
+		write_wd33c93(regs, WD_QUEUE_TAG, 0xa5);	/* any random number */
+		sr = read_wd33c93(regs, WD_QUEUE_TAG);
+		if (sr == 0xa5) {
+			hostdata->chip = C_WD33C93B;
+			write_wd33c93(regs, WD_QUEUE_TAG, 0);
+		} else
+			hostdata->chip = C_WD33C93A;
+	} else
+		hostdata->chip = C_UNKNOWN_CHIP;
+
+	write_wd33c93(regs, WD_TIMEOUT_PERIOD, TIMEOUT_PERIOD_VALUE);
+	write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
+}
+
+int
+wd33c93_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+{
+	struct Scsi_Host *instance;
+	struct WD33C93_hostdata *hostdata;
+	int i;
+
+	instance = SCpnt->device->host;
+	hostdata = (struct WD33C93_hostdata *) instance->hostdata;
+
+	printk("scsi%d: reset. ", instance->host_no);
+	disable_irq(instance->irq);
+
+	hostdata->dma_stop(instance, NULL, 0);
+	for (i = 0; i < 8; i++) {
+		hostdata->busy[i] = 0;
+		hostdata->sync_xfer[i] =
+		    calc_sync_xfer(DEFAULT_SX_PER / 4, DEFAULT_SX_OFF);
+		hostdata->sync_stat[i] = SS_UNSET;	/* using default sync values */
+	}
+	hostdata->input_Q = NULL;
+	hostdata->selecting = NULL;
+	hostdata->connected = NULL;
+	hostdata->disconnected_Q = NULL;
+	hostdata->state = S_UNCONNECTED;
+	hostdata->dma = D_DMA_OFF;
+	hostdata->incoming_ptr = 0;
+	hostdata->outgoing_len = 0;
+
+	reset_wd33c93(instance);
+	SCpnt->result = DID_RESET << 16;
+	enable_irq(instance->irq);
+	return 0;
+}
+
+int
+wd33c93_abort(Scsi_Cmnd * cmd)
+{
+	struct Scsi_Host *instance;
+	struct WD33C93_hostdata *hostdata;
+	wd33c93_regs regs;
+	Scsi_Cmnd *tmp, *prev;
+
+	disable_irq(cmd->device->host->irq);
+
+	instance = cmd->device->host;
+	hostdata = (struct WD33C93_hostdata *) instance->hostdata;
+	regs = hostdata->regs;
 
 /*
  * Case 1 : If the command hasn't been issued yet, we simply remove it
  *     from the input_Q.
  */
 
-   tmp = (Scsi_Cmnd *)hostdata->input_Q;
-   prev = 0;
-   while (tmp) {
-      if (tmp == cmd) {
-         if (prev)
-            prev->host_scribble = cmd->host_scribble;
-	 else
-            hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble;
-         cmd->host_scribble = NULL;
-         cmd->result = DID_ABORT << 16;
-         printk("scsi%d: Abort - removing command %ld from input_Q. ",
-           instance->host_no, cmd->pid);
-    enable_irq(cmd->host->irq);
-         cmd->scsi_done(cmd);
-         return SCSI_ABORT_SUCCESS;
-         }
-      prev = tmp;
-      tmp = (Scsi_Cmnd *)tmp->host_scribble;
-      }
+	tmp = (Scsi_Cmnd *) hostdata->input_Q;
+	prev = 0;
+	while (tmp) {
+		if (tmp == cmd) {
+			if (prev)
+				prev->host_scribble = cmd->host_scribble;
+			else
+				hostdata->input_Q =
+				    (Scsi_Cmnd *) cmd->host_scribble;
+			cmd->host_scribble = NULL;
+			cmd->result = DID_ABORT << 16;
+			printk
+			    ("scsi%d: Abort - removing command %ld from input_Q. ",
+			     instance->host_no, cmd->pid);
+			enable_irq(cmd->device->host->irq);
+			cmd->scsi_done(cmd);
+			return SCSI_ABORT_SUCCESS;
+		}
+		prev = tmp;
+		tmp = (Scsi_Cmnd *) tmp->host_scribble;
+	}
 
 /*
  * Case 2 : If the command is connected, we're going to fail the abort
@@ -1545,64 +1608,66 @@
  *     we fail.
  */
 
-   if (hostdata->connected == cmd) {
-      uchar sr, asr;
-      unsigned long timeout;
-
-      printk("scsi%d: Aborting connected command %ld - ",
-              instance->host_no, cmd->pid);
-
-      printk("stopping DMA - ");
-      if (hostdata->dma == D_DMA_RUNNING) {
-         hostdata->dma_stop(instance, cmd, 0);
-         hostdata->dma = D_DMA_OFF;
-         }
-
-      printk("sending wd33c93 ABORT command - ");
-      write_wd33c93(regs, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
-      write_wd33c93_cmd(regs, WD_CMD_ABORT);
+	if (hostdata->connected == cmd) {
+		uchar sr, asr;
+		unsigned long timeout;
+
+		printk("scsi%d: Aborting connected command %ld - ",
+		       instance->host_no, cmd->pid);
+
+		printk("stopping DMA - ");
+		if (hostdata->dma == D_DMA_RUNNING) {
+			hostdata->dma_stop(instance, cmd, 0);
+			hostdata->dma = D_DMA_OFF;
+		}
+
+		printk("sending wd33c93 ABORT command - ");
+		write_wd33c93(regs, WD_CONTROL,
+			      CTRL_IDI | CTRL_EDI | CTRL_POLLED);
+		write_wd33c93_cmd(regs, WD_CMD_ABORT);
 
 /* Now we have to attempt to flush out the FIFO... */
 
-      printk("flushing fifo - ");
-      timeout = 1000000;
-      do {
-         asr = READ_AUX_STAT();
-         if (asr & ASR_DBR)
-            read_wd33c93(regs, WD_DATA);
-         } while (!(asr & ASR_INT) && timeout-- > 0);
-      sr = read_wd33c93(regs, WD_SCSI_STATUS);
-      printk("asr=%02x, sr=%02x, %ld bytes un-transferred (timeout=%ld) - ",
-             asr, sr, read_wd33c93_count(regs), timeout);
-
-   /*
-    * Abort command processed.
-    * Still connected.
-    * We must disconnect.
-    */
-
-      printk("sending wd33c93 DISCONNECT command - ");
-      write_wd33c93_cmd(regs, WD_CMD_DISCONNECT);
-
-      timeout = 1000000;
-      asr = READ_AUX_STAT();
-      while ((asr & ASR_CIP) && timeout-- > 0)
-         asr = READ_AUX_STAT();
-      sr = read_wd33c93(regs, WD_SCSI_STATUS);
-      printk("asr=%02x, sr=%02x.",asr,sr);
-
-      hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-      hostdata->connected = NULL;
-      hostdata->state = S_UNCONNECTED;
-      cmd->result = DID_ABORT << 16;
+		printk("flushing fifo - ");
+		timeout = 1000000;
+		do {
+			asr = read_aux_stat(regs);
+			if (asr & ASR_DBR)
+				read_wd33c93(regs, WD_DATA);
+		} while (!(asr & ASR_INT) && timeout-- > 0);
+		sr = read_wd33c93(regs, WD_SCSI_STATUS);
+		printk
+		    ("asr=%02x, sr=%02x, %ld bytes un-transferred (timeout=%ld) - ",
+		     asr, sr, read_wd33c93_count(regs), timeout);
+
+		/*
+		 * Abort command processed.
+		 * Still connected.
+		 * We must disconnect.
+		 */
+
+		printk("sending wd33c93 DISCONNECT command - ");
+		write_wd33c93_cmd(regs, WD_CMD_DISCONNECT);
+
+		timeout = 1000000;
+		asr = read_aux_stat(regs);
+		while ((asr & ASR_CIP) && timeout-- > 0)
+			asr = read_aux_stat(regs);
+		sr = read_wd33c93(regs, WD_SCSI_STATUS);
+		printk("asr=%02x, sr=%02x.", asr, sr);
+
+		hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+		hostdata->connected = NULL;
+		hostdata->state = S_UNCONNECTED;
+		cmd->result = DID_ABORT << 16;
 
 /*      sti();*/
-      wd33c93_execute (instance);
+		wd33c93_execute(instance);
 
-      enable_irq(cmd->host->irq);
-      cmd->scsi_done(cmd);
-      return SCSI_ABORT_SUCCESS;
-      }
+		enable_irq(cmd->device->host->irq);
+		cmd->scsi_done(cmd);
+		return SCSI_ABORT_SUCCESS;
+	}
 
 /*
  * Case 3: If the command is currently disconnected from the bus,
@@ -1610,17 +1675,18 @@
  * an ABORT_SNOOZE and hope for the best...
  */
 
-   tmp = (Scsi_Cmnd *)hostdata->disconnected_Q;
-   while (tmp) {
-      if (tmp == cmd) {
-         printk("scsi%d: Abort - command %ld found on disconnected_Q - ",
-                 instance->host_no, cmd->pid);
-         printk("returning ABORT_SNOOZE. ");
-    enable_irq(cmd->host->irq);
-         return SCSI_ABORT_SNOOZE;
-         }
-      tmp = (Scsi_Cmnd *)tmp->host_scribble;
-      }
+	tmp = (Scsi_Cmnd *) hostdata->disconnected_Q;
+	while (tmp) {
+		if (tmp == cmd) {
+			printk
+			    ("scsi%d: Abort - command %ld found on disconnected_Q - ",
+			     instance->host_no, cmd->pid);
+			printk("returning ABORT_SNOOZE. ");
+			enable_irq(cmd->device->host->irq);
+			return SCSI_ABORT_SNOOZE;
+		}
+		tmp = (Scsi_Cmnd *) tmp->host_scribble;
+	}
 
 /*
  * Case 4 : If we reached this point, the command was not found in any of
@@ -1633,16 +1699,14 @@
  */
 
 /*   sti();*/
-   wd33c93_execute (instance);
+	wd33c93_execute(instance);
 
-   enable_irq(cmd->host->irq);
-   printk("scsi%d: warning : SCSI command probably completed successfully"
-      "         before abortion. ", instance->host_no);
-   return SCSI_ABORT_NOT_RUNNING;
+	enable_irq(cmd->device->host->irq);
+	printk("scsi%d: warning : SCSI command probably completed successfully"
+	       "         before abortion. ", instance->host_no);
+	return SCSI_ABORT_NOT_RUNNING;
 }
 
-
-
 #define MAX_WD33C93_HOSTS 4
 #define MAX_SETUP_ARGS ((int)(sizeof(setup_args) / sizeof(char *)))
 #define SETUP_BUFFER_SIZE 200
@@ -1650,238 +1714,224 @@
 static char setup_used[MAX_SETUP_ARGS];
 static int done_setup = 0;
 
-int wd33c93_setup (char *str)
+int
+wd33c93_setup(char *str)
 {
-   int i;
-   char *p1,*p2;
+	int i;
+	char *p1, *p2;
 
-   /* The kernel does some processing of the command-line before calling
-    * this function: If it begins with any decimal or hex number arguments,
-    * ints[0] = how many numbers found and ints[1] through [n] are the values
-    * themselves. str points to where the non-numeric arguments (if any)
-    * start: We do our own parsing of those. We construct synthetic 'nosync'
-    * keywords out of numeric args (to maintain compatibility with older
-    * versions) and then add the rest of the arguments.
-    */
-
-   p1 = setup_buffer;
-   *p1 = '\0';
-#if 0
-/*
- * Old style command line arguments are now dead
- */
-   if (ints[0]) {
-      for (i=0; i<ints[0]; i++) {
-         x = vsprintf(p1,"nosync:0x%02x,",&(ints[i+1]));
-         p1 += x;
-         }
-      }
-#endif
-   if (str)
-      strncpy(p1, str, SETUP_BUFFER_SIZE - strlen(setup_buffer));
-   setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0';
-   p1 = setup_buffer;
-   i = 0;
-   while (*p1 && (i < MAX_SETUP_ARGS)) {
-      p2 = strchr(p1, ',');
-      if (p2) {
-         *p2 = '\0';
-         if (p1 != p2)
-            setup_args[i] = p1;
-         p1 = p2 + 1;
-         i++;
-         }
-      else {
-         setup_args[i] = p1;
-         break;
-         }
-      }
-   for (i=0; i<MAX_SETUP_ARGS; i++)
-      setup_used[i] = 0;
-   done_setup = 1;
+	/* The kernel does some processing of the command-line before calling
+	 * this function: If it begins with any decimal or hex number arguments,
+	 * ints[0] = how many numbers found and ints[1] through [n] are the values
+	 * themselves. str points to where the non-numeric arguments (if any)
+	 * start: We do our own parsing of those. We construct synthetic 'nosync'
+	 * keywords out of numeric args (to maintain compatibility with older
+	 * versions) and then add the rest of the arguments.
+	 */
+
+	p1 = setup_buffer;
+	*p1 = '\0';
+	if (str)
+		strncpy(p1, str, SETUP_BUFFER_SIZE - strlen(setup_buffer));
+	setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0';
+	p1 = setup_buffer;
+	i = 0;
+	while (*p1 && (i < MAX_SETUP_ARGS)) {
+		p2 = strchr(p1, ',');
+		if (p2) {
+			*p2 = '\0';
+			if (p1 != p2)
+				setup_args[i] = p1;
+			p1 = p2 + 1;
+			i++;
+		} else {
+			setup_args[i] = p1;
+			break;
+		}
+	}
+	for (i = 0; i < MAX_SETUP_ARGS; i++)
+		setup_used[i] = 0;
+	done_setup = 1;
 
-   return 1;
+	return 1;
 }
-
-__setup("wd33c93", wd33c93_setup);
-
+__setup("wd33c9=", wd33c93_setup);
 
 /* check_setup_args() returns index if key found, 0 if not
  */
-
-static int check_setup_args(char *key, int *flags, int *val, char *buf)
+static int
+check_setup_args(char *key, int *flags, int *val, char *buf)
 {
-int x;
-char *cp;
-
-   for  (x=0; x<MAX_SETUP_ARGS; x++) {
-      if (setup_used[x])
-         continue;
-      if (!strncmp(setup_args[x], key, strlen(key)))
-         break;
-      if (!strncmp(setup_args[x], "next", strlen("next")))
-         return 0;
-      }
-   if (x == MAX_SETUP_ARGS)
-      return 0;
-   setup_used[x] = 1;
-   cp = setup_args[x] + strlen(key);
-   *val = -1;
-   if (*cp != ':')
-      return ++x;
-   cp++;
-   if ((*cp >= '0') && (*cp <= '9')) {
-      *val = simple_strtoul(cp,NULL,0);
-      }
-   return ++x;
-}
-
-
+	int x;
+	char *cp;
 
-void wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs,
-		  dma_setup_t setup, dma_stop_t stop, int clock_freq)
-{
-struct WD33C93_hostdata *hostdata;
-int i;
-int flags;
-int val;
-char buf[32];
-
-   if (!done_setup && setup_strings)
-      wd33c93_setup(setup_strings);
-
-   hostdata = (struct WD33C93_hostdata *)instance->hostdata;
-
-   hostdata->regs = regs;
-   hostdata->clock_freq = clock_freq;
-   hostdata->dma_setup = setup;
-   hostdata->dma_stop = stop;
-   hostdata->dma_bounce_buffer = NULL;
-   hostdata->dma_bounce_len = 0;
-   for (i = 0; i < 8; i++) {
-      hostdata->busy[i] = 0;
-      hostdata->sync_xfer[i] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
-      hostdata->sync_stat[i] = SS_UNSET;  /* using default sync values */
+	for (x = 0; x < MAX_SETUP_ARGS; x++) {
+		if (setup_used[x])
+			continue;
+		if (!strncmp(setup_args[x], key, strlen(key)))
+			break;
+		if (!strncmp(setup_args[x], "next", strlen("next")))
+			return 0;
+	}
+	if (x == MAX_SETUP_ARGS)
+		return 0;
+	setup_used[x] = 1;
+	cp = setup_args[x] + strlen(key);
+	*val = -1;
+	if (*cp != ':')
+		return ++x;
+	cp++;
+	if ((*cp >= '0') && (*cp <= '9')) {
+		*val = simple_strtoul(cp, NULL, 0);
+	}
+	return ++x;
+}
+
+void
+wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs,
+	     dma_setup_t setup, dma_stop_t stop, int clock_freq)
+{
+	struct WD33C93_hostdata *hostdata;
+	int i;
+	int flags;
+	int val;
+	char buf[32];
+
+	if (!done_setup && setup_strings)
+		wd33c93_setup(setup_strings);
+
+	hostdata = (struct WD33C93_hostdata *) instance->hostdata;
+
+	hostdata->regs = regs;
+	hostdata->clock_freq = clock_freq;
+	hostdata->dma_setup = setup;
+	hostdata->dma_stop = stop;
+	hostdata->dma_bounce_buffer = NULL;
+	hostdata->dma_bounce_len = 0;
+	for (i = 0; i < 8; i++) {
+		hostdata->busy[i] = 0;
+		hostdata->sync_xfer[i] =
+		    calc_sync_xfer(DEFAULT_SX_PER / 4, DEFAULT_SX_OFF);
+		hostdata->sync_stat[i] = SS_UNSET;	/* using default sync values */
 #ifdef PROC_STATISTICS
-      hostdata->cmd_cnt[i] = 0;
-      hostdata->disc_allowed_cnt[i] = 0;
-      hostdata->disc_done_cnt[i] = 0;
+		hostdata->cmd_cnt[i] = 0;
+		hostdata->disc_allowed_cnt[i] = 0;
+		hostdata->disc_done_cnt[i] = 0;
 #endif
-      }
-   hostdata->input_Q = NULL;
-   hostdata->selecting = NULL;
-   hostdata->connected = NULL;
-   hostdata->disconnected_Q = NULL;
-   hostdata->state = S_UNCONNECTED;
-   hostdata->dma = D_DMA_OFF;
-   hostdata->level2 = L2_BASIC;
-   hostdata->disconnect = DIS_ADAPTIVE;
-   hostdata->args = DEBUG_DEFAULTS;
-   hostdata->incoming_ptr = 0;
-   hostdata->outgoing_len = 0;
-   hostdata->default_sx_per = DEFAULT_SX_PER;
-   hostdata->no_sync = 0xff;     /* sync defaults to off */
-   hostdata->no_dma = 0;         /* default is DMA enabled */
+	}
+	hostdata->input_Q = NULL;
+	hostdata->selecting = NULL;
+	hostdata->connected = NULL;
+	hostdata->disconnected_Q = NULL;
+	hostdata->state = S_UNCONNECTED;
+	hostdata->dma = D_DMA_OFF;
+	hostdata->level2 = L2_BASIC;
+	hostdata->disconnect = DIS_ADAPTIVE;
+	hostdata->args = DEBUG_DEFAULTS;
+	hostdata->incoming_ptr = 0;
+	hostdata->outgoing_len = 0;
+	hostdata->default_sx_per = DEFAULT_SX_PER;
+	hostdata->no_sync = 0xff;	/* sync defaults to off */
+	hostdata->no_dma = 0;	/* default is DMA enabled */
 
 #ifdef PROC_INTERFACE
-   hostdata->proc = PR_VERSION|PR_INFO|PR_STATISTICS|
-                    PR_CONNECTED|PR_INPUTQ|PR_DISCQ|
-                    PR_STOP;
+	hostdata->proc = PR_VERSION | PR_INFO | PR_STATISTICS |
+	    PR_CONNECTED | PR_INPUTQ | PR_DISCQ | PR_STOP;
 #ifdef PROC_STATISTICS
-   hostdata->dma_cnt = 0;
-   hostdata->pio_cnt = 0;
-   hostdata->int_cnt = 0;
+	hostdata->dma_cnt = 0;
+	hostdata->pio_cnt = 0;
+	hostdata->int_cnt = 0;
 #endif
 #endif
 
+	if (check_setup_args("nosync", &flags, &val, buf))
+		hostdata->no_sync = val;
 
-   if (check_setup_args("nosync",&flags,&val,buf))
-      hostdata->no_sync = val;
-
-   if (check_setup_args("nodma",&flags,&val,buf))
-      hostdata->no_dma = (val == -1) ? 1 : val;
-
-   if (check_setup_args("period",&flags,&val,buf))
-      hostdata->default_sx_per = sx_table[round_period((unsigned int)val)].period_ns;
-
-   if (check_setup_args("disconnect",&flags,&val,buf)) {
-      if ((val >= DIS_NEVER) && (val <= DIS_ALWAYS))
-         hostdata->disconnect = val;
-      else
-         hostdata->disconnect = DIS_ADAPTIVE;
-      }
-
-   if (check_setup_args("level2",&flags,&val,buf))
-      hostdata->level2 = val;
-
-   if (check_setup_args("debug",&flags,&val,buf))
-      hostdata->args = val & DB_MASK;
-
-   if (check_setup_args("clock",&flags,&val,buf)) {
-      if (val>7 && val<11)
-         val = WD33C93_FS_8_10;
-      else if (val>11 && val<16)
-         val = WD33C93_FS_12_15;
-      else if (val>15 && val<21)
-         val = WD33C93_FS_16_20;
-      else
-         val = WD33C93_FS_8_10;
-      hostdata->clock_freq = val;
-      }
-
-   if ((i = check_setup_args("next",&flags,&val,buf))) {
-      while (i)
-         setup_used[--i] = 1;
-      }
+	if (check_setup_args("nodma", &flags, &val, buf))
+		hostdata->no_dma = (val == -1) ? 1 : val;
 
+	if (check_setup_args("period", &flags, &val, buf))
+		hostdata->default_sx_per =
+		    sx_table[round_period((unsigned int) val)].period_ns;
+
+	if (check_setup_args("disconnect", &flags, &val, buf)) {
+		if ((val >= DIS_NEVER) && (val <= DIS_ALWAYS))
+			hostdata->disconnect = val;
+		else
+			hostdata->disconnect = DIS_ADAPTIVE;
+	}
+
+	if (check_setup_args("level2", &flags, &val, buf))
+		hostdata->level2 = val;
+
+	if (check_setup_args("debug", &flags, &val, buf))
+		hostdata->args = val & DB_MASK;
+
+	if (check_setup_args("clock", &flags, &val, buf)) {
+		if (val > 7 && val < 11)
+			val = WD33C93_FS_8_10;
+		else if (val > 11 && val < 16)
+			val = WD33C93_FS_12_15;
+		else if (val > 15 && val < 21)
+			val = WD33C93_FS_16_20;
+		else
+			val = WD33C93_FS_8_10;
+		hostdata->clock_freq = val;
+	}
+
+	if ((i = check_setup_args("next", &flags, &val, buf))) {
+		while (i)
+			setup_used[--i] = 1;
+	}
 #ifdef PROC_INTERFACE
-   if (check_setup_args("proc",&flags,&val,buf))
-      hostdata->proc = val;
+	if (check_setup_args("proc", &flags, &val, buf))
+		hostdata->proc = val;
 #endif
 
-
-   spin_lock_irq(&hostdata->lock);
-   reset_wd33c93(instance);
-   spin_unlock_irq(&hostdata->lock);
-
-   printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d",instance->host_no,
-         (hostdata->chip==C_WD33C93)?"WD33c93":
-         (hostdata->chip==C_WD33C93A)?"WD33c93A":
-         (hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown",
-         hostdata->microcode,hostdata->no_sync,hostdata->no_dma);
+	spin_lock_irq(&hostdata->lock);
+	reset_wd33c93(instance);
+	spin_unlock_irq(&hostdata->lock);
+
+	printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d",
+	       instance->host_no,
+	       (hostdata->chip == C_WD33C93) ? "WD33c93" : (hostdata->chip ==
+							    C_WD33C93A) ?
+	       "WD33c93A" : (hostdata->chip ==
+			     C_WD33C93B) ? "WD33c93B" : "unknown",
+	       hostdata->microcode, hostdata->no_sync, hostdata->no_dma);
 #ifdef DEBUGGING_ON
-   printk(" debug_flags=0x%02x\n",hostdata->args);
+	printk(" debug_flags=0x%02x\n", hostdata->args);
 #else
-   printk(" debugging=OFF\n");
+	printk(" debugging=OFF\n");
 #endif
-   printk("           setup_args=");
-   for (i=0; i<MAX_SETUP_ARGS; i++)
-      printk("%s,",setup_args[i]);
-   printk("\n");
-   printk("           Version %s - %s, Compiled %s at %s\n",
-               WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__);
+	printk("           setup_args=");
+	for (i = 0; i < MAX_SETUP_ARGS; i++)
+		printk("%s,", setup_args[i]);
+	printk("\n");
+	printk("           Version %s - %s, Compiled %s at %s\n",
+	       WD33C93_VERSION, WD33C93_DATE, __DATE__, __TIME__);
 }
 
-
-int wd33c93_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
+int
+wd33c93_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
 {
 
 #ifdef PROC_INTERFACE
 
-char *bp;
-char tbuf[128];
-struct Scsi_Host *instance;
-struct WD33C93_hostdata *hd;
-Scsi_Cmnd *cmd;
-int x,i;
-static int stop = 0;
-
-   instance = scsi_host_hn_get(hn);
-   if (!instance) {
-      printk("*** Hmm... Can't find host #%d!\n",hn);
-      return (-ESRCH);
-      }
-   hd = (struct WD33C93_hostdata *)instance->hostdata;
+	char *bp;
+	char tbuf[128];
+	struct Scsi_Host *instance;
+	struct WD33C93_hostdata *hd;
+	Scsi_Cmnd *cmd;
+	int x, i;
+	static int stop = 0;
+
+	instance = scsi_host_hn_get(hn);
+	if (!instance) {
+		printk("*** Hmm... Can't find host #%d!\n", hn);
+		return (-ESRCH);
+	}
+	hd = (struct WD33C93_hostdata *) instance->hostdata;
 
 /* If 'in' is TRUE we need to _read_ the proc file. We accept the following
  * keywords (same format as command-line, but only ONE per read):
@@ -1893,148 +1943,146 @@
  *    nodma
  */
 
-   if (in) {
-      buf[len] = '\0';
-      bp = buf;
-      if (!strncmp(bp,"debug:",6)) {
-         bp += 6;
-         hd->args = simple_strtoul(bp,NULL,0) & DB_MASK;
-         }
-      else if (!strncmp(bp,"disconnect:",11)) {
-         bp += 11;
-         x = simple_strtoul(bp,NULL,0);
-         if (x < DIS_NEVER || x > DIS_ALWAYS)
-            x = DIS_ADAPTIVE;
-         hd->disconnect = x;
-         }
-      else if (!strncmp(bp,"period:",7)) {
-         bp += 7;
-         x = simple_strtoul(bp,NULL,0);
-         hd->default_sx_per = sx_table[round_period((unsigned int)x)].period_ns;
-         }
-      else if (!strncmp(bp,"resync:",7)) {
-         bp += 7;
-         x = simple_strtoul(bp,NULL,0);
-         for (i=0; i<7; i++)
-            if (x & (1<<i))
-               hd->sync_stat[i] = SS_UNSET;
-         }
-      else if (!strncmp(bp,"proc:",5)) {
-         bp += 5;
-         hd->proc = simple_strtoul(bp,NULL,0);
-         }
-      else if (!strncmp(bp,"nodma:",6)) {
-         bp += 6;
-         hd->no_dma = simple_strtoul(bp,NULL,0);
-         }
-      else if (!strncmp(bp,"level2:",7)) {
-         bp += 7;
-         hd->level2 = simple_strtoul(bp,NULL,0);
-         }
-      return len;
-      }
-
-   spin_lock_irq(&hd->lock);
-   bp = buf;
-   *bp = '\0';
-   if (hd->proc & PR_VERSION) {
-      sprintf(tbuf,"\nVersion %s - %s. Compiled %s %s",
-            WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__);
-      strcat(bp,tbuf);
-      }
-   if (hd->proc & PR_INFO) {
-      sprintf(tbuf,"\nclock_freq=%02x no_sync=%02x no_dma=%d",
-            hd->clock_freq,hd->no_sync,hd->no_dma);
-      strcat(bp,tbuf);
-      strcat(bp,"\nsync_xfer[] =       ");
-      for (x=0; x<7; x++) {
-         sprintf(tbuf,"\t%02x",hd->sync_xfer[x]);
-         strcat(bp,tbuf);
-         }
-      strcat(bp,"\nsync_stat[] =       ");
-      for (x=0; x<7; x++) {
-         sprintf(tbuf,"\t%02x",hd->sync_stat[x]);
-         strcat(bp,tbuf);
-         }
-      }
+	if (in) {
+		buf[len] = '\0';
+		bp = buf;
+		if (!strncmp(bp, "debug:", 6)) {
+			bp += 6;
+			hd->args = simple_strtoul(bp, NULL, 0) & DB_MASK;
+		} else if (!strncmp(bp, "disconnect:", 11)) {
+			bp += 11;
+			x = simple_strtoul(bp, NULL, 0);
+			if (x < DIS_NEVER || x > DIS_ALWAYS)
+				x = DIS_ADAPTIVE;
+			hd->disconnect = x;
+		} else if (!strncmp(bp, "period:", 7)) {
+			bp += 7;
+			x = simple_strtoul(bp, NULL, 0);
+			hd->default_sx_per =
+			    sx_table[round_period((unsigned int) x)].period_ns;
+		} else if (!strncmp(bp, "resync:", 7)) {
+			bp += 7;
+			x = simple_strtoul(bp, NULL, 0);
+			for (i = 0; i < 7; i++)
+				if (x & (1 << i))
+					hd->sync_stat[i] = SS_UNSET;
+		} else if (!strncmp(bp, "proc:", 5)) {
+			bp += 5;
+			hd->proc = simple_strtoul(bp, NULL, 0);
+		} else if (!strncmp(bp, "nodma:", 6)) {
+			bp += 6;
+			hd->no_dma = simple_strtoul(bp, NULL, 0);
+		} else if (!strncmp(bp, "level2:", 7)) {
+			bp += 7;
+			hd->level2 = simple_strtoul(bp, NULL, 0);
+		}
+		return len;
+	}
+
+	spin_lock_irq(&hd->lock);
+	bp = buf;
+	*bp = '\0';
+	if (hd->proc & PR_VERSION) {
+		sprintf(tbuf, "\nVersion %s - %s. Compiled %s %s",
+			WD33C93_VERSION, WD33C93_DATE, __DATE__, __TIME__);
+		strcat(bp, tbuf);
+	}
+	if (hd->proc & PR_INFO) {
+		sprintf(tbuf, "\nclock_freq=%02x no_sync=%02x no_dma=%d",
+			hd->clock_freq, hd->no_sync, hd->no_dma);
+		strcat(bp, tbuf);
+		strcat(bp, "\nsync_xfer[] =       ");
+		for (x = 0; x < 7; x++) {
+			sprintf(tbuf, "\t%02x", hd->sync_xfer[x]);
+			strcat(bp, tbuf);
+		}
+		strcat(bp, "\nsync_stat[] =       ");
+		for (x = 0; x < 7; x++) {
+			sprintf(tbuf, "\t%02x", hd->sync_stat[x]);
+			strcat(bp, tbuf);
+		}
+	}
 #ifdef PROC_STATISTICS
-   if (hd->proc & PR_STATISTICS) {
-      strcat(bp,"\ncommands issued:    ");
-      for (x=0; x<7; x++) {
-         sprintf(tbuf,"\t%ld",hd->cmd_cnt[x]);
-         strcat(bp,tbuf);
-         }
-      strcat(bp,"\ndisconnects allowed:");
-      for (x=0; x<7; x++) {
-         sprintf(tbuf,"\t%ld",hd->disc_allowed_cnt[x]);
-         strcat(bp,tbuf);
-         }
-      strcat(bp,"\ndisconnects done:   ");
-      for (x=0; x<7; x++) {
-         sprintf(tbuf,"\t%ld",hd->disc_done_cnt[x]);
-         strcat(bp,tbuf);
-         }
-      sprintf(tbuf,"\ninterrupts: %ld, DATA_PHASE ints: %ld DMA, %ld PIO",
-            hd->int_cnt,hd->dma_cnt,hd->pio_cnt);
-      strcat(bp,tbuf);
-      }
+	if (hd->proc & PR_STATISTICS) {
+		strcat(bp, "\ncommands issued:    ");
+		for (x = 0; x < 7; x++) {
+			sprintf(tbuf, "\t%ld", hd->cmd_cnt[x]);
+			strcat(bp, tbuf);
+		}
+		strcat(bp, "\ndisconnects allowed:");
+		for (x = 0; x < 7; x++) {
+			sprintf(tbuf, "\t%ld", hd->disc_allowed_cnt[x]);
+			strcat(bp, tbuf);
+		}
+		strcat(bp, "\ndisconnects done:   ");
+		for (x = 0; x < 7; x++) {
+			sprintf(tbuf, "\t%ld", hd->disc_done_cnt[x]);
+			strcat(bp, tbuf);
+		}
+		sprintf(tbuf,
+			"\ninterrupts: %ld, DATA_PHASE ints: %ld DMA, %ld PIO",
+			hd->int_cnt, hd->dma_cnt, hd->pio_cnt);
+		strcat(bp, tbuf);
+	}
 #endif
-   if (hd->proc & PR_CONNECTED) {
-      strcat(bp,"\nconnected:     ");
-      if (hd->connected) {
-         cmd = (Scsi_Cmnd *)hd->connected;
-         sprintf(tbuf," %ld-%d:%d(%02x)",
-               cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
-         strcat(bp,tbuf);
-         }
-      }
-   if (hd->proc & PR_INPUTQ) {
-      strcat(bp,"\ninput_Q:       ");
-      cmd = (Scsi_Cmnd *)hd->input_Q;
-      while (cmd) {
-         sprintf(tbuf," %ld-%d:%d(%02x)",
-               cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
-         strcat(bp,tbuf);
-         cmd = (Scsi_Cmnd *)cmd->host_scribble;
-         }
-      }
-   if (hd->proc & PR_DISCQ) {
-      strcat(bp,"\ndisconnected_Q:");
-      cmd = (Scsi_Cmnd *)hd->disconnected_Q;
-      while (cmd) {
-         sprintf(tbuf," %ld-%d:%d(%02x)",
-               cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
-         strcat(bp,tbuf);
-         cmd = (Scsi_Cmnd *)cmd->host_scribble;
-         }
-      }
-   strcat(bp,"\n");
-   spin_unlock_irq(&hd->lock);
-   *start = buf;
-   if (stop) {
-      stop = 0;
-      return 0;
-      }
-   if (off > 0x40000)   /* ALWAYS stop after 256k bytes have been read */
-      stop = 1;;
-   if (hd->proc & PR_STOP)    /* stop every other time */
-      stop = 1;
-   return strlen(bp);
-
-#else    /* PROC_INTERFACE */
-
-   return 0;
-
-#endif   /* PROC_INTERFACE */
+	if (hd->proc & PR_CONNECTED) {
+		strcat(bp, "\nconnected:     ");
+		if (hd->connected) {
+			cmd = (Scsi_Cmnd *) hd->connected;
+			sprintf(tbuf, " %ld-%d:%d(%02x)",
+				cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			strcat(bp, tbuf);
+		}
+	}
+	if (hd->proc & PR_INPUTQ) {
+		strcat(bp, "\ninput_Q:       ");
+		cmd = (Scsi_Cmnd *) hd->input_Q;
+		while (cmd) {
+			sprintf(tbuf, " %ld-%d:%d(%02x)",
+				cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			strcat(bp, tbuf);
+			cmd = (Scsi_Cmnd *) cmd->host_scribble;
+		}
+	}
+	if (hd->proc & PR_DISCQ) {
+		strcat(bp, "\ndisconnected_Q:");
+		cmd = (Scsi_Cmnd *) hd->disconnected_Q;
+		while (cmd) {
+			sprintf(tbuf, " %ld-%d:%d(%02x)",
+				cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			strcat(bp, tbuf);
+			cmd = (Scsi_Cmnd *) cmd->host_scribble;
+		}
+	}
+	strcat(bp, "\n");
+	spin_unlock_irq(&hd->lock);
+	*start = buf;
+	if (stop) {
+		stop = 0;
+		return 0;
+	}
+	if (off > 0x40000)	/* ALWAYS stop after 256k bytes have been read */
+		stop = 1;;
+	if (hd->proc & PR_STOP)	/* stop every other time */
+		stop = 1;
+	return strlen(bp);
+
+#else				/* PROC_INTERFACE */
+
+	return 0;
+
+#endif				/* PROC_INTERFACE */
 
 }
 
-#ifdef MODULE
-int init_module(void) { return 0; }
-void cleanup_module(void) {}
-#endif
-void wd33c93_release(void)
+void
+wd33c93_release(void)
 {
 }
 
-MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(wd33c93_reset);
+EXPORT_SYMBOL(wd33c93_init);
+EXPORT_SYMBOL(wd33c93_release);
+EXPORT_SYMBOL(wd33c93_abort);
+EXPORT_SYMBOL(wd33c93_queuecommand);
+EXPORT_SYMBOL(wd33c93_intr);
diff -Nru a/drivers/serial/21285.c b/drivers/serial/21285.c
--- a/drivers/serial/21285.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/serial/21285.c	Tue Mar  4 19:30:12 2003
@@ -237,7 +237,7 @@
 			struct termios *old)
 {
 	unsigned long flags;
-	unsigned int quot, h_lcr;
+	unsigned int baud, quot, h_lcr;
 
 	/*
 	 * We don't support modem control lines.
@@ -253,7 +253,8 @@
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	quot = uart_get_divisor(port, termios, old);
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = uart_get_divisor(port, baud);
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
@@ -286,7 +287,7 @@
 	/*
 	 * Update the per-port timeout.
 	 */
-	uart_update_timeout(port, termios->c_cflag, quot);
+	uart_update_timeout(port, termios->c_cflag, baud);
 
 	/*
 	 * Which character status flags are we interested in?
diff -Nru a/drivers/serial/68328serial.h b/drivers/serial/68328serial.h
--- a/drivers/serial/68328serial.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/serial/68328serial.h	Tue Mar  4 19:30:13 2003
@@ -93,7 +93,7 @@
  * board I would assume that RXRE is the safest setting.
  *
  * For EZ328 I use RXHE (Half empty) interrupt to reduce the number of
- * interrupts. RXFE (receive queue full) causes the system to loose data
+ * interrupts. RXFE (receive queue full) causes the system to lose data
  * at least at 115200 baud
  *
  * If your board is busy doing other stuff, you might consider to use
diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c
--- a/drivers/serial/8250.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/serial/8250.c	Tue Mar  4 19:30:04 2003
@@ -159,7 +159,8 @@
 	{ "16C950/954",	128,	UART_CLEAR_FIFO | UART_USE_FIFO },
 	{ "ST16654",	64,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
 	{ "XR16850",	128,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
-	{ "RSA",	2048,	UART_CLEAR_FIFO | UART_USE_FIFO }
+	{ "RSA",	2048,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "NS16550A",	16,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_NATSEMI }
 };
 
 static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
@@ -482,6 +483,40 @@
 	}
 
 	/*
+	 * Check for a National Semiconductor SuperIO chip.
+	 * Attempt to switch to bank 2, read the value of the LOOP bit
+	 * from EXCR1. Switch back to bank 0, change it in MCR. Then
+	 * switch back to bank 2, read it from EXCR1 again and check
+	 * it's changed. If so, set baud_base in EXCR2 to 921600.
+	 */
+	serial_outp(up, UART_LCR, 0);
+	status1 = serial_in(up, UART_MCR);
+	serial_outp(up, UART_LCR, 0xE0);
+	status2 = serial_in(up, 0x02); /* EXCR1 */
+
+	if (!((status2 ^ status1) & UART_MCR_LOOP)) {
+		serial_outp(up, UART_LCR, 0);
+		serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP);
+		serial_outp(up, UART_LCR, 0xE0);
+		status2 = serial_in(up, 0x02); /* EXCR1 */
+		serial_outp(up, UART_LCR, 0);
+		serial_outp(up, UART_MCR, status1);
+
+		if ((status2 ^ status1) & UART_MCR_LOOP) {
+			serial_outp(up, UART_LCR, 0xE0);
+			status1 = serial_in(up, 0x04); /* EXCR1 */
+			status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
+			status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
+			serial_outp(up, 0x04, status1);
+			serial_outp(up, UART_LCR, 0);
+
+			up->port.type = PORT_NS16550A;
+			up->port.uartclk = 921600*16;
+			return;
+		}
+	}
+
+	/*
 	 * No EFR.  Try to detect a TI16750, which only sets bit 5 of
 	 * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
 	 * Try setting it with and without DLAB set.  Cheap clones
@@ -1241,7 +1276,7 @@
 
 	/*
 	 * Finally, enable interrupts.  Note: Modem status interrupts
-	 * are set via set_termios(), which will be occuring imminently
+	 * are set via set_termios(), which will be occurring imminently
 	 * anyway, so we don't enable them here.
 	 */
 	up->ier = UART_IER_RLSI | UART_IER_RDI;
@@ -1318,6 +1353,26 @@
 		serial_unlink_irq_chain(up);
 }
 
+static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
+{
+	unsigned int quot;
+
+	/*
+	 * Handle magic divisors for baud rates above baud_base on
+	 * SMSC SuperIO chips.
+	 */
+	if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
+	    baud == (port->uartclk/4))
+		quot = 0x8001;
+	else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
+		 baud == (port->uartclk/8))
+		quot = 0x8002;
+	else
+		quot = uart_get_divisor(port, baud);
+
+	return quot;
+}
+
 static void
 serial8250_set_termios(struct uart_port *port, struct termios *termios,
 		       struct termios *old)
@@ -1325,7 +1380,7 @@
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
 	unsigned char cval, fcr = 0;
 	unsigned long flags;
-	unsigned int quot;
+	unsigned int baud, quot;
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
@@ -1357,7 +1412,8 @@
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	quot = uart_get_divisor(port, termios, old);
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = serial8250_get_divisor(port, baud);
 
 	/*
 	 * Work around a bug in the Oxford Semiconductor 952 rev B
@@ -1369,7 +1425,7 @@
 		quot ++;
 
 	if (uart_config[up->port.type].flags & UART_USE_FIFO) {
-		if ((up->port.uartclk / quot) < (2400 * 16))
+		if (baud < 2400)
 			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
 #ifdef CONFIG_SERIAL_8250_RSA
 		else if (up->port.type == PORT_RSA)
@@ -1390,7 +1446,7 @@
 	/*
 	 * Update the per-port timeout.
 	 */
-	uart_update_timeout(port, termios->c_cflag, quot);
+	uart_update_timeout(port, termios->c_cflag, baud);
 
 	up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
 	if (termios->c_iflag & INPCK)
@@ -1434,7 +1490,13 @@
 		serial_outp(up, UART_EFR,
 			    termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0);
 	}
-	serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+
+	if (uart_config[up->port.type].flags & UART_NATSEMI) {
+		/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
+		serial_outp(up, UART_LCR, 0xe0);
+	} else {
+		serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
+	}
 	serial_outp(up, UART_DLL, quot & 0xff);		/* LS of divisor */
 	serial_outp(up, UART_DLM, quot >> 8);		/* MS of divisor */
 	if (up->port.type == PORT_16750)
@@ -1989,7 +2051,7 @@
  *	port exists and is in use an error is returned. If the port
  *	is not currently in the table it is added.
  *
- *	The port is then probed and if neccessary the IRQ is autodetected
+ *	The port is then probed and if necessary the IRQ is autodetected
  *	If this fails an error is returned.
  *
  *	On success the port is ready to use and the line number is returned.
diff -Nru a/drivers/serial/amba.c b/drivers/serial/amba.c
--- a/drivers/serial/amba.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/serial/amba.c	Tue Mar  4 19:30:04 2003
@@ -408,12 +408,13 @@
 {
 	unsigned int lcr_h, old_cr;
 	unsigned long flags;
-	unsigned int quot;
+	unsigned int baud, quot;
 
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	quot = uart_get_divisor(port, termios, old);
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = uart_get_divisor(port, baud);
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
@@ -444,7 +445,7 @@
 	/*
 	 * Update the per-port timeout.
 	 */
-	uart_update_timeout(port, termios->c_cflag, quot);
+	uart_update_timeout(port, termios->c_cflag, baud);
 
 	port->read_status_mask = AMBA_UARTRSR_OE;
 	if (termios->c_iflag & INPCK)
diff -Nru a/drivers/serial/anakin.c b/drivers/serial/anakin.c
--- a/drivers/serial/anakin.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/serial/anakin.c	Tue Mar  4 19:30:05 2003
@@ -287,7 +287,7 @@
 		   struct termios *old)
 {
 	unsigned long flags;
-	unsigned int quot;
+	unsigned int baud, quot;
 
 	/*
 	 * We don't support parity, stop bits, or anything other
@@ -304,11 +304,12 @@
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	quot = uart_get_divisor(port, termios, old);
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = uart_get_divisor(port, baud);
 
 	spin_lock_irqsave(&port->lock, flags);
 
-	uart_update_timeout(port, termios->c_cflag, quot);
+	uart_update_timeout(port, termios->c_cflag, baud);
 
 	while (!(anakin_in(port, 0x10) & TXEMPTY))
 		barrier();
diff -Nru a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
--- a/drivers/serial/clps711x.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/serial/clps711x.c	Tue Mar  4 19:30:05 2003
@@ -320,7 +320,7 @@
 clps711xuart_set_termios(struct uart_port *port, struct termios *termios,
 			 struct termios *old)
 {
-	unsigned int ubrlcr, quot;
+	unsigned int ubrlcr, baud, quot;
 	unsigned long flags;
 
 	/*
@@ -331,7 +331,8 @@
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	quot = uart_get_divisor(port, termios, old);
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = uart_get_divisor(port, baud);
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
@@ -362,7 +363,7 @@
 	/*
 	 * Update the per-port timeout.
 	 */
-	uart_update_timeout(port, termios->c_cflag, quot);
+	uart_update_timeout(port, termios->c_cflag, baud);
 
 	port->read_status_mask = UARTDR_OVERR;
 	if (termios->c_iflag & INPCK)
diff -Nru a/drivers/serial/core.c b/drivers/serial/core.c
--- a/drivers/serial/core.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/serial/core.c	Tue Mar  4 19:30:05 2003
@@ -271,7 +271,7 @@
  */
 void
 uart_update_timeout(struct uart_port *port, unsigned int cflag,
-		    unsigned int quot)
+		    unsigned int baud)
 {
 	unsigned int bits;
 
@@ -305,7 +305,7 @@
 	 * Figure the timeout to send the above number of bits.
 	 * Add .02 seconds of slop
 	 */
-	port->timeout = (HZ * bits) / (port->uartclk / (16 * quot)) + HZ/50;
+	port->timeout = (HZ * bits) / baud + HZ/50;
 }
 
 EXPORT_SYMBOL(uart_update_timeout);
@@ -321,6 +321,12 @@
  *	Decode the termios structure into a numeric baud rate,
  *	taking account of the magic 38400 baud rate (with spd_*
  *	flags), and mapping the %B0 rate to 9600 baud.
+ *
+ *	If the new baud rate is invalid, try the old termios setting.
+ *	If it's still invalid, we try 9600 baud.
+ *
+ *	Update the @termios structure to reflect the baud rate
+ *	we're actually going to be using.
  */
 unsigned int
 uart_get_baud_rate(struct uart_port *port, struct termios *termios,
@@ -383,26 +389,14 @@
 /**
  *	uart_get_divisor - return uart clock divisor
  *	@port: uart_port structure describing the port.
- *	@termios: desired termios settings
- *	@old_termios: the original port settings, or NULL
- *
- *	Calculate the uart clock divisor for the port.  If the
- *	divisor is invalid, try the old termios setting.  If
- *	the divisor is still invalid, we try 9600 baud.
+ *	@baud: desired baud rate
  *
- *	Update the @termios structure to reflect the baud rate
- *	we're actually going to be using.
- *
- *	If 9600 baud fails, we return a zero divisor.
+ *	Calculate the uart clock divisor for the port.
  */
 unsigned int
-uart_get_divisor(struct uart_port *port, struct termios *termios,
-		 struct termios *old_termios)
+uart_get_divisor(struct uart_port *port, unsigned int baud)
 {
-	unsigned int quot, baud, max = port->uartclk / 16;
-
-	/* Determine divisor based on baud rate */
-	baud = uart_get_baud_rate(port, termios, old_termios, 0, max);
+	unsigned int quot;
 
 	/*
 	 * Old custom speed handling.
@@ -832,8 +826,17 @@
 		goto exit;
 	if (info->flags & UIF_INITIALIZED) {
 		if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
-		    old_custom_divisor != port->custom_divisor)
+		    old_custom_divisor != port->custom_divisor) {
+			/* If they're setting up a custom divisor or speed,
+			 * instead of clearing it, then bitch about it. No
+			 * need to rate-limit; it's CAP_SYS_ADMIN only. */
+			if (port->flags & UPF_SPD_MASK) {
+				printk(KERN_NOTICE "%s sets custom speed on %s%d. This is deprecated.\n",
+				       current->comm, info->tty->driver.name, 
+				       info->port->line);
+			}
 			uart_change_speed(info, NULL);
+		}
 	} else
 		retval = uart_startup(info, 1);
  exit:
@@ -2024,11 +2027,11 @@
 	switch (rqst) {
 	case PM_SUSPEND:
 	case PM_RESUME:
-		err = uart_pm_set_state(state, (int)data, dev->state);
+		err = uart_pm_set_state(state, (int)(long)data, dev->state);
 		break;
 
 	case PM_SET_WAKEUP:
-		err = uart_pm_set_wakeup(state, (int)data);
+		err = uart_pm_set_wakeup(state, (int)(long)data);
 		break;
 	}
 	return err;
diff -Nru a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
--- a/drivers/serial/sa1100.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/serial/sa1100.c	Tue Mar  4 19:30:04 2003
@@ -327,7 +327,7 @@
 			sa1100_rx_chars(sport, regs);
 		}
 
-		/* Clear the relevent break bits */
+		/* Clear the relevant break bits */
 		if (status & (UTSR0_RBB | UTSR0_REB))
 			UART_PUT_UTSR0(sport, status & (UTSR0_RBB | UTSR0_REB));
 
@@ -441,7 +441,7 @@
 {
 	struct sa1100_port *sport = (struct sa1100_port *)port;
 	unsigned long flags;
-	unsigned int utcr0, old_utcr3, quot;
+	unsigned int utcr0, old_utcr3, baud, quot;
 	unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
 
 	/*
@@ -470,7 +470,8 @@
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	quot = uart_get_divisor(port, termios, old);
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = uart_get_divisor(port, baud);
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
@@ -507,7 +508,7 @@
 	/*
 	 * Update the per-port timeout.
 	 */
-	uart_update_timeout(port, termios->c_cflag, quot);
+	uart_update_timeout(port, termios->c_cflag, baud);
 
 	/*
 	 * disable interrupts and drain transmitter
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/serial/sunsu.c	Tue Mar  4 19:30:05 2003
@@ -478,7 +478,7 @@
 	spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
-/* Seperate interrupt handling path for keyboard/mouse ports.  */
+/* Separate interrupt handling path for keyboard/mouse ports.  */
 
 static void
 sunsu_change_speed(struct uart_port *port, unsigned int cflag,
@@ -713,7 +713,7 @@
 
 	/*
 	 * Finally, enable interrupts.  Note: Modem status interrupts
-	 * are set via set_termios(), which will be occuring imminently
+	 * are set via set_termios(), which will be occurring imminently
 	 * anyway, so we don't enable them here.
 	 */
 	up->ier = UART_IER_RLSI | UART_IER_RDI;
@@ -852,7 +852,7 @@
 	/*
 	 * Update the per-port timeout.
 	 */
-	uart_update_timeout(port, cflag, quot);
+	uart_update_timeout(port, cflag, (port->uartclk / (16 * quot)));
 
 	up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
 	if (iflag & INPCK)
@@ -919,12 +919,13 @@
 sunsu_set_termios(struct uart_port *port, struct termios *termios,
 		  struct termios *old)
 {
-	unsigned int quot;
+	unsigned int baud, quot;
 
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	quot = uart_get_divisor(port, termios, old);
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = uart_get_divisor(port, baud);
 
 	sunsu_change_speed(port, termios->c_cflag, termios->c_iflag, quot);
 }
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/serial/sunzilog.c	Tue Mar  4 19:30:14 2003
@@ -48,7 +48,7 @@
 #include "sunzilog.h"
 
 /* On 32-bit sparcs we need to delay after register accesses
- * to accomodate sun4 systems, but we do not need to flush writes.
+ * to accommodate sun4 systems, but we do not need to flush writes.
  * On 64-bit sparc we only need to flush single writes to ensure
  * completion.
  */
diff -Nru a/drivers/serial/uart00.c b/drivers/serial/uart00.c
--- a/drivers/serial/uart00.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/serial/uart00.c	Tue Mar  4 19:30:07 2003
@@ -317,7 +317,7 @@
 uart00_set_termios(struct uart_port *port, struct termios *termios,
 		   struct termios *old)
 {
-	unsigned int uart_mc, old_ies, quot;
+	unsigned int uart_mc, old_ies, baud, quot;
 	unsigned long flags;
 
 	/*
@@ -328,7 +328,8 @@
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	quot = uart_get_divisor(port, termios, old);
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = uart_get_divisor(port, baud);
 
 	/* byte size and parity */
 	switch (termios->c_cflag & CSIZE) {
@@ -358,7 +359,7 @@
 	/*
 	 * Update the per-port timeout.
 	 */
-	uart_update_timeout(port, termios->c_cflag, quot);
+	uart_update_timeout(port, termios->c_cflag, baud);
 
 	port->read_status_mask = UART_RDS_OE_MSK;
 	if (termios->c_iflag & INPCK)
diff -Nru a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
--- a/drivers/telephony/ixj.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/telephony/ixj.c	Tue Mar  4 19:30:04 2003
@@ -7717,7 +7717,7 @@
 				printk("pnp attach failed %d \n", result);
 				break;
 			}
-			if (pnp_activate_dev(dev, NULL) < 0) {
+			if (pnp_activate_dev(dev) < 0) {
 				printk("pnp activate failed (out of resources?)\n");
 				pnp_device_detach(dev);
 				return -ENOMEM;
diff -Nru a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
--- a/drivers/usb/class/bluetty.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/usb/class/bluetty.c	Tue Mar  4 19:30:12 2003
@@ -267,7 +267,7 @@
 {
 	if (!bluetooth || 
 	    bluetooth_paranoia_check (bluetooth, function)) { 
-		/* then say that we dont have a valid usb_bluetooth thing, which will
+		/* then say that we don't have a valid usb_bluetooth thing, which will
 		 * end up generating -ENODEV return values */
 		return NULL;
 	}
diff -Nru a/drivers/usb/class/usb-midi.h b/drivers/usb/class/usb-midi.h
--- a/drivers/usb/class/usb-midi.h	Tue Mar  4 19:30:10 2003
+++ b/drivers/usb/class/usb-midi.h	Tue Mar  4 19:30:10 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
@@ -102,6 +103,13 @@
     USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_SC8850, 2, -1,
     { { 0x81, 15 }, {-1, -1} }, /** cables 0,1,2, and 3 **/
     { { 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 */
diff -Nru a/drivers/usb/core/driverfs.c b/drivers/usb/core/driverfs.c
--- a/drivers/usb/core/driverfs.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/usb/core/driverfs.c	Tue Mar  4 19:30:05 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 -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h	Tue Mar  4 19:30:05 2003
+++ b/drivers/usb/core/hcd.h	Tue Mar  4 19:30:05 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))
+#define usb_rcvdefctrl(dev)		((PIPE_CONTROL << 30) | USB_DIR_IN)
+
 /*-------------------------------------------------------------------------*/
 
 /*
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/usb/core/hub.c	Tue Mar  4 19:30:08 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 -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/usb/host/ehci-dbg.c	Tue Mar  4 19:30:12 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 -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/usb/host/ehci-hcd.c	Tue Mar  4 19:30:11 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 -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c	Tue Mar  4 19:30:12 2003
+++ b/drivers/usb/host/ehci-q.c	Tue Mar  4 19:30:12 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 -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/usb/host/ehci-sched.c	Tue Mar  4 19:30:05 2003
@@ -417,7 +417,7 @@
 		if (unlikely (ehci->pshadow [frame].ptr != 0)) {
 
 // FIXME -- just link toward the end, before any qh with a shorter period,
-// AND accomodate it already having been linked here (after some other qh)
+// AND accommodate it already having been linked here (after some other qh)
 // AS WELL AS updating the schedule checking logic
 
 			BUG ();
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h	Tue Mar  4 19:30:13 2003
+++ b/drivers/usb/host/ehci.h	Tue Mar  4 19:30:13 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 -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
--- a/drivers/usb/host/ohci-dbg.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/usb/host/ohci-dbg.c	Tue Mar  4 19:30:13 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 -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/usb/host/ohci-hcd.c	Tue Mar  4 19:30:04 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,17 +669,15 @@
 	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
 
diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
--- a/drivers/usb/host/ohci-hub.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/usb/host/ohci-hub.c	Tue Mar  4 19:30:04 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 -Nru a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
--- a/drivers/usb/host/ohci-mem.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/usb/host/ohci-mem.c	Tue Mar  4 19:30:11 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 -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
--- a/drivers/usb/host/ohci-pci.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/usb/host/ohci-pci.c	Tue Mar  4 19:30:11 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 -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/usb/host/ohci-q.c	Tue Mar  4 19:30:13 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 -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
--- a/drivers/usb/host/ohci-sa1111.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/usb/host/ohci-sa1111.c	Tue Mar  4 19:30:09 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
  *
@@ -24,14 +24,6 @@
 #endif
 
 extern int usb_disabled(void);
-
-/*-------------------------------------------------------------------------*/
-
-struct ohci_hcd *dev_to_ohci(struct device *dev) {
-	struct usb_hcd *hcd = dev->driver_data;
-
-	return hcd_to_ohci(hcd);
-}
 
 /*-------------------------------------------------------------------------*/
 
diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
--- a/drivers/usb/host/ohci.h	Tue Mar  4 19:30:14 2003
+++ b/drivers/usb/host/ohci.h	Tue Mar  4 19:30:14 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 -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
--- a/drivers/usb/image/mdc800.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/usb/image/mdc800.c	Tue Mar  4 19:30:09 2003
@@ -213,7 +213,7 @@
 
 
 /*
- * Checks wether the camera responds busy
+ * Checks whether the camera responds busy
  */
 static int mdc800_isBusy (char* ch)
 {
@@ -229,7 +229,7 @@
 
 
 /*
- * Checks wether the Camera is ready
+ * Checks whether the Camera is ready
  */
 static int mdc800_isReady (char *ch)
 {
diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
--- a/drivers/usb/image/microtek.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/usb/image/microtek.c	Tue Mar  4 19:30:14 2003
@@ -572,7 +572,7 @@
 			MTS_DEBUG_GOT_HERE();
 			context->srb->result = DID_ABORT<<16;
                 } else {
-		        /* A genuine error has occured */
+		        /* A genuine error has occurred */
 			MTS_DEBUG_GOT_HERE();
 
 		        context->srb->result = DID_ERROR<<16;
diff -Nru a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c
--- a/drivers/usb/image/scanner.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/usb/image/scanner.c	Tue Mar  4 19:30:05 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 -Nru a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h
--- a/drivers/usb/image/scanner.h	Tue Mar  4 19:30:07 2003
+++ b/drivers/usb/image/scanner.h	Tue Mar  4 19:30:07 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 -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
--- a/drivers/usb/input/Kconfig	Tue Mar  4 19:30:12 2003
+++ b/drivers/usb/input/Kconfig	Tue Mar  4 19:30:12 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 -Nru a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
--- a/drivers/usb/input/Makefile	Tue Mar  4 19:30:10 2003
+++ b/drivers/usb/input/Makefile	Tue Mar  4 19:30:10 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 -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/usb/input/hid-core.c	Tue Mar  4 19:30:10 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 -Nru a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/input/kbtab.c	Tue Mar  4 19:30:14 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 -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
--- a/drivers/usb/media/konicawc.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/usb/media/konicawc.c	Tue Mar  4 19:30:03 2003
@@ -266,7 +266,7 @@
 			sts &= ~0x40;
 		}
 		
-		/* work out the button status, but dont do
+		/* work out the button status, but don't do
 		   anything with it for now */
 
 		if(button != cam->buttonsts) {
@@ -607,7 +607,7 @@
 	}
 
 	if(newsize > MAX_FRAME_SIZE) {
-		DEBUG(1, "couldnt find size %d,%d", x, y);
+		DEBUG(1, "couldn't find size %d,%d", x, y);
 		return -EINVAL;
 	}
 
@@ -806,7 +806,7 @@
 				while(i--) {
 					usb_free_urb(cam->sts_urb[i]);
 				}
-				err("cant allocate urbs");
+				err("can't allocate urbs");
 				return -ENOMEM;
 			}
 		}
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c	Tue Mar  4 19:30:07 2003
+++ b/drivers/usb/misc/auerswald.c	Tue Mar  4 19:30:07 2003
@@ -1946,7 +1946,7 @@
         if (intf->altsetting->desc.bInterfaceNumber != 0)
 		return -ENODEV;
 
-	/* allocate memory for our device and intialize it */
+	/* allocate memory for our device and initialize it */
 	cp = kmalloc (sizeof(auerswald_t), GFP_KERNEL);
 	if (cp == NULL) {
 		err ("out of memory");
diff -Nru a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
--- a/drivers/usb/misc/rio500.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/usb/misc/rio500.c	Tue Mar  4 19:30:11 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 -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c
--- a/drivers/usb/misc/speedtouch.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/usb/misc/speedtouch.c	Tue Mar  4 19:30:14 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 -Nru a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
--- a/drivers/usb/misc/usblcd.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/usb/misc/usblcd.c	Tue Mar  4 19:30:03 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 -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/usb/misc/usbtest.c	Tue Mar  4 19:30:13 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 -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig	Tue Mar  4 19:30:11 2003
+++ b/drivers/usb/serial/Kconfig	Tue Mar  4 19:30:11 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
@@ -311,6 +317,12 @@
 	depends on USB_SERIAL_KEYSPAN
 	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)"
diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
--- a/drivers/usb/serial/belkin_sa.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/usb/serial/belkin_sa.c	Tue Mar  4 19:30:10 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 -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
--- a/drivers/usb/serial/ipaq.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/usb/serial/ipaq.c	Tue Mar  4 19:30:13 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 -Nru a/drivers/usb/serial/ipaq.h b/drivers/usb/serial/ipaq.h
--- a/drivers/usb/serial/ipaq.h	Tue Mar  4 19:30:04 2003
+++ b/drivers/usb/serial/ipaq.h	Tue Mar  4 19:30:04 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 -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/usb/serial/keyspan.c	Tue Mar  4 19:30:04 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";
@@ -1026,6 +1052,11 @@
 	case keyspan_usa49w_pre_product_id:
 		record = &keyspan_usa49w_firmware[0];
 		fw_name = "USA49W";
+		break;
+
+	case keyspan_usa49wlc_pre_product_id:
+		record = &keyspan_usa49wlc_firmware[0];
+		fw_name = "USA49WLC";
 		break;
 
 	default:
diff -Nru a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
--- a/drivers/usb/serial/keyspan.h	Tue Mar  4 19:30:11 2003
+++ b/drivers/usb/serial/keyspan.h	Tue Mar  4 19:30:11 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 -Nru a/drivers/usb/serial/keyspan_mpr_fw.h b/drivers/usb/serial/keyspan_mpr_fw.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/serial/keyspan_mpr_fw.h	Tue Mar  4 19:30:14 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 -Nru a/drivers/usb/serial/keyspan_usa49wlc_fw.h b/drivers/usb/serial/keyspan_usa49wlc_fw.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/serial/keyspan_usa49wlc_fw.h	Tue Mar  4 19:30:14 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 -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
--- a/drivers/usb/serial/kl5kusb105.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/usb/serial/kl5kusb105.c	Tue Mar  4 19:30:09 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 -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
--- a/drivers/usb/serial/kobil_sct.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/usb/serial/kobil_sct.c	Tue Mar  4 19:30:13 2003
@@ -159,7 +159,7 @@
 	}
 	usb_set_serial_port_data(serial->port, priv);
 
-	// search for the neccessary endpoints
+	// search for the necessary endpoints
 	pdev = serial->dev;
  	actconfig = pdev->actconfig;
  	interface = actconfig->interface;
diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
--- a/drivers/usb/serial/mct_u232.c	Tue Mar  4 19:30:11 2003
+++ b/drivers/usb/serial/mct_u232.c	Tue Mar  4 19:30:11 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 -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/usb/serial/pl2303.c	Tue Mar  4 19:30:08 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,15 +521,21 @@
 			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 -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h	Tue Mar  4 19:30:14 2003
+++ b/drivers/usb/serial/usb-serial.h	Tue Mar  4 19:30:14 2003
@@ -342,7 +342,7 @@
 	if (!port || 
 		port_paranoia_check (port, function) ||
 		serial_paranoia_check (port->serial, function)) {
-		/* then say that we dont have a valid usb_serial thing, which will
+		/* then say that we don't have a valid usb_serial thing, which will
 		 * end up genrating -ENODEV return values */ 
 		return NULL;
 	}
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/usb/serial/visor.c	Tue Mar  4 19:30:05 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 -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
--- a/drivers/usb/storage/freecom.c	Tue Mar  4 19:30:14 2003
+++ b/drivers/usb/storage/freecom.c	Tue Mar  4 19:30:14 2003
@@ -240,7 +240,7 @@
 	 * may not work, but that is a condition that should never happen.
 	 */
 	while (fst->Status & FCM_STATUS_BUSY) {
-		US_DEBUGP("20 second USB/ATAPI bridge TIMEOUT occured!\n");
+		US_DEBUGP("20 second USB/ATAPI bridge TIMEOUT occurred!\n");
 		US_DEBUGP("fst->Status is %x\n", fst->Status);
 
 		/* Get the status again */
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h	Tue Mar  4 19:30:12 2003
+++ b/drivers/usb/storage/unusual_devs.h	Tue Mar  4 19:30:12 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 -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	Tue Mar  4 19:30:08 2003
+++ b/drivers/usb/usb-skeleton.c	Tue Mar  4 19:30:08 2003
@@ -498,7 +498,7 @@
 		goto exit;
 	}
 
-	/* allocate memory for our device state and intialize it */
+	/* allocate memory for our device state and initialize it */
 	dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL);
 	if (dev == NULL) {
 		err ("Out of memory");
diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	Tue Mar  4 19:30:04 2003
+++ b/drivers/video/Kconfig	Tue Mar  4 19:30:04 2003
@@ -376,19 +376,19 @@
 	bool "Sun3 framebuffer support"
 	depends on FB && (SUN3 || SUN3X)
 
-config FB_BWTWO
+config FB_BW2
 	bool "BWtwo support"
 	depends on FB && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
 	help
 	  This is the frame buffer device driver for the BWtwo frame buffer.
 
-config FB_CGTHREE
+config FB_CG3
 	bool "CGthree support"
 	depends on FB && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
 	help
 	  This is the frame buffer device driver for the CGthree frame buffer.
 
-config FB_CGSIX
+config FB_CG6
 	bool "CGsix (GX,TurboGX) support"
 	depends on FB && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
 	help
@@ -809,30 +809,30 @@
 	help
 	  Say Y if you want support for SBUS or UPA based frame buffer device.
 
-config FB_CREATOR
-	bool "Creator/Creator3D support"
+config FB_FFB
+	bool "Creator/Creator3D/Elite3D support"
 	depends on FB_SBUS && SPARC64
 	help
-	  This is the frame buffer device driver for the Creator and Creator3D
-	  graphics boards.
+	  This is the frame buffer device driver for the Creator, Creator3D,
+	  and Elite3D graphics boards.
 
 config FB_TCX
 	bool "TCX (SS4/SS5 only) support"
-	depends on FB_SBUS && SPARC32
+	depends on FB_SBUS
 	help
 	  This is the frame buffer device driver for the TCX 24/8bit frame
 	  buffer.
 
-config FB_CGFOURTEEN
+config FB_CG14
 	bool "CGfourteen (SX) support"
-	depends on FB_SBUS && SPARC32
+	depends on FB_SBUS
 	help
 	  This is the frame buffer device driver for the CGfourteen frame
 	  buffer on Desktop SPARCsystems with the SX graphics option.
 
 config FB_P9100
 	bool "P9100 (Sparcbook 3 only) support"
-	depends on FB_SBUS && SPARC32
+	depends on FB_SBUS
 	help
 	  This is the frame buffer device driver for the P9100 card
 	  supported on Sparcbook 3 machines.
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	Tue Mar  4 19:30:04 2003
+++ b/drivers/video/Makefile	Tue Mar  4 19:30:04 2003
@@ -48,14 +48,6 @@
 obj-$(CONFIG_FB_VIRGE)            += virgefb.o
 obj-$(CONFIG_FB_G364)             += g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_FM2)              += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_CREATOR)          += creatorfb.o sbusfb.o
-obj-$(CONFIG_FB_CGSIX)            += cgsixfb.o sbusfb.o
-obj-$(CONFIG_FB_BWTWO)            += bwtwofb.o sbusfb.o
-obj-$(CONFIG_FB_CGTHREE)          += cgthreefb.o sbusfb.o
-obj-$(CONFIG_FB_TCX)              += tcxfb.o sbusfb.o
-obj-$(CONFIG_FB_CGFOURTEEN)       += cgfourteenfb.o sbusfb.o
-obj-$(CONFIG_FB_P9100)            += p9100fb.o sbusfb.o
-obj-$(CONFIG_FB_LEO)              += leofb.o sbusfb.o
 obj-$(CONFIG_FB_STI)              += stifb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PMAG_BA)          += pmag-ba-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PMAGB_B)          += pmagb-b-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -77,6 +69,22 @@
 obj-$(CONFIG_FB_E1355)            += epson1355fb.o
 obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
 obj-$(CONFIG_FB_VOODOO1)          += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+
+# One by one these are being converted over to the new APIs
+#obj-$(CONFIG_FB_LEO)              += leofb.o sbusfb.o
+
+obj-$(CONFIG_FB_FFB)               += ffb.o sbuslib.o cfbimgblt.o cfbcopyarea.o
+obj-$(CONFIG_FB_CG6)               += cg6.o sbuslib.o cfbimgblt.o cfbcopyarea.o
+obj-$(CONFIG_FB_CG3)               += cg3.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
+				      cfbfillrect.o
+obj-$(CONFIG_FB_BW2)               += bw2.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
+				      cfbfillrect.o
+obj-$(CONFIG_FB_CG14)              += cg14.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
+				      cfbfillrect.o
+obj-$(CONFIG_FB_P9100)             += p9100.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
+				      cfbfillrect.o
+obj-$(CONFIG_FB_TCX)               += tcx.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
+				      cfbfillrect.o
 
 # Files generated that shall be removed upon make clean
 clean-files := promcon_tbl.c
diff -Nru a/drivers/video/amifb.c b/drivers/video/amifb.c
--- a/drivers/video/amifb.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/video/amifb.c	Tue Mar  4 19:30:13 2003
@@ -274,9 +274,9 @@
    display of sprites, I use the following policy on horizontal panning and
    the hardware cursor:
 
-      - if you want to start display DMA too early, you loose the ability to
+      - if you want to start display DMA too early, you lose the ability to
         do smooth horizontal panning (xpanstep 1 -> 64).
-      - if you want to go even further, you loose the hardware cursor too.
+      - if you want to go even further, you lose the hardware cursor too.
 
    IMHO a hardware cursor is more important for X than horizontal scrolling,
    so that's my motivation.
diff -Nru a/drivers/video/bw2.c b/drivers/video/bw2.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/bw2.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,448 @@
+/* bw2.c: BWTWO frame buffer driver
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
+ *
+ * Driver layout based loosely on tgafb.c, see that file for credits.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/fbio.h>
+
+#ifdef CONFIG_SPARC32
+#include <asm/sun4paddr.h>
+#endif
+
+#include "sbuslib.h"
+
+/*
+ * Local functions.
+ */
+
+static int bw2_check_var(struct fb_var_screeninfo *, struct fb_info *);
+static int bw2_set_par(struct fb_info *);
+static int bw2_blank(int, struct fb_info *);
+
+static int bw2_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+
+/*
+ *  Frame buffer operations
+ */
+
+static struct fb_ops bw2_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= bw2_check_var,
+	.fb_set_par		= bw2_set_par,
+	.fb_blank		= bw2_blank,
+	.fb_fillrect		= cfb_fillrect,
+	.fb_copyarea		= cfb_copyarea,
+	.fb_imageblit		= cfb_imageblit,
+	.fb_mmap		= bw2_mmap,
+	.fb_cursor		= soft_cursor,
+};
+
+/* OBio addresses for the bwtwo registers */
+#define BWTWO_REGISTER_OFFSET 0x400000
+
+struct bt_regs {
+	volatile u32 addr;
+	volatile u32 color_map;
+	volatile u32 control;
+	volatile u32 cursor;
+};
+
+struct bw2_regs {
+	struct bt_regs	cmap;
+	volatile u8	control;
+	volatile u8	status;
+	volatile u8	cursor_start;
+	volatile u8	cursor_end;
+	volatile u8	h_blank_start;
+	volatile u8	h_blank_end;
+	volatile u8	h_sync_start;
+	volatile u8	h_sync_end;
+	volatile u8	comp_sync_end;
+	volatile u8	v_blank_start_high;
+	volatile u8	v_blank_start_low;
+	volatile u8	v_blank_end;
+	volatile u8	v_sync_start;
+	volatile u8	v_sync_end;
+	volatile u8	xfer_holdoff_start;
+	volatile u8	xfer_holdoff_end;
+};
+
+/* Status Register Constants */
+#define BWTWO_SR_RES_MASK	0x70
+#define BWTWO_SR_1600_1280	0x50
+#define BWTWO_SR_1152_900_76_A	0x40
+#define BWTWO_SR_1152_900_76_B	0x60
+#define BWTWO_SR_ID_MASK	0x0f
+#define BWTWO_SR_ID_MONO	0x02
+#define BWTWO_SR_ID_MONO_ECL	0x03
+#define BWTWO_SR_ID_MSYNC	0x04
+#define BWTWO_SR_ID_NOCONN	0x0a
+
+/* Control Register Constants */
+#define BWTWO_CTL_ENABLE_INTS   0x80
+#define BWTWO_CTL_ENABLE_VIDEO  0x40
+#define BWTWO_CTL_ENABLE_TIMING 0x20
+#define BWTWO_CTL_ENABLE_CURCMP 0x10
+#define BWTWO_CTL_XTAL_MASK     0x0C
+#define BWTWO_CTL_DIVISOR_MASK  0x03
+
+/* Status Register Constants */
+#define BWTWO_STAT_PENDING_INT  0x80
+#define BWTWO_STAT_MSENSE_MASK  0x70
+#define BWTWO_STAT_ID_MASK      0x0f
+
+struct bw2_par {
+	spinlock_t		lock;
+	struct bw2_regs		*regs;
+
+	u32			flags;
+#define BW2_FLAG_BLANKED	0x00000001
+
+	unsigned long		physbase;
+	unsigned long		fbsize;
+
+	struct sbus_dev		*sdev;
+	struct list_head	list;
+};
+
+/**
+ *      bw2_check_var - Optional function.  Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int bw2_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->bits_per_pixel != 8)
+		return -EINVAL;
+
+	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
+		return -EINVAL;
+	if (var->nonstd)
+		return -EINVAL;
+	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+
+	if (var->xres != info->var.xres || var->yres != info->var.yres)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ *      bw2_set_par - Optional function.  Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+bw2_set_par(struct fb_info *info)
+{
+	return 0;
+}
+
+/**
+ *      bw2_blank - Optional function.  Blanks the display.
+ *      @blank_mode: the blank mode we want.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+bw2_blank(int blank, struct fb_info *info)
+{
+	struct bw2_par *par = (struct bw2_par *) info->par;
+	struct bw2_regs *regs = par->regs;
+	unsigned long flags;
+	u8 val;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	switch (blank) {
+	case 0: /* Unblanking */
+		val = sbus_readb(&regs->control);
+		val |= BWTWO_CTL_ENABLE_VIDEO;
+		sbus_writeb(val, &regs->control);
+		par->flags &= ~BW2_FLAG_BLANKED;
+		break;
+
+	case 1: /* Normal blanking */
+	case 2: /* VESA blank (vsync off) */
+	case 3: /* VESA blank (hsync off) */
+	case 4: /* Poweroff */
+		val = sbus_readb(&regs->control);
+		val &= ~BWTWO_CTL_ENABLE_VIDEO;
+		sbus_writeb(val, &regs->control);
+		par->flags |= BW2_FLAG_BLANKED;
+		break;
+	}
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+static struct sbus_mmap_map bw2_mmap_map[] = {
+	{ 0,			0,			SBUS_MMAP_FBSIZE(1) },
+	{ 0,			0,			0		    }
+};
+
+static int bw2_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	struct bw2_par *par = (struct bw2_par *)info->par;
+
+	return sbusfb_mmap_helper(bw2_mmap_map,
+				  par->physbase, par->fbsize,
+				  (par->sdev ?
+				   par->sdev->reg_addrs[0].which_io :
+				   0),
+				  vma);
+}
+
+/*
+ *  Initialisation
+ */
+
+static void
+bw2_init_fix(struct fb_info *info, int linebytes)
+{
+	strncpy(info->fix.id, "bwtwo", sizeof(info->fix.id) - 1);
+	info->fix.id[sizeof(info->fix.id)-1] = 0;
+
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_MONO01;
+
+	info->fix.line_length = linebytes;
+
+	info->fix.accel = FB_ACCEL_SUN_BWTWO;
+}
+
+static u8 bw2regs_1600[] __initdata = {
+	0x14, 0x8b,	0x15, 0x28,	0x16, 0x03,	0x17, 0x13,
+	0x18, 0x7b,	0x19, 0x05,	0x1a, 0x34,	0x1b, 0x2e,
+	0x1c, 0x00,	0x1d, 0x0a,	0x1e, 0xff,	0x1f, 0x01,
+	0x10, 0x21,	0
+};
+
+static u8 bw2regs_ecl[] __initdata = {
+	0x14, 0x65,	0x15, 0x1e,	0x16, 0x04,	0x17, 0x0c,
+	0x18, 0x5e,	0x19, 0x03,	0x1a, 0xa7,	0x1b, 0x23,
+	0x1c, 0x00,	0x1d, 0x08,	0x1e, 0xff,	0x1f, 0x01,
+	0x10, 0x20,	0
+};
+
+static u8 bw2regs_analog[] __initdata = {
+	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x03,	0x17, 0x13,
+	0x18, 0xb0,	0x19, 0x03,	0x1a, 0xa6,	0x1b, 0x22,
+	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
+	0x10, 0x20,	0
+};
+
+static u8 bw2regs_76hz[] __initdata = {
+	0x14, 0xb7,	0x15, 0x27,	0x16, 0x03,	0x17, 0x0f,
+	0x18, 0xae,	0x19, 0x03,	0x1a, 0xae,	0x1b, 0x2a,
+	0x1c, 0x01,	0x1d, 0x09,	0x1e, 0xff,	0x1f, 0x01,
+	0x10, 0x24,	0
+};
+
+static u8 bw2regs_66hz[] __initdata = {
+	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x04,	0x17, 0x14,
+	0x18, 0xae,	0x19, 0x03,	0x1a, 0xa8,	0x1b, 0x24,
+	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
+	0x10, 0x20,	0
+};
+
+static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info,
+				int *linebytes)
+{
+	u8 status, mon;
+	u8 *p;
+
+	status = sbus_readb(&par->regs->status);
+	mon = status & BWTWO_SR_RES_MASK;
+	switch (status & BWTWO_SR_ID_MASK) {
+	case BWTWO_SR_ID_MONO_ECL:
+		if (mon == BWTWO_SR_1600_1280) {
+			p = bw2regs_1600;
+			info->var.xres = info->var.xres_virtual = 1600;
+			info->var.yres = info->var.yres_virtual = 1280;
+			*linebytes = 1600 / 8;
+		} else
+			p = bw2regs_ecl;
+		break;
+
+	case BWTWO_SR_ID_MONO:
+		p = bw2regs_analog;
+		break;
+
+	case BWTWO_SR_ID_MSYNC:
+		if (mon == BWTWO_SR_1152_900_76_A ||
+		    mon == BWTWO_SR_1152_900_76_B)
+			p = bw2regs_76hz;
+		else
+			p = bw2regs_66hz;
+		break;
+
+	case BWTWO_SR_ID_NOCONN:
+		return;
+
+	default:
+		prom_printf("bw2: can't handle SR %02x\n",
+			    status);
+		prom_halt();
+	}
+	for ( ; *p; p += 2) {
+		u8 *regp = &((u8 *)par->regs)[p[0]];
+		sbus_writeb(p[1], regp);
+	}
+}
+
+struct all_info {
+	struct fb_info info;
+	struct bw2_par par;
+	struct list_head list;
+};
+static LIST_HEAD(bw2_list);
+
+static void bw2_init_one(struct sbus_dev *sdev)
+{
+	struct all_info *all;
+	struct resource *resp;
+#ifdef CONFIG_SUN4
+	struct resource res;
+#endif
+	int linebytes;
+
+	all = kmalloc(sizeof(*all), GFP_KERNEL);
+	if (!all) {
+		printk(KERN_ERR "bw2: Cannot allocate memory.\n");
+		return;
+	}
+	memset(all, 0, sizeof(*all));
+
+	INIT_LIST_HEAD(&all->list);
+
+	spin_lock_init(&all->par.lock);
+	all->par.sdev = sdev;
+
+#ifdef CONFIG_SUN4
+	if (!sdev) {
+		all->par.physbase = sun4_bwtwo_physaddr;
+		res.start = sun4_bwtwo_physaddr;
+		res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1;
+		res.flags = IORESOURCE_IO;
+		resp = &res;
+		all->info.var.xres = all->info.var.xres_virtual = 1152;
+		all->info.var.yres = all->info.var.yres_virtual = 900;
+		all->info.bits_per_pixel = 1;
+		linebytes = 1152 / 8;
+	} else
+#else
+	{
+		if (!sdev)
+			BUG();
+		all->par.physbase = sdev->reg_addrs[0].phys_addr;
+		resp = &sdev->resource[0];
+		sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1);
+		linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
+					       all->info.var.xres);
+	}
+#endif
+
+	all->par.regs = (struct bw2_regs *)
+		sbus_ioremap(resp, BWTWO_REGISTER_OFFSET,
+			     sizeof(struct bw2_regs), "bw2 regs");
+
+	if (sdev && !prom_getbool(sdev->prom_node, "width"))
+		bw2_do_default_mode(&all->par, &all->info, &linebytes);
+
+	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+
+	all->info.node = NODEV;
+	all->info.flags = FBINFO_FLAG_DEFAULT;
+	all->info.fbops = &bw2_ops;
+#if defined(CONFIG_SPARC32)
+	if (sdev)
+		all->info.screen_base = (char *)
+			prom_getintdefault(sdev->prom_node, "address", 0);
+#endif
+	if (!all->info.screen_base)
+		all->info.screen_base = (char *)
+			sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram");
+	all->info.currcon = -1;
+	all->info.par = &all->par;
+
+	bw2_blank(0, &all->info);
+
+	bw2_set_par(&all->info);
+	bw2_init_fix(&all->info, linebytes);
+
+	if (register_framebuffer(&all->info) < 0) {
+		printk(KERN_ERR "bw2: Could not register framebuffer.\n");
+		kfree(all);
+		return;
+	}
+
+	list_add(&all->list, &bw2_list);
+
+	printk("bw2: bwtwo at %lx:%lx\n",
+	       (long) (sdev ? sdev->reg_addrs[0].which_io : 0),
+	       (long) all->par.physbase);
+}
+
+int __init bw2_init(void)
+{
+	struct sbus_bus *sbus;
+	struct sbus_dev *sdev;
+
+#ifdef CONFIG_SUN4
+	bw2_init_one(NULL);
+#endif
+	for_all_sbusdev(sdev, sbus) {
+		if (!strcmp(sdev->prom_name, "bwtwo"))
+			bw2_init_one(sdev);
+	}
+
+	return 0;
+}
+
+void __exit bw2_exit(void)
+{
+	struct list_head *pos, *tmp;
+
+	list_for_each_safe(pos, tmp, &bw2_list) {
+		struct all_info *all = list_entry(pos, typeof(*all), list);
+
+		unregister_framebuffer(&all->info);
+		kfree(all);
+	}
+}
+
+int __init
+bw2_setup(char *arg)
+{
+	/* No cmdline options yet... */
+	return 0;
+}
+
+#ifdef MODULE
+module_init(bw2_init);
+module_exit(bw2_exit);
+#endif
+
+MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets");
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/bwtwofb.c b/drivers/video/bwtwofb.c
--- a/drivers/video/bwtwofb.c	Tue Mar  4 19:30:03 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,269 +0,0 @@
-/* $Id: bwtwofb.c,v 1.15 2001/09/19 00:04:33 davem Exp $
- * bwtwofb.c: BWtwo frame buffer driver
- *
- * Copyright (C) 1998 Jakub Jelinek   (jj@ultra.linux.cz)
- * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- * Copyright (C) 1997 Eddie C. Dost   (ecd@skynet.be)
- * Copyright (C) 1998 Pavel Machek    (pavel@ucw.cz)
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-
-#include <video/sbusfb.h>
-#include <asm/io.h>
-#if !defined(__sparc_v9__) && !defined(__mc68000__)
-#include <asm/sun4paddr.h>
-#endif
-
-#include <video/fbcon-mfb.h>
-
-/* OBio addresses for the bwtwo registers */
-#define BWTWO_REGISTER_OFFSET 0x400000
-
-struct bw2_regs {
-	struct bt_regs		bt;
-	volatile u8		control;
-	volatile u8		status;
-	volatile u8		cursor_start;
-	volatile u8		cursor_end;
-	volatile u8		h_blank_start;
-	volatile u8		h_blank_end;
-	volatile u8		h_sync_start;
-	volatile u8		h_sync_end;
-	volatile u8		comp_sync_end;
-	volatile u8		v_blank_start_high;
-	volatile u8		v_blank_start_low;
-	volatile u8		v_blank_end;
-	volatile u8		v_sync_start;
-	volatile u8		v_sync_end;
-	volatile u8		xfer_holdoff_start;
-	volatile u8		xfer_holdoff_end;
-};
-
-/* Status Register Constants */
-#define BWTWO_SR_RES_MASK	0x70
-#define BWTWO_SR_1600_1280	0x50
-#define BWTWO_SR_1152_900_76_A	0x40
-#define BWTWO_SR_1152_900_76_B	0x60
-#define BWTWO_SR_ID_MASK	0x0f
-#define BWTWO_SR_ID_MONO	0x02
-#define BWTWO_SR_ID_MONO_ECL	0x03
-#define BWTWO_SR_ID_MSYNC	0x04
-#define BWTWO_SR_ID_NOCONN	0x0a
-
-/* Control Register Constants */
-#define BWTWO_CTL_ENABLE_INTS   0x80
-#define BWTWO_CTL_ENABLE_VIDEO  0x40
-#define BWTWO_CTL_ENABLE_TIMING 0x20
-#define BWTWO_CTL_ENABLE_CURCMP 0x10
-#define BWTWO_CTL_XTAL_MASK     0x0C
-#define BWTWO_CTL_DIVISOR_MASK  0x03
-
-/* Status Register Constants */
-#define BWTWO_STAT_PENDING_INT  0x80
-#define BWTWO_STAT_MSENSE_MASK  0x70
-#define BWTWO_STAT_ID_MASK      0x0f
-
-static struct sbus_mmap_map bw2_mmap_map[] = {
-	{ 0,			0,			SBUS_MMAP_FBSIZE(1) },
-	{ 0,			0,			0		    }
-};
-
-static int bw2_blank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u8 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readb(&fb->s.bw2.regs->control);
-	tmp &= ~BWTWO_CTL_ENABLE_VIDEO;
-	sbus_writeb(tmp, &fb->s.bw2.regs->control);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static int bw2_unblank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u8 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readb(&fb->s.bw2.regs->control);
-	tmp |= BWTWO_CTL_ENABLE_VIDEO;
-	sbus_writeb(tmp, &fb->s.bw2.regs->control);
-	spin_unlock_irqrestore(&fb->lock, flags);
- 	return 0;
-}
-
-static void bw2_margins (struct fb_info_sbusfb *fb, struct display *p,
-			 int x_margin, int y_margin)
-{
-	fb->info.screen_base += (y_margin - fb->y_margin) *
-		p->fb_info->fix.line_length + ((x_margin - fb->x_margin) >> 3);
-}
-
-static u8 bw2regs_1600[] __initdata = {
-	0x14, 0x8b,	0x15, 0x28,	0x16, 0x03,	0x17, 0x13,
-	0x18, 0x7b,	0x19, 0x05,	0x1a, 0x34,	0x1b, 0x2e,
-	0x1c, 0x00,	0x1d, 0x0a,	0x1e, 0xff,	0x1f, 0x01,
-	0x10, 0x21,	0
-};
-
-static u8 bw2regs_ecl[] __initdata = {
-	0x14, 0x65,	0x15, 0x1e,	0x16, 0x04,	0x17, 0x0c,
-	0x18, 0x5e,	0x19, 0x03,	0x1a, 0xa7,	0x1b, 0x23,
-	0x1c, 0x00,	0x1d, 0x08,	0x1e, 0xff,	0x1f, 0x01,
-	0x10, 0x20,	0
-};
-
-static u8 bw2regs_analog[] __initdata = {
-	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x03,	0x17, 0x13,
-	0x18, 0xb0,	0x19, 0x03,	0x1a, 0xa6,	0x1b, 0x22,
-	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
-	0x10, 0x20,	0
-};
-
-static u8 bw2regs_76hz[] __initdata = {
-	0x14, 0xb7,	0x15, 0x27,	0x16, 0x03,	0x17, 0x0f,
-	0x18, 0xae,	0x19, 0x03,	0x1a, 0xae,	0x1b, 0x2a,
-	0x1c, 0x01,	0x1d, 0x09,	0x1e, 0xff,	0x1f, 0x01,
-	0x10, 0x24,	0
-};
-
-static u8 bw2regs_66hz[] __initdata = {
-	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x04,	0x17, 0x14,
-	0x18, 0xae,	0x19, 0x03,	0x1a, 0xa8,	0x1b, 0x24,
-	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
-	0x10, 0x20,	0
-};
-
-static char idstring[60] __initdata = { 0 };
-
-char __init *bwtwofb_init(struct fb_info_sbusfb *fb)
-{
-	struct fb_fix_screeninfo *fix = &fb->info.fix;
-	struct display *disp = &fb->disp;
-	struct fbtype *type = &fb->type;
-#ifdef CONFIG_SUN4
-	unsigned long phys = sun4_bwtwo_physaddr;
-	struct resource res;
-#else
-	unsigned long phys = fb->sbdp->reg_addrs[0].phys_addr;
-#endif
-	struct resource *resp;
-	unsigned int vaddr;
-
-#ifndef FBCON_HAS_MFB
-	return NULL;
-#endif
-
-#ifdef CONFIG_SUN4
-	res.start = phys;
-	res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1;
-	res.flags = IORESOURCE_IO | (fb->iospace & 0xff);
-	resp = &res;
-#else
-	resp = &fb->sbdp->resource[0];
-#endif
-	if (!fb->s.bw2.regs) {
-		fb->s.bw2.regs = (struct bw2_regs *)
-			sbus_ioremap(resp, BWTWO_REGISTER_OFFSET,
-				     sizeof(struct bw2_regs), "bw2 regs");
-		if ((!ARCH_SUN4) && (!prom_getbool(fb->prom_node, "width"))) {
-			/* Ugh, broken PROM didn't initialize us.
-			 * Let's deal with this ourselves.
-			 */
-			u8 status, mon;
-			u8 *p;
-			int sizechange = 0;
-
-			status = sbus_readb(&fb->s.bw2.regs->status);
-			mon = status & BWTWO_SR_RES_MASK;
-			switch (status & BWTWO_SR_ID_MASK) {
-				case BWTWO_SR_ID_MONO_ECL:
-					if (mon == BWTWO_SR_1600_1280) {
-						p = bw2regs_1600;
-						fb->type.fb_width = 1600;
-						fb->type.fb_height = 1280;
-						sizechange = 1;
-					} else
-						p = bw2regs_ecl;
-					break;
-				case BWTWO_SR_ID_MONO:
-					p = bw2regs_analog;
-					break;
-				case BWTWO_SR_ID_MSYNC:
-					if (mon == BWTWO_SR_1152_900_76_A ||
-					    mon == BWTWO_SR_1152_900_76_B)
-						p = bw2regs_76hz;
-					else
-						p = bw2regs_66hz;
-					break;
-				case BWTWO_SR_ID_NOCONN:
-					return NULL;
-				default:
-#ifndef CONFIG_FB_SUN3
-					prom_printf("bw2: can't handle SR %02x\n",
-						    status);
-					prom_halt();
-#endif					
-					return NULL; /* fool gcc. */
-			}
-			for ( ; *p; p += 2) {
-				u8 *regp = &((u8 *)fb->s.bw2.regs)[p[0]];
-				sbus_writeb(p[1], regp);
-			}
-		}
-	}
-
-	strcpy(fb->info.modename, "BWtwo");
-	strcpy(fix->id, "BWtwo");
-	fix->line_length = fb->info.var.xres_virtual >> 3;
-	fix->accel = FB_ACCEL_SUN_BWTWO;
-	
-	disp->scrollmode = SCROLL_YREDRAW;
-	disp->inverse = 1;
-	if (!fb->info.screen_base) {
-		fb->info.screen_base = (char *)
-			sbus_ioremap(resp, 0, type->fb_size, "bw2 ram");
-	}
-	fb->info.screen_base += fix->line_length * fb->y_margin + (fb->x_margin >> 3);
-	fb->dispsw = fbcon_mfb;
-	fix->visual = FB_VISUAL_MONO01;
-
-#ifndef CONFIG_SUN4
-	fb->blank = bw2_blank;
-	fb->unblank = bw2_unblank;
-
-	prom_getproperty(fb->sbdp->prom_node, "address",
-			 (char *)&vaddr, sizeof(vaddr));
-	fb->physbase = __get_phys((unsigned long)vaddr);
-
-#endif
-	fb->margins = bw2_margins;
-	fb->mmap_map = bw2_mmap_map;
-
-#ifdef __sparc_v9__
-	sprintf(idstring, "bwtwo at %016lx", phys);
-#else	
-	sprintf(idstring, "bwtwo at %x.%08lx", fb->iospace, phys);
-#endif
-	
-	return idstring;
-}
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
--- a/drivers/video/cfbcopyarea.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/video/cfbcopyarea.c	Tue Mar  4 19:30:13 2003
@@ -65,14 +65,14 @@
 			// Single word
 			if (last)
 				first &= last;
-			FB_WRITEL((*src & first) | (FB_READL(dst) & ~first),
+			FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first),
 				  dst);
 		} else {
 			// Multiple destination words
 			// Leading bits
 			if (first) {
 				
-				FB_WRITEL((*src & first) | (FB_READL(dst) & 
+				FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & 
 							    ~first), dst);
 				dst++;
 				src++;
@@ -82,21 +82,21 @@
 			// Main chunk
 			n /= BITS_PER_LONG;
 			while (n >= 8) {
-				FB_WRITEL(*src++, dst++);
-				FB_WRITEL(*src++, dst++);
-				FB_WRITEL(*src++, dst++);
-				FB_WRITEL(*src++, dst++);
-				FB_WRITEL(*src++, dst++);
-				FB_WRITEL(*src++, dst++);
-				FB_WRITEL(*src++, dst++);
-				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
 				n -= 8;
 			}
 			while (n--)
-				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(FB_READL(src++), dst++);
 			// Trailing bits
 			if (last)
-				FB_WRITEL((*src & last) | (FB_READL(dst) & 
+				FB_WRITEL((FB_READL(src) & last) | (FB_READL(dst) & 
 							   ~last), dst);
 		}
 	} else {
@@ -111,22 +111,22 @@
 				first &= last;
 			if (shift > 0) {
 				// Single source word
-				FB_WRITEL(((*src >> right) & first) | 
+				FB_WRITEL(((FB_READL(src) >> right) & first) | 
 					  (FB_READL(dst) & ~first), dst);
 			} else if (src_idx+n <= BITS_PER_LONG) {
 				// Single source word
-				FB_WRITEL(((*src << left) & first) | 
+				FB_WRITEL(((FB_READL(src) << left) & first) | 
 					  (FB_READL(dst) & ~first), dst);
 			} else {
 				// 2 source words
-				d0 = *src++;
-				d1 = *src;
+				d0 = FB_READL(src++);
+				d1 = FB_READL(src);
 				FB_WRITEL(((d0<<left | d1>>right) & first) | 
 					  (FB_READL(dst) & ~first), dst);
 			}
 		} else {
 			// Multiple destination words
-			d0 = *src++;
+			d0 = FB_READL(src++);
 			// Leading bits
 			if (shift > 0) {
 				// Single source word
@@ -136,7 +136,7 @@
 				n -= BITS_PER_LONG-dst_idx;
 			} else {
 				// 2 source words
-				d1 = *src++;
+				d1 = FB_READL(src++);
 				FB_WRITEL(((d0<<left | d1>>right) & first) | 
 					  (FB_READL(dst) & ~first), dst);
 				d0 = d1;
@@ -148,22 +148,22 @@
 			m = n % BITS_PER_LONG;
 			n /= BITS_PER_LONG;
 			while (n >= 4) {
-				d1 = *src++;
+				d1 = FB_READL(src++);
 				FB_WRITEL(d0 << left | d1 >> right, dst++);
 				d0 = d1;
-				d1 = *src++;
+				d1 = FB_READL(src++);
 				FB_WRITEL(d0 << left | d1 >> right, dst++);
 				d0 = d1;
-				d1 = *src++;
+				d1 = FB_READL(src++);
 				FB_WRITEL(d0 << left | d1 >> right, dst++);
 				d0 = d1;
-				d1 = *src++;
+				d1 = FB_READL(src++);
 				FB_WRITEL(d0 << left | d1 >> right, dst++);
 				d0 = d1;
 				n -= 4;
 			}
 			while (n--) {
-				d1 = *src++;
+				d1 = FB_READL(src++);
 				FB_WRITEL(d0 << left | d1 >> right, dst++);
 				d0 = d1;
 			}
@@ -177,7 +177,7 @@
 						  dst);
 				} else {
 					// 2 source words
-					d1 = *src;
+					d1 = FB_READL(src);
 					FB_WRITEL(((d0<<left | d1>>right) & 
 						   last) | (FB_READL(dst) & 
 							    ~last), dst);
@@ -220,13 +220,13 @@
 			// Single word
 			if (last)
 				first &= last;
-			FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), 
+			FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first), 
 				  dst);
 		} else {
 			// Multiple destination words
 			// Leading bits
 			if (first) {
-				FB_WRITEL((*src & first) | (FB_READL(dst) & 
+				FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & 
 							    ~first), dst);
 				dst--;
 				src--;
@@ -236,22 +236,22 @@
 			// Main chunk
 			n /= BITS_PER_LONG;
 			while (n >= 8) {
-				FB_WRITEL(*src--, dst--);
-				FB_WRITEL(*src--, dst--);
-				FB_WRITEL(*src--, dst--);
-				FB_WRITEL(*src--, dst--);
-				FB_WRITEL(*src--, dst--);
-				FB_WRITEL(*src--, dst--);
-				FB_WRITEL(*src--, dst--);
-				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
 				n -= 8;
 			}
 			while (n--)
-				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(FB_READL(src--), dst--);
 			
 			// Trailing bits
 			if (last)
-				FB_WRITEL((*src & last) | (FB_READL(dst) & 
+				FB_WRITEL((FB_READL(src) & last) | (FB_READL(dst) & 
 							   ~last), dst);
 		}
 	} else {
@@ -266,22 +266,22 @@
 				first &= last;
 			if (shift < 0) {
 				// Single source word
-				FB_WRITEL((*src << left & first) | 
+				FB_WRITEL((FB_READL(src) << left & first) | 
 					  (FB_READL(dst) & ~first), dst);
 			} else if (1+(unsigned long)src_idx >= n) {
 				// Single source word
-				FB_WRITEL(((*src >> right) & first) | 
+				FB_WRITEL(((FB_READL(src) >> right) & first) | 
 					  (FB_READL(dst) & ~first), dst);
 			} else {
 				// 2 source words
-				d0 = *src--;
-				d1 = *src;
+				d0 = FB_READL(src--);
+				d1 = FB_READL(src);
 				FB_WRITEL(((d0>>right | d1<<left) & first) | 
 					  (FB_READL(dst) & ~first), dst);
 			}
 		} else {
 			// Multiple destination words
-			d0 = *src--;
+			d0 = FB_READL(src--);
 			// Leading bits
 			if (shift < 0) {
 				// Single source word
@@ -291,7 +291,7 @@
 				n -= dst_idx+1;
 			} else {
 				// 2 source words
-				d1 = *src--;
+				d1 = FB_READL(src--);
 				FB_WRITEL(((d0>>right | d1<<left) & first) | 
 					  (FB_READL(dst) & ~first), dst);
 				d0 = d1;
@@ -303,22 +303,22 @@
 			m = n % BITS_PER_LONG;
 			n /= BITS_PER_LONG;
 			while (n >= 4) {
-				d1 = *src--;
+				d1 = FB_READL(src--);
 				FB_WRITEL(d0 >> right | d1 << left, dst--);
 				d0 = d1;
-				d1 = *src--;
+				d1 = FB_READL(src--);
 				FB_WRITEL(d0 >> right | d1 << left, dst--);
 				d0 = d1;
-				d1 = *src--;
+				d1 = FB_READL(src--);
 				FB_WRITEL(d0 >> right | d1 << left, dst--);
 				d0 = d1;
-				d1 = *src--;
+				d1 = FB_READL(src--);
 				FB_WRITEL(d0 >> right | d1 << left, dst--);
 				d0 = d1;
 				n -= 4;
 			}
 			while (n--) {
-				d1 = *src--;
+				d1 = FB_READL(src--);
 				FB_WRITEL(d0 >> right | d1 << left, dst--);
 				d0 = d1;
 			}
@@ -332,7 +332,7 @@
 						  dst);
 				} else {
 					// 2 source words
-					d1 = *src;
+					d1 = FB_READL(src);
 					FB_WRITEL(((d0>>right | d1<<left) & 
 						   last) | (FB_READL(dst) & 
 							    ~last), dst);
@@ -410,8 +410,8 @@
 			dst_idx &= (BYTES_PER_LONG-1);
 			src += src_idx >> SHIFT_PER_LONG;
 			src_idx &= (BYTES_PER_LONG-1);
-			bitcpy_rev((unsigned long*)dst, dst_idx, 
-				   (unsigned long *)src, src_idx, 
+			bitcpy_rev(dst, dst_idx,
+				   src, src_idx, 
 				   area->width*p->var.bits_per_pixel);
 		}	
 	} else {
@@ -420,8 +420,8 @@
 			dst_idx &= (BYTES_PER_LONG-1);
 			src += src_idx >> SHIFT_PER_LONG;
 			src_idx &= (BYTES_PER_LONG-1);
-			bitcpy((unsigned long*)dst, dst_idx, 
-			       (unsigned long *)src, src_idx, 
+			bitcpy(dst, dst_idx, 
+			       src, src_idx, 
 			       area->width*p->var.bits_per_pixel);
 			dst_idx += next_line*8;
 			src_idx += next_line*8;
diff -Nru a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
--- a/drivers/video/cfbimgblt.c	Tue Mar  4 19:30:09 2003
+++ b/drivers/video/cfbimgblt.c	Tue Mar  4 19:30:09 2003
@@ -73,16 +73,11 @@
 	0x00000000, 0xffffffff
 };
 
-#if BITS_PER_LONG == 32
 #define FB_WRITEL fb_writel
 #define FB_READL  fb_readl
-#else
-#define FB_WRITEL fb_writeq
-#define FB_READL  fb_readq
-#endif 
 
 #if defined (__BIG_ENDIAN)
-#define LEFT_POS(bpp)          (BITS_PER_LONG - bpp)
+#define LEFT_POS(bpp)          (32 - bpp)
 #define NEXT_POS(pos, bpp)     ((pos) -= (bpp))
 #define SHIFT_HIGH(val, bits)  ((val) >> (bits))
 #define SHIFT_LOW(val, bits)   ((val) << (bits))
@@ -94,26 +89,25 @@
 #endif
 
 static inline void color_imageblit(struct fb_image *image, struct fb_info *p, 
-				   u8 *dst1, unsigned long start_index,
-				   unsigned long pitch_index)
+				   u8 *dst1, u32 start_index,
+				   u32 pitch_index)
 {
 	/* Draw the penguin */
-	unsigned long *dst, *dst2, color = 0, val, shift;
+	u32 *dst, *dst2, color = 0, val, shift;
 	int i, n, bpp = p->var.bits_per_pixel;
-	unsigned long null_bits = BITS_PER_LONG - bpp;
+	u32 null_bits = 32 - bpp;
 	u32 *palette = (u32 *) p->pseudo_palette;
 	u8 *src = image->data;
 
-	dst2 = (unsigned long *) dst1;
+	dst2 = (u32 *) dst1;
 	for (i = image->height; i--; ) {
 		n = image->width;
-		dst = (unsigned long *) dst1;
+		dst = (u32 *) dst1;
 		shift = 0;
 		val = 0;
 		
 		if (start_index) {
-			unsigned long start_mask = ~(SHIFT_HIGH(~0UL,
-								start_index));
+			u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
 			val = FB_READL(dst) & start_mask;
 			shift = start_index;
 		}
@@ -129,14 +123,14 @@
 				FB_WRITEL(val, dst++);
 	
 				val = (shift == null_bits) ? 0 : 
-					SHIFT_LOW(color,BITS_PER_LONG - shift);
+					SHIFT_LOW(color, 32 - shift);
 			}
 			shift += bpp;
-			shift &= (BITS_PER_LONG - 1);
+			shift &= (32 - 1);
 			src++;
 		}
 		if (shift) {
-			unsigned long  end_mask = SHIFT_HIGH(~0UL, shift);
+			u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
 
 			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
 		}
@@ -144,40 +138,39 @@
 		if (pitch_index) {
 			dst2 += p->fix.line_length;
 			dst1 = (char *) dst2;
-			(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
+			(unsigned long) dst1 &= ~(sizeof(u32) - 1);
 
 			start_index += pitch_index;
-			start_index &= BITS_PER_LONG - 1;
+			start_index &= 32 - 1;
 		}
 	}
 }
 
 static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, 
-				  u8 *dst1, unsigned long fgcolor,
-				  unsigned long bgcolor, 
-				  unsigned long start_index,
-				  unsigned long pitch_index)
+				  u8 *dst1, u32 fgcolor,
+				  u32 bgcolor, 
+				  u32 start_index,
+				  u32 pitch_index)
 {
-	unsigned long shift, color = 0, bpp = p->var.bits_per_pixel;
-	unsigned long *dst, *dst2, val, pitch = p->fix.line_length;
-	unsigned long null_bits = BITS_PER_LONG - bpp;
-	unsigned long spitch = (image->width+7)/8;
+	u32 shift, color = 0, bpp = p->var.bits_per_pixel;
+	u32 *dst, *dst2, val, pitch = p->fix.line_length;
+	u32 null_bits = 32 - bpp;
+	u32 spitch = (image->width+7)/8;
 	u8 *src = image->data, *s;
-	unsigned long i, j, l;
+	u32 i, j, l;
 	
-	dst2 = (unsigned long *) dst1;
+	dst2 = (u32 *) dst1;
 
 	for (i = image->height; i--; ) {
 		shift = val = 0;
 		l = 8;
 		j = image->width;
-		dst = (unsigned long *) dst1;
+		dst = (u32 *) dst1;
 		s = src;
 
 		/* write leading bits */
 		if (start_index) {
-			unsigned long start_mask = ~(SHIFT_HIGH(~0UL,
-								start_index));
+			u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
 			val = FB_READL(dst) & start_mask;
 			shift = start_index;
 		}
@@ -192,16 +185,16 @@
 			if (shift >= null_bits) {
 				FB_WRITEL(val, dst++);
 				val = (shift == null_bits) ? 0 :
-					 SHIFT_LOW(color,BITS_PER_LONG - shift);
+					 SHIFT_LOW(color,32 - shift);
 			}
 			shift += bpp;
-			shift &= (BITS_PER_LONG - 1);
+			shift &= (32 - 1);
 			if (!l) { l = 8; s++; };
 		}
 
 		/* write trailing bits */
  		if (shift) {
-			unsigned long end_mask = SHIFT_HIGH(~0UL, shift);
+			u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
 
 			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
 		}
@@ -211,10 +204,10 @@
 		if (pitch_index) {
 			dst2 += pitch;
 			dst1 = (char *) dst2;
-			(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
+			(unsigned long) dst1 &= ~(sizeof(u32) - 1);
 
 			start_index += pitch_index;
-			start_index &= BITS_PER_LONG - 1;
+			start_index &= 32 - 1;
 		}
 		
 	}
@@ -229,14 +222,14 @@
  *           beginning and end of a scanline is dword aligned
  */
 static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, 
-				  u8 *dst1, unsigned long fgcolor, 
-				  unsigned long bgcolor) 
+				  u8 *dst1, u32 fgcolor, 
+				  u32 bgcolor) 
 {
-	unsigned long fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
-	unsigned long ppw = BITS_PER_LONG/bpp, spitch = (image->width + 7)/8;
-	unsigned long bit_mask, end_mask, eorx, shift;
+	u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
+	u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
+	u32 bit_mask, end_mask, eorx, shift;
 	char *s = image->data, *src;
-	unsigned long *dst;
+	u32 *dst;
 	u32 *tab = NULL;
 	int i, j, k;
 		
@@ -264,7 +257,7 @@
 	k = image->width/ppw;
 
 	for (i = image->height; i--; ) {
-		dst = (unsigned long *) dst1, shift = 8; src = s;
+		dst = (u32 *) dst1, shift = 8; src = s;
 		
 		for (j = k; j--; ) {
 			shift -= ppw;
@@ -279,8 +272,8 @@
 	
 void cfb_imageblit(struct fb_info *p, struct fb_image *image)
 {
-	unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
-	unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel;
+	u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
+	u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
 	int x2, y2, vxres, vyres;
 	u8 *dst1;
 
@@ -304,7 +297,7 @@
 	image->height = y2 - image->dy;
 
 	bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp);
-	start_index = bitstart & (BITS_PER_LONG - 1);
+	start_index = bitstart & (32 - 1);
 	pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
 
 	bitstart /= 8;
@@ -324,8 +317,8 @@
 			bgcolor = image->bg_color;
 		}	
 		
-		if (BITS_PER_LONG % bpp == 0 && !start_index && !pitch_index && 
-		    ((image->width & (BITS_PER_LONG/bpp-1)) == 0) &&
+		if (32 % bpp == 0 && !start_index && !pitch_index && 
+		    ((image->width & (32/bpp-1)) == 0) &&
 		    bpp >= 8 && bpp <= 32) 			
 			fast_imageblit(image, p, dst1, fgcolor, bgcolor);
 		else 
diff -Nru a/drivers/video/cg14.c b/drivers/video/cg14.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/cg14.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,597 @@
+/* cg14.c: CGFOURTEEN frame buffer driver
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ *
+ * Driver layout based loosely on tgafb.c, see that file for credits.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/fbio.h>
+
+#include "sbuslib.h"
+
+/*
+ * Local functions.
+ */
+
+static int cg14_check_var(struct fb_var_screeninfo *, struct fb_info *);
+static int cg14_set_par(struct fb_info *);
+static int cg14_setcolreg(unsigned, unsigned, unsigned, unsigned,
+			 unsigned, struct fb_info *);
+
+static int cg14_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+static int cg14_ioctl(struct inode *, struct file *, unsigned int,
+		      unsigned long, struct fb_info *);
+
+/*
+ *  Frame buffer operations
+ */
+
+static struct fb_ops cg14_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= cg14_check_var,
+	.fb_set_par		= cg14_set_par,
+	.fb_setcolreg		= cg14_setcolreg,
+	.fb_fillrect		= cfb_fillrect,
+	.fb_copyarea		= cfb_copyarea,
+	.fb_imageblit		= cfb_imageblit,
+	.fb_mmap		= cg14_mmap,
+	.fb_ioctl		= cg14_ioctl,
+	.fb_cursor		= soft_cursor,
+};
+
+#define CG14_MCR_INTENABLE_SHIFT	7
+#define CG14_MCR_INTENABLE_MASK		0x80
+#define CG14_MCR_VIDENABLE_SHIFT	6
+#define CG14_MCR_VIDENABLE_MASK		0x40
+#define CG14_MCR_PIXMODE_SHIFT		4
+#define CG14_MCR_PIXMODE_MASK		0x30
+#define CG14_MCR_TMR_SHIFT		2
+#define CG14_MCR_TMR_MASK		0x0c
+#define CG14_MCR_TMENABLE_SHIFT		1
+#define CG14_MCR_TMENABLE_MASK		0x02
+#define CG14_MCR_RESET_SHIFT		0
+#define CG14_MCR_RESET_MASK		0x01
+#define CG14_REV_REVISION_SHIFT		4
+#define CG14_REV_REVISION_MASK		0xf0
+#define CG14_REV_IMPL_SHIFT		0
+#define CG14_REV_IMPL_MASK		0x0f
+#define CG14_VBR_FRAMEBASE_SHIFT	12
+#define CG14_VBR_FRAMEBASE_MASK		0x00fff000
+#define CG14_VMCR1_SETUP_SHIFT		0
+#define CG14_VMCR1_SETUP_MASK		0x000001ff
+#define CG14_VMCR1_VCONFIG_SHIFT	9
+#define CG14_VMCR1_VCONFIG_MASK		0x00000e00
+#define CG14_VMCR2_REFRESH_SHIFT	0
+#define CG14_VMCR2_REFRESH_MASK		0x00000001
+#define CG14_VMCR2_TESTROWCNT_SHIFT	1
+#define CG14_VMCR2_TESTROWCNT_MASK	0x00000002
+#define CG14_VMCR2_FBCONFIG_SHIFT	2
+#define CG14_VMCR2_FBCONFIG_MASK	0x0000000c
+#define CG14_VCR_REFRESHREQ_SHIFT	0
+#define CG14_VCR_REFRESHREQ_MASK	0x000003ff
+#define CG14_VCR1_REFRESHENA_SHIFT	10
+#define CG14_VCR1_REFRESHENA_MASK	0x00000400
+#define CG14_VCA_CAD_SHIFT		0
+#define CG14_VCA_CAD_MASK		0x000003ff
+#define CG14_VCA_VERS_SHIFT		10
+#define CG14_VCA_VERS_MASK		0x00000c00
+#define CG14_VCA_RAMSPEED_SHIFT		12
+#define CG14_VCA_RAMSPEED_MASK		0x00001000
+#define CG14_VCA_8MB_SHIFT		13
+#define CG14_VCA_8MB_MASK		0x00002000
+
+#define CG14_MCR_PIXMODE_8		0
+#define CG14_MCR_PIXMODE_16		2
+#define CG14_MCR_PIXMODE_32		3
+
+struct cg14_regs{
+	volatile u8 mcr;	/* Master Control Reg */
+	volatile u8 ppr;	/* Packed Pixel Reg */
+	volatile u8 tms[2];	/* Test Mode Status Regs */
+	volatile u8 msr;	/* Master Status Reg */
+	volatile u8 fsr;	/* Fault Status Reg */
+	volatile u8 rev;	/* Revision & Impl */
+	volatile u8 ccr;	/* Clock Control Reg */
+	volatile u32 tmr;	/* Test Mode Read Back */
+	volatile u8 mod;	/* Monitor Operation Data Reg */
+	volatile u8 acr;	/* Aux Control */
+	u8 xxx0[6];
+	volatile u16 hct;	/* Hor Counter */
+	volatile u16 vct;	/* Vert Counter */
+	volatile u16 hbs;	/* Hor Blank Start */
+	volatile u16 hbc;	/* Hor Blank Clear */
+	volatile u16 hss;	/* Hor Sync Start */
+	volatile u16 hsc;	/* Hor Sync Clear */
+	volatile u16 csc;	/* Composite Sync Clear */
+	volatile u16 vbs;	/* Vert Blank Start */
+	volatile u16 vbc;	/* Vert Blank Clear */
+	volatile u16 vss;	/* Vert Sync Start */
+	volatile u16 vsc;	/* Vert Sync Clear */
+	volatile u16 xcs;
+	volatile u16 xcc;
+	volatile u16 fsa;	/* Fault Status Address */
+	volatile u16 adr;	/* Address Registers */
+	u8 xxx1[0xce];
+	volatile u8 pcg[0x100]; /* Pixel Clock Generator */
+	volatile u32 vbr;	/* Frame Base Row */
+	volatile u32 vmcr;	/* VBC Master Control */
+	volatile u32 vcr;	/* VBC refresh */
+	volatile u32 vca;	/* VBC Config */
+};
+
+#define CG14_CCR_ENABLE	0x04
+#define CG14_CCR_SELECT 0x02	/* HW/Full screen */
+
+struct cg14_cursor {
+	volatile u32 cpl0[32];	/* Enable plane 0 */
+	volatile u32 cpl1[32];  /* Color selection plane */
+	volatile u8 ccr;	/* Cursor Control Reg */
+	u8 xxx0[3];
+	volatile u16 cursx;	/* Cursor x,y position */
+	volatile u16 cursy;	/* Cursor x,y position */
+	volatile u32 color0;
+	volatile u32 color1;
+	u32 xxx1[0x1bc];
+	volatile u32 cpl0i[32];	/* Enable plane 0 autoinc */
+	volatile u32 cpl1i[32]; /* Color selection autoinc */
+};
+
+struct cg14_dac {
+	volatile u8 addr;	/* Address Register */
+	u8 xxx0[255];
+	volatile u8 glut;	/* Gamma table */
+	u8 xxx1[255];
+	volatile u8 select;	/* Register Select */
+	u8 xxx2[255];
+	volatile u8 mode;	/* Mode Register */
+};
+
+struct cg14_xlut{
+	volatile u8 x_xlut [256];
+	volatile u8 x_xlutd [256];
+	u8 xxx0[0x600];
+	volatile u8 x_xlut_inc [256];
+	volatile u8 x_xlutd_inc [256];
+};
+
+/* Color look up table (clut) */
+/* Each one of these arrays hold the color lookup table (for 256
+ * colors) for each MDI page (I assume then there should be 4 MDI
+ * pages, I still wonder what they are.  I have seen NeXTStep split
+ * the screen in four parts, while operating in 24 bits mode.  Each
+ * integer holds 4 values: alpha value (transparency channel, thanks
+ * go to John Stone (johns@umr.edu) from OpenBSD), red, green and blue
+ *
+ * I currently use the clut instead of the Xlut
+ */
+struct cg14_clut {
+	u32 c_clut [256];
+	u32 c_clutd [256];    /* i wonder what the 'd' is for */
+	u32 c_clut_inc [256];
+	u32 c_clutd_inc [256];
+};
+
+#define CG14_MMAP_ENTRIES	16
+
+struct cg14_par {
+	spinlock_t		lock;
+	struct cg14_regs	*regs;
+	struct cg14_clut	*clut;
+	struct cg14_cursor	*cursor;
+
+	u32			flags;
+#define CG14_FLAG_BLANKED	0x00000001
+
+	unsigned long		physbase;
+	unsigned long		iospace;
+	unsigned long		fbsize;
+
+	struct sbus_mmap_map	mmap_map[CG14_MMAP_ENTRIES];
+
+	int			mode;
+	int			ramsize;
+	struct sbus_dev		*sdev;
+	struct list_head	list;
+};
+
+static void __cg14_reset(struct cg14_par *par)
+{
+	struct cg14_regs *regs = par->regs;
+	u8 val;
+
+	val = sbus_readb(&regs->mcr);
+	val &= ~(CG14_MCR_PIXMODE_MASK);
+	sbus_writeb(val, &regs->mcr);
+}
+
+/**
+ *      cg14_check_var - Optional function.  Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int cg14_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->bits_per_pixel != 8)
+		return -EINVAL;
+
+	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
+		return -EINVAL;
+	if (var->nonstd)
+		return -EINVAL;
+	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+
+	if (var->xres != info->var.xres || var->yres != info->var.yres)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ *      cg14_set_par - Optional function.  Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+cg14_set_par(struct fb_info *info)
+{
+	return 0;
+}
+
+/**
+ *      cg14_setcolreg - Optional function. Sets a color register.
+ *      @regno: boolean, 0 copy local, 1 get_user() function
+ *      @red: frame buffer colormap structure
+ *      @green: The green value which can be up to 16 bits wide
+ *      @blue:  The blue value which can be up to 16 bits wide.
+ *      @transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ */
+static int cg14_setcolreg(unsigned regno,
+			  unsigned red, unsigned green, unsigned blue,
+			  unsigned transp, struct fb_info *info)
+{
+	struct cg14_par *par = (struct cg14_par *) info->par;
+	struct cg14_clut *clut = par->clut;
+	unsigned long flags;
+	u32 val;
+
+	if (regno >= 256)
+		return 1;
+
+	val = (red | (green << 8) | (blue << 16));
+
+	spin_lock_irqsave(&par->lock, flags);
+	sbus_writel(val, &clut->c_clut[regno]);
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+static int cg14_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	struct cg14_par *par = (struct cg14_par *) info->par;
+
+	return sbusfb_mmap_helper(par->mmap_map,
+				  par->physbase, par->fbsize,
+				  par->iospace, vma);
+}
+
+static int cg14_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		      unsigned long arg, struct fb_info *info)
+{
+	struct cg14_par *par = (struct cg14_par *) info->par;
+	struct cg14_regs *regs = par->regs;
+	struct mdi_cfginfo kmdi, *mdii;
+	unsigned long flags;
+	int cur_mode, mode, ret = 0;
+
+	switch (cmd) {
+	case MDI_RESET:
+		spin_lock_irqsave(&par->lock, flags);
+		__cg14_reset(par);
+		spin_unlock_irqrestore(&par->lock, flags);
+		break;
+
+	case MDI_GET_CFGINFO:
+		memset(&kmdi, 0, sizeof(kmdi));
+
+		spin_lock_irqsave(&par->lock, flags);
+		kmdi.mdi_type = FBTYPE_MDICOLOR;
+		kmdi.mdi_height = info->var.yres;
+		kmdi.mdi_width = info->var.xres;
+		kmdi.mdi_mode = par->mode;
+		kmdi.mdi_pixfreq = 72; /* FIXME */
+		kmdi.mdi_size = par->ramsize;
+		spin_unlock_irqrestore(&par->lock, flags);
+
+		mdii = (struct mdi_cfginfo *) arg;
+		if (copy_to_user(mdii, &kmdi, sizeof(kmdi)))
+			ret = -EFAULT;
+		break;
+
+	case MDI_SET_PIXELMODE:
+		if (get_user(mode, (int *) arg)) {
+			ret = -EFAULT;
+			break;
+		}
+
+		spin_lock_irqsave(&par->lock, flags);
+		cur_mode = sbus_readb(&regs->mcr);
+		cur_mode &= ~CG14_MCR_PIXMODE_MASK;
+		switch(mode) {
+		case MDI_32_PIX:
+			cur_mode |= (CG14_MCR_PIXMODE_32 <<
+				     CG14_MCR_PIXMODE_SHIFT);
+			break;
+
+		case MDI_16_PIX:
+			cur_mode |= 0x20;
+			break;
+
+		case MDI_8_PIX:
+			break;
+
+		default:
+			ret = -ENOSYS;
+			break;
+		};
+		if (!ret) {
+			sbus_writeb(cur_mode, &regs->mcr);
+			par->mode = mode;
+		}
+		spin_unlock_irqrestore(&par->lock, flags);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+/*
+ *  Initialisation
+ */
+
+static void cg14_init_fix(struct fb_info *info, int linebytes)
+{
+	struct cg14_par *par = (struct cg14_par *)info->par;
+
+	strncpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id) - 1);
+	info->fix.id[sizeof(info->fix.id)-1] = 0;
+
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	info->fix.line_length = linebytes;
+
+	info->fix.accel = FB_ACCEL_SUN_CG14;
+}
+
+static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = {
+	{ CG14_REGS,		0x80000000,		0x1000		    },
+	{ CG14_XLUT,		0x80003000,		0x1000		    },
+	{ CG14_CLUT1,		0x80004000,		0x1000		    },
+	{ CG14_CLUT2,		0x80005000,		0x1000		    },
+	{ CG14_CLUT3,		0x80006000,		0x1000		    },
+	{ CG3_MMAP_OFFSET - 
+	  0x7000,		0x80000000,		0x7000		    },
+	{ CG3_MMAP_OFFSET,	0x00000000,		SBUS_MMAP_FBSIZE(1) },
+	{ MDI_CURSOR_MAP,	0x80001000,		0x1000		    },
+	{ MDI_CHUNKY_BGR_MAP,	0x01000000,		0x400000	    },
+	{ MDI_PLANAR_X16_MAP,	0x02000000,		0x200000	    },
+	{ MDI_PLANAR_C16_MAP,	0x02800000,		0x200000	    },
+	{ MDI_PLANAR_X32_MAP,	0x03000000,		0x100000	    },
+	{ MDI_PLANAR_B32_MAP,	0x03400000,		0x100000	    },
+	{ MDI_PLANAR_G32_MAP,	0x03800000,		0x100000	    },
+	{ MDI_PLANAR_R32_MAP,	0x03c00000,		0x100000	    },
+	{ 0,			0,			0		    }
+};
+
+struct all_info {
+	struct fb_info info;
+	struct cg14_par par;
+	struct list_head list;
+};
+static LIST_HEAD(cg14_list);
+
+static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node)
+{
+	struct all_info *all;
+	unsigned long phys, rphys;
+	u32 bases[6];
+	int is_8mb, linebytes, i;
+
+	if (!sdev) {
+		prom_getproperty(node, "address",
+				 (char *) &bases[0], sizeof(bases));
+		if (!bases[0]) {
+			printk(KERN_ERR "cg14: Device is not mapped.\n");
+			return;
+		}
+		if (__get_iospace(bases[0]) != __get_iospace(bases[1])) {
+			printk(KERN_ERR "cg14: I/O spaces don't match.\n");
+			return;
+		}
+	}
+
+	all = kmalloc(sizeof(*all), GFP_KERNEL);
+	if (!all) {
+		printk(KERN_ERR "cg14: Cannot allocate memory.\n");
+		return;
+	}
+	memset(all, 0, sizeof(*all));
+
+	INIT_LIST_HEAD(&all->list);
+
+	spin_lock_init(&all->par.lock);
+
+	sbusfb_fill_var(&all->info.var, node, 8);
+
+	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
+				       all->info.var.xres);
+	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+
+	all->par.sdev = sdev;
+	if (sdev) {
+		rphys = sdev->reg_addrs[0].phys_addr;
+		all->par.physbase = phys = sdev->reg_addrs[1].phys_addr;
+		all->par.iospace = sdev->reg_addrs[0].which_io;
+
+		all->par.regs = (struct cg14_regs *)
+			sbus_ioremap(&sdev->resource[0], 0,
+				     sizeof(struct cg14_regs),
+				     "cg14 regs");
+		all->par.clut = (struct cg14_clut *)
+			sbus_ioremap(&sdev->resource[0], CG14_CLUT1,
+				     sizeof(struct cg14_clut),
+				     "cg14 clut");
+		all->par.cursor = (struct cg14_cursor *)
+			sbus_ioremap(&sdev->resource[0], CG14_CURSORREGS,
+				     sizeof(struct cg14_cursor),
+				     "cg14 cursor");
+		all->info.screen_base = (char *)
+			sbus_ioremap(&sdev->resource[1], 0,
+				     all->par.fbsize, "cg14 ram");
+	} else {
+		rphys = __get_phys(bases[0]);
+		all->par.physbase = phys = __get_phys(bases[1]);
+		all->par.iospace = __get_iospace(bases[0]);
+		all->par.regs = (struct cg14_regs *)(unsigned long)bases[0];
+		all->par.clut = (struct cg14_clut *)((unsigned long)bases[0] +
+						     CG14_CLUT1);
+		all->par.cursor =
+			(struct cg14_cursor *)((unsigned long)bases[0] +
+					       CG14_CURSORREGS);
+
+		all->info.screen_base = (char *)(unsigned long)bases[1];
+	}
+
+	prom_getproperty(node, "reg", (char *) &bases[0], sizeof(bases));
+	is_8mb = (bases[5] == 0x800000);
+
+	if (sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)) {
+		extern void __cg14_mmap_sized_wrongly(void);
+
+		__cg14_mmap_sized_wrongly();
+	}
+		
+	memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map));
+	for (i = 0; i < CG14_MMAP_ENTRIES; i++) {
+		struct sbus_mmap_map *map = &all->par.mmap_map[i];
+
+		if (!map->size)
+			break;
+		if (map->poff & 0x80000000)
+			map->poff = (map->poff & 0x7fffffff) + rphys - phys;
+		if (is_8mb &&
+		    map->size >= 0x100000 &&
+		    map->size <= 0x400000)
+			map->size *= 2;
+	}
+
+	all->par.mode = MDI_8_PIX;
+	all->par.ramsize = (is_8mb ? 0x800000 : 0x400000);
+
+	all->info.node = NODEV;
+	all->info.flags = FBINFO_FLAG_DEFAULT;
+	all->info.fbops = &cg14_ops;
+	all->info.currcon = -1;
+	all->info.par = &all->par;
+
+	__cg14_reset(&all->par);
+
+	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+		printk(KERN_ERR "cg14: Could not allocate color map.\n");
+		kfree(all);
+		return;
+	}
+
+	cg14_set_par(&all->info);
+	cg14_init_fix(&all->info, linebytes);
+
+	if (register_framebuffer(&all->info) < 0) {
+		printk(KERN_ERR "cg14: Could not register framebuffer.\n");
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+		return;
+	}
+
+	list_add(&all->list, &cg14_list);
+
+	printk("cg14: cgfourteen at %lx:%lx\n",
+	       all->par.physbase, all->par.iospace);
+
+}
+
+int __init cg14_init(void)
+{
+	struct sbus_bus *sbus;
+	struct sbus_dev *sdev;
+
+#ifdef CONFIG_SPARC32
+	{
+		int root, node;
+
+		root = prom_getchild(prom_root_node);
+		root = prom_searchsiblings(root, "obio");
+		if (root) {
+			node = prom_searchsiblings(prom_getchild(root),
+						   "cgfourteen");
+			if (node)
+				cg14_init_one(NULL, node, root);
+		}
+	}
+#endif
+	for_all_sbusdev(sdev, sbus) {
+		if (!strcmp(sdev->prom_name, "cgfourteen"))
+			cg14_init_one(sdev, sdev->prom_node, sbus->prom_node);
+	}
+
+	return 0;
+}
+
+void __exit cg14_exit(void)
+{
+	struct list_head *pos, *tmp;
+
+	list_for_each_safe(pos, tmp, &cg14_list) {
+		struct all_info *all = list_entry(pos, typeof(*all), list);
+
+		unregister_framebuffer(&all->info);
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+	}
+}
+
+int __init
+cg14_setup(char *arg)
+{
+	/* No cmdline options yet... */
+	return 0;
+}
+
+#ifdef MODULE
+module_init(cg14_init);
+module_exit(cg14_exit);
+#endif
+
+MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets");
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/cg3.c b/drivers/video/cg3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/cg3.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,507 @@
+/* cg3.c: CGTHREE frame buffer driver
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
+ *
+ * Driver layout based loosely on tgafb.c, see that file for credits.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/fbio.h>
+
+#include "sbuslib.h"
+
+/*
+ * Local functions.
+ */
+
+static int cg3_check_var(struct fb_var_screeninfo *, struct fb_info *);
+static int cg3_set_par(struct fb_info *);
+static int cg3_setcolreg(unsigned, unsigned, unsigned, unsigned,
+			 unsigned, struct fb_info *);
+static int cg3_blank(int, struct fb_info *);
+
+static int cg3_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+
+/*
+ *  Frame buffer operations
+ */
+
+static struct fb_ops cg3_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= cg3_check_var,
+	.fb_set_par		= cg3_set_par,
+	.fb_setcolreg		= cg3_setcolreg,
+	.fb_blank		= cg3_blank,
+	.fb_fillrect		= cfb_fillrect,
+	.fb_copyarea		= cfb_copyarea,
+	.fb_imageblit		= cfb_imageblit,
+	.fb_mmap		= cg3_mmap,
+	.fb_cursor		= soft_cursor,
+};
+
+
+/* Control Register Constants */
+#define CG3_CR_ENABLE_INTS      0x80
+#define CG3_CR_ENABLE_VIDEO     0x40
+#define CG3_CR_ENABLE_TIMING    0x20
+#define CG3_CR_ENABLE_CURCMP    0x10
+#define CG3_CR_XTAL_MASK        0x0c
+#define CG3_CR_DIVISOR_MASK     0x03
+
+/* Status Register Constants */
+#define CG3_SR_PENDING_INT      0x80
+#define CG3_SR_RES_MASK         0x70
+#define CG3_SR_1152_900_76_A    0x40
+#define CG3_SR_1152_900_76_B    0x60
+#define CG3_SR_ID_MASK          0x0f
+#define CG3_SR_ID_COLOR         0x01
+#define CG3_SR_ID_MONO          0x02
+#define CG3_SR_ID_MONO_ECL      0x03
+
+enum cg3_type {
+	CG3_AT_66HZ = 0,
+	CG3_AT_76HZ,
+	CG3_RDI
+};
+
+struct bt_regs {
+	volatile u32 addr;
+	volatile u32 color_map;
+	volatile u32 control;
+	volatile u32 cursor;
+};
+
+struct cg3_regs {
+	struct bt_regs	cmap;
+	volatile u8	control;
+	volatile u8	status;
+	volatile u8	cursor_start;
+	volatile u8	cursor_end;
+	volatile u8	h_blank_start;
+	volatile u8	h_blank_end;
+	volatile u8	h_sync_start;
+	volatile u8	h_sync_end;
+	volatile u8	comp_sync_end;
+	volatile u8	v_blank_start_high;
+	volatile u8	v_blank_start_low;
+	volatile u8	v_blank_end;
+	volatile u8	v_sync_start;
+	volatile u8	v_sync_end;
+	volatile u8	xfer_holdoff_start;
+	volatile u8	xfer_holdoff_end;
+};
+
+/* Offset of interesting structures in the OBIO space */
+#define CG3_REGS_OFFSET	     0x400000UL
+#define CG3_RAM_OFFSET	     0x800000UL
+
+struct cg3_par {
+	spinlock_t		lock;
+	struct cg3_regs		*regs;
+	u32			sw_cmap[((256 * 3) + 3) / 4];
+
+	u32			flags;
+#define CG3_FLAG_BLANKED	0x00000001
+#define CG3_FLAG_RDI		0x00000002
+
+	unsigned long		physbase;
+	unsigned long		fbsize;
+
+	struct sbus_dev		*sdev;
+	struct list_head	list;
+};
+
+/**
+ *      cg3_check_var - Optional function.  Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int cg3_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->bits_per_pixel != 8)
+		return -EINVAL;
+
+	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
+		return -EINVAL;
+	if (var->nonstd)
+		return -EINVAL;
+	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+
+	if (var->xres != info->var.xres || var->yres != info->var.yres)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ *      cg3_set_par - Optional function.  Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+cg3_set_par(struct fb_info *info)
+{
+	return 0;
+}
+
+/**
+ *      cg3_setcolreg - Optional function. Sets a color register.
+ *      @regno: boolean, 0 copy local, 1 get_user() function
+ *      @red: frame buffer colormap structure
+ *      @green: The green value which can be up to 16 bits wide
+ *      @blue:  The blue value which can be up to 16 bits wide.
+ *      @transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ *
+ * The cg3 palette is loaded with 4 color values at each time
+ * so you end up with: (rgb)(r), (gb)(rg), (b)(rgb), and so on.
+ * We keep a sw copy of the hw cmap to assist us in this esoteric
+ * loading procedure.
+ */
+static int cg3_setcolreg(unsigned regno,
+			 unsigned red, unsigned green, unsigned blue,
+			 unsigned transp, struct fb_info *info)
+{
+	struct cg3_par *par = (struct cg3_par *) info->par;
+	struct bt_regs *bt = &par->regs->cmap;
+	unsigned long flags;
+	u32 *p32;
+	u8 *p8;
+	int count;
+
+	if (regno >= 256)
+		return 1;
+
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	p8 = (u8 *)par->sw_cmap + (regno * 3);
+	p8[0] = red;
+	p8[1] = green;
+	p8[2] = blue;
+
+#define D4M3(x) ((((x)>>2)<<1) + ((x)>>2))      /* (x/4)*3 */
+#define D4M4(x) ((x)&~0x3)                      /* (x/4)*4 */
+
+	count = 3;
+	p32 = &par->sw_cmap[D4M3(regno)];
+	sbus_writel(D4M4(regno), &bt->addr);
+	while (count--)
+		sbus_writel(*p32++, &bt->color_map);
+
+#undef D4M3
+#undef D4M4
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+/**
+ *      cg3_blank - Optional function.  Blanks the display.
+ *      @blank_mode: the blank mode we want.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+cg3_blank(int blank, struct fb_info *info)
+{
+	struct cg3_par *par = (struct cg3_par *) info->par;
+	struct cg3_regs *regs = par->regs;
+	unsigned long flags;
+	u8 val;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	switch (blank) {
+	case 0: /* Unblanking */
+		val = sbus_readl(&regs->control);
+		val |= CG3_CR_ENABLE_VIDEO;
+		sbus_writel(val, &regs->control);
+		par->flags &= ~CG3_FLAG_BLANKED;
+		break;
+
+	case 1: /* Normal blanking */
+	case 2: /* VESA blank (vsync off) */
+	case 3: /* VESA blank (hsync off) */
+	case 4: /* Poweroff */
+		val = sbus_readl(&regs->control);
+		val |= CG3_CR_ENABLE_VIDEO;
+		sbus_writel(val, &regs->control);
+		par->flags |= CG3_FLAG_BLANKED;
+		break;
+	}
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+static struct sbus_mmap_map cg3_mmap_map[] = {
+	{ CG3_MMAP_OFFSET,	CG3_RAM_OFFSET,		SBUS_MMAP_FBSIZE(1) },
+	{ 0,			0,			0		    }
+};
+
+static int cg3_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	struct cg3_par *par = (struct cg3_par *)info->par;
+
+	return sbusfb_mmap_helper(cg3_mmap_map,
+				  par->physbase, par->fbsize,
+				  par->sdev->reg_addrs[0].which_io,
+				  vma);
+}
+
+/*
+ *  Initialisation
+ */
+
+static void
+cg3_init_fix(struct fb_info *info, int linebytes)
+{
+	struct cg3_par *par = (struct cg3_par *)info->par;
+
+	strncpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id) - 1);
+	info->fix.id[sizeof(info->fix.id)-1] = 0;
+
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+	info->fix.line_length = linebytes;
+
+	info->fix.accel = FB_ACCEL_SUN_CGTHREE;
+}
+
+static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
+				    struct sbus_dev *sdev)
+{
+	char buffer[40];
+	char *p;
+	int ww, hh;
+
+	*buffer = 0;
+	prom_getstring(sdev->prom_node, "params", buffer, sizeof(buffer));
+	if (*buffer) {
+		ww = simple_strtoul(buffer, &p, 10);
+		if (ww && *p == 'x') {
+			hh = simple_strtoul(p + 1, &p, 10);
+			if (hh && *p == '-') {
+				if (var->xres != ww ||
+				    var->yres != hh) {
+					var->xres = var->xres_virtual = ww;
+					var->yres = var->yres_virtual = hh;
+				}
+			}
+		}
+	}
+}
+
+static u8 cg3regvals_66hz[] __initdata = {	/* 1152 x 900, 66 Hz */
+	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x04,	0x17, 0x14,
+	0x18, 0xae,	0x19, 0x03,	0x1a, 0xa8,	0x1b, 0x24,
+	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
+	0x10, 0x20,	0
+};
+
+static u8 cg3regvals_76hz[] __initdata = {	/* 1152 x 900, 76 Hz */
+	0x14, 0xb7,	0x15, 0x27,	0x16, 0x03,	0x17, 0x0f,
+	0x18, 0xae,	0x19, 0x03,	0x1a, 0xae,	0x1b, 0x2a,
+	0x1c, 0x01,	0x1d, 0x09,	0x1e, 0xff,	0x1f, 0x01,
+	0x10, 0x24,	0
+};
+
+static u8 cg3regvals_rdi[] __initdata = {	/* 640 x 480, cgRDI */
+	0x14, 0x70,	0x15, 0x20,	0x16, 0x08,	0x17, 0x10,
+	0x18, 0x06,	0x19, 0x02,	0x1a, 0x31,	0x1b, 0x51,
+	0x1c, 0x06,	0x1d, 0x0c,	0x1e, 0xff,	0x1f, 0x01,
+	0x10, 0x22,	0
+};
+
+static u8 *cg3_regvals[] __initdata = {
+	cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
+};
+
+static u_char cg3_dacvals[] __initdata = {
+	4, 0xff,	5, 0x00,	6, 0x70,	7, 0x00,	0
+};
+
+static void cg3_do_default_mode(struct cg3_par *par)
+{
+	enum cg3_type type;
+	u8 *p;
+
+	if (par->flags & CG3_FLAG_RDI)
+		type = CG3_RDI;
+	else {
+		u8 status = sbus_readb(&par->regs->status), mon;
+		if ((status & CG3_SR_ID_MASK) == CG3_SR_ID_COLOR) {
+			mon = status & CG3_SR_RES_MASK;
+			if (mon == CG3_SR_1152_900_76_A ||
+			    mon == CG3_SR_1152_900_76_B)
+				type = CG3_AT_76HZ;
+			else
+				type = CG3_AT_66HZ;
+		} else {
+			prom_printf("cgthree: can't handle SR %02x\n",
+				    status);
+			prom_halt();
+			return;
+		}
+	}
+
+	for (p = cg3_regvals[type]; *p; p += 2) {
+		u8 *regp = &((u8 *)par->regs)[p[0]];
+		sbus_writeb(p[1], regp);
+	}
+	for (p = cg3_dacvals; *p; p += 2) {
+		volatile u8 *regp;
+
+		regp = (volatile u8 *)&par->regs->cmap.addr;
+		sbus_writeb(p[0], regp);
+		regp = (volatile u8 *)&par->regs->cmap.control;
+		sbus_writeb(p[1], regp);
+	}
+}
+
+struct all_info {
+	struct fb_info info;
+	struct cg3_par par;
+	struct list_head list;
+};
+static LIST_HEAD(cg3_list);
+
+static void cg3_init_one(struct sbus_dev *sdev)
+{
+	struct all_info *all;
+	int linebytes;
+
+	all = kmalloc(sizeof(*all), GFP_KERNEL);
+	if (!all) {
+		printk(KERN_ERR "cg3: Cannot allocate memory.\n");
+		return;
+	}
+	memset(all, 0, sizeof(*all));
+
+	INIT_LIST_HEAD(&all->list);
+
+	spin_lock_init(&all->par.lock);
+	all->par.sdev = sdev;
+
+	all->par.physbase = sdev->reg_addrs[0].phys_addr;
+
+	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+	if (!strcmp(sdev->prom_name, "cgRDI"))
+		all->par.flags |= CG3_FLAG_RDI;
+	if (all->par.flags & CG3_FLAG_RDI)
+		cg3_rdi_maybe_fixup_var(&all->info.var, sdev);
+
+	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
+				       all->info.var.xres);
+	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+
+	all->par.regs = (struct cg3_regs *)
+		sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
+			     sizeof(struct cg3_regs), "cg3 regs");
+
+	all->info.node = NODEV;
+	all->info.flags = FBINFO_FLAG_DEFAULT;
+	all->info.fbops = &cg3_ops;
+#ifdef CONFIG_SPARC32
+	all->info.screen_base = (char *)
+		prom_getintdefault(sdev->prom_node, "address", 0);
+#endif
+	if (!all->info.screen_base)
+		all->info.screen_base = (char *)
+			sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
+				     all->par.fbsize, "cg3 ram");
+	all->info.currcon = -1;
+	all->info.par = &all->par;
+
+	cg3_blank(0, &all->info);
+
+	if (!prom_getbool(sdev->prom_node, "width"))
+		cg3_do_default_mode(&all->par);
+
+	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+		printk(KERN_ERR "cg3: Could not allocate color map.\n");
+		kfree(all);
+		return;
+	}
+
+	cg3_set_par(&all->info);
+	cg3_init_fix(&all->info, linebytes);
+
+	if (register_framebuffer(&all->info) < 0) {
+		printk(KERN_ERR "cg3: Could not register framebuffer.\n");
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+		return;
+	}
+
+	list_add(&all->list, &cg3_list);
+
+	printk("cg3: %s at %lx:%lx\n",
+	       sdev->prom_name,
+	       (long) sdev->reg_addrs[0].which_io,
+	       (long) sdev->reg_addrs[0].phys_addr);
+}
+
+int __init cg3_init(void)
+{
+	struct sbus_bus *sbus;
+	struct sbus_dev *sdev;
+
+	for_all_sbusdev(sdev, sbus) {
+		if (!strcmp(sdev->prom_name, "cgthree") ||
+		    !strcmp(sdev->prom_name, "cgRDI"))
+			cg3_init_one(sdev);
+	}
+
+	return 0;
+}
+
+void __exit cg3_exit(void)
+{
+	struct list_head *pos, *tmp;
+
+	list_for_each_safe(pos, tmp, &cg3_list) {
+		struct all_info *all = list_entry(pos, typeof(*all), list);
+
+		unregister_framebuffer(&all->info);
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+	}
+}
+
+int __init
+cg3_setup(char *arg)
+{
+	/* No cmdline options yet... */
+	return 0;
+}
+
+#ifdef MODULE
+module_init(cg3_init);
+module_exit(cg3_exit);
+#endif
+
+MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets");
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/cg6.c b/drivers/video/cg6.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/cg6.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,793 @@
+/* cg6.c: CGSIX (GX, GXplus, TGX) frame buffer driver
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
+ *
+ * Driver layout based loosely on tgafb.c, see that file for credits.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/fbio.h>
+
+#include "sbuslib.h"
+
+/*
+ * Local functions.
+ */
+
+static int cg6_check_var(struct fb_var_screeninfo *, struct fb_info *);
+static int cg6_set_par(struct fb_info *);
+static int cg6_setcolreg(unsigned, unsigned, unsigned, unsigned,
+			 unsigned, struct fb_info *);
+static int cg6_blank(int, struct fb_info *);
+
+static void cg6_imageblit(struct fb_info *, struct fb_image *);
+static void cg6_fillrect(struct fb_info *, struct fb_fillrect *);
+static int cg6_sync(struct fb_info *);
+static int cg6_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+
+/*
+ *  Frame buffer operations
+ */
+
+static struct fb_ops cg6_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= cg6_check_var,
+	.fb_set_par		= cg6_set_par,
+	.fb_setcolreg		= cg6_setcolreg,
+	.fb_blank		= cg6_blank,
+	.fb_fillrect		= cg6_fillrect,
+	.fb_copyarea		= cfb_copyarea,
+	.fb_imageblit		= cg6_imageblit,
+	.fb_sync		= cg6_sync,
+	.fb_mmap		= cg6_mmap,
+	.fb_cursor		= soft_cursor,
+};
+
+/* Offset of interesting structures in the OBIO space */
+/*
+ * Brooktree is the video dac and is funny to program on the cg6.
+ * (it's even funnier on the cg3)
+ * The FBC could be the frame buffer control
+ * The FHC could is the frame buffer hardware control.
+ */
+#define CG6_ROM_OFFSET       0x0UL
+#define CG6_BROOKTREE_OFFSET 0x200000UL
+#define CG6_DHC_OFFSET       0x240000UL
+#define CG6_ALT_OFFSET       0x280000UL
+#define CG6_FHC_OFFSET       0x300000UL
+#define CG6_THC_OFFSET       0x301000UL
+#define CG6_FBC_OFFSET       0x700000UL
+#define CG6_TEC_OFFSET       0x701000UL
+#define CG6_RAM_OFFSET       0x800000UL
+
+/* FHC definitions */
+#define CG6_FHC_FBID_SHIFT           24
+#define CG6_FHC_FBID_MASK            255
+#define CG6_FHC_REV_SHIFT            20
+#define CG6_FHC_REV_MASK             15
+#define CG6_FHC_FROP_DISABLE         (1 << 19)
+#define CG6_FHC_ROW_DISABLE          (1 << 18)
+#define CG6_FHC_SRC_DISABLE          (1 << 17)
+#define CG6_FHC_DST_DISABLE          (1 << 16)
+#define CG6_FHC_RESET                (1 << 15)
+#define CG6_FHC_LITTLE_ENDIAN        (1 << 13)
+#define CG6_FHC_RES_MASK             (3 << 11)
+#define CG6_FHC_1024                 (0 << 11)
+#define CG6_FHC_1152                 (1 << 11)
+#define CG6_FHC_1280                 (2 << 11)
+#define CG6_FHC_1600                 (3 << 11)
+#define CG6_FHC_CPU_MASK             (3 << 9)
+#define CG6_FHC_CPU_SPARC            (0 << 9)
+#define CG6_FHC_CPU_68020            (1 << 9)
+#define CG6_FHC_CPU_386              (2 << 9)
+#define CG6_FHC_TEST		     (1 << 8)
+#define CG6_FHC_TEST_X_SHIFT	     4
+#define CG6_FHC_TEST_X_MASK	     15
+#define CG6_FHC_TEST_Y_SHIFT	     0
+#define CG6_FHC_TEST_Y_MASK	     15
+
+/* FBC mode definitions */
+#define CG6_FBC_BLIT_IGNORE		0x00000000
+#define CG6_FBC_BLIT_NOSRC		0x00100000
+#define CG6_FBC_BLIT_SRC		0x00200000
+#define CG6_FBC_BLIT_ILLEGAL		0x00300000
+#define CG6_FBC_BLIT_MASK		0x00300000
+
+#define CG6_FBC_VBLANK			0x00080000
+
+#define CG6_FBC_MODE_IGNORE		0x00000000
+#define CG6_FBC_MODE_COLOR8		0x00020000
+#define CG6_FBC_MODE_COLOR1		0x00040000
+#define CG6_FBC_MODE_HRMONO		0x00060000
+#define CG6_FBC_MODE_MASK		0x00060000
+
+#define CG6_FBC_DRAW_IGNORE		0x00000000
+#define CG6_FBC_DRAW_RENDER		0x00008000
+#define CG6_FBC_DRAW_PICK		0x00010000
+#define CG6_FBC_DRAW_ILLEGAL		0x00018000
+#define CG6_FBC_DRAW_MASK		0x00018000
+
+#define CG6_FBC_BWRITE0_IGNORE		0x00000000
+#define CG6_FBC_BWRITE0_ENABLE		0x00002000
+#define CG6_FBC_BWRITE0_DISABLE		0x00004000
+#define CG6_FBC_BWRITE0_ILLEGAL		0x00006000
+#define CG6_FBC_BWRITE0_MASK		0x00006000
+
+#define CG6_FBC_BWRITE1_IGNORE		0x00000000
+#define CG6_FBC_BWRITE1_ENABLE		0x00000800
+#define CG6_FBC_BWRITE1_DISABLE		0x00001000
+#define CG6_FBC_BWRITE1_ILLEGAL		0x00001800
+#define CG6_FBC_BWRITE1_MASK		0x00001800
+
+#define CG6_FBC_BREAD_IGNORE		0x00000000
+#define CG6_FBC_BREAD_0			0x00000200
+#define CG6_FBC_BREAD_1			0x00000400
+#define CG6_FBC_BREAD_ILLEGAL		0x00000600
+#define CG6_FBC_BREAD_MASK		0x00000600
+
+#define CG6_FBC_BDISP_IGNORE		0x00000000
+#define CG6_FBC_BDISP_0			0x00000080
+#define CG6_FBC_BDISP_1			0x00000100
+#define CG6_FBC_BDISP_ILLEGAL		0x00000180
+#define CG6_FBC_BDISP_MASK		0x00000180
+
+#define CG6_FBC_INDEX_MOD		0x00000040
+#define CG6_FBC_INDEX_MASK		0x00000030
+
+/* THC definitions */
+#define CG6_THC_MISC_REV_SHIFT       16
+#define CG6_THC_MISC_REV_MASK        15
+#define CG6_THC_MISC_RESET           (1 << 12)
+#define CG6_THC_MISC_VIDEO           (1 << 10)
+#define CG6_THC_MISC_SYNC            (1 << 9)
+#define CG6_THC_MISC_VSYNC           (1 << 8)
+#define CG6_THC_MISC_SYNC_ENAB       (1 << 7)
+#define CG6_THC_MISC_CURS_RES        (1 << 6)
+#define CG6_THC_MISC_INT_ENAB        (1 << 5)
+#define CG6_THC_MISC_INT             (1 << 4)
+#define CG6_THC_MISC_INIT            0x9f
+
+/* The contents are unknown */
+struct cg6_tec {
+	volatile int tec_matrix;
+	volatile int tec_clip;
+	volatile int tec_vdc;
+};
+
+struct cg6_thc {
+        uint thc_pad0[512];
+	volatile uint thc_hs;		/* hsync timing */
+	volatile uint thc_hsdvs;
+	volatile uint thc_hd;
+	volatile uint thc_vs;		/* vsync timing */
+	volatile uint thc_vd;
+	volatile uint thc_refresh;
+	volatile uint thc_misc;
+	uint thc_pad1[56];
+	volatile uint thc_cursxy;	/* cursor x,y position (16 bits each) */
+	volatile uint thc_cursmask[32];	/* cursor mask bits */
+	volatile uint thc_cursbits[32];	/* what to show where mask enabled */
+};
+
+struct cg6_fbc {
+	u32		xxx0[1];
+	volatile u32	mode;
+	volatile u32	clip;
+	u32		xxx1[1];	    
+	volatile u32	s;
+	volatile u32	draw;
+	volatile u32	blit;
+	volatile u32	font;
+	u32		xxx2[24];
+	volatile u32	x0, y0, z0, color0;
+	volatile u32	x1, y1, z1, color1;
+	volatile u32	x2, y2, z2, color2;
+	volatile u32	x3, y3, z3, color3;
+	volatile u32	offx, offy;
+	u32		xxx3[2];
+	volatile u32	incx, incy;
+	u32		xxx4[2];
+	volatile u32	clipminx, clipminy;
+	u32		xxx5[2];
+	volatile u32	clipmaxx, clipmaxy;
+	u32		xxx6[2];
+	volatile u32	fg;
+	volatile u32	bg;
+	volatile u32	alu;
+	volatile u32	pm;
+	volatile u32	pixelm;
+	u32		xxx7[2];
+	volatile u32	patalign;
+	volatile u32	pattern[8];
+	u32		xxx8[432];
+	volatile u32	apointx, apointy, apointz;
+	u32		xxx9[1];
+	volatile u32	rpointx, rpointy, rpointz;
+	u32		xxx10[5];
+	volatile u32	pointr, pointg, pointb, pointa;
+	volatile u32	alinex, aliney, alinez;
+	u32		xxx11[1];
+	volatile u32	rlinex, rliney, rlinez;
+	u32		xxx12[5];
+	volatile u32	liner, lineg, lineb, linea;
+	volatile u32	atrix, atriy, atriz;
+	u32		xxx13[1];
+	volatile u32	rtrix, rtriy, rtriz;
+	u32		xxx14[5];
+	volatile u32	trir, trig, trib, tria;
+	volatile u32	aquadx, aquady, aquadz;
+	u32		xxx15[1];
+	volatile u32	rquadx, rquady, rquadz;
+	u32		xxx16[5];
+	volatile u32	quadr, quadg, quadb, quada;
+	volatile u32	arectx, arecty, arectz;
+	u32		xxx17[1];
+	volatile u32	rrectx, rrecty, rrectz;
+	u32		xxx18[5];
+	volatile u32	rectr, rectg, rectb, recta;
+};
+
+struct bt_regs {
+	volatile u32 addr;
+	volatile u32 color_map;
+	volatile u32 control;
+	volatile u32 cursor;
+};
+
+struct cg6_par {
+	spinlock_t		lock;
+	struct bt_regs		*bt;
+	struct cg6_fbc		*fbc;
+	struct cg6_thc		*thc;
+	struct cg6_tec		*tec;
+	volatile u32		*fhc;
+
+	u32			flags;
+#define CG6_FLAG_BLANKED	0x00000001
+
+	unsigned long		physbase;
+	unsigned long		fbsize;
+
+	struct sbus_dev		*sdev;
+	struct list_head	list;
+};
+
+static int cg6_sync(struct fb_info *info)
+{
+	struct cg6_par *par = (struct cg6_par *) info->par;
+	struct cg6_fbc *fbc = par->fbc;
+	int limit = 10000;
+
+	do {
+		if (!(sbus_readl(&fbc->s) & 0x10000000))
+			break;
+		udelay(10);
+	} while (--limit > 0);
+
+	return 0;
+}
+
+/**
+ *      cg6_fillrect - REQUIRED function. Can use generic routines if 
+ *                     non acclerated hardware and packed pixel based.
+ *                     Draws a rectangle on the screen.               
+ *
+ *      @info: frame buffer structure that represents a single frame buffer
+ *      @rect: structure defining the rectagle and operation.
+ */
+static void cg6_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+	struct cg6_par *par = (struct cg6_par *) info->par;
+	struct cg6_fbc *fbc = par->fbc;
+	unsigned long flags;
+	s32 val;
+
+	/* XXX doesn't handle ROP_XOR */
+
+	spin_lock_irqsave(&par->lock, flags);
+	cg6_sync(info);
+	sbus_writel(rect->color, &fbc->fg);
+	sbus_writel(~(u32)0, &fbc->pixelm);
+	sbus_writel(0xea80ff00, &fbc->alu);
+	sbus_writel(0, &fbc->s);
+	sbus_writel(0, &fbc->clip);
+	sbus_writel(~(u32)0, &fbc->pm);
+	sbus_writel(rect->dy, &fbc->arecty);
+	sbus_writel(rect->dx, &fbc->arectx);
+	sbus_writel(rect->dy + rect->height, &fbc->arecty);
+	sbus_writel(rect->dx + rect->width, &fbc->arectx);
+	do {
+		val = sbus_readl(&fbc->draw);
+	} while (val < 0 && (val & 0x20000000));
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+/**
+ *      cg6_imageblit - REQUIRED function. Can use generic routines if
+ *                      non acclerated hardware and packed pixel based.
+ *                      Copies a image from system memory to the screen. 
+ *
+ *      @info: frame buffer structure that represents a single frame buffer
+ *      @image: structure defining the image.
+ */
+static void cg6_imageblit(struct fb_info *info, struct fb_image *image)
+{
+	struct cg6_par *par = (struct cg6_par *) info->par;
+	struct cg6_fbc *fbc = par->fbc;
+	u8 *data = image->data;
+	unsigned long flags;
+	u32 x, y;
+	int i, width;
+
+	if (image->depth > 1) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	cg6_sync(info);
+
+	sbus_writel(image->fg_color, &fbc->fg);
+	sbus_writel(image->bg_color, &fbc->bg);
+	sbus_writel(0x140000, &fbc->mode);
+	sbus_writel(0xe880fc30, &fbc->alu);
+	sbus_writel(~(u32)0, &fbc->pixelm);
+	sbus_writel(0, &fbc->s);
+	sbus_writel(0, &fbc->clip);
+	sbus_writel(0xff, &fbc->pm);
+	sbus_writel(32, &fbc->incx);
+	sbus_writel(0, &fbc->incy);
+
+	x = image->dx;
+	y = image->dy;
+	for (i = 0; i < image->height; i++) {
+		width = image->width;
+
+		while (width >= 32) {
+			u32 val;
+
+			sbus_writel(y, &fbc->y0);
+			sbus_writel(x, &fbc->x0);
+			sbus_writel(x + 32 - 1, &fbc->x1);
+			
+			val = ((u32)data[0] << 24) |
+			      ((u32)data[1] << 16) |
+			      ((u32)data[2] <<  8) |
+			      ((u32)data[3] <<  0);
+			sbus_writel(val, &fbc->font);
+
+			data += 4;
+			x += 32;
+			width -= 32;
+		}
+		if (width) {
+			u32 val;
+
+			sbus_writel(y, &fbc->y0);
+			sbus_writel(x, &fbc->x0);
+			sbus_writel(x + width - 1, &fbc->x1);
+			if (width <= 8) {
+				val = (u32) data[0] << 24;
+				data += 1;
+			} else if (width <= 16) {
+				val = ((u32) data[0] << 24) |
+				      ((u32) data[1] << 16);
+				data += 2;
+			} else {
+				val = ((u32) data[0] << 24) |
+				      ((u32) data[1] << 16) |
+				      ((u32) data[2] <<  8);
+				data += 3;
+			}
+			sbus_writel(val, &fbc->font);
+		}
+
+		y += 1;
+		x = image->dx;
+	}
+
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+/**
+ *      cg6_check_var - Optional function.  Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int cg6_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->bits_per_pixel != 8)
+		return -EINVAL;
+
+	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
+		return -EINVAL;
+	if (var->nonstd)
+		return -EINVAL;
+	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+
+	if (var->xres != info->var.xres || var->yres != info->var.yres)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ *      cg6_set_par - Optional function.  Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+cg6_set_par(struct fb_info *info)
+{
+	return 0;
+}
+
+/**
+ *      cg6_setcolreg - Optional function. Sets a color register.
+ *      @regno: boolean, 0 copy local, 1 get_user() function
+ *      @red: frame buffer colormap structure
+ *      @green: The green value which can be up to 16 bits wide
+ *      @blue:  The blue value which can be up to 16 bits wide.
+ *      @transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ */
+static int cg6_setcolreg(unsigned regno,
+			 unsigned red, unsigned green, unsigned blue,
+			 unsigned transp, struct fb_info *info)
+{
+	struct cg6_par *par = (struct cg6_par *) info->par;
+	struct bt_regs *bt = par->bt;
+	unsigned long flags;
+
+	if (regno >= 256)
+		return 1;
+
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	sbus_writel((u32)regno << 24, &bt->addr);
+	sbus_writel((u32)red << 24, &bt->color_map);
+	sbus_writel((u32)green << 24, &bt->color_map);
+	sbus_writel((u32)blue << 24, &bt->color_map);
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+/**
+ *      cg6_blank - Optional function.  Blanks the display.
+ *      @blank_mode: the blank mode we want.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+cg6_blank(int blank, struct fb_info *info)
+{
+	struct cg6_par *par = (struct cg6_par *) info->par;
+	struct cg6_thc *thc = par->thc;
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	switch (blank) {
+	case 0: /* Unblanking */
+		val = sbus_readl(&thc->thc_misc);
+		val |= CG6_THC_MISC_VIDEO;
+		sbus_writel(val, &thc->thc_misc);
+		par->flags &= ~CG6_FLAG_BLANKED;
+		break;
+
+	case 1: /* Normal blanking */
+	case 2: /* VESA blank (vsync off) */
+	case 3: /* VESA blank (hsync off) */
+	case 4: /* Poweroff */
+		val = sbus_readl(&thc->thc_misc);
+		val &= ~CG6_THC_MISC_VIDEO;
+		sbus_writel(val, &thc->thc_misc);
+		par->flags |= CG6_FLAG_BLANKED;
+		break;
+	}
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+static struct sbus_mmap_map cg6_mmap_map[] = {
+	{ CG6_FBC,		CG6_FBC_OFFSET,		PAGE_SIZE 		},
+	{ CG6_TEC,		CG6_TEC_OFFSET,		PAGE_SIZE 		},
+	{ CG6_BTREGS,		CG6_BROOKTREE_OFFSET,	PAGE_SIZE 		},
+	{ CG6_FHC,		CG6_FHC_OFFSET,		PAGE_SIZE 		},
+	{ CG6_THC,		CG6_THC_OFFSET,		PAGE_SIZE 		},
+	{ CG6_ROM,		CG6_ROM_OFFSET,		0x10000   		},
+	{ CG6_RAM,		CG6_RAM_OFFSET,		SBUS_MMAP_FBSIZE(1)  	},
+	{ CG6_DHC,		CG6_DHC_OFFSET,		0x40000   		},
+	{ 0,			0,			0	  		}
+};
+
+static int cg6_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	struct cg6_par *par = (struct cg6_par *)info->par;
+
+	return sbusfb_mmap_helper(cg6_mmap_map,
+				  par->physbase, par->fbsize,
+				  par->sdev->reg_addrs[0].which_io,
+				  vma);
+}
+
+/*
+ *  Initialisation
+ */
+
+static void
+cg6_init_fix(struct fb_info *info, int linebytes)
+{
+	struct cg6_par *par = (struct cg6_par *)info->par;
+	const char *cg6_cpu_name, *cg6_card_name;
+	u32 conf;
+
+	conf = sbus_readl(par->fhc);
+	switch(conf & CG6_FHC_CPU_MASK) {
+	case CG6_FHC_CPU_SPARC:
+		cg6_cpu_name = "sparc";
+		break;
+	case CG6_FHC_CPU_68020:
+		cg6_cpu_name = "68020";
+		break;
+	default:
+		cg6_cpu_name = "i386";
+		break;
+	};
+	if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) {
+		if (par->fbsize <= 0x100000) {
+			cg6_card_name = "TGX";
+		} else {
+			cg6_card_name = "TGX+";
+		}
+	} else {
+		if (par->fbsize <= 0x100000) {
+			cg6_card_name = "GX";
+		} else {
+			cg6_card_name = "GX+";
+		}
+	}
+
+	sprintf(info->fix.id, "%s %s", cg6_card_name, cg6_cpu_name);
+	info->fix.id[sizeof(info->fix.id)-1] = 0;
+
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+	info->fix.line_length = linebytes;
+
+	info->fix.accel = FB_ACCEL_SUN_CGSIX;
+}
+
+/* Initialize Brooktree DAC */
+static void cg6_bt_init(struct cg6_par *par)
+{
+	struct bt_regs *bt = par->bt;
+
+	sbus_writel(0x04 << 24, &bt->addr);         /* color planes */
+	sbus_writel(0xff << 24, &bt->control);
+	sbus_writel(0x05 << 24, &bt->addr);
+	sbus_writel(0x00 << 24, &bt->control);
+	sbus_writel(0x06 << 24, &bt->addr);         /* overlay plane */
+	sbus_writel(0x73 << 24, &bt->control);
+	sbus_writel(0x07 << 24, &bt->addr);
+	sbus_writel(0x00 << 24, &bt->control);
+}
+
+static void cg6_chip_init(struct fb_info *info)
+{
+	struct cg6_par *par = (struct cg6_par *) info->par;
+	struct cg6_tec *tec = par->tec;
+	struct cg6_fbc *fbc = par->fbc;
+	u32 rev, conf, mode, tmp;
+	int i;
+	
+	/* Turn off stuff in the Transform Engine. */
+	sbus_writel(0, &tec->tec_matrix);
+	sbus_writel(0, &tec->tec_clip);
+	sbus_writel(0, &tec->tec_vdc);
+
+	/* Take care of bugs in old revisions. */
+	rev = (sbus_readl(par->fhc) >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK;
+	if (rev < 5) {
+		conf = (sbus_readl(par->fhc) & CG6_FHC_RES_MASK) |
+			CG6_FHC_CPU_68020 | CG6_FHC_TEST |
+			(11 << CG6_FHC_TEST_X_SHIFT) |
+			(11 << CG6_FHC_TEST_Y_SHIFT);
+		if (rev < 2)
+			conf |= CG6_FHC_DST_DISABLE;
+		sbus_writel(conf, par->fhc);
+	}
+
+	/* Set things in the FBC. Bad things appear to happen if we do
+	 * back to back store/loads on the mode register, so copy it
+	 * out instead. */
+	mode = sbus_readl(&fbc->mode);
+	do {
+		i = sbus_readl(&fbc->s);
+	} while (i & 0x10000000);
+	mode &= ~(CG6_FBC_BLIT_MASK | CG6_FBC_MODE_MASK |
+		       CG6_FBC_DRAW_MASK | CG6_FBC_BWRITE0_MASK |
+		       CG6_FBC_BWRITE1_MASK | CG6_FBC_BREAD_MASK |
+		       CG6_FBC_BDISP_MASK);
+	mode |= (CG6_FBC_BLIT_SRC | CG6_FBC_MODE_COLOR8 |
+		      CG6_FBC_DRAW_RENDER | CG6_FBC_BWRITE0_ENABLE |
+		      CG6_FBC_BWRITE1_DISABLE | CG6_FBC_BREAD_0 |
+		      CG6_FBC_BDISP_0);
+	sbus_writel(mode, &fbc->mode);
+
+	sbus_writel(0, &fbc->clip);
+	sbus_writel(0, &fbc->offx);
+	sbus_writel(0, &fbc->offy);
+	sbus_writel(0, &fbc->clipminx);
+	sbus_writel(0, &fbc->clipminy);
+	sbus_writel(info->var.xres - 1, &fbc->clipmaxx);
+	sbus_writel(info->var.yres - 1, &fbc->clipmaxy);
+
+	/* Disable cursor in Brooktree DAC. */
+	sbus_writel(0x06 << 24, &par->bt->addr);
+	tmp = sbus_readl(&par->bt->control);
+	tmp &= ~(0x03 << 24);
+	sbus_writel(tmp, &par->bt->control);
+}
+
+struct all_info {
+	struct fb_info info;
+	struct cg6_par par;
+	struct list_head list;
+};
+static LIST_HEAD(cg6_list);
+
+static void cg6_init_one(struct sbus_dev *sdev)
+{
+	struct all_info *all;
+	int linebytes;
+
+	all = kmalloc(sizeof(*all), GFP_KERNEL);
+	if (!all) {
+		printk(KERN_ERR "cg6: Cannot allocate memory.\n");
+		return;
+	}
+	memset(all, 0, sizeof(*all));
+
+	INIT_LIST_HEAD(&all->list);
+
+	spin_lock_init(&all->par.lock);
+	all->par.sdev = sdev;
+
+	all->par.physbase = sdev->reg_addrs[0].phys_addr;
+
+	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+
+	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
+				       all->info.var.xres);
+	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+	if (prom_getbool(sdev->prom_node, "dblbuf"))
+		all->par.fbsize *= 4;
+
+	all->par.fbc = (struct cg6_fbc *)
+		sbus_ioremap(&sdev->resource[0], CG6_FBC_OFFSET,
+			     4096, "cgsix fbc");
+	all->par.tec = (struct cg6_tec *)
+		sbus_ioremap(&sdev->resource[0], CG6_TEC_OFFSET,
+			     sizeof(struct cg6_tec), "cgsix tec");
+	all->par.thc = (struct cg6_thc *)
+		sbus_ioremap(&sdev->resource[0], CG6_THC_OFFSET,
+			     sizeof(struct cg6_thc), "cgsix thc");
+	all->par.bt = (struct bt_regs *)
+		sbus_ioremap(&sdev->resource[0], CG6_BROOKTREE_OFFSET,
+			     sizeof(struct bt_regs), "cgsix dac");
+	all->par.fhc = (u32 *)
+		sbus_ioremap(&sdev->resource[0], CG6_FHC_OFFSET,
+			     sizeof(u32), "cgsix fhc");
+
+	all->info.node = NODEV;
+	all->info.flags = FBINFO_FLAG_DEFAULT;
+	all->info.fbops = &cg6_ops;
+#ifdef CONFIG_SPARC32
+	all->info.screen_base = (char *)
+		prom_getintdefault(sdev->prom_node, "address", 0);
+#endif
+	if (!all->info.screen_base)
+		all->info.screen_base = (char *)
+			sbus_ioremap(&sdev->resource[0], CG6_RAM_OFFSET,
+				     all->par.fbsize, "cgsix ram");
+	all->info.currcon = -1;
+	all->info.par = &all->par;
+
+	all->info.var.accel_flags = FB_ACCELF_TEXT;
+
+	cg6_bt_init(&all->par);
+	cg6_chip_init(&all->info);
+	cg6_blank(0, &all->info);
+
+	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+		printk(KERN_ERR "cg6: Could not allocate color map.\n");
+		kfree(all);
+		return;
+	}
+
+	cg6_set_par(&all->info);
+	cg6_init_fix(&all->info, linebytes);
+
+	if (register_framebuffer(&all->info) < 0) {
+		printk(KERN_ERR "cg6: Could not register framebuffer.\n");
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+		return;
+	}
+
+	list_add(&all->list, &cg6_list);
+
+	printk("cg6: CGsix [%s] at %lx:%lx\n",
+	       all->info.fix.id,
+	       (long) sdev->reg_addrs[0].which_io,
+	       (long) sdev->reg_addrs[0].phys_addr);
+}
+
+int __init cg6_init(void)
+{
+	struct sbus_bus *sbus;
+	struct sbus_dev *sdev;
+
+	for_all_sbusdev(sdev, sbus) {
+		if (!strcmp(sdev->prom_name, "cgsix") ||
+		    !strcmp(sdev->prom_name, "cgthree+"))
+			cg6_init_one(sdev);
+	}
+
+	return 0;
+}
+
+void __exit cg6_exit(void)
+{
+	struct list_head *pos, *tmp;
+
+	list_for_each_safe(pos, tmp, &cg6_list) {
+		struct all_info *all = list_entry(pos, typeof(*all), list);
+
+		unregister_framebuffer(&all->info);
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+	}
+}
+
+int __init
+cg6_setup(char *arg)
+{
+	/* No cmdline options yet... */
+	return 0;
+}
+
+#ifdef MODULE
+module_init(cg6_init);
+module_exit(cg6_exit);
+#endif
+
+MODULE_DESCRIPTION("framebuffer driver for CGsix chipsets");
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/cgfourteenfb.c b/drivers/video/cgfourteenfb.c
--- a/drivers/video/cgfourteenfb.c	Tue Mar  4 19:30:13 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,445 +0,0 @@
-/* $Id: cgfourteenfb.c,v 1.11 2001/09/19 00:04:33 davem Exp $
- * cgfourteenfb.c: CGfourteen frame buffer driver
- *
- * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
- * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-
-#include <video/sbusfb.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-
-#include <video/fbcon-cfb8.h>
-
-#define CG14_MCR_INTENABLE_SHIFT	7
-#define CG14_MCR_INTENABLE_MASK		0x80
-#define CG14_MCR_VIDENABLE_SHIFT	6
-#define CG14_MCR_VIDENABLE_MASK		0x40
-#define CG14_MCR_PIXMODE_SHIFT		4
-#define CG14_MCR_PIXMODE_MASK		0x30
-#define CG14_MCR_TMR_SHIFT		2
-#define CG14_MCR_TMR_MASK		0x0c
-#define CG14_MCR_TMENABLE_SHIFT		1
-#define CG14_MCR_TMENABLE_MASK		0x02
-#define CG14_MCR_RESET_SHIFT		0
-#define CG14_MCR_RESET_MASK		0x01
-#define CG14_REV_REVISION_SHIFT		4
-#define CG14_REV_REVISION_MASK		0xf0
-#define CG14_REV_IMPL_SHIFT		0
-#define CG14_REV_IMPL_MASK		0x0f
-#define CG14_VBR_FRAMEBASE_SHIFT	12
-#define CG14_VBR_FRAMEBASE_MASK		0x00fff000
-#define CG14_VMCR1_SETUP_SHIFT		0
-#define CG14_VMCR1_SETUP_MASK		0x000001ff
-#define CG14_VMCR1_VCONFIG_SHIFT	9
-#define CG14_VMCR1_VCONFIG_MASK		0x00000e00
-#define CG14_VMCR2_REFRESH_SHIFT	0
-#define CG14_VMCR2_REFRESH_MASK		0x00000001
-#define CG14_VMCR2_TESTROWCNT_SHIFT	1
-#define CG14_VMCR2_TESTROWCNT_MASK	0x00000002
-#define CG14_VMCR2_FBCONFIG_SHIFT	2
-#define CG14_VMCR2_FBCONFIG_MASK	0x0000000c
-#define CG14_VCR_REFRESHREQ_SHIFT	0
-#define CG14_VCR_REFRESHREQ_MASK	0x000003ff
-#define CG14_VCR1_REFRESHENA_SHIFT	10
-#define CG14_VCR1_REFRESHENA_MASK	0x00000400
-#define CG14_VCA_CAD_SHIFT		0
-#define CG14_VCA_CAD_MASK		0x000003ff
-#define CG14_VCA_VERS_SHIFT		10
-#define CG14_VCA_VERS_MASK		0x00000c00
-#define CG14_VCA_RAMSPEED_SHIFT		12
-#define CG14_VCA_RAMSPEED_MASK		0x00001000
-#define CG14_VCA_8MB_SHIFT		13
-#define CG14_VCA_8MB_MASK		0x00002000
-
-#define CG14_MCR_PIXMODE_8		0
-#define CG14_MCR_PIXMODE_16		2
-#define CG14_MCR_PIXMODE_32		3
-
-MODULE_LICENSE("GPL");
-
-struct cg14_regs{
-	volatile u8 mcr;	/* Master Control Reg */
-	volatile u8 ppr;	/* Packed Pixel Reg */
-	volatile u8 tms[2];	/* Test Mode Status Regs */
-	volatile u8 msr;	/* Master Status Reg */
-	volatile u8 fsr;	/* Fault Status Reg */
-	volatile u8 rev;	/* Revision & Impl */
-	volatile u8 ccr;	/* Clock Control Reg */
-	volatile u32 tmr;	/* Test Mode Read Back */
-	volatile u8 mod;	/* Monitor Operation Data Reg */
-	volatile u8 acr;	/* Aux Control */
-	u8 xxx0[6];
-	volatile u16 hct;	/* Hor Counter */
-	volatile u16 vct;	/* Vert Counter */
-	volatile u16 hbs;	/* Hor Blank Start */
-	volatile u16 hbc;	/* Hor Blank Clear */
-	volatile u16 hss;	/* Hor Sync Start */
-	volatile u16 hsc;	/* Hor Sync Clear */
-	volatile u16 csc;	/* Composite Sync Clear */
-	volatile u16 vbs;	/* Vert Blank Start */
-	volatile u16 vbc;	/* Vert Blank Clear */
-	volatile u16 vss;	/* Vert Sync Start */
-	volatile u16 vsc;	/* Vert Sync Clear */
-	volatile u16 xcs;
-	volatile u16 xcc;
-	volatile u16 fsa;	/* Fault Status Address */
-	volatile u16 adr;	/* Address Registers */
-	u8 xxx1[0xce];
-	volatile u8 pcg[0x100]; /* Pixel Clock Generator */
-	volatile u32 vbr;	/* Frame Base Row */
-	volatile u32 vmcr;	/* VBC Master Control */
-	volatile u32 vcr;	/* VBC refresh */
-	volatile u32 vca;	/* VBC Config */
-};
-
-#define CG14_CCR_ENABLE	0x04
-#define CG14_CCR_SELECT 0x02	/* HW/Full screen */
-
-struct cg14_cursor {
-	volatile u32 cpl0[32];	/* Enable plane 0 */
-	volatile u32 cpl1[32];  /* Color selection plane */
-	volatile u8 ccr;	/* Cursor Control Reg */
-	u8 xxx0[3];
-	volatile u16 cursx;	/* Cursor x,y position */
-	volatile u16 cursy;	/* Cursor x,y position */
-	volatile u32 color0;
-	volatile u32 color1;
-	u32 xxx1[0x1bc];
-	volatile u32 cpl0i[32];	/* Enable plane 0 autoinc */
-	volatile u32 cpl1i[32]; /* Color selection autoinc */
-};
-
-struct cg14_dac {
-	volatile u8 addr;	/* Address Register */
-	u8 xxx0[255];
-	volatile u8 glut;	/* Gamma table */
-	u8 xxx1[255];
-	volatile u8 select;	/* Register Select */
-	u8 xxx2[255];
-	volatile u8 mode;	/* Mode Register */
-};
-
-struct cg14_xlut{
-	volatile u8 x_xlut [256];
-	volatile u8 x_xlutd [256];
-	u8 xxx0[0x600];
-	volatile u8 x_xlut_inc [256];
-	volatile u8 x_xlutd_inc [256];
-};
-
-/* Color look up table (clut) */
-/* Each one of these arrays hold the color lookup table (for 256
- * colors) for each MDI page (I assume then there should be 4 MDI
- * pages, I still wonder what they are.  I have seen NeXTStep split
- * the screen in four parts, while operating in 24 bits mode.  Each
- * integer holds 4 values: alpha value (transparency channel, thanks
- * go to John Stone (johns@umr.edu) from OpenBSD), red, green and blue
- *
- * I currently use the clut instead of the Xlut
- */
-struct cg14_clut {
-	u32 c_clut [256];
-	u32 c_clutd [256];    /* i wonder what the 'd' is for */
-	u32 c_clut_inc [256];
-	u32 c_clutd_inc [256];
-};
-
-static struct sbus_mmap_map cg14_mmap_map[] __initdata = {
-	{ CG14_REGS,		0x80000000,		0x1000		    },
-	{ CG14_XLUT,		0x80003000,		0x1000		    },
-	{ CG14_CLUT1,		0x80004000,		0x1000		    },
-	{ CG14_CLUT2,		0x80005000,		0x1000		    },
-	{ CG14_CLUT3,		0x80006000,		0x1000		    },
-	{ CG3_MMAP_OFFSET - 
-	  0x7000,		0x80000000,		0x7000		    },
-	{ CG3_MMAP_OFFSET,	0x00000000,		SBUS_MMAP_FBSIZE(1) },
-	{ MDI_CURSOR_MAP,	0x80001000,		0x1000		    },
-	{ MDI_CHUNKY_BGR_MAP,	0x01000000,		0x400000	    },
-	{ MDI_PLANAR_X16_MAP,	0x02000000,		0x200000	    },
-	{ MDI_PLANAR_C16_MAP,	0x02800000,		0x200000	    },
-	{ MDI_PLANAR_X32_MAP,	0x03000000,		0x100000	    },
-	{ MDI_PLANAR_B32_MAP,	0x03400000,		0x100000	    },
-	{ MDI_PLANAR_G32_MAP,	0x03800000,		0x100000	    },
-	{ MDI_PLANAR_R32_MAP,	0x03c00000,		0x100000	    },
-	{ 0,			0,			0		    }
-};
-
-static void cg14_loadcmap (struct fb_info_sbusfb *fb, struct display *p,
-			   int index, int count)
-{
-	struct cg14_clut *clut = fb->s.cg14.clut;
-	unsigned long flags;
-	        
-	spin_lock_irqsave(&fb->lock, flags);
-	for (; count--; index++) {
-		u32 val;
-
-		val = ((fb->color_map CM(index,2) << 16) |
-		       (fb->color_map CM(index,1) << 8) |
-		       (fb->color_map CM(index,0)));
-		sbus_writel(val, &clut->c_clut[index]);
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg14_margins (struct fb_info_sbusfb *fb, struct display *p,
-			  int x_margin, int y_margin)
-{
-	fb->info.screen_base += (y_margin - fb->y_margin) *
-		fb->info.fix.line_length + (x_margin - fb->x_margin);
-}
-
-static void cg14_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
-{
-	struct cg14_cursor *cur = fb->s.cg14.cursor;
-	unsigned long flags;
-	
-	spin_lock_irqsave(&fb->lock, flags);
-	sbus_writel(((red[0]) | (green[0] << 8) | (blue[0] << 16)), &cur->color0);
-	sbus_writel(((red[1]) | (green[1] << 8) | (blue[1] << 16)), &cur->color1);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-/* Set cursor shape */
-static void cg14_setcurshape (struct fb_info_sbusfb *fb)
-{
-	struct cg14_cursor *cur = fb->s.cg14.cursor;
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	for (i = 0; i < 32; i++){
-		sbus_writel(fb->cursor.bits[0][i], &cur->cpl0[i]);
-		sbus_writel(fb->cursor.bits[1][i], &cur->cpl1[i]);
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-/* Load cursor information */
-static void cg14_setcursor (struct fb_info_sbusfb *fb)
-{
-	struct cg_cursor *c = &fb->cursor;
-	struct cg14_cursor *cur = fb->s.cg14.cursor;
-	unsigned long flags;
-                
-	spin_lock_irqsave(&fb->lock, flags);
-	if (c->enable) {
-		u8 tmp = sbus_readb(&cur->ccr);
-
-		tmp |= CG14_CCR_ENABLE;
-		sbus_writeb(tmp, &cur->ccr);
-	} else {
-		u8 tmp = sbus_readb(&cur->ccr);
-
-		tmp &= ~CG14_CCR_ENABLE;
-		sbus_writeb(tmp, &cur->ccr);
-	}
-	sbus_writew(((c->cpos.fbx - c->chot.fbx) & 0xfff), &cur->cursx);
-	sbus_writew(((c->cpos.fby - c->chot.fby) & 0xfff), &cur->cursy);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg14_switch_from_graph (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&fb->lock, flags);
-
-	/* Set the 8-bpp mode */
-	if (fb->open && fb->mmaped){
-		volatile char *mcr = &fb->s.cg14.regs->mcr;
-		char tmp;
-	                                
-		fb->s.cg14.mode = 8;
-		tmp = sbus_readb(mcr);
-		tmp &= ~(CG14_MCR_PIXMODE_MASK);
-		sbus_writeb(tmp, mcr);
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg14_reset (struct fb_info_sbusfb *fb)
-{
-	volatile char *mcr = &fb->s.cg14.regs->mcr;
-	unsigned long flags;
-	char tmp;
-	        
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readb(mcr);
-	tmp &= ~(CG14_MCR_PIXMODE_MASK);
-	sbus_writeb(tmp, mcr);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static int cg14_ioctl (struct fb_info_sbusfb *fb, unsigned int cmd, unsigned long arg)
-{
-	volatile char *mcr = &fb->s.cg14.regs->mcr;
-	struct mdi_cfginfo *mdii;
-	unsigned long flags;
-	int mode, ret = 0;
-	char tmp;
-	        
-	switch (cmd) {
-	case MDI_RESET:
-		spin_lock_irqsave(&fb->lock, flags);
-		tmp = sbus_readb(mcr);
-		tmp &= ~CG14_MCR_PIXMODE_MASK;
-		sbus_writeb(tmp, mcr);
-		spin_unlock_irqrestore(&fb->lock, flags);
-		break;
-	case MDI_GET_CFGINFO:
-		mdii = (struct mdi_cfginfo *)arg;
-		if (put_user(FBTYPE_MDICOLOR, &mdii->mdi_type) ||
-		    __put_user(fb->type.fb_height, &mdii->mdi_height) ||
-		    __put_user(fb->type.fb_width, &mdii->mdi_width) ||
-		    __put_user(fb->s.cg14.mode, &mdii->mdi_mode) ||
-		    __put_user(72, &mdii->mdi_pixfreq) || /* FIXME */
-		    __put_user(fb->s.cg14.ramsize, &mdii->mdi_size))
-			return -EFAULT;
-		break;
-	case MDI_SET_PIXELMODE:
-		if (get_user(mode, (int *)arg))
-			return -EFAULT;
-
-		spin_lock_irqsave(&fb->lock, flags);
-		tmp = sbus_readb(mcr);
-		switch (mode){
-		case MDI_32_PIX:
-			tmp = (tmp & ~CG14_MCR_PIXMODE_MASK) |
-				(CG14_MCR_PIXMODE_32 << CG14_MCR_PIXMODE_SHIFT);
-			break;
-		case MDI_16_PIX:
-			tmp = (tmp & ~CG14_MCR_PIXMODE_MASK) | 0x20;
-			break;
-		case MDI_8_PIX:
-			tmp = (tmp & ~CG14_MCR_PIXMODE_MASK);
-			break;
-		default:
-			ret = -ENOSYS;
-			break;
-		};
-		if (ret == 0) {
-			sbus_writeb(tmp, mcr);
-			fb->s.cg14.mode = mode;
-		}
-		spin_unlock_irqrestore(&fb->lock, flags);
-		break;
-	default:
-		ret = -EINVAL;
-	};
-
-	return ret;
-}
-
-static unsigned long __init get_phys(unsigned long addr)
-{
-	return __get_phys(addr);
-}
-
-static int __init get_iospace(unsigned long addr)
-{
-	return __get_iospace(addr);
-}
-
-static char idstring[60] __initdata = { 0 };
-
-char __init *cgfourteenfb_init(struct fb_info_sbusfb *fb)
-{
-	struct fb_fix_screeninfo *fix = &fb->info.fix;
-	struct display *disp = &fb->disp;
-	struct fbtype *type = &fb->type;
-	unsigned long rphys, phys;
-	u32 bases[6];
-	int is_8mb, i;
-
-#ifndef FBCON_HAS_CFB8
-	return NULL;
-#endif
-	prom_getproperty (fb->prom_node, "address", (char *) &bases[0], 8);
-	if (!bases[0]) {
-		printk("cg14 not mmaped\n");
-		return NULL;
-	}
-	if (get_iospace(bases[0]) != get_iospace(bases[1])) {
-		printk("Ugh. cg14 iospaces don't match\n");
-		return NULL;
-	}
-	fb->physbase = phys = get_phys(bases[1]);
-	rphys = get_phys(bases[0]);
-	fb->iospace = get_iospace(bases[0]);
-	fb->s.cg14.regs = (struct cg14_regs *)(unsigned long)bases[0];
-	fb->s.cg14.clut = (void *)((unsigned long)bases[0]+CG14_CLUT1);
-	fb->s.cg14.cursor = (void *)((unsigned long)bases[0]+CG14_CURSORREGS);
-	fb->info.screen_base = (char *)bases[1];
-	
-	/* CG14_VCA_8MB_MASK is not correctly set on the 501-2482
-	 * VSIMM, so we read the memory size from the PROM
-	 */
-	prom_getproperty(fb->prom_node, "reg", (char *) &bases[0], 24);
-	is_8mb = bases[5] == 0x800000;
-
-	fb->mmap_map = kmalloc(sizeof(cg14_mmap_map), GFP_KERNEL);
-	if (!fb->mmap_map)
-		return NULL;
-
-	for (i = 0; ; i++) {
-		fb->mmap_map[i].voff = cg14_mmap_map[i].voff;
-		fb->mmap_map[i].poff = (cg14_mmap_map[i].poff & 0x80000000) ?
-				       (cg14_mmap_map[i].poff & 0x7fffffff) + rphys - phys :
-				       cg14_mmap_map[i].poff;
-		fb->mmap_map[i].size = cg14_mmap_map[i].size;
-		if (is_8mb && fb->mmap_map[i].size >= 0x100000 &&
-		    fb->mmap_map[i].size <= 0x400000)
-			fb->mmap_map[i].size <<= 1;
-		if (!cg14_mmap_map[i].size)
-			break;
-	}
-
-	strcpy(fb->info.modename, "CGfourteen");
-	strcpy(fix->id, "CGfourteen");
-	fix->line_length = fb->info.var.xres_virtual;
-	fix->accel = FB_ACCEL_SUN_CG14;
-	
-	disp->scrollmode = SCROLL_YREDRAW;
-	fb->info.screen_base += fix->line_length * fb->y_margin + fb->x_margin;
-	fb->dispsw = fbcon_cfb8;
-	
-	type->fb_depth = 24;
-	fb->emulations[1] = FBTYPE_SUN3COLOR;
-
-	fb->margins = cg14_margins;
-	fb->loadcmap = cg14_loadcmap;
-	fb->setcursor = cg14_setcursor;
-	fb->setcursormap = cg14_setcursormap;
-	fb->setcurshape = cg14_setcurshape;
-	fb->reset = cg14_reset;
-	fb->switch_from_graph = cg14_switch_from_graph;
-	fb->ioctl = cg14_ioctl;
-
-	fb->s.cg14.mode = 8;
-	fb->s.cg14.ramsize = (is_8mb) ? 0x800000 : 0x400000;
-	
-	cg14_reset(fb);
-	
-	sprintf(idstring, "cgfourteen at %x.%08lx, %dMB, rev=%d, impl=%d", fb->iospace, phys,
-		is_8mb ? 8 : 4, fb->s.cg14.regs->rev >> 4, fb->s.cg14.regs->rev & 0xf);
-	
-	return idstring;
-}
diff -Nru a/drivers/video/cgsixfb.c b/drivers/video/cgsixfb.c
--- a/drivers/video/cgsixfb.c	Tue Mar  4 19:30:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,824 +0,0 @@
-/* $Id: cgsixfb.c,v 1.26 2001/10/16 05:44:44 davem Exp $
- * cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
- *
- * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
- * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-
-#include <video/sbusfb.h>
-#include <asm/io.h>
-
-/* Offset of interesting structures in the OBIO space */
-/*
- * Brooktree is the video dac and is funny to program on the cg6.
- * (it's even funnier on the cg3)
- * The FBC could be the frame buffer control
- * The FHC could is the frame buffer hardware control.
- */
-#define CG6_ROM_OFFSET       0x0UL
-#define CG6_BROOKTREE_OFFSET 0x200000UL
-#define CG6_DHC_OFFSET       0x240000UL
-#define CG6_ALT_OFFSET       0x280000UL
-#define CG6_FHC_OFFSET       0x300000UL
-#define CG6_THC_OFFSET       0x301000UL
-#define CG6_FBC_OFFSET       0x700000UL
-#define CG6_TEC_OFFSET       0x701000UL
-#define CG6_RAM_OFFSET       0x800000UL
-
-/* FHC definitions */
-#define CG6_FHC_FBID_SHIFT           24
-#define CG6_FHC_FBID_MASK            255
-#define CG6_FHC_REV_SHIFT            20
-#define CG6_FHC_REV_MASK             15
-#define CG6_FHC_FROP_DISABLE         (1 << 19)
-#define CG6_FHC_ROW_DISABLE          (1 << 18)
-#define CG6_FHC_SRC_DISABLE          (1 << 17)
-#define CG6_FHC_DST_DISABLE          (1 << 16)
-#define CG6_FHC_RESET                (1 << 15)
-#define CG6_FHC_LITTLE_ENDIAN        (1 << 13)
-#define CG6_FHC_RES_MASK             (3 << 11)
-#define CG6_FHC_1024                 (0 << 11)
-#define CG6_FHC_1152                 (1 << 11)
-#define CG6_FHC_1280                 (2 << 11)
-#define CG6_FHC_1600                 (3 << 11)
-#define CG6_FHC_CPU_MASK             (3 << 9)
-#define CG6_FHC_CPU_SPARC            (0 << 9)
-#define CG6_FHC_CPU_68020            (1 << 9)
-#define CG6_FHC_CPU_386              (2 << 9)
-#define CG6_FHC_TEST		     (1 << 8)
-#define CG6_FHC_TEST_X_SHIFT	     4
-#define CG6_FHC_TEST_X_MASK	     15
-#define CG6_FHC_TEST_Y_SHIFT	     0
-#define CG6_FHC_TEST_Y_MASK	     15
-
-/* FBC mode definitions */
-#define CG6_FBC_BLIT_IGNORE		0x00000000
-#define CG6_FBC_BLIT_NOSRC		0x00100000
-#define CG6_FBC_BLIT_SRC		0x00200000
-#define CG6_FBC_BLIT_ILLEGAL		0x00300000
-#define CG6_FBC_BLIT_MASK		0x00300000
-
-#define CG6_FBC_VBLANK			0x00080000
-
-#define CG6_FBC_MODE_IGNORE		0x00000000
-#define CG6_FBC_MODE_COLOR8		0x00020000
-#define CG6_FBC_MODE_COLOR1		0x00040000
-#define CG6_FBC_MODE_HRMONO		0x00060000
-#define CG6_FBC_MODE_MASK		0x00060000
-
-#define CG6_FBC_DRAW_IGNORE		0x00000000
-#define CG6_FBC_DRAW_RENDER		0x00008000
-#define CG6_FBC_DRAW_PICK		0x00010000
-#define CG6_FBC_DRAW_ILLEGAL		0x00018000
-#define CG6_FBC_DRAW_MASK		0x00018000
-
-#define CG6_FBC_BWRITE0_IGNORE		0x00000000
-#define CG6_FBC_BWRITE0_ENABLE		0x00002000
-#define CG6_FBC_BWRITE0_DISABLE		0x00004000
-#define CG6_FBC_BWRITE0_ILLEGAL		0x00006000
-#define CG6_FBC_BWRITE0_MASK		0x00006000
-
-#define CG6_FBC_BWRITE1_IGNORE		0x00000000
-#define CG6_FBC_BWRITE1_ENABLE		0x00000800
-#define CG6_FBC_BWRITE1_DISABLE		0x00001000
-#define CG6_FBC_BWRITE1_ILLEGAL		0x00001800
-#define CG6_FBC_BWRITE1_MASK		0x00001800
-
-#define CG6_FBC_BREAD_IGNORE		0x00000000
-#define CG6_FBC_BREAD_0			0x00000200
-#define CG6_FBC_BREAD_1			0x00000400
-#define CG6_FBC_BREAD_ILLEGAL		0x00000600
-#define CG6_FBC_BREAD_MASK		0x00000600
-
-#define CG6_FBC_BDISP_IGNORE		0x00000000
-#define CG6_FBC_BDISP_0			0x00000080
-#define CG6_FBC_BDISP_1			0x00000100
-#define CG6_FBC_BDISP_ILLEGAL		0x00000180
-#define CG6_FBC_BDISP_MASK		0x00000180
-
-#define CG6_FBC_INDEX_MOD		0x00000040
-#define CG6_FBC_INDEX_MASK		0x00000030
-
-/* THC definitions */
-#define CG6_THC_MISC_REV_SHIFT       16
-#define CG6_THC_MISC_REV_MASK        15
-#define CG6_THC_MISC_RESET           (1 << 12)
-#define CG6_THC_MISC_VIDEO           (1 << 10)
-#define CG6_THC_MISC_SYNC            (1 << 9)
-#define CG6_THC_MISC_VSYNC           (1 << 8)
-#define CG6_THC_MISC_SYNC_ENAB       (1 << 7)
-#define CG6_THC_MISC_CURS_RES        (1 << 6)
-#define CG6_THC_MISC_INT_ENAB        (1 << 5)
-#define CG6_THC_MISC_INT             (1 << 4)
-#define CG6_THC_MISC_INIT            0x9f
-
-MODULE_LICENSE("GPL");
-
-/* The contents are unknown */
-struct cg6_tec {
-	volatile int tec_matrix;
-	volatile int tec_clip;
-	volatile int tec_vdc;
-};
-
-struct cg6_thc {
-        uint thc_pad0[512];
-	volatile uint thc_hs;		/* hsync timing */
-	volatile uint thc_hsdvs;
-	volatile uint thc_hd;
-	volatile uint thc_vs;		/* vsync timing */
-	volatile uint thc_vd;
-	volatile uint thc_refresh;
-	volatile uint thc_misc;
-	uint thc_pad1[56];
-	volatile uint thc_cursxy;	/* cursor x,y position (16 bits each) */
-	volatile uint thc_cursmask[32];	/* cursor mask bits */
-	volatile uint thc_cursbits[32];	/* what to show where mask enabled */
-};
-
-struct cg6_fbc {
-	u32		xxx0[1];
-	volatile u32	mode;
-	volatile u32	clip;
-	u32		xxx1[1];	    
-	volatile u32	s;
-	volatile u32	draw;
-	volatile u32	blit;
-	volatile u32	font;
-	u32		xxx2[24];
-	volatile u32	x0, y0, z0, color0;
-	volatile u32	x1, y1, z1, color1;
-	volatile u32	x2, y2, z2, color2;
-	volatile u32	x3, y3, z3, color3;
-	volatile u32	offx, offy;
-	u32		xxx3[2];
-	volatile u32	incx, incy;
-	u32		xxx4[2];
-	volatile u32	clipminx, clipminy;
-	u32		xxx5[2];
-	volatile u32	clipmaxx, clipmaxy;
-	u32		xxx6[2];
-	volatile u32	fg;
-	volatile u32	bg;
-	volatile u32	alu;
-	volatile u32	pm;
-	volatile u32	pixelm;
-	u32		xxx7[2];
-	volatile u32	patalign;
-	volatile u32	pattern[8];
-	u32		xxx8[432];
-	volatile u32	apointx, apointy, apointz;
-	u32		xxx9[1];
-	volatile u32	rpointx, rpointy, rpointz;
-	u32		xxx10[5];
-	volatile u32	pointr, pointg, pointb, pointa;
-	volatile u32	alinex, aliney, alinez;
-	u32		xxx11[1];
-	volatile u32	rlinex, rliney, rlinez;
-	u32		xxx12[5];
-	volatile u32	liner, lineg, lineb, linea;
-	volatile u32	atrix, atriy, atriz;
-	u32		xxx13[1];
-	volatile u32	rtrix, rtriy, rtriz;
-	u32		xxx14[5];
-	volatile u32	trir, trig, trib, tria;
-	volatile u32	aquadx, aquady, aquadz;
-	u32		xxx15[1];
-	volatile u32	rquadx, rquady, rquadz;
-	u32		xxx16[5];
-	volatile u32	quadr, quadg, quadb, quada;
-	volatile u32	arectx, arecty, arectz;
-	u32		xxx17[1];
-	volatile u32	rrectx, rrecty, rrectz;
-	u32		xxx18[5];
-	volatile u32	rectr, rectg, rectb, recta;
-};
-
-static struct sbus_mmap_map cg6_mmap_map[] = {
-	{ CG6_FBC,		CG6_FBC_OFFSET,		PAGE_SIZE 		},
-	{ CG6_TEC,		CG6_TEC_OFFSET,		PAGE_SIZE 		},
-	{ CG6_BTREGS,		CG6_BROOKTREE_OFFSET,	PAGE_SIZE 		},
-	{ CG6_FHC,		CG6_FHC_OFFSET,		PAGE_SIZE 		},
-	{ CG6_THC,		CG6_THC_OFFSET,		PAGE_SIZE 		},
-	{ CG6_ROM,		CG6_ROM_OFFSET,		0x10000   		},
-	{ CG6_RAM,		CG6_RAM_OFFSET,		SBUS_MMAP_FBSIZE(1)  	},
-	{ CG6_DHC,		CG6_DHC_OFFSET,		0x40000   		},
-	{ 0,			0,			0	  		}
-};
-
-static void cg6_setup(struct display *p)
-{
-	p->next_line = p->fb_info->var.xres_virtual;
-	p->next_plane = 0;
-}
-
-static void cg6_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		      int height, int width)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(p->fb_info);
-	register struct cg6_fbc *fbc = fb->s.cg6.fbc;
-	unsigned long flags;
-	int x, y, w, h;
-	int i;
-	
-	spin_lock_irqsave(&fb->lock, flags);
-	do {
-		i = sbus_readl(&fbc->s);
-	} while (i & 0x10000000);
-	sbus_writel(attr_bgcol_ec(p,conp), &fbc->fg);
-	sbus_writel(attr_bgcol_ec(p,conp), &fbc->bg);
-	sbus_writel(~0, &fbc->pixelm);
-	sbus_writel(0xea80ff00, &fbc->alu);
-	sbus_writel(0, &fbc->s);
-	sbus_writel(0, &fbc->clip);
-	sbus_writel(~0, &fbc->pm);
-
-        if (fontheightlog(p)) {
-		y = sy << fontheightlog(p); h = height << fontheightlog(p);
-	} else {
-		y = sy * fontheight(p); h = height * fontheight(p);
-	}
-	if (fontwidthlog(p)) {
-		x = sx << fontwidthlog(p); w = width << fontwidthlog(p);
-	} else {
-		x = sx * fontwidth(p); w = width * fontwidth(p);
-	}
-	sbus_writel(y + fb->y_margin, &fbc->arecty);
-	sbus_writel(x + fb->x_margin, &fbc->arectx);
-	sbus_writel(y + fb->y_margin + h, &fbc->arecty);
-	sbus_writel(x + fb->x_margin + w, &fbc->arectx);
-	do {
-		i = sbus_readl(&fbc->draw);
-	} while (i < 0 && (i & 0x20000000));
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg6_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
-		     int count, unsigned short *boxes)
-{
-	int i;
-	register struct cg6_fbc *fbc = fb->s.cg6.fbc;
-	unsigned long flags;
-	
-	spin_lock_irqsave(&fb->lock, flags);
-	do {
-		i = sbus_readl(&fbc->s);
-	} while (i & 0x10000000);
-	sbus_writel(attr_bgcol(p,s), &fbc->fg);
-	sbus_writel(attr_bgcol(p,s), &fbc->bg);
-	sbus_writel(~0, &fbc->pixelm);
-	sbus_writel(0xea80ff00, &fbc->alu);
-	sbus_writel(0, &fbc->s);
-	sbus_writel(0, &fbc->clip);
-	sbus_writel(~0, &fbc->pm);
-	while (count-- > 0) {
-		sbus_writel(boxes[1], &fbc->arecty);
-		sbus_writel(boxes[0], &fbc->arectx);
-		sbus_writel(boxes[3], &fbc->arecty);
-		sbus_writel(boxes[2], &fbc->arectx);
-		boxes += 4;
-		do {
-			i = sbus_readl(&fbc->draw);
-		} while (i < 0 && (i & 0x20000000));
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg6_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(p->fb_info);
-	register struct cg6_fbc *fbc = fb->s.cg6.fbc;
-	unsigned long flags;
-	int i, x, y;
-	u8 *fd;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	if (fontheightlog(p)) {
-		y = fb->y_margin + (yy << fontheightlog(p));
-		i = ((c & p->charmask) << fontheightlog(p));
-	} else {
-		y = fb->y_margin + (yy * fontheight(p));
-		i = (c & p->charmask) * fontheight(p);
-	}
-	if (fontwidth(p) <= 8)
-		fd = p->fontdata + i;
-	else
-		fd = p->fontdata + (i << 1);
-	if (fontwidthlog(p))
-		x = fb->x_margin + (xx << fontwidthlog(p));
-	else
-		x = fb->x_margin + (xx * fontwidth(p));
-	do {
-		i = sbus_readl(&fbc->s);
-	} while (i & 0x10000000);
-	sbus_writel(attr_fgcol(p,c), &fbc->fg);
-	sbus_writel(attr_bgcol(p,c), &fbc->bg);
-	sbus_writel(0x140000, &fbc->mode);
-	sbus_writel(0xe880fc30, &fbc->alu);
-	sbus_writel(~0, &fbc->pixelm);
-	sbus_writel(0, &fbc->s);
-	sbus_writel(0, &fbc->clip);
-	sbus_writel(0xff, &fbc->pm);
-	sbus_writel(0, &fbc->incx);
-	sbus_writel(1, &fbc->incy);
-	sbus_writel(x, &fbc->x0);
-	sbus_writel(x + fontwidth(p) - 1, &fbc->x1);
-	sbus_writel(y, &fbc->y0);
-	if (fontwidth(p) <= 8) {
-		for (i = 0; i < fontheight(p); i++) {
-			u32 val = *fd++ << 24;
-			sbus_writel(val, &fbc->font);
-		}
-	} else {
-		for (i = 0; i < fontheight(p); i++) {
-			u32 val = *(u16 *)fd << 16;
-
-			sbus_writel(val, &fbc->font);
-			fd += 2;
-		}
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg6_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
-		      int count, int yy, int xx)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(p->fb_info);
-	register struct cg6_fbc *fbc = fb->s.cg6.fbc;
-	unsigned long flags;
-	int i, x, y;
-	u8 *fd1, *fd2, *fd3, *fd4;
-	u16 c;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	do {
-		i = sbus_readl(&fbc->s);
-	} while (i & 0x10000000);
-	c = scr_readw(s);
-	sbus_writel(attr_fgcol(p, c), &fbc->fg);
-	sbus_writel(attr_bgcol(p, c), &fbc->bg);
-	sbus_writel(0x140000, &fbc->mode);
-	sbus_writel(0xe880fc30, &fbc->alu);
-	sbus_writel(~0, &fbc->pixelm);
-	sbus_writel(0, &fbc->s);
-	sbus_writel(0, &fbc->clip);
-	sbus_writel(0xff, &fbc->pm);
-	x = fb->x_margin;
-	y = fb->y_margin;
-	if (fontwidthlog(p))
-		x += (xx << fontwidthlog(p));
-	else
-		x += xx * fontwidth(p);
-	if (fontheightlog(p))
-		y += (yy << fontheightlog(p));
-	else
-		y += (yy * fontheight(p));
-	if (fontwidth(p) <= 8) {
-		while (count >= 4) {
-			count -= 4;
-			sbus_writel(0, &fbc->incx);
-			sbus_writel(1, &fbc->incy);
-			sbus_writel(x, &fbc->x0);
-			sbus_writel((x += 4 * fontwidth(p)) - 1, &fbc->x1);
-			sbus_writel(y, &fbc->y0);
-			if (fontheightlog(p)) {
-				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-				fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-				fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-			} else {
-				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
-				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
-				fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
-				fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
-			}
-			if (fontwidth(p) == 8) {
-				for (i = 0; i < fontheight(p); i++) {
-					u32 val = ((u32)*fd4++) |
-						((((u32)*fd3++) |
-						  ((((u32)*fd2++) |
-						    (((u32)*fd1++)
-						     << 8)) << 8)) << 8);
-					sbus_writel(val, &fbc->font);
-				}
-			} else {
-				for (i = 0; i < fontheight(p); i++) {
-					u32 val = (((u32)*fd4++) |
-						   ((((u32)*fd3++) |
-						     ((((u32)*fd2++) |
-						       (((u32)*fd1++) 
-							<< fontwidth(p))) <<
-						      fontwidth(p))) <<
-						    fontwidth(p))) <<
-						(24 - 3 * fontwidth(p));
-					sbus_writel(val, &fbc->font);
-				}
-			}
-		}
-	} else {
-		while (count >= 2) {
-			count -= 2;
-			sbus_writel(0, &fbc->incx);
-			sbus_writel(1, &fbc->incy);
-			sbus_writel(x, &fbc->x0);
-			sbus_writel((x += 2 * fontwidth(p)) - 1, &fbc->x1);
-			sbus_writel(y, &fbc->y0);
-			if (fontheightlog(p)) {
-				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
-				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
-			} else {
-				fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
-				fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
-			}
-			for (i = 0; i < fontheight(p); i++) {
-				u32 val = ((((u32)*(u16 *)fd1) << fontwidth(p)) |
-					   ((u32)*(u16 *)fd2)) << (16 - fontwidth(p));
-				sbus_writel(val, &fbc->font);
-				fd1 += 2; fd2 += 2;
-			}
-		}
-	}
-	while (count) {
-		count--;
-		sbus_writel(0, &fbc->incx);
-		sbus_writel(1, &fbc->incy);
-		sbus_writel(x, &fbc->x0);
-		sbus_writel((x += fontwidth(p)) - 1, &fbc->x1);
-		sbus_writel(y, &fbc->y0);
-		if (fontheightlog(p))
-			i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-		else
-			i = ((scr_readw(s++) & p->charmask) * fontheight(p));
-		if (fontwidth(p) <= 8) {
-			fd1 = p->fontdata + i;
-			for (i = 0; i < fontheight(p); i++) {
-				u32 val = *fd1++ << 24;
-				sbus_writel(val, &fbc->font);
-			}
-		} else {
-			fd1 = p->fontdata + (i << 1);
-			for (i = 0; i < fontheight(p); i++) {
-				u32 val = *(u16 *)fd1 << 16;
-				sbus_writel(val, &fbc->font);
-				fd1 += 2;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg6_revc(struct display *p, int xx, int yy)
-{
-	/* Not used if hw cursor */
-}
-
-static void cg6_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count)
-{
-	struct bt_regs *bt = fb->s.cg6.bt;
-	unsigned long flags;
-	int i;
-                
-	spin_lock_irqsave(&fb->lock, flags);
-	sbus_writel(index << 24, &bt->addr);
-	for (i = index; count--; i++){
-		sbus_writel(fb->color_map CM(i,0) << 24,
-			    &bt->color_map);
-		sbus_writel(fb->color_map CM(i,1) << 24,
-			    &bt->color_map);
-		sbus_writel(fb->color_map CM(i,2) << 24,
-			    &bt->color_map);
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg6_restore_palette (struct fb_info_sbusfb *fb)
-{
-	struct bt_regs *bt = fb->s.cg6.bt;
-	unsigned long flags;
-                
-	spin_lock_irqsave(&fb->lock, flags);
-	sbus_writel(0, &bt->addr);
-	sbus_writel(0xffffffff, &bt->color_map);
-	sbus_writel(0xffffffff, &bt->color_map);
-	sbus_writel(0xffffffff, &bt->color_map);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static struct display_switch cg6_dispsw __initdata = {
-	.setup =	cg6_setup,
-	.bmove =	fbcon_redraw_bmove,
-	.clear =	cg6_clear,
-	.putc =		cg6_putc,
-	.putcs =	cg6_putcs,
-	.revc =		cg6_revc, 
-	.fontwidthmask =FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
-};
-
-static void cg6_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
-{
-        struct bt_regs *bt = fb->s.cg6.bt;
-	unsigned long flags;
-        
-	spin_lock_irqsave(&fb->lock, flags);
-	sbus_writel(1 << 24, &bt->addr);
-	sbus_writel(red[0] << 24, &bt->cursor);
-	sbus_writel(green[0] << 24, &bt->cursor);
-	sbus_writel(blue[0] << 24, &bt->cursor);
-	sbus_writel(3 << 24, &bt->addr);
-	sbus_writel(red[1] << 24, &bt->cursor);
-	sbus_writel(green[1] << 24, &bt->cursor);
-	sbus_writel(blue[1] << 24, &bt->cursor);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-/* Set cursor shape */
-static void cg6_setcurshape (struct fb_info_sbusfb *fb)
-{
-	struct cg6_thc *thc = fb->s.cg6.thc;
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	for (i = 0; i < 32; i++) {
-		sbus_writel(fb->cursor.bits[0][i],
-			    &thc->thc_cursmask [i]);
-		sbus_writel(fb->cursor.bits[1][i],
-			    &thc->thc_cursbits [i]);
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-/* Load cursor information */
-static void cg6_setcursor (struct fb_info_sbusfb *fb)
-{
-	unsigned int v;
-	unsigned long flags;
-	struct cg_cursor *c = &fb->cursor;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	if (c->enable)
-		v = ((c->cpos.fbx - c->chot.fbx) << 16)
-		    |((c->cpos.fby - c->chot.fby) & 0xffff);
-	else
-		/* Magic constant to turn off the cursor */
-		v = ((65536-32) << 16) | (65536-32);
-	sbus_writel(v, &fb->s.cg6.thc->thc_cursxy);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static int cg6_blank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u32 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readl(&fb->s.cg6.thc->thc_misc);
-	tmp &= ~CG6_THC_MISC_VIDEO;
-	sbus_writel(tmp, &fb->s.cg6.thc->thc_misc);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static int cg6_unblank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u32 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readl(&fb->s.cg6.thc->thc_misc);
-	tmp |= CG6_THC_MISC_VIDEO;
-	sbus_writel(tmp, &fb->s.cg6.thc->thc_misc);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static void cg6_reset (struct fb_info_sbusfb *fb)
-{
-	unsigned int rev, conf;
-	struct cg6_tec *tec = fb->s.cg6.tec;
-	struct cg6_fbc *fbc = fb->s.cg6.fbc;
-	unsigned long flags;
-	u32 mode, tmp;
-	int i;
-	
-	spin_lock_irqsave(&fb->lock, flags);
-
-	/* Turn off stuff in the Transform Engine. */
-	sbus_writel(0, &tec->tec_matrix);
-	sbus_writel(0, &tec->tec_clip);
-	sbus_writel(0, &tec->tec_vdc);
-
-	/* Take care of bugs in old revisions. */
-	rev = (sbus_readl(fb->s.cg6.fhc) >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK;
-	if (rev < 5) {
-		conf = (sbus_readl(fb->s.cg6.fhc) & CG6_FHC_RES_MASK) |
-			CG6_FHC_CPU_68020 | CG6_FHC_TEST |
-			(11 << CG6_FHC_TEST_X_SHIFT) |
-			(11 << CG6_FHC_TEST_Y_SHIFT);
-		if (rev < 2)
-			conf |= CG6_FHC_DST_DISABLE;
-		sbus_writel(conf, fb->s.cg6.fhc);
-	}
-
-	/* Set things in the FBC. Bad things appear to happen if we do
-	 * back to back store/loads on the mode register, so copy it
-	 * out instead. */
-	mode = sbus_readl(&fbc->mode);
-	do {
-		i = sbus_readl(&fbc->s);
-	} while (i & 0x10000000);
-	mode &= ~(CG6_FBC_BLIT_MASK | CG6_FBC_MODE_MASK |
-		       CG6_FBC_DRAW_MASK | CG6_FBC_BWRITE0_MASK |
-		       CG6_FBC_BWRITE1_MASK | CG6_FBC_BREAD_MASK |
-		       CG6_FBC_BDISP_MASK);
-	mode |= (CG6_FBC_BLIT_SRC | CG6_FBC_MODE_COLOR8 |
-		      CG6_FBC_DRAW_RENDER | CG6_FBC_BWRITE0_ENABLE |
-		      CG6_FBC_BWRITE1_DISABLE | CG6_FBC_BREAD_0 |
-		      CG6_FBC_BDISP_0);
-	sbus_writel(mode, &fbc->mode);
-
-	sbus_writel(0, &fbc->clip);
-	sbus_writel(0, &fbc->offx);
-	sbus_writel(0, &fbc->offy);
-	sbus_writel(0, &fbc->clipminx);
-	sbus_writel(0, &fbc->clipminy);
-	sbus_writel(fb->type.fb_width - 1, &fbc->clipmaxx);
-	sbus_writel(fb->type.fb_height - 1, &fbc->clipmaxy);
-
-	/* Enable cursor in Brooktree DAC. */
-	sbus_writel(0x06 << 24, &fb->s.cg6.bt->addr);
-	tmp = sbus_readl(&fb->s.cg6.bt->control);
-	tmp |= 0x03 << 24;
-	sbus_writel(tmp, &fb->s.cg6.bt->control);
-
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void cg6_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
-{
-	fb->info.screen_base += (y_margin - fb->y_margin) *
-		fb->info.fix.line_length + (x_margin - fb->x_margin);
-}
-
-static int __init cg6_rasterimg (struct fb_info *info, int start)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(info);
-	register struct cg6_fbc *fbc = fb->s.cg6.fbc;
-	int i;
-	
-	do {
-		i = sbus_readl(&fbc->s);
-	} while (i & 0x10000000);
-	return 0;
-}
-
-static char idstring[70] __initdata = { 0 };
-
-char __init *cgsixfb_init(struct fb_info_sbusfb *fb)
-{
-	struct fb_fix_screeninfo *fix = &fb->info.fix;
-	struct fb_var_screeninfo *var = &fb->info.var;
-	struct display *disp = &fb->disp;
-	struct fbtype *type = &fb->type;
-	struct sbus_dev *sdev = fb->sbdp;
-	unsigned long phys = sdev->reg_addrs[0].phys_addr;
-	u32 conf;
-	char *p;
-	char *cardtype;
-	struct bt_regs *bt;
-	struct fb_ops *fbops;
-
-	fbops = kmalloc(sizeof(*fbops), GFP_KERNEL);
-	if (fbops == NULL)
-		return NULL;
-	
-	*fbops = *fb->info.fbops;
-	fbops->fb_rasterimg = cg6_rasterimg;
-	fb->info.fbops = fbops;
-	
-	if (prom_getbool (fb->prom_node, "dblbuf")) {
-		type->fb_size *= 4;
-		fix->smem_len *= 4;
-	}
-
-	fix->line_length = fb->info.var.xres_virtual;
-	fix->accel = FB_ACCEL_SUN_CGSIX;
-	
-	var->accel_flags = FB_ACCELF_TEXT;
-	
-	disp->scrollmode = SCROLL_YREDRAW;
-	if (!fb->info.screen_base) {
-		fb->info.screen_base = (char *)
-			sbus_ioremap(&sdev->resource[0], CG6_RAM_OFFSET,
-				     type->fb_size, "cgsix ram");
-	}
-	fb->info.screen_base += fix->line_length * fb->y_margin + fb->x_margin;
-	fb->s.cg6.fbc = (struct cg6_fbc *)
-		sbus_ioremap(&sdev->resource[0], CG6_FBC_OFFSET,
-			     4096, "cgsix fbc");
-	fb->s.cg6.tec = (struct cg6_tec *)
-		sbus_ioremap(&sdev->resource[0], CG6_TEC_OFFSET,
-			     sizeof(struct cg6_tec), "cgsix tec");
-	fb->s.cg6.thc = (struct cg6_thc *)
-		sbus_ioremap(&sdev->resource[0], CG6_THC_OFFSET,
-			     sizeof(struct cg6_thc), "cgsix thc");
-	fb->s.cg6.bt = bt = (struct bt_regs *)
-		sbus_ioremap(&sdev->resource[0], CG6_BROOKTREE_OFFSET,
-			     sizeof(struct bt_regs), "cgsix dac");
-	fb->s.cg6.fhc = (u32 *)
-		sbus_ioremap(&sdev->resource[0], CG6_FHC_OFFSET,
-			     sizeof(u32), "cgsix fhc");
-#if 0
-	prom_printf("CG6: RES[%016lx:%016lx:%016lx]\n",
-		    sdev->resource[0].start,
-		    sdev->resource[0].end,
-		    sdev->resource[0].flags);
-	prom_printf("CG6: fbc(%p) tec(%p) thc(%p) bt(%p) fhc(%p)\n",
-		    fb->s.cg6.fbc,
-		    fb->s.cg6.tec,
-		    fb->s.cg6.thc,
-		    fb->s.cg6.bt,
-		    fb->s.cg6.fhc);
-	prom_halt();
-#endif
-	fb->dispsw = cg6_dispsw;
-
-	fb->margins = cg6_margins;
-	fb->loadcmap = cg6_loadcmap;
-	fb->setcursor = cg6_setcursor;
-	fb->setcursormap = cg6_setcursormap;
-	fb->setcurshape = cg6_setcurshape;
-	fb->restore_palette = cg6_restore_palette;
-	fb->fill = cg6_fill;
-	fb->blank = cg6_blank;
-	fb->unblank = cg6_unblank;
-	fb->reset = cg6_reset;
-	
-	fb->physbase = phys;
-	fb->mmap_map = cg6_mmap_map;
-	
-	/* Initialize Brooktree DAC */
-	sbus_writel(0x04 << 24, &bt->addr);         /* color planes */
-	sbus_writel(0xff << 24, &bt->control);
-	sbus_writel(0x05 << 24, &bt->addr);
-	sbus_writel(0x00 << 24, &bt->control);
-	sbus_writel(0x06 << 24, &bt->addr);         /* overlay plane */
-	sbus_writel(0x73 << 24, &bt->control);
-	sbus_writel(0x07 << 24, &bt->addr);
-	sbus_writel(0x00 << 24, &bt->control);
-	
-	conf = sbus_readl(fb->s.cg6.fhc);
-	switch(conf & CG6_FHC_CPU_MASK) {
-	case CG6_FHC_CPU_SPARC: p = "sparc"; break;
-	case CG6_FHC_CPU_68020: p = "68020"; break;
-	default: p = "i386"; break;
-	}
-
-	if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) {
-		if (fix->smem_len <= 0x100000) {
-			cardtype = "TGX";
-		} else {
-			cardtype = "TGX+";
-		}
-	} else {
-		if (fix->smem_len <= 0x100000) {
-			cardtype = "GX";
-		} else {
-			cardtype = "GX+";
-		}
-	}
-	                                                                        
-	sprintf(idstring, 
-#ifdef __sparc_v9__
-		    "cgsix at %016lx TEC Rev %x CPU %s Rev %x [%s]", phys,
-#else	
-		    "cgsix at %x.%08lx TEC Rev %x CPU %s Rev %x [%s]",
-		    fb->iospace, phys, 
-#endif
-		    ((sbus_readl(&fb->s.cg6.thc->thc_misc) >> CG6_THC_MISC_REV_SHIFT) &
-		     CG6_THC_MISC_REV_MASK),
-		    p, (conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK, cardtype);
-
-	sprintf(fb->info.modename, "CGsix [%s]", cardtype);
-	sprintf(fix->id, "CGsix [%s]", cardtype);
-		    
-	cg6_reset(fb);
-		    
-	return idstring;
-}
diff -Nru a/drivers/video/cgthreefb.c b/drivers/video/cgthreefb.c
--- a/drivers/video/cgthreefb.c	Tue Mar  4 19:30:13 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,286 +0,0 @@
-/* $Id: cgthreefb.c,v 1.11 2001/09/19 00:04:33 davem Exp $
- * cgthreefb.c: CGthree frame buffer driver
- *
- * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
- * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-
-#include <video/sbusfb.h>
-#include <asm/io.h>
-
-#include <video/fbcon-cfb8.h>
-
-/* Control Register Constants */
-#define CG3_CR_ENABLE_INTS      0x80
-#define CG3_CR_ENABLE_VIDEO     0x40
-#define CG3_CR_ENABLE_TIMING    0x20
-#define CG3_CR_ENABLE_CURCMP    0x10
-#define CG3_CR_XTAL_MASK        0x0c
-#define CG3_CR_DIVISOR_MASK     0x03
-
-/* Status Register Constants */
-#define CG3_SR_PENDING_INT      0x80
-#define CG3_SR_RES_MASK         0x70
-#define CG3_SR_1152_900_76_A    0x40
-#define CG3_SR_1152_900_76_B    0x60
-#define CG3_SR_ID_MASK          0x0f
-#define CG3_SR_ID_COLOR         0x01
-#define CG3_SR_ID_MONO          0x02
-#define CG3_SR_ID_MONO_ECL      0x03
-
-MODULE_LICENSE("GPL");
-
-enum cg3_type {
-	CG3_AT_66HZ = 0,
-	CG3_AT_76HZ,
-	CG3_RDI
-};
-
-struct cg3_regs {
-	struct bt_regs	cmap;
-	volatile u8	control;
-	volatile u8	status;
-	volatile u8	cursor_start;
-	volatile u8	cursor_end;
-	volatile u8	h_blank_start;
-	volatile u8	h_blank_end;
-	volatile u8	h_sync_start;
-	volatile u8	h_sync_end;
-	volatile u8	comp_sync_end;
-	volatile u8	v_blank_start_high;
-	volatile u8	v_blank_start_low;
-	volatile u8	v_blank_end;
-	volatile u8	v_sync_start;
-	volatile u8	v_sync_end;
-	volatile u8	xfer_holdoff_start;
-	volatile u8	xfer_holdoff_end;
-};
-
-/* Offset of interesting structures in the OBIO space */
-#define CG3_REGS_OFFSET	     0x400000UL
-#define CG3_RAM_OFFSET	     0x800000UL
-
-static struct sbus_mmap_map cg3_mmap_map[] = {
-	{ CG3_MMAP_OFFSET,	CG3_RAM_OFFSET,		SBUS_MMAP_FBSIZE(1) },
-	{ 0,			0,			0		    }
-};
-
-/* The cg3 palette is loaded with 4 color values at each time  */
-/* so you end up with: (rgb)(r), (gb)(rg), (b)(rgb), and so on */
-
-#define D4M3(x) ((((x)>>2)<<1) + ((x)>>2))      /* (x/4)*3 */
-#define D4M4(x) ((x)&~0x3)                      /* (x/4)*4 */
-
-static void cg3_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count)
-{
-	struct bt_regs *bt = &fb->s.cg3.regs->cmap;
-	unsigned long flags;
-	u32 *i;
-	volatile u8 *regp;
-	int steps;
-	        
-	spin_lock_irqsave(&fb->lock, flags);
-
-	i = (((u32 *)fb->color_map) + D4M3(index));
-	steps = D4M3(index+count-1) - D4M3(index)+3;
-	                        
-	regp = (volatile u8 *)&bt->addr;
-	sbus_writeb(D4M4(index), regp);
-	while (steps--) {
-		u32 val = *i++;
-		sbus_writel(val, &bt->color_map);
-	}
-
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static int cg3_blank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u8 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readb(&fb->s.cg3.regs->control);
-	tmp &= ~CG3_CR_ENABLE_VIDEO;
-	sbus_writeb(tmp, &fb->s.cg3.regs->control);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static int cg3_unblank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u8 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readb(&fb->s.cg3.regs->control);
-	tmp |= CG3_CR_ENABLE_VIDEO;
-	sbus_writeb(tmp, &fb->s.cg3.regs->control);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static void cg3_margins (struct fb_info_sbusfb *fb, struct display *p,
-			 int x_margin, int y_margin)
-{
-	fb->info.screen_base += (y_margin - fb->y_margin) *
-		fb->info.fix.line_length + (x_margin - fb->x_margin);
-}
-
-static u8 cg3regvals_66hz[] __initdata = {	/* 1152 x 900, 66 Hz */
-	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x04,	0x17, 0x14,
-	0x18, 0xae,	0x19, 0x03,	0x1a, 0xa8,	0x1b, 0x24,
-	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
-	0x10, 0x20,	0
-};
-
-static u8 cg3regvals_76hz[] __initdata = {	/* 1152 x 900, 76 Hz */
-	0x14, 0xb7,	0x15, 0x27,	0x16, 0x03,	0x17, 0x0f,
-	0x18, 0xae,	0x19, 0x03,	0x1a, 0xae,	0x1b, 0x2a,
-	0x1c, 0x01,	0x1d, 0x09,	0x1e, 0xff,	0x1f, 0x01,
-	0x10, 0x24,	0
-};
-
-static u8 cg3regvals_rdi[] __initdata = {	/* 640 x 480, cgRDI */
-	0x14, 0x70,	0x15, 0x20,	0x16, 0x08,	0x17, 0x10,
-	0x18, 0x06,	0x19, 0x02,	0x1a, 0x31,	0x1b, 0x51,
-	0x1c, 0x06,	0x1d, 0x0c,	0x1e, 0xff,	0x1f, 0x01,
-	0x10, 0x22,	0
-};
-
-static u8 *cg3_regvals[] __initdata = {
-	cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
-};
-
-static u_char cg3_dacvals[] __initdata = {
-	4, 0xff,	5, 0x00,	6, 0x70,	7, 0x00,	0
-};
-
-static char idstring[60] __initdata = { 0 };
-
-char __init *cgthreefb_init(struct fb_info_sbusfb *fb)
-{
-	struct fb_fix_screeninfo *fix = &fb->info.fix;
-	struct display *disp = &fb->disp;
-	struct fbtype *type = &fb->type;
-	struct sbus_dev *sdev = fb->sbdp;
-	unsigned long phys = sdev->reg_addrs[0].phys_addr;
-	int cgRDI = strstr(fb->sbdp->prom_name, "cgRDI") != NULL;
-
-#ifndef FBCON_HAS_CFB8
-	return NULL;
-#endif
-
-	if (!fb->s.cg3.regs) {
-		fb->s.cg3.regs = (struct cg3_regs *)
-			sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
-				     sizeof(struct cg3_regs), "cg3 regs");
-		if (cgRDI) {
-			char buffer[40];
-			char *p;
-			int ww, hh;
-		
-			*buffer = 0;
-			prom_getstring (fb->prom_node, "params", buffer, sizeof(buffer));
-			if (*buffer) {
-				ww = simple_strtoul (buffer, &p, 10);
-				if (ww && *p == 'x') {
-					hh = simple_strtoul (p + 1, &p, 10);
-					if (hh && *p == '-') {
-						if (type->fb_width != ww || type->fb_height != hh) {
-							type->fb_width = ww;
-							type->fb_height = hh;
-							return SBUSFBINIT_SIZECHANGE;
-						}
-					}
-				}
-			}
-		}
-	}
-
-	strcpy(fb->info.modename, "CGthree");
-	strcpy(fix->id, "CGthree");
-	fix->line_length = fb->info.var.xres_virtual;
-	fix->accel = FB_ACCEL_SUN_CGTHREE;
-	
-	disp->scrollmode = SCROLL_YREDRAW;
-	if (!fb->info.screen_base) {
-		fb->info.screen_base = (char *)
-			sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
-				     type->fb_size, "cg3 ram");
-	}
-	fb->info.screen_base += fix->line_length * fb->y_margin + fb->x_margin;
-	fb->dispsw = fbcon_cfb8;
-
-	fb->margins = cg3_margins;
-	fb->loadcmap = cg3_loadcmap;
-	fb->blank = cg3_blank;
-	fb->unblank = cg3_unblank;
-	
-	fb->physbase = phys;
-	fb->mmap_map = cg3_mmap_map;
-	
-#ifdef __sparc_v9__	
-	sprintf(idstring, "%s at %016lx", cgRDI ? "cgRDI" : "cgthree", phys);
-#else
-	sprintf(idstring, "%s at %x.%08lx", cgRDI ? "cgRDI" : "cgthree", fb->iospace, phys);
-#endif
-	
-	if (!prom_getbool(fb->prom_node, "width")) {
-		/* Ugh, broken PROM didn't initialize us.
-		 * Let's deal with this ourselves.
-		 */
-		enum cg3_type type;
-		u8 *p;
-
-		if (cgRDI)
-			type = CG3_RDI;
-		else {
-			u8 status = sbus_readb(&fb->s.cg3.regs->status), mon;
-			if ((status & CG3_SR_ID_MASK) == CG3_SR_ID_COLOR) {
-				mon = status & CG3_SR_RES_MASK;
-				if (mon == CG3_SR_1152_900_76_A ||
-				    mon == CG3_SR_1152_900_76_B)
-					type = CG3_AT_76HZ;
-				else
-					type = CG3_AT_66HZ;
-			} else {
-				prom_printf("cgthree: can't handle SR %02x\n",
-					    status);
-				prom_halt();
-				return NULL; /* fool gcc. */
-			}
-		}
-
-		for (p = cg3_regvals[type]; *p; p += 2) {
-			u8 *regp = &((u8 *)fb->s.cg3.regs)[p[0]];
-			sbus_writeb(p[1], regp);
-		}
-		for (p = cg3_dacvals; *p; p += 2) {
-			volatile u8 *regp;
-
-			regp = (volatile u8 *)&fb->s.cg3.regs->cmap.addr;
-			sbus_writeb(p[0], regp);
-			regp = (volatile u8 *)&fb->s.cg3.regs->cmap.control;
-			sbus_writeb(p[1], regp);
-		}
-	}
-
-	return idstring;
-}
diff -Nru a/drivers/video/controlfb.c b/drivers/video/controlfb.c
--- a/drivers/video/controlfb.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/video/controlfb.c	Tue Mar  4 19:30:05 2003
@@ -554,7 +554,7 @@
 
 
 /*
- * Called from fbmem.c for probing & intializing
+ * Called from fbmem.c for probing & initializing
  */
 int __init control_init(void)
 {
diff -Nru a/drivers/video/creatorfb.c b/drivers/video/creatorfb.c
--- a/drivers/video/creatorfb.c	Tue Mar  4 19:30:04 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,928 +0,0 @@
-/* $Id: creatorfb.c,v 1.37 2001/10/16 05:44:44 davem Exp $
- * creatorfb.c: Creator/Creator3D frame buffer driver
- *
- * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-
-#include <video/sbusfb.h>
-
-#include <asm/upa.h>
-
-#define	FFB_SFB8R_VOFF		0x00000000
-#define	FFB_SFB8G_VOFF		0x00400000
-#define	FFB_SFB8B_VOFF		0x00800000
-#define	FFB_SFB8X_VOFF		0x00c00000
-#define	FFB_SFB32_VOFF		0x01000000
-#define	FFB_SFB64_VOFF		0x02000000
-#define	FFB_FBC_REGS_VOFF	0x04000000
-#define	FFB_BM_FBC_REGS_VOFF	0x04002000
-#define	FFB_DFB8R_VOFF		0x04004000
-#define	FFB_DFB8G_VOFF		0x04404000
-#define	FFB_DFB8B_VOFF		0x04804000
-#define	FFB_DFB8X_VOFF		0x04c04000
-#define	FFB_DFB24_VOFF		0x05004000
-#define	FFB_DFB32_VOFF		0x06004000
-#define	FFB_DFB422A_VOFF	0x07004000	/* DFB 422 mode write to A */
-#define	FFB_DFB422AD_VOFF	0x07804000	/* DFB 422 mode with line doubling */
-#define	FFB_DFB24B_VOFF		0x08004000	/* DFB 24bit mode write to B */
-#define	FFB_DFB422B_VOFF	0x09004000	/* DFB 422 mode write to B */
-#define	FFB_DFB422BD_VOFF	0x09804000	/* DFB 422 mode with line doubling */
-#define	FFB_SFB16Z_VOFF		0x0a004000	/* 16bit mode Z planes */
-#define	FFB_SFB8Z_VOFF		0x0a404000	/* 8bit mode Z planes */
-#define	FFB_SFB422_VOFF		0x0ac04000	/* SFB 422 mode write to A/B */
-#define	FFB_SFB422D_VOFF	0x0b404000	/* SFB 422 mode with line doubling */
-#define	FFB_FBC_KREGS_VOFF	0x0bc04000
-#define	FFB_DAC_VOFF		0x0bc06000
-#define	FFB_PROM_VOFF		0x0bc08000
-#define	FFB_EXP_VOFF		0x0bc18000
-
-#define	FFB_SFB8R_POFF		0x04000000UL
-#define	FFB_SFB8G_POFF		0x04400000UL
-#define	FFB_SFB8B_POFF		0x04800000UL
-#define	FFB_SFB8X_POFF		0x04c00000UL
-#define	FFB_SFB32_POFF		0x05000000UL
-#define	FFB_SFB64_POFF		0x06000000UL
-#define	FFB_FBC_REGS_POFF	0x00600000UL
-#define	FFB_BM_FBC_REGS_POFF	0x00600000UL
-#define	FFB_DFB8R_POFF		0x01000000UL
-#define	FFB_DFB8G_POFF		0x01400000UL
-#define	FFB_DFB8B_POFF		0x01800000UL
-#define	FFB_DFB8X_POFF		0x01c00000UL
-#define	FFB_DFB24_POFF		0x02000000UL
-#define	FFB_DFB32_POFF		0x03000000UL
-#define	FFB_FBC_KREGS_POFF	0x00610000UL
-#define	FFB_DAC_POFF		0x00400000UL
-#define	FFB_PROM_POFF		0x00000000UL
-#define	FFB_EXP_POFF		0x00200000UL
-#define FFB_DFB422A_POFF	0x09000000UL
-#define FFB_DFB422AD_POFF	0x09800000UL
-#define FFB_DFB24B_POFF		0x0a000000UL
-#define FFB_DFB422B_POFF	0x0b000000UL
-#define FFB_DFB422BD_POFF	0x0b800000UL
-#define FFB_SFB16Z_POFF		0x0c800000UL
-#define FFB_SFB8Z_POFF		0x0c000000UL
-#define FFB_SFB422_POFF		0x0d000000UL
-#define FFB_SFB422D_POFF	0x0d800000UL
-
-/* Draw operations */
-#define FFB_DRAWOP_DOT		0x00
-#define FFB_DRAWOP_AADOT	0x01
-#define FFB_DRAWOP_BRLINECAP	0x02
-#define FFB_DRAWOP_BRLINEOPEN	0x03
-#define FFB_DRAWOP_DDLINE	0x04
-#define FFB_DRAWOP_AALINE	0x05
-#define FFB_DRAWOP_TRIANGLE	0x06
-#define FFB_DRAWOP_POLYGON	0x07
-#define FFB_DRAWOP_RECTANGLE	0x08
-#define FFB_DRAWOP_FASTFILL	0x09
-#define FFB_DRAWOP_BCOPY	0x0a
-#define FFB_DRAWOP_VSCROLL	0x0b
-
-/* Pixel processor control */
-/* Force WID */
-#define FFB_PPC_FW_DISABLE	0x800000
-#define FFB_PPC_FW_ENABLE	0xc00000
-/* Auxiliary clip */
-#define FFB_PPC_ACE_DISABLE	0x040000
-#define FFB_PPC_ACE_AUX_SUB	0x080000
-#define FFB_PPC_ACE_AUX_ADD	0x0c0000
-/* Depth cue */
-#define FFB_PPC_DCE_DISABLE	0x020000
-#define FFB_PPC_DCE_ENABLE	0x030000
-/* Alpha blend */
-#define FFB_PPC_ABE_DISABLE	0x008000
-#define FFB_PPC_ABE_ENABLE	0x00c000
-/* View clip */
-#define FFB_PPC_VCE_DISABLE	0x001000
-#define FFB_PPC_VCE_2D		0x002000
-#define FFB_PPC_VCE_3D		0x003000
-/* Area pattern */
-#define FFB_PPC_APE_DISABLE	0x000800
-#define FFB_PPC_APE_ENABLE	0x000c00
-/* Transparent background */
-#define FFB_PPC_TBE_OPAQUE	0x000200
-#define FFB_PPC_TBE_TRANSPARENT	0x000300
-/* Z source */
-#define FFB_PPC_ZS_VAR		0x000080
-#define FFB_PPC_ZS_CONST	0x0000c0
-/* Y source */
-#define FFB_PPC_YS_VAR		0x000020
-#define FFB_PPC_YS_CONST	0x000030
-/* X source */
-#define FFB_PPC_XS_WID		0x000004
-#define FFB_PPC_XS_VAR		0x000008
-#define FFB_PPC_XS_CONST	0x00000c
-/* Color (BGR) source */
-#define FFB_PPC_CS_VAR		0x000002
-#define FFB_PPC_CS_CONST	0x000003
-
-#define FFB_ROP_NEW                  0x83
-
-#define FFB_UCSR_FIFO_MASK     0x00000fff
-#define FFB_UCSR_FB_BUSY       0x01000000
-#define FFB_UCSR_RP_BUSY       0x02000000
-#define FFB_UCSR_ALL_BUSY      (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
-#define FFB_UCSR_READ_ERR      0x40000000
-#define FFB_UCSR_FIFO_OVFL     0x80000000
-#define FFB_UCSR_ALL_ERRORS    (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL)
-
-struct ffb_fbc {
-	/* Next vertex registers */
-	u32		xxx1[3];
-	volatile u32	alpha;
-	volatile u32	red;
-	volatile u32	green;
-	volatile u32	blue;
-	volatile u32	depth;
-	volatile u32	y;
-	volatile u32	x;
-	u32		xxx2[2];
-	volatile u32	ryf;
-	volatile u32	rxf;
-	u32		xxx3[2];
-	
-	volatile u32	dmyf;
-	volatile u32	dmxf;
-	u32		xxx4[2];
-	volatile u32	ebyi;
-	volatile u32	ebxi;
-	u32		xxx5[2];
-	volatile u32	by;
-	volatile u32	bx;
-	u32		dy;
-	u32		dx;
-	volatile u32	bh;
-	volatile u32	bw;
-	u32		xxx6[2];
-	
-	u32		xxx7[32];
-	
-	/* Setup unit vertex state register */
-	volatile u32	suvtx;
-	u32		xxx8[63];
-	
-	/* Control registers */
-	volatile u32	ppc;
-	volatile u32	wid;
-	volatile u32	fg;
-	volatile u32	bg;
-	volatile u32	consty;
-	volatile u32	constz;
-	volatile u32	xclip;
-	volatile u32	dcss;
-	volatile u32	vclipmin;
-	volatile u32	vclipmax;
-	volatile u32	vclipzmin;
-	volatile u32	vclipzmax;
-	volatile u32	dcsf;
-	volatile u32	dcsb;
-	volatile u32	dczf;
-	volatile u32	dczb;
-	
-	u32		xxx9;
-	volatile u32	blendc;
-	volatile u32	blendc1;
-	volatile u32	blendc2;
-	volatile u32	fbramitc;
-	volatile u32	fbc;
-	volatile u32	rop;
-	volatile u32	cmp;
-	volatile u32	matchab;
-	volatile u32	matchc;
-	volatile u32	magnab;
-	volatile u32	magnc;
-	volatile u32	fbcfg0;
-	volatile u32	fbcfg1;
-	volatile u32	fbcfg2;
-	volatile u32	fbcfg3;
-	
-	u32		ppcfg;
-	volatile u32	pick;
-	volatile u32	fillmode;
-	volatile u32	fbramwac;
-	volatile u32	pmask;
-	volatile u32	xpmask;
-	volatile u32	ypmask;
-	volatile u32	zpmask;
-	volatile u32	clip0min;
-	volatile u32	clip0max;
-	volatile u32	clip1min;
-	volatile u32	clip1max;
-	volatile u32	clip2min;
-	volatile u32	clip2max;
-	volatile u32	clip3min;
-	volatile u32	clip3max;
-	
-	/* New 3dRAM III support regs */
-	volatile u32	rawblend2;
-	volatile u32	rawpreblend;
-	volatile u32	rawstencil;
-	volatile u32	rawstencilctl;
-	volatile u32	threedram1;
-	volatile u32	threedram2;
-	volatile u32	passin;
-	volatile u32	rawclrdepth;
-	volatile u32	rawpmask;
-	volatile u32	rawcsrc;
-	volatile u32	rawmatch;
-	volatile u32	rawmagn;
-	volatile u32	rawropblend;
-	volatile u32	rawcmp;
-	volatile u32	rawwac;
-	volatile u32	fbramid;
-	
-	volatile u32	drawop;
-	u32		xxx10[2];
-	volatile u32	fontlpat;
-	u32		xxx11;
-	volatile u32	fontxy;
-	volatile u32	fontw;
-	volatile u32	fontinc;
-	volatile u32	font;
-	u32		xxx12[3];
-	volatile u32	blend2;
-	volatile u32	preblend;
-	volatile u32	stencil;
-	volatile u32	stencilctl;
-
-	u32		xxx13[4];	
-	volatile u32	dcss1;
-	volatile u32	dcss2;
-	volatile u32	dcss3;
-	volatile u32	widpmask;
-	volatile u32	dcs2;
-	volatile u32	dcs3;
-	volatile u32	dcs4;
-	u32		xxx14;
-	volatile u32	dcd2;
-	volatile u32	dcd3;
-	volatile u32	dcd4;
-	u32		xxx15;
-	
-	volatile u32	pattern[32];
-	
-	u32		xxx16[256];
-	
-	volatile u32	devid;
-	u32		xxx17[63];
-	
-	volatile u32	ucsr;
-	u32		xxx18[31];
-	
-	volatile u32	mer;
-};
-
-static __inline__ void FFBFifo(struct fb_info_sbusfb *fb, int n)
-{
-	struct ffb_fbc *fbc;
-	int cache = fb->s.ffb.fifo_cache;
-
-	if (cache - n < 0) {
-		fbc = fb->s.ffb.fbc;
-		do {	cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK) - 8;
-		} while (cache - n < 0);
-	}
-	fb->s.ffb.fifo_cache = cache - n;
-}
-
-static __inline__ void FFBWait(struct ffb_fbc *ffb)
-{
-	int limit = 10000;
-
-	do {
-		if ((upa_readl(&ffb->ucsr) & FFB_UCSR_ALL_BUSY) == 0)
-			break;
-		if ((upa_readl(&ffb->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) {
-			upa_writel(FFB_UCSR_ALL_ERRORS, &ffb->ucsr);
-		}
-	} while(--limit > 0);
-}
-
-struct ffb_dac {
-	volatile u32	type;
-	volatile u32	value;
-	volatile u32	type2;
-	volatile u32	value2;
-};
-
-static struct sbus_mmap_map ffb_mmap_map[] = {
-	{ FFB_SFB8R_VOFF,	FFB_SFB8R_POFF,		0x0400000 },
-	{ FFB_SFB8G_VOFF,	FFB_SFB8G_POFF,		0x0400000 },
-	{ FFB_SFB8B_VOFF,	FFB_SFB8B_POFF,		0x0400000 },
-	{ FFB_SFB8X_VOFF,	FFB_SFB8X_POFF,		0x0400000 },
-	{ FFB_SFB32_VOFF,	FFB_SFB32_POFF,		0x1000000 },
-	{ FFB_SFB64_VOFF,	FFB_SFB64_POFF,		0x2000000 },
-	{ FFB_FBC_REGS_VOFF,	FFB_FBC_REGS_POFF,	0x0002000 },
-	{ FFB_BM_FBC_REGS_VOFF,	FFB_BM_FBC_REGS_POFF,	0x0002000 },
-	{ FFB_DFB8R_VOFF,	FFB_DFB8R_POFF,		0x0400000 },
-	{ FFB_DFB8G_VOFF,	FFB_DFB8G_POFF,		0x0400000 },
-	{ FFB_DFB8B_VOFF,	FFB_DFB8B_POFF,		0x0400000 },
-	{ FFB_DFB8X_VOFF,	FFB_DFB8X_POFF,		0x0400000 },
-	{ FFB_DFB24_VOFF,	FFB_DFB24_POFF,		0x1000000 },
-	{ FFB_DFB32_VOFF,	FFB_DFB32_POFF,		0x1000000 },
-	{ FFB_FBC_KREGS_VOFF,	FFB_FBC_KREGS_POFF,	0x0002000 },
-	{ FFB_DAC_VOFF,		FFB_DAC_POFF,		0x0002000 },
-	{ FFB_PROM_VOFF,	FFB_PROM_POFF,		0x0010000 },
-	{ FFB_EXP_VOFF,		FFB_EXP_POFF,		0x0002000 },
-	{ FFB_DFB422A_VOFF,	FFB_DFB422A_POFF,	0x0800000 },
-	{ FFB_DFB422AD_VOFF,	FFB_DFB422AD_POFF,	0x0800000 },
-	{ FFB_DFB24B_VOFF,	FFB_DFB24B_POFF,	0x1000000 },
-	{ FFB_DFB422B_VOFF,	FFB_DFB422B_POFF,	0x0800000 },
-	{ FFB_DFB422BD_VOFF,	FFB_DFB422BD_POFF,	0x0800000 },
-	{ FFB_SFB16Z_VOFF,	FFB_SFB16Z_POFF,	0x0800000 },
-	{ FFB_SFB8Z_VOFF,	FFB_SFB8Z_POFF,		0x0800000 },
-	{ FFB_SFB422_VOFF,	FFB_SFB422_POFF,	0x0800000 },
-	{ FFB_SFB422D_VOFF,	FFB_SFB422D_POFF,	0x0800000 },
-	{ 0,			0,			0	  }
-};
-
-static void ffb_setup(struct display *p)
-{
-	p->next_line = 8192;
-	p->next_plane = 0;
-}
-
-static void ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		      int height, int width)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(p->fb_info);
-	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
-	unsigned long flags;
-	u64 yx, hw;
-	int fg;
-	
-	spin_lock_irqsave(&fb->lock, flags);
-	fg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p,conp)];
-	if (fg != fb->s.ffb.fg_cache) {
-		FFBFifo(fb, 5);
-		upa_writel(fg, &fbc->fg);
-		fb->s.ffb.fg_cache = fg;
-	} else
-		FFBFifo(fb, 4);
-
-	if (fontheightlog(p)) {
-		yx = (u64)sy << (fontheightlog(p) + 32); hw = (u64)height << (fontheightlog(p) + 32);
-	} else {
-		yx = (u64)(sy * fontheight(p)) << 32; hw = (u64)(height * fontheight(p)) << 32;
-	}
-	if (fontwidthlog(p)) {
-		yx += sx << fontwidthlog(p); hw += width << fontwidthlog(p);
-	} else {
-		yx += sx * fontwidth(p); hw += width * fontwidth(p);
-	}
-	upa_writeq(yx + fb->s.ffb.yx_margin, &fbc->by);
-	upa_writeq(hw, &fbc->bh);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void ffb_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
-		     int count, unsigned short *boxes)
-{
-	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
-	unsigned long flags;
-	int fg;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	fg = ((u32 *)p->dispsw_data)[attr_bgcol(p,s)];
-	if (fg != fb->s.ffb.fg_cache) {
-		FFBFifo(fb, 1);
-		upa_writel(fg, &fbc->fg);
-		fb->s.ffb.fg_cache = fg;
-	}
-	while (count-- > 0) {
-		FFBFifo(fb, 4);
-		upa_writel(boxes[1], &fbc->by);
-		upa_writel(boxes[0], &fbc->bx);
-		upa_writel(boxes[3] - boxes[1], &fbc->bh);
-		upa_writel(boxes[2] - boxes[0], &fbc->bw);
-		boxes += 4;
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(p->fb_info);
-	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
-	unsigned long flags;
-	int i, xy;
-	u8 *fd;
-	u64 fgbg;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	if (fontheightlog(p)) {
-		xy = (yy << (16 + fontheightlog(p)));
-		i = ((c & p->charmask) << fontheightlog(p));
-	} else {
-		xy = ((yy * fontheight(p)) << 16);
-		i = (c & p->charmask) * fontheight(p);
-	}
-	if (fontwidth(p) <= 8)
-		fd = p->fontdata + i;
-	else
-		fd = p->fontdata + (i << 1);
-	if (fontwidthlog(p))
-		xy += (xx << fontwidthlog(p)) + fb->s.ffb.xy_margin;
-	else
-		xy += (xx * fontwidth(p)) + fb->s.ffb.xy_margin;
-	fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p,c)])) << 32) |
-	       ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
-	if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) {
-		FFBFifo(fb, 2);
-		upa_writeq(fgbg, &fbc->fg);
-		*(u64 *)&fb->s.ffb.fg_cache = fgbg;
-	}
-	FFBFifo(fb, 2 + fontheight(p));
-	upa_writel(xy, &fbc->fontxy);
-	upa_writel(fontwidth(p), &fbc->fontw);
-	if (fontwidth(p) <= 8) {
-		for (i = 0; i < fontheight(p); i++) {
-			u32 val = *fd++ << 24;
-
-			upa_writel(val, &fbc->font);
-		}
-	} else {
-		for (i = 0; i < fontheight(p); i++) {
-			u32 val = *(u16 *)fd << 16;
-
-			upa_writel(val, &fbc->font);
-			fd += 2;
-		}
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
-		      int count, int yy, int xx)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(p->fb_info);
-	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
-	unsigned long flags;
-	int i, xy;
-	u8 *fd1, *fd2, *fd3, *fd4;
-	u16 c;
-	u64 fgbg;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	c = scr_readw(s);
-	fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p, c)])) << 32) |
-	       ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
-	if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) {
-		FFBFifo(fb, 2);
-		upa_writeq(fgbg, &fbc->fg);
-		*(u64 *)&fb->s.ffb.fg_cache = fgbg;
-	}
-	xy = fb->s.ffb.xy_margin;
-	if (fontwidthlog(p))
-		xy += (xx << fontwidthlog(p));
-	else
-		xy += xx * fontwidth(p);
-	if (fontheightlog(p))
-		xy += (yy << (16 + fontheightlog(p)));
-	else
-		xy += ((yy * fontheight(p)) << 16);
-	if (fontwidth(p) <= 8) {
-		while (count >= 4) {
-			count -= 4;
-			FFBFifo(fb, 2 + fontheight(p));
-			upa_writel(4 * fontwidth(p), &fbc->fontw);
-			upa_writel(xy, &fbc->fontxy);
-			if (fontheightlog(p)) {
-				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-				fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-				fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-			} else {
-				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
-				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
-				fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
-				fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
-			}
-			if (fontwidth(p) == 8) {
-				for (i = 0; i < fontheight(p); i++) {
-					u32 val;
-
-					val = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
-						<< 8)) << 8)) << 8);
-					upa_writel(val, &fbc->font);
-				}
-				xy += 32;
-			} else {
-				for (i = 0; i < fontheight(p); i++) {
-					u32 val = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
-						<< fontwidth(p))) << fontwidth(p))) << fontwidth(p))) << (24 - 3 * fontwidth(p));
-					upa_writel(val, &fbc->font);
-				}
-				xy += 4 * fontwidth(p);
-			}
-		}
-	} else {
-		while (count >= 2) {
-			count -= 2;
-			FFBFifo(fb, 2 + fontheight(p));
-			upa_writel(2 * fontwidth(p), &fbc->fontw);
-			upa_writel(xy, &fbc->fontxy);
-			if (fontheightlog(p)) {
-				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
-				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
-			} else {
-				fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
-				fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
-			}
-			for (i = 0; i < fontheight(p); i++) {
-				u32 val = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p));
-
-				upa_writel(val, &fbc->font);
-				fd1 += 2; fd2 += 2;
-			}
-			xy += 2 * fontwidth(p);
-		}
-	}
-	while (count) {
-		count--;
-		FFBFifo(fb, 2 + fontheight(p));
-		upa_writel(fontwidth(p), &fbc->fontw);
-		upa_writel(xy, &fbc->fontxy);
-		if (fontheightlog(p))
-			i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));
-		else
-			i = ((scr_readw(s++) & p->charmask) * fontheight(p));
-		if (fontwidth(p) <= 8) {
-			fd1 = p->fontdata + i;
-			for (i = 0; i < fontheight(p); i++) {
-				u32 val = *fd1++ << 24;
-
-				upa_writel(val, &fbc->font);
-			}
-		} else {
-			fd1 = p->fontdata + (i << 1);
-			for (i = 0; i < fontheight(p); i++) {
-				u32 val = *(u16 *)fd1 << 16;
-
-				upa_writel(val, &fbc->font);
-				fd1 += 2;
-			}
-		}
-		xy += fontwidth(p);
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void ffb_revc(struct display *p, int xx, int yy)
-{
-	/* Not used if hw cursor */
-}
-
-#if 0
-static int ffb_blank(struct fb_info_sbusfb *fb)
-{
-	struct ffb_dac *dac = fb->s.ffb.dac;
-	unsigned long flags;
-	u32 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	upa_writel(0x6000, &dac->type);
-	tmp = (upa_readl(&dac->value) & ~0x1);
-	upa_writel(0x6000, &dac->type);
-	upa_writel(tmp, &dac->value);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-#endif
-
-static int ffb_unblank(struct fb_info_sbusfb *fb)
-{
-	struct ffb_dac *dac = fb->s.ffb.dac;
-	unsigned long flags;
-	u32 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	upa_writel(0x6000, &dac->type);
-	tmp = (upa_readl(&dac->value) | 0x1);
-	upa_writel(0x6000, &dac->type);
-	upa_writel(tmp, &dac->value);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static void ffb_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count)
-{
-	struct ffb_dac *dac = fb->s.ffb.dac;
-	unsigned long flags;
-	int i, j = count;
-	
-	spin_lock_irqsave(&fb->lock, flags);
-	upa_writel(0x2000 | index, &dac->type);
-	for (i = index; j--; i++) {
-		u32 val;
-
-		/* Feed the colors in :)) */
-		val = ((fb->color_map CM(i,0))) |
-			((fb->color_map CM(i,1)) << 8) |
-			((fb->color_map CM(i,2)) << 16);
-		upa_writel(val, &dac->value);
-	}
-	if (!p)
-		goto out;
-	for (i = index, j = count; i < 16 && j--; i++)
-		((u32 *)p->dispsw_data)[i] = ((fb->color_map CM(i,0))) |
-			      		     ((fb->color_map CM(i,1)) << 8) |
-					     ((fb->color_map CM(i,2)) << 16);
-out:
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static struct display_switch ffb_dispsw __initdata = {
-	.setup =	ffb_setup,
-	.bmove =	fbcon_redraw_bmove,
-	.clear =	ffb_clear,
-	.putc =		ffb_putc,
-	.putcs =	ffb_putcs,
-	.revc =		ffb_revc, 
-	.fontwidthmask =FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
-};
-
-static void ffb_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
-{
-	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
-	unsigned long flags;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	fb->s.ffb.xy_margin = (y_margin << 16) + x_margin;
-	fb->s.ffb.yx_margin = (((u64)y_margin) << 32) + x_margin;
-	fb->info.screen_base += 8192 * (y_margin - fb->y_margin) + 4 * (x_margin - fb->x_margin);
-	FFBWait(fbc);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static __inline__ void __ffb_curs_enable (struct fb_info_sbusfb *fb, int enable)
-{
-	struct ffb_dac *dac = fb->s.ffb.dac;
-	u32 val;
-
-	upa_writel(0x100, &dac->type2);
-	if (fb->s.ffb.dac_rev <= 2) {
-		val = enable ? 3 : 0;
-	} else {
-		val = enable ? 0 : 3;
-	}
-	upa_writel(val, &dac->value2);
-}
-
-static void ffb_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
-{
-	struct ffb_dac *dac = fb->s.ffb.dac;
-	unsigned long flags;
-	
-	spin_lock_irqsave(&fb->lock, flags);
-	__ffb_curs_enable (fb, 0);
-	upa_writel(0x102, &dac->type2);
-	upa_writel((red[0] | (green[0]<<8) | (blue[0]<<16)), &dac->value2);
-	upa_writel((red[1] | (green[1]<<8) | (blue[1]<<16)), &dac->value2);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-/* Set cursor shape */
-static void ffb_setcurshape (struct fb_info_sbusfb *fb)
-{
-	struct ffb_dac *dac = fb->s.ffb.dac;
-	unsigned long flags;
-	int i, j;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	__ffb_curs_enable (fb, 0);
-	for (j = 0; j < 2; j++) {
-		u32 val = j ? 0 : 0x80;
-
-		upa_writel(val, &dac->type2);
-		for (i = 0; i < 0x40; i++) {
-			if (fb->cursor.size.fbx <= 32) {
-				upa_writel(fb->cursor.bits [j][i], &dac->value2);
-				upa_writel(0, &dac->value2);
-			} else {
-				upa_writel(fb->cursor.bits [j][2*i], &dac->value2);
-				upa_writel(fb->cursor.bits [j][2*i+1], &dac->value2);
-			}
-		}
-	}	
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-/* Load cursor information */
-static void ffb_setcursor (struct fb_info_sbusfb *fb)
-{
-	struct ffb_dac *dac = fb->s.ffb.dac;
-	struct cg_cursor *c = &fb->cursor;
-	unsigned long flags;
-	u32 val;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	upa_writel(0x104, &dac->type2);
-	/* Should this be just 0x7ff?? 
-	   Should I do some margin handling and setcurshape in that case? */
-	val = (((c->cpos.fby - c->chot.fby) & 0xffff) << 16)
-		|((c->cpos.fbx - c->chot.fbx) & 0xffff);
-	upa_writel(val, &dac->value2);
-	__ffb_curs_enable (fb, fb->cursor.enable);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void ffb_switch_from_graph (struct fb_info_sbusfb *fb)
-{
-	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
-	unsigned long flags;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	FFBWait(fbc);
-	fb->s.ffb.fifo_cache = 0;
-	FFBFifo(fb, 8);
-	upa_writel(FFB_PPC_VCE_DISABLE|FFB_PPC_TBE_OPAQUE|
-		   FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST,
-		   &fbc->ppc);
-	upa_writel(0x2000707f, &fbc->fbc);
-	upa_writel(FFB_ROP_NEW, &fbc->rop);
-	upa_writel(FFB_DRAWOP_RECTANGLE, &fbc->drawop);
-	upa_writel(0xffffffff, &fbc->pmask);
-	upa_writel(0x10000, &fbc->fontinc);
-	upa_writel(fb->s.ffb.fg_cache, &fbc->fg);
-	upa_writel(fb->s.ffb.bg_cache, &fbc->bg);
-	FFBWait(fbc);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static int __init ffb_rasterimg (struct fb_info *info, int start)
-{
-	ffb_switch_from_graph (sbusfbinfo(info));
-	return 0;
-}
-
-static char idstring[60] __initdata = { 0 };
-
-static int __init creator_apply_upa_parent_ranges(int parent, struct linux_prom64_registers *regs)
-{
-	struct linux_prom64_ranges ranges[PROMREG_MAX];
-	char name[128];
-	int len, i;
-
-	prom_getproperty(parent, "name", name, sizeof(name));
-	if (strcmp(name, "upa") != 0)
-		return 0;
-
-	len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
-	if (len <= 0)
-		return 1;
-
-	len /= sizeof(struct linux_prom64_ranges);
-	for (i = 0; i < len; i++) {
-		struct linux_prom64_ranges *rng = &ranges[i];
-		u64 phys_addr = regs->phys_addr;
-
-		if (phys_addr >= rng->ot_child_base &&
-		    phys_addr < (rng->ot_child_base + rng->or_size)) {
-			regs->phys_addr -= rng->ot_child_base;
-			regs->phys_addr += rng->ot_parent_base;
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-char __init *creatorfb_init(struct fb_info_sbusfb *fb)
-{
-	struct fb_fix_screeninfo *fix = &fb->info.fix;
-	struct fb_var_screeninfo *var = &fb->info.var;
-	struct display *disp = &fb->disp;
-	struct fbtype *type = &fb->type;
-	struct linux_prom64_registers regs[2*PROMREG_MAX];
-	int i, afb = 0;
-	unsigned int btype;
-	char name[64];
-	struct fb_ops *fbops;
-
-	if (prom_getproperty(fb->prom_node, "reg", (void *) regs, sizeof(regs)) <= 0)
-		return NULL;
-
-	if (creator_apply_upa_parent_ranges(fb->prom_parent, &regs[0]))
-		return NULL;
-		
-	disp->dispsw_data = (void *)kmalloc(16 * sizeof(u32), GFP_KERNEL);
-	if (disp->dispsw_data == NULL)
-		return NULL;
-	memset(disp->dispsw_data, 0, 16 * sizeof(u32));
-
-	fbops = kmalloc(sizeof(*fbops), GFP_KERNEL);
-	if (fbops == NULL) {
-		kfree(disp->dispsw_data);
-		return NULL;
-	}
-	
-	*fbops = *fb->info.fbops;
-	fbops->fb_rasterimg = ffb_rasterimg;
-	fb->info.fbops = fbops;
-
-	prom_getstring(fb->prom_node, "name", name, sizeof(name));
-	if (!strcmp(name, "SUNW,afb"))
-		afb = 1;
-		
-	btype = prom_getintdefault(fb->prom_node, "board_type", 0);
-		
-	strcpy(fb->info.modename, "Creator");
-	if (!afb) {
-		if ((btype & 7) == 3)
-		    strcpy(fix->id, "Creator 3D");
-		else
-		    strcpy(fix->id, "Creator");
-	} else
-		strcpy(fix->id, "Elite 3D");
-	
-	fix->visual = FB_VISUAL_TRUECOLOR;
-	fix->line_length = 8192;
-	fix->accel = FB_ACCEL_SUN_CREATOR;
-	
-	var->bits_per_pixel = 32;
-	var->green.offset = 8;
-	var->blue.offset = 16;
-	var->accel_flags = FB_ACCELF_TEXT;
-	
-	disp->scrollmode = SCROLL_YREDRAW;
-	fb->info.screen_base = (char *)(regs[0].phys_addr) + FFB_DFB24_POFF + 8192 * fb->y_margin + 4 * fb->x_margin;
-	fb->s.ffb.xy_margin = (fb->y_margin << 16) + fb->x_margin;
-	fb->s.ffb.yx_margin = (((u64)fb->y_margin) << 32) + fb->x_margin;
-	fb->s.ffb.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF);
-	fb->s.ffb.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF);
-	fb->dispsw = ffb_dispsw;
-
-	fb->margins = ffb_margins;
-	fb->loadcmap = ffb_loadcmap;
-	fb->setcursor = ffb_setcursor;
-	fb->setcursormap = ffb_setcursormap;
-	fb->setcurshape = ffb_setcurshape;
-	fb->switch_from_graph = ffb_switch_from_graph;
-	fb->fill = ffb_fill;
-#if 0
-	/* XXX Can't enable this for now, I've seen cases
-	 * XXX where the VC was blanked, and Xsun24 was started
-	 * XXX via a remote login, the sunfb code did not
-	 * XXX unblank creator when it was mmap'd for some
-	 * XXX reason, investigate later... -DaveM
-	 */
-	fb->blank = ffb_blank;
-	fb->unblank = ffb_unblank;
-#endif
-	
-	/* If there are any read errors or fifo overflow conditions,
-	 * clear them now.
-	 */
-	if((upa_readl(&fb->s.ffb.fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
-		upa_writel(FFB_UCSR_ALL_ERRORS, &fb->s.ffb.fbc->ucsr);
-
-	ffb_switch_from_graph(fb);
-	
-	fb->physbase = regs[0].phys_addr;
-	fb->mmap_map = ffb_mmap_map;
-	
-	fb->cursor.hwsize.fbx = 64;
-	fb->cursor.hwsize.fby = 64;
-	
-	type->fb_depth = 24;
-	
-	upa_writel(0x8000, &fb->s.ffb.dac->type);
-	fb->s.ffb.dac_rev = (upa_readl(&fb->s.ffb.dac->value) >> 0x1c);
-	                
-	i = prom_getintdefault (fb->prom_node, "board_type", 8);
-
-	sprintf(idstring, "%s at %016lx type %d DAC %d",
-		fix->id, regs[0].phys_addr, i, fb->s.ffb.dac_rev);
-	
-	/* Elite3D has different DAC revision numbering, and no DAC revisions
-	   have the reversed meaning of cursor enable */
-	if (afb)
-		fb->s.ffb.dac_rev = 10;
-	
-	/* Unblank it just to be sure.  When there are multiple
-	 * FFB/AFB cards in the system, or it is not the OBP
-	 * chosen console, it will have video outputs off in
-	 * the DAC.
-	 */
-	ffb_unblank(fb);
-
-	return idstring;
-}
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
--- a/drivers/video/cyber2000fb.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/video/cyber2000fb.c	Tue Mar  4 19:30:05 2003
@@ -1697,7 +1697,7 @@
 	unsigned char val;
 
 #if defined(__sparc_v9__)
-#error "You loose, consult DaveM."
+#error "You lose, consult DaveM."
 #elif defined(__sparc__)
 	/*
 	 * SPARC does not have an "outb" instruction, so we generate
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c	Tue Mar  4 19:30:03 2003
+++ b/drivers/video/fbmem.c	Tue Mar  4 19:30:03 2003
@@ -103,8 +103,6 @@
 extern int matroxfb_init(void);
 extern int matroxfb_setup(char*);
 extern int hpfb_init(void);
-extern int sbusfb_init(void);
-extern int sbusfb_setup(char*);
 extern int control_init(void);
 extern int control_setup(char*);
 extern int platinum_init(void);
@@ -146,6 +144,20 @@
 extern int sstfb_setup(char*);
 extern int i810fb_init(void);
 extern int i810fb_setup(char*);
+extern int ffb_init(void);
+extern int ffb_setup(char*);
+extern int cg6_init(void);
+extern int cg6_setup(char*);
+extern int cg3_init(void);
+extern int cg3_setup(char*);
+extern int bw2_init(void);
+extern int bw2_setup(char*);
+extern int cg14_init(void);
+extern int cg14_setup(char*);
+extern int p9100_init(void);
+extern int p9100_setup(char*);
+extern int tcx_init(void);
+extern int tcx_setup(char*);
 
 static struct {
 	const char *name;
@@ -153,13 +165,6 @@
 	int (*setup)(char*);
 } fb_drivers[] __initdata = {
 
-#ifdef CONFIG_FB_SBUS
-	/*
-	 * Sbusfb must be initialized _before_ other frame buffer devices that
-	 * use PCI probing
-	 */
-	{ "sbus", sbusfb_init, sbusfb_setup },
-#endif
 	/*
 	 * Chipset specific drivers that use resource management
 	 */
@@ -243,6 +248,27 @@
 #endif	
 #ifdef CONFIG_FB_STI
 	{ "stifb", stifb_init, stifb_setup },
+#endif
+#ifdef CONFIG_FB_FFB
+	{ "ffb", ffb_init, ffb_setup },
+#endif
+#ifdef CONFIG_FB_CG6
+	{ "cg6", cg6_init, cg6_setup },
+#endif
+#ifdef CONFIG_FB_CG3
+	{ "cg3", cg3_init, cg3_setup },
+#endif
+#ifdef CONFIG_FB_BW2
+	{ "bw2", bw2_init, bw2_setup },
+#endif
+#ifdef CONFIG_FB_CG14
+	{ "cg14", cg14_init, cg14_setup },
+#endif
+#ifdef CONFIG_FB_P9100
+	{ "p9100", p9100_init, p9100_setup },
+#endif
+#ifdef CONFIG_FB_TCX
+	{ "tcx", tcx_init, tcx_setup },
 #endif
 
 	/*
diff -Nru a/drivers/video/ffb.c b/drivers/video/ffb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/ffb.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,1046 @@
+/* ffb.c: Creator/Elite3D frame buffer driver
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
+ *
+ * Driver layout based loosely on tgafb.c, see that file for credits.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/mm.h>
+#include <linux/timer.h>
+
+#include <asm/io.h>
+#include <asm/upa.h>
+#include <asm/oplib.h>
+
+#include "sbuslib.h"
+
+/*
+ * Local functions.
+ */
+
+static int ffb_check_var(struct fb_var_screeninfo *, struct fb_info *);
+static int ffb_set_par(struct fb_info *);
+static int ffb_setcolreg(unsigned, unsigned, unsigned, unsigned,
+			 unsigned, struct fb_info *);
+static int ffb_blank(int, struct fb_info *);
+static void ffb_init_fix(struct fb_info *);
+
+static void ffb_imageblit(struct fb_info *, struct fb_image *);
+static void ffb_fillrect(struct fb_info *, struct fb_fillrect *);
+static void ffb_copyarea(struct fb_info *, struct fb_copyarea *);
+static int ffb_sync(struct fb_info *);
+static int ffb_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+
+/*
+ *  Frame buffer operations
+ */
+
+static struct fb_ops ffb_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= ffb_check_var,
+	.fb_set_par		= ffb_set_par,
+	.fb_setcolreg		= ffb_setcolreg,
+	.fb_blank		= ffb_blank,
+	.fb_fillrect		= ffb_fillrect,
+	.fb_copyarea		= ffb_copyarea,
+	.fb_imageblit		= ffb_imageblit,
+	.fb_sync		= ffb_sync,
+	.fb_mmap		= ffb_mmap,
+
+	/* XXX Use FFB hw cursor once fb cursor API is better understood... */
+	.fb_cursor		= soft_cursor,
+};
+
+/* Register layout and definitions */
+#define	FFB_SFB8R_VOFF		0x00000000
+#define	FFB_SFB8G_VOFF		0x00400000
+#define	FFB_SFB8B_VOFF		0x00800000
+#define	FFB_SFB8X_VOFF		0x00c00000
+#define	FFB_SFB32_VOFF		0x01000000
+#define	FFB_SFB64_VOFF		0x02000000
+#define	FFB_FBC_REGS_VOFF	0x04000000
+#define	FFB_BM_FBC_REGS_VOFF	0x04002000
+#define	FFB_DFB8R_VOFF		0x04004000
+#define	FFB_DFB8G_VOFF		0x04404000
+#define	FFB_DFB8B_VOFF		0x04804000
+#define	FFB_DFB8X_VOFF		0x04c04000
+#define	FFB_DFB24_VOFF		0x05004000
+#define	FFB_DFB32_VOFF		0x06004000
+#define	FFB_DFB422A_VOFF	0x07004000	/* DFB 422 mode write to A */
+#define	FFB_DFB422AD_VOFF	0x07804000	/* DFB 422 mode with line doubling */
+#define	FFB_DFB24B_VOFF		0x08004000	/* DFB 24bit mode write to B */
+#define	FFB_DFB422B_VOFF	0x09004000	/* DFB 422 mode write to B */
+#define	FFB_DFB422BD_VOFF	0x09804000	/* DFB 422 mode with line doubling */
+#define	FFB_SFB16Z_VOFF		0x0a004000	/* 16bit mode Z planes */
+#define	FFB_SFB8Z_VOFF		0x0a404000	/* 8bit mode Z planes */
+#define	FFB_SFB422_VOFF		0x0ac04000	/* SFB 422 mode write to A/B */
+#define	FFB_SFB422D_VOFF	0x0b404000	/* SFB 422 mode with line doubling */
+#define	FFB_FBC_KREGS_VOFF	0x0bc04000
+#define	FFB_DAC_VOFF		0x0bc06000
+#define	FFB_PROM_VOFF		0x0bc08000
+#define	FFB_EXP_VOFF		0x0bc18000
+
+#define	FFB_SFB8R_POFF		0x04000000UL
+#define	FFB_SFB8G_POFF		0x04400000UL
+#define	FFB_SFB8B_POFF		0x04800000UL
+#define	FFB_SFB8X_POFF		0x04c00000UL
+#define	FFB_SFB32_POFF		0x05000000UL
+#define	FFB_SFB64_POFF		0x06000000UL
+#define	FFB_FBC_REGS_POFF	0x00600000UL
+#define	FFB_BM_FBC_REGS_POFF	0x00600000UL
+#define	FFB_DFB8R_POFF		0x01000000UL
+#define	FFB_DFB8G_POFF		0x01400000UL
+#define	FFB_DFB8B_POFF		0x01800000UL
+#define	FFB_DFB8X_POFF		0x01c00000UL
+#define	FFB_DFB24_POFF		0x02000000UL
+#define	FFB_DFB32_POFF		0x03000000UL
+#define	FFB_FBC_KREGS_POFF	0x00610000UL
+#define	FFB_DAC_POFF		0x00400000UL
+#define	FFB_PROM_POFF		0x00000000UL
+#define	FFB_EXP_POFF		0x00200000UL
+#define FFB_DFB422A_POFF	0x09000000UL
+#define FFB_DFB422AD_POFF	0x09800000UL
+#define FFB_DFB24B_POFF		0x0a000000UL
+#define FFB_DFB422B_POFF	0x0b000000UL
+#define FFB_DFB422BD_POFF	0x0b800000UL
+#define FFB_SFB16Z_POFF		0x0c800000UL
+#define FFB_SFB8Z_POFF		0x0c000000UL
+#define FFB_SFB422_POFF		0x0d000000UL
+#define FFB_SFB422D_POFF	0x0d800000UL
+
+/* Draw operations */
+#define FFB_DRAWOP_DOT		0x00
+#define FFB_DRAWOP_AADOT	0x01
+#define FFB_DRAWOP_BRLINECAP	0x02
+#define FFB_DRAWOP_BRLINEOPEN	0x03
+#define FFB_DRAWOP_DDLINE	0x04
+#define FFB_DRAWOP_AALINE	0x05
+#define FFB_DRAWOP_TRIANGLE	0x06
+#define FFB_DRAWOP_POLYGON	0x07
+#define FFB_DRAWOP_RECTANGLE	0x08
+#define FFB_DRAWOP_FASTFILL	0x09
+#define FFB_DRAWOP_BCOPY	0x0a
+#define FFB_DRAWOP_VSCROLL	0x0b
+
+/* Pixel processor control */
+/* Force WID */
+#define FFB_PPC_FW_DISABLE	0x800000
+#define FFB_PPC_FW_ENABLE	0xc00000
+/* Auxiliary clip */
+#define FFB_PPC_ACE_DISABLE	0x040000
+#define FFB_PPC_ACE_AUX_SUB	0x080000
+#define FFB_PPC_ACE_AUX_ADD	0x0c0000
+/* Depth cue */
+#define FFB_PPC_DCE_DISABLE	0x020000
+#define FFB_PPC_DCE_ENABLE	0x030000
+/* Alpha blend */
+#define FFB_PPC_ABE_DISABLE	0x008000
+#define FFB_PPC_ABE_ENABLE	0x00c000
+/* View clip */
+#define FFB_PPC_VCE_DISABLE	0x001000
+#define FFB_PPC_VCE_2D		0x002000
+#define FFB_PPC_VCE_3D		0x003000
+/* Area pattern */
+#define FFB_PPC_APE_DISABLE	0x000800
+#define FFB_PPC_APE_ENABLE	0x000c00
+/* Transparent background */
+#define FFB_PPC_TBE_OPAQUE	0x000200
+#define FFB_PPC_TBE_TRANSPARENT	0x000300
+/* Z source */
+#define FFB_PPC_ZS_VAR		0x000080
+#define FFB_PPC_ZS_CONST	0x0000c0
+/* Y source */
+#define FFB_PPC_YS_VAR		0x000020
+#define FFB_PPC_YS_CONST	0x000030
+/* X source */
+#define FFB_PPC_XS_WID		0x000004
+#define FFB_PPC_XS_VAR		0x000008
+#define FFB_PPC_XS_CONST	0x00000c
+/* Color (BGR) source */
+#define FFB_PPC_CS_VAR		0x000002
+#define FFB_PPC_CS_CONST	0x000003
+
+#define FFB_ROP_NEW                  0x83
+#define FFB_ROP_OLD                  0x85
+#define FFB_ROP_NEW_XOR_OLD          0x86
+
+#define FFB_UCSR_FIFO_MASK     0x00000fff
+#define FFB_UCSR_FB_BUSY       0x01000000
+#define FFB_UCSR_RP_BUSY       0x02000000
+#define FFB_UCSR_ALL_BUSY      (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
+#define FFB_UCSR_READ_ERR      0x40000000
+#define FFB_UCSR_FIFO_OVFL     0x80000000
+#define FFB_UCSR_ALL_ERRORS    (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL)
+
+struct ffb_fbc {
+	/* Next vertex registers */
+	u32		xxx1[3];
+	volatile u32	alpha;
+	volatile u32	red;
+	volatile u32	green;
+	volatile u32	blue;
+	volatile u32	depth;
+	volatile u32	y;
+	volatile u32	x;
+	u32		xxx2[2];
+	volatile u32	ryf;
+	volatile u32	rxf;
+	u32		xxx3[2];
+	
+	volatile u32	dmyf;
+	volatile u32	dmxf;
+	u32		xxx4[2];
+	volatile u32	ebyi;
+	volatile u32	ebxi;
+	u32		xxx5[2];
+	volatile u32	by;
+	volatile u32	bx;
+	u32		dy;
+	u32		dx;
+	volatile u32	bh;
+	volatile u32	bw;
+	u32		xxx6[2];
+	
+	u32		xxx7[32];
+	
+	/* Setup unit vertex state register */
+	volatile u32	suvtx;
+	u32		xxx8[63];
+	
+	/* Control registers */
+	volatile u32	ppc;
+	volatile u32	wid;
+	volatile u32	fg;
+	volatile u32	bg;
+	volatile u32	consty;
+	volatile u32	constz;
+	volatile u32	xclip;
+	volatile u32	dcss;
+	volatile u32	vclipmin;
+	volatile u32	vclipmax;
+	volatile u32	vclipzmin;
+	volatile u32	vclipzmax;
+	volatile u32	dcsf;
+	volatile u32	dcsb;
+	volatile u32	dczf;
+	volatile u32	dczb;
+	
+	u32		xxx9;
+	volatile u32	blendc;
+	volatile u32	blendc1;
+	volatile u32	blendc2;
+	volatile u32	fbramitc;
+	volatile u32	fbc;
+	volatile u32	rop;
+	volatile u32	cmp;
+	volatile u32	matchab;
+	volatile u32	matchc;
+	volatile u32	magnab;
+	volatile u32	magnc;
+	volatile u32	fbcfg0;
+	volatile u32	fbcfg1;
+	volatile u32	fbcfg2;
+	volatile u32	fbcfg3;
+	
+	u32		ppcfg;
+	volatile u32	pick;
+	volatile u32	fillmode;
+	volatile u32	fbramwac;
+	volatile u32	pmask;
+	volatile u32	xpmask;
+	volatile u32	ypmask;
+	volatile u32	zpmask;
+	volatile u32	clip0min;
+	volatile u32	clip0max;
+	volatile u32	clip1min;
+	volatile u32	clip1max;
+	volatile u32	clip2min;
+	volatile u32	clip2max;
+	volatile u32	clip3min;
+	volatile u32	clip3max;
+	
+	/* New 3dRAM III support regs */
+	volatile u32	rawblend2;
+	volatile u32	rawpreblend;
+	volatile u32	rawstencil;
+	volatile u32	rawstencilctl;
+	volatile u32	threedram1;
+	volatile u32	threedram2;
+	volatile u32	passin;
+	volatile u32	rawclrdepth;
+	volatile u32	rawpmask;
+	volatile u32	rawcsrc;
+	volatile u32	rawmatch;
+	volatile u32	rawmagn;
+	volatile u32	rawropblend;
+	volatile u32	rawcmp;
+	volatile u32	rawwac;
+	volatile u32	fbramid;
+	
+	volatile u32	drawop;
+	u32		xxx10[2];
+	volatile u32	fontlpat;
+	u32		xxx11;
+	volatile u32	fontxy;
+	volatile u32	fontw;
+	volatile u32	fontinc;
+	volatile u32	font;
+	u32		xxx12[3];
+	volatile u32	blend2;
+	volatile u32	preblend;
+	volatile u32	stencil;
+	volatile u32	stencilctl;
+
+	u32		xxx13[4];	
+	volatile u32	dcss1;
+	volatile u32	dcss2;
+	volatile u32	dcss3;
+	volatile u32	widpmask;
+	volatile u32	dcs2;
+	volatile u32	dcs3;
+	volatile u32	dcs4;
+	u32		xxx14;
+	volatile u32	dcd2;
+	volatile u32	dcd3;
+	volatile u32	dcd4;
+	u32		xxx15;
+	
+	volatile u32	pattern[32];
+	
+	u32		xxx16[256];
+	
+	volatile u32	devid;
+	u32		xxx17[63];
+	
+	volatile u32	ucsr;
+	u32		xxx18[31];
+	
+	volatile u32	mer;
+};
+
+struct ffb_dac {
+	volatile u32	type;
+	volatile u32	value;
+	volatile u32	type2;
+	volatile u32	value2;
+};
+
+struct ffb_par {
+	spinlock_t		lock;
+	struct ffb_fbc		*fbc;
+	struct ffb_dac		*dac;
+
+	u32			flags;
+#define FFB_FLAG_AFB		0x00000001
+#define FFB_FLAG_BLANKED	0x00000002
+
+	u32			fg_cache __attribute__((aligned (8)));
+	u32			bg_cache;
+	u32			rop_cache;
+
+	int			fifo_cache;
+
+	unsigned long		physbase;
+	unsigned long		fbsize;
+
+	char			name[64];
+	int			prom_node;
+	int			prom_parent_node;
+	int			dac_rev;
+	int			board_type;
+	struct list_head	list;
+};
+
+#undef FFB_DO_DEBUG_LOG
+
+#ifdef FFB_DO_DEBUG_LOG
+#define FFB_DEBUG_LOG_ENTS	32
+static struct ffb_log {
+	int op;
+#define OP_FILLRECT	1
+#define OP_IMAGEBLIT	2
+
+	int depth, x, y, w, h;
+} ffb_debug_log[FFB_DEBUG_LOG_ENTS];
+static int ffb_debug_log_ent;
+
+static void ffb_do_log(unsigned long unused)
+{
+	int i;
+
+	for (i = 0; i < FFB_DEBUG_LOG_ENTS; i++) {
+		struct ffb_log *p = &ffb_debug_log[i];
+
+		printk("FFB_LOG: OP[%s] depth(%d) x(%d) y(%d) w(%d) h(%d)\n",
+		       (p->op == OP_FILLRECT ? "FILLRECT" : "IMAGEBLIT"),
+		       p->depth, p->x, p->y, p->w, p->h);
+	}
+}
+static struct timer_list ffb_log_timer =
+	TIMER_INITIALIZER(ffb_do_log, 0, 0);
+
+static void ffb_log(int op, int depth, int x, int y, int w, int h)
+{
+	if (ffb_debug_log_ent < FFB_DEBUG_LOG_ENTS) {
+		struct ffb_log *p = &ffb_debug_log[ffb_debug_log_ent];
+
+		if (ffb_debug_log_ent != 0 &&
+		    p[-1].op == op && p[-1].depth == depth)
+			return;
+		p->op = op;
+		p->depth = depth;
+		p->x = x;
+		p->y = y;
+		p->w = w;
+		p->h = h;
+
+		if (++ffb_debug_log_ent == FFB_DEBUG_LOG_ENTS) {
+			ffb_log_timer.expires = jiffies + 2;
+			add_timer(&ffb_log_timer);
+		}
+	}
+}
+#else
+#define ffb_log(a,b,c,d,e,f)	do { } while(0)
+#endif
+
+#undef FORCE_WAIT_EVERY_ROP
+
+static void FFBFifo(struct ffb_par *par, int n)
+{
+	struct ffb_fbc *fbc;
+	int cache = par->fifo_cache;
+
+	if (cache - n < 0) {
+		fbc = par->fbc;
+		do {	cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK) - 8;
+		} while (cache - n < 0);
+	}
+	par->fifo_cache = cache - n;
+}
+
+static void FFBWait(struct ffb_par *par)
+{
+	struct ffb_fbc *fbc;
+	int limit = 10000;
+
+	fbc = par->fbc;
+	do {
+		if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_BUSY) == 0)
+			break;
+		if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) {
+			upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
+		}
+		udelay(10);
+	} while(--limit > 0);
+}
+
+static int ffb_sync(struct fb_info *p)
+{
+	struct ffb_par *par = (struct ffb_par *) p->par;
+
+	FFBWait(par);
+	return 0;
+}
+
+static __inline__ void ffb_rop(struct ffb_par *par, u32 rop)
+{
+	if (par->rop_cache != rop) {
+		FFBFifo(par, 1);
+		upa_writel(rop, &par->fbc->rop);
+		par->rop_cache = rop;
+	}
+}
+
+static void ffb_switch_from_graph(struct ffb_par *par)
+{
+	struct ffb_fbc *fbc = par->fbc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&par->lock, flags);
+	FFBWait(par);
+	par->fifo_cache = 0;
+	FFBFifo(par, 7);
+	upa_writel(FFB_PPC_VCE_DISABLE|FFB_PPC_TBE_OPAQUE|
+		   FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST,
+		   &fbc->ppc);
+	upa_writel(0x2000707f, &fbc->fbc);
+	upa_writel(par->rop_cache, &fbc->rop);
+	upa_writel(0xffffffff, &fbc->pmask);
+	upa_writel((0 << 16) | (32 << 0), &fbc->fontinc);
+	upa_writel(par->fg_cache, &fbc->fg);
+	upa_writel(par->bg_cache, &fbc->bg);
+	FFBWait(par);
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+/**
+ *      ffb_fillrect - REQUIRED function. Can use generic routines if 
+ *                     non acclerated hardware and packed pixel based.
+ *                     Draws a rectangle on the screen.               
+ *
+ *      @info: frame buffer structure that represents a single frame buffer
+ *      @rect: structure defining the rectagle and operation.
+ */
+static void ffb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+	struct ffb_par *par = (struct ffb_par *) info->par;
+	struct ffb_fbc *fbc = par->fbc;
+	unsigned long flags;
+	u32 fg;
+
+	if (rect->rop != ROP_COPY && rect->rop != ROP_XOR)
+		BUG();
+
+	ffb_log(OP_FILLRECT, 0, rect->dx, rect->dy, rect->width, rect->height);
+
+	fg = ((u32 *)info->pseudo_palette)[rect->color];
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	if (fg != par->fg_cache) {
+		FFBFifo(par, 1);
+		upa_writel(fg, &fbc->fg);
+		par->fg_cache = fg;
+	}
+
+	ffb_rop(par, (rect->rop == ROP_COPY ?
+		      FFB_ROP_NEW :
+		      FFB_ROP_NEW_XOR_OLD));
+
+	FFBFifo(par, 5);
+	upa_writel(FFB_DRAWOP_RECTANGLE, &fbc->drawop);
+	upa_writel(rect->dy, &fbc->by);
+	upa_writel(rect->dx, &fbc->bx);
+	upa_writel(rect->height, &fbc->bh);
+	upa_writel(rect->width, &fbc->bw);
+#ifdef FORCE_WAIT_EVERY_ROP
+	FFBWait(par);
+#endif
+
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+/**
+ *      ffb_copyarea - REQUIRED function. Can use generic routines if
+ *                     non acclerated hardware and packed pixel based.
+ *                     Copies on area of the screen to another area.
+ *
+ *      @info: frame buffer structure that represents a single frame buffer
+ *      @area: structure defining the source and destination.
+ */
+
+static void
+ffb_copyarea(struct fb_info *info, struct fb_copyarea *area) 
+{
+	struct ffb_par *par = (struct ffb_par *) info->par;
+	struct ffb_fbc *fbc = par->fbc;
+	unsigned long flags;
+
+	if (area->dx != area->sx ||
+	    area->dy == area->dy) {
+		cfb_copyarea(info, area);
+		return;
+	}
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	ffb_rop(par, FFB_ROP_OLD);
+
+	FFBFifo(par, 7);
+	upa_writel(FFB_DRAWOP_VSCROLL, &fbc->drawop);
+	upa_writel(area->sy, &fbc->by);
+	upa_writel(area->sx, &fbc->bx);
+	upa_writel(area->dy, &fbc->dy);
+	upa_writel(area->dx, &fbc->dx);
+	upa_writel(area->height, &fbc->bh);
+	upa_writel(area->width, &fbc->bw);
+
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+/**
+ *      ffb_imageblit - REQUIRED function. Can use generic routines if
+ *                      non acclerated hardware and packed pixel based.
+ *                      Copies a image from system memory to the screen. 
+ *
+ *      @info: frame buffer structure that represents a single frame buffer
+ *      @image: structure defining the image.
+ */
+static void ffb_imageblit(struct fb_info *info, struct fb_image *image)
+{
+	struct ffb_par *par = (struct ffb_par *) info->par;
+	struct ffb_fbc *fbc = par->fbc;
+	u8 *data = (u8 *) image->data;
+	unsigned long flags;
+	u32 fg, bg, xy;
+	u64 fgbg;
+	int i, width;
+
+	ffb_log(OP_IMAGEBLIT, image->depth,
+		image->dx, image->dy, image->width, image->height);
+
+	if (image->depth > 1) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	fg = ((u32 *)info->pseudo_palette)[image->fg_color];
+	bg = ((u32 *)info->pseudo_palette)[image->bg_color];
+	fgbg = ((u64) fg << 32) | (u64) bg;
+	xy = (image->dy << 16) | image->dx;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	if (fgbg != *(u64 *)&par->fg_cache) {
+		FFBFifo(par, 2);
+		upa_writeq(fgbg, &fbc->fg);
+		*(u64 *)&par->fg_cache = fgbg;
+	}
+
+	ffb_rop(par, FFB_ROP_NEW);
+
+	for (i = 0; i < image->height; i++) {
+		width = image->width;
+
+		FFBFifo(par, 1);
+		upa_writel(xy, &fbc->fontxy);
+		xy += (1 << 16);
+
+		while (width >= 32) {
+			u32 val;
+
+			FFBFifo(par, 2);
+			upa_writel(32, &fbc->fontw);
+
+			val = ((u32)data[0] << 24) |
+			      ((u32)data[1] << 16) |
+			      ((u32)data[2] <<  8) |
+			      ((u32)data[3] <<  0);
+			upa_writel(val, &fbc->font);
+
+			data += 4;
+			width -= 32;
+		}
+
+		if (width) {
+			u32 val;
+
+			FFBFifo(par, 2);
+			upa_writel(width, &fbc->fontw);
+			if (width <= 8) {
+				val = (u32) data[0] << 24;
+				data += 1;
+			} else if (width <= 16) {
+				val = ((u32) data[0] << 24) |
+				      ((u32) data[1] << 16);
+				data += 2;
+			} else {
+				val = ((u32) data[0] << 24) |
+				      ((u32) data[1] << 16) |
+				      ((u32) data[2] <<  8);
+				data += 3;
+			}
+			upa_writel(val, &fbc->font);
+		}
+	}
+#ifdef FORCE_WAIT_EVERY_ROP
+	FFBWait(par);
+#endif
+
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+static void ffb_fixup_var_rgb(struct fb_var_screeninfo *var)
+{
+	var->red.offset = 0;
+	var->red.length = 8;
+	var->green.offset = 8;
+	var->green.length = 8;
+	var->blue.offset = 16;
+	var->blue.length = 8;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+}
+
+/**
+ *      ffb_check_var - Optional function.  Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int ffb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->bits_per_pixel != 32)
+		return -EINVAL;
+
+	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
+		return -EINVAL;
+	if (var->nonstd)
+		return -EINVAL;
+	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+
+	if (var->xres != info->var.xres || var->yres != info->var.yres)
+		return -EINVAL;
+
+	ffb_fixup_var_rgb(var);
+
+	return 0;
+}
+
+/**
+ *      ffb_set_par - Optional function.  Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+ffb_set_par(struct fb_info *info)
+{
+	return 0;
+}
+
+/**
+ *      ffb_setcolreg - Optional function. Sets a color register.
+ *      @regno: boolean, 0 copy local, 1 get_user() function
+ *      @red: frame buffer colormap structure
+ *      @green: The green value which can be up to 16 bits wide
+ *      @blue:  The blue value which can be up to 16 bits wide.
+ *      @transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ */
+static int ffb_setcolreg(unsigned regno,
+			 unsigned red, unsigned green, unsigned blue,
+			 unsigned transp, struct fb_info *info)
+{
+	u32 value;
+
+	if (regno >= 256)
+		return 1;
+
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	value = (blue << 16) | (green << 8) | red;
+	((u32 *)info->pseudo_palette)[regno] = value;
+
+	return 0;
+}
+
+/**
+ *      ffb_blank - Optional function.  Blanks the display.
+ *      @blank_mode: the blank mode we want.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+ffb_blank(int blank, struct fb_info *info)
+{
+	struct ffb_par *par = (struct ffb_par *) info->par;
+	struct ffb_dac *dac = par->dac;
+	unsigned long flags;
+	u32 tmp;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	FFBWait(par);
+
+	switch (blank) {
+	case 0: /* Unblanking */
+		upa_writel(0x6000, &dac->type);
+		tmp = (upa_readl(&dac->value) | 0x1);
+		upa_writel(0x6000, &dac->type);
+		upa_writel(tmp, &dac->value);
+		par->flags &= ~FFB_FLAG_BLANKED;
+		break;
+
+	case 1: /* Normal blanking */
+	case 2: /* VESA blank (vsync off) */
+	case 3: /* VESA blank (hsync off) */
+	case 4: /* Poweroff */
+		upa_writel(0x6000, &dac->type);
+		tmp = (upa_readl(&dac->value) & ~0x1);
+		upa_writel(0x6000, &dac->type);
+		upa_writel(tmp, &dac->value);
+		par->flags |= FFB_FLAG_BLANKED;
+		break;
+	}
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+static struct sbus_mmap_map ffb_mmap_map[] = {
+	{ FFB_SFB8R_VOFF,	FFB_SFB8R_POFF,		0x0400000 },
+	{ FFB_SFB8G_VOFF,	FFB_SFB8G_POFF,		0x0400000 },
+	{ FFB_SFB8B_VOFF,	FFB_SFB8B_POFF,		0x0400000 },
+	{ FFB_SFB8X_VOFF,	FFB_SFB8X_POFF,		0x0400000 },
+	{ FFB_SFB32_VOFF,	FFB_SFB32_POFF,		0x1000000 },
+	{ FFB_SFB64_VOFF,	FFB_SFB64_POFF,		0x2000000 },
+	{ FFB_FBC_REGS_VOFF,	FFB_FBC_REGS_POFF,	0x0002000 },
+	{ FFB_BM_FBC_REGS_VOFF,	FFB_BM_FBC_REGS_POFF,	0x0002000 },
+	{ FFB_DFB8R_VOFF,	FFB_DFB8R_POFF,		0x0400000 },
+	{ FFB_DFB8G_VOFF,	FFB_DFB8G_POFF,		0x0400000 },
+	{ FFB_DFB8B_VOFF,	FFB_DFB8B_POFF,		0x0400000 },
+	{ FFB_DFB8X_VOFF,	FFB_DFB8X_POFF,		0x0400000 },
+	{ FFB_DFB24_VOFF,	FFB_DFB24_POFF,		0x1000000 },
+	{ FFB_DFB32_VOFF,	FFB_DFB32_POFF,		0x1000000 },
+	{ FFB_FBC_KREGS_VOFF,	FFB_FBC_KREGS_POFF,	0x0002000 },
+	{ FFB_DAC_VOFF,		FFB_DAC_POFF,		0x0002000 },
+	{ FFB_PROM_VOFF,	FFB_PROM_POFF,		0x0010000 },
+	{ FFB_EXP_VOFF,		FFB_EXP_POFF,		0x0002000 },
+	{ FFB_DFB422A_VOFF,	FFB_DFB422A_POFF,	0x0800000 },
+	{ FFB_DFB422AD_VOFF,	FFB_DFB422AD_POFF,	0x0800000 },
+	{ FFB_DFB24B_VOFF,	FFB_DFB24B_POFF,	0x1000000 },
+	{ FFB_DFB422B_VOFF,	FFB_DFB422B_POFF,	0x0800000 },
+	{ FFB_DFB422BD_VOFF,	FFB_DFB422BD_POFF,	0x0800000 },
+	{ FFB_SFB16Z_VOFF,	FFB_SFB16Z_POFF,	0x0800000 },
+	{ FFB_SFB8Z_VOFF,	FFB_SFB8Z_POFF,		0x0800000 },
+	{ FFB_SFB422_VOFF,	FFB_SFB422_POFF,	0x0800000 },
+	{ FFB_SFB422D_VOFF,	FFB_SFB422D_POFF,	0x0800000 },
+	{ 0,			0,			0	  }
+};
+
+static int ffb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	struct ffb_par *par = (struct ffb_par *)info->par;
+
+	return sbusfb_mmap_helper(ffb_mmap_map,
+				  par->physbase, par->fbsize,
+				  0, vma);
+}
+
+/*
+ *  Initialisation
+ */
+
+static void
+ffb_init_fix(struct fb_info *info)
+{
+	struct ffb_par *par = (struct ffb_par *)info->par;
+	const char *ffb_type_name;
+
+	if (!(par->flags & FFB_FLAG_AFB)) {
+		if ((par->board_type & 0x7) == 0x3)
+			ffb_type_name = "Creator 3D";
+		else
+			ffb_type_name = "Creator";
+	} else
+		ffb_type_name = "Elite 3D";
+
+	strncpy(info->fix.id, ffb_type_name, sizeof(info->fix.id) - 1);
+	info->fix.id[sizeof(info->fix.id)-1] = 0;
+
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	/* Framebuffer length is the same regardless of resolution. */
+	info->fix.line_length = 8192;
+
+	info->fix.accel = FB_ACCEL_SUN_CREATOR;
+}
+
+static int ffb_apply_upa_parent_ranges(int parent,
+				       struct linux_prom64_registers *regs)
+{
+	struct linux_prom64_ranges ranges[PROMREG_MAX];
+	char name[128];
+	int len, i;
+
+	prom_getproperty(parent, "name", name, sizeof(name));
+	if (strcmp(name, "upa") != 0)
+		return 0;
+
+	len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
+	if (len <= 0)
+		return 1;
+
+	len /= sizeof(struct linux_prom64_ranges);
+	for (i = 0; i < len; i++) {
+		struct linux_prom64_ranges *rng = &ranges[i];
+		u64 phys_addr = regs->phys_addr;
+
+		if (phys_addr >= rng->ot_child_base &&
+		    phys_addr < (rng->ot_child_base + rng->or_size)) {
+			regs->phys_addr -= rng->ot_child_base;
+			regs->phys_addr += rng->ot_parent_base;
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+struct all_info {
+	struct fb_info info;
+	struct ffb_par par;
+	u32 pseudo_palette[256];
+	struct list_head list;
+};
+static LIST_HEAD(ffb_list);
+
+static void ffb_init_one(int node, int parent)
+{
+	struct linux_prom64_registers regs[2*PROMREG_MAX];
+	struct ffb_fbc *fbc;
+	struct ffb_dac *dac;
+	struct all_info *all;
+
+	if (prom_getproperty(node, "reg", (void *) regs, sizeof(regs)) <= 0) {
+		printk("ffb: Cannot get reg device node property.\n");
+		return;
+	}
+
+	if (ffb_apply_upa_parent_ranges(parent, &regs[0])) {
+		printk("ffb: Cannot apply parent ranges to regs.\n");
+		return;
+	}
+
+	all = kmalloc(sizeof(*all), GFP_KERNEL);
+	if (!all) {
+		printk(KERN_ERR "ffb: Cannot allocate memory.\n");
+		return;
+	}
+	memset(all, 0, sizeof(*all));
+
+	INIT_LIST_HEAD(&all->list);	
+
+	spin_lock_init(&all->par.lock);
+	all->par.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF);
+	all->par.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF);
+	all->par.rop_cache = FFB_ROP_NEW;
+	all->par.physbase = regs[0].phys_addr;
+	all->par.prom_node = node;
+	all->par.prom_parent_node = parent;
+
+	all->info.node = NODEV;
+	all->info.flags = FBINFO_FLAG_DEFAULT;
+	all->info.fbops = &ffb_ops;
+	all->info.screen_base = (char *) all->par.physbase + FFB_DFB24_POFF;
+	all->info.currcon = -1;
+	all->info.par = &all->par;
+	all->info.pseudo_palette = all->pseudo_palette;
+
+	sbusfb_fill_var(&all->info.var, all->par.prom_node, 32);
+	all->par.fbsize = PAGE_ALIGN(all->info.var.xres *
+				     all->info.var.yres *
+				     4);
+	ffb_fixup_var_rgb(&all->info.var);
+
+	all->info.var.accel_flags = FB_ACCELF_TEXT;
+
+	prom_getstring(node, "name", all->par.name, sizeof(all->par.name));
+	if (!strcmp(all->par.name, "SUNW,afb"))
+		all->par.flags |= FFB_FLAG_AFB;
+
+	all->par.board_type = prom_getintdefault(node, "board_type", 0);
+
+	fbc = all->par.fbc;
+	if((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
+		upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
+
+	ffb_switch_from_graph(&all->par);
+
+	dac = all->par.dac;
+	upa_writel(0x8000, &dac->type);
+	all->par.dac_rev = upa_readl(&dac->value) >> 0x1c;
+
+	/* Elite3D has different DAC revision numbering, and no DAC revisions
+	 * have the reversed meaning of cursor enable.
+	 */
+	if (all->par.flags & FFB_FLAG_AFB)
+		all->par.dac_rev = 10;
+
+	/* Unblank it just to be sure.  When there are multiple
+	 * FFB/AFB cards in the system, or it is not the OBP
+	 * chosen console, it will have video outputs off in
+	 * the DAC.
+	 */
+	ffb_blank(0, &all->info);
+
+	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+		printk(KERN_ERR "ffb: Could not allocate color map.\n");
+		kfree(all);
+		return;
+	}
+
+	ffb_set_par(&all->info);
+	ffb_init_fix(&all->info);
+
+	if (register_framebuffer(&all->info) < 0) {
+		printk(KERN_ERR "ffb: Could not register framebuffer.\n");
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+		return;
+	}
+
+	list_add(&all->list, &ffb_list);
+
+	printk("ffb: %s at %016lx type %d DAC %d\n",
+	       ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
+	       regs[0].phys_addr, all->par.board_type, all->par.dac_rev);
+}
+
+static void ffb_scan_siblings(int root)
+{
+	int node, child;
+
+	child = prom_getchild(root);
+	for (node = prom_searchsiblings(child, "SUNW,ffb"); node;
+	     node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb"))
+		ffb_init_one(node, root);
+	for (node = prom_searchsiblings(child, "SUNW,afb"); node;
+	     node = prom_searchsiblings(prom_getsibling(node), "SUNW,afb"))
+		ffb_init_one(node, root);
+}
+
+int __init ffb_init(void)
+{
+	int root;
+
+	ffb_scan_siblings(prom_root_node);
+
+	root = prom_getchild(prom_root_node);
+	for (root = prom_searchsiblings(root, "upa"); root;
+	     root = prom_searchsiblings(prom_getsibling(root), "upa"))
+		ffb_scan_siblings(root);
+
+	return 0;
+}
+
+void __exit ffb_exit(void)
+{
+	struct list_head *pos, *tmp;
+
+	list_for_each_safe(pos, tmp, &ffb_list) {
+		struct all_info *all = list_entry(pos, typeof(*all), list);
+
+		unregister_framebuffer(&all->info);
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+	}
+}
+
+int __init
+ffb_setup(char *arg)
+{
+	/* No cmdline options yet... */
+	return 0;
+}
+
+#ifdef MODULE
+module_init(ffb_init);
+module_exit(ffb_exit);
+#endif
+
+MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets");
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/macfb.c b/drivers/video/macfb.c
--- a/drivers/video/macfb.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/video/macfb.c	Tue Mar  4 19:30:04 2003
@@ -223,7 +223,7 @@
 	local_irq_save(flags);
 	
 	/* fbdev will set an entire colourmap, but X won't.  Hopefully
-	   this should accomodate both of them */
+	   this should accommodate both of them */
 	if (regno != lastreg+1) {
 		int i;
 		
diff -Nru a/drivers/video/p9100.c b/drivers/video/p9100.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/p9100.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,405 @@
+/* p9100.c: P9100 frame buffer driver
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright 1999 Derrick J Brashear (shadow@dementia.org)
+ *
+ * Driver layout based loosely on tgafb.c, see that file for credits.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/fbio.h>
+
+#include "sbuslib.h"
+
+/*
+ * Local functions.
+ */
+
+static int p9100_check_var(struct fb_var_screeninfo *, struct fb_info *);
+static int p9100_set_par(struct fb_info *);
+static int p9100_setcolreg(unsigned, unsigned, unsigned, unsigned,
+			   unsigned, struct fb_info *);
+static int p9100_blank(int, struct fb_info *);
+
+static int p9100_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+
+/*
+ *  Frame buffer operations
+ */
+
+static struct fb_ops p9100_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= p9100_check_var,
+	.fb_set_par		= p9100_set_par,
+	.fb_setcolreg		= p9100_setcolreg,
+	.fb_blank		= p9100_blank,
+	.fb_fillrect		= cfb_fillrect,
+	.fb_copyarea		= cfb_copyarea,
+	.fb_imageblit		= cfb_imageblit,
+	.fb_mmap		= p9100_mmap,
+	.fb_cursor		= soft_cursor,
+};
+
+/* P9100 control registers */
+#define P9100_SYSCTL_OFF	0x0UL
+#define P9100_VIDEOCTL_OFF	0x100UL
+#define P9100_VRAMCTL_OFF 	0x180UL
+#define P9100_RAMDAC_OFF 	0x200UL
+#define P9100_VIDEOCOPROC_OFF 	0x400UL
+
+/* P9100 command registers */
+#define P9100_CMD_OFF 0x0UL
+
+/* P9100 framebuffer memory */
+#define P9100_FB_OFF 0x0UL
+
+/* 3 bits: 2=8bpp 3=16bpp 5=32bpp 7=24bpp */
+#define SYS_CONFIG_PIXELSIZE_SHIFT 26 
+
+#define SCREENPAINT_TIMECTL1_ENABLE_VIDEO 0x20 /* 0 = off, 1 = on */
+
+struct p9100_regs {
+	/* Registers for the system control */
+	volatile u32 sys_base;
+	volatile u32 sys_config;
+	volatile u32 sys_intr;
+	volatile u32 sys_int_ena;
+	volatile u32 sys_alt_rd;
+	volatile u32 sys_alt_wr;
+	volatile u32 sys_xxx[58];
+
+	/* Registers for the video control */
+	volatile u32 vid_base;
+	volatile u32 vid_hcnt;
+	volatile u32 vid_htotal;
+	volatile u32 vid_hsync_rise;
+	volatile u32 vid_hblank_rise;
+	volatile u32 vid_hblank_fall;
+	volatile u32 vid_hcnt_preload;
+	volatile u32 vid_vcnt;
+	volatile u32 vid_vlen;
+	volatile u32 vid_vsync_rise;
+	volatile u32 vid_vblank_rise;
+	volatile u32 vid_vblank_fall;
+	volatile u32 vid_vcnt_preload;
+	volatile u32 vid_screenpaint_addr;
+	volatile u32 vid_screenpaint_timectl1;
+	volatile u32 vid_screenpaint_qsfcnt;
+	volatile u32 vid_screenpaint_timectl2;
+	volatile u32 vid_xxx[15];
+
+	/* Registers for the video control */
+	volatile u32 vram_base;
+	volatile u32 vram_memcfg;
+	volatile u32 vram_refresh_pd;
+	volatile u32 vram_refresh_cnt;
+	volatile u32 vram_raslo_max;
+	volatile u32 vram_raslo_cur;
+	volatile u32 pwrup_cfg;
+	volatile u32 vram_xxx[25];
+
+	/* Registers for IBM RGB528 Palette */
+	volatile u32 ramdac_cmap_wridx; 
+	volatile u32 ramdac_palette_data;
+	volatile u32 ramdac_pixel_mask;
+	volatile u32 ramdac_palette_rdaddr;
+	volatile u32 ramdac_idx_lo;
+	volatile u32 ramdac_idx_hi;
+	volatile u32 ramdac_idx_data;
+	volatile u32 ramdac_idx_ctl;
+	volatile u32 ramdac_xxx[1784];
+};
+
+struct p9100_cmd_parameng {
+	volatile u32 parameng_status;
+	volatile u32 parameng_bltcmd;
+	volatile u32 parameng_quadcmd;
+};
+
+struct p9100_par {
+	spinlock_t		lock;
+	struct p9100_regs	*regs;
+
+	u32			flags;
+#define P9100_FLAG_BLANKED	0x00000001
+
+	unsigned long		physbase;
+	unsigned long		fbsize;
+
+	struct sbus_dev		*sdev;
+	struct list_head	list;
+};
+
+/**
+ *      p9100_check_var - Optional function.  Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int p9100_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->bits_per_pixel != 8)
+		return -EINVAL;
+
+	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
+		return -EINVAL;
+	if (var->nonstd)
+		return -EINVAL;
+	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+
+	if (var->xres != info->var.xres || var->yres != info->var.yres)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ *      p9100_set_par - Optional function.  Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+p9100_set_par(struct fb_info *info)
+{
+	return 0;
+}
+
+/**
+ *      p9100_setcolreg - Optional function. Sets a color register.
+ *      @regno: boolean, 0 copy local, 1 get_user() function
+ *      @red: frame buffer colormap structure
+ *      @green: The green value which can be up to 16 bits wide
+ *      @blue:  The blue value which can be up to 16 bits wide.
+ *      @transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ */
+static int p9100_setcolreg(unsigned regno,
+			   unsigned red, unsigned green, unsigned blue,
+			   unsigned transp, struct fb_info *info)
+{
+	struct p9100_par *par = (struct p9100_par *) info->par;
+	struct p9100_regs *regs = par->regs;
+	unsigned long flags;
+
+	if (regno >= 256)
+		return 1;
+
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	sbus_writel((regno << 16), &regs->ramdac_cmap_wridx);
+	sbus_writel((red << 16), &regs->ramdac_palette_data);
+	sbus_writel((green << 16), &regs->ramdac_palette_data);
+	sbus_writel((blue << 16), &regs->ramdac_palette_data);
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+/**
+ *      p9100_blank - Optional function.  Blanks the display.
+ *      @blank_mode: the blank mode we want.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+p9100_blank(int blank, struct fb_info *info)
+{
+	struct p9100_par *par = (struct p9100_par *) info->par;
+	struct p9100_regs *regs = par->regs;
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	switch (blank) {
+	case 0: /* Unblanking */
+		val = sbus_readl(&regs->vid_screenpaint_timectl1);
+		val |= SCREENPAINT_TIMECTL1_ENABLE_VIDEO;
+		sbus_writel(val, &regs->vid_screenpaint_timectl1);
+		par->flags &= ~P9100_FLAG_BLANKED;
+		break;
+
+	case 1: /* Normal blanking */
+	case 2: /* VESA blank (vsync off) */
+	case 3: /* VESA blank (hsync off) */
+	case 4: /* Poweroff */
+		val = sbus_readl(&regs->vid_screenpaint_timectl1);
+		val &= ~SCREENPAINT_TIMECTL1_ENABLE_VIDEO;
+		sbus_writel(val, &regs->vid_screenpaint_timectl1);
+		par->flags |= P9100_FLAG_BLANKED;
+		break;
+	}
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+static struct sbus_mmap_map p9100_mmap_map[] = {
+	{ CG3_MMAP_OFFSET,	0,		SBUS_MMAP_FBSIZE(1) },
+	{ 0,			0,		0		    }
+};
+
+static int p9100_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	struct p9100_par *par = (struct p9100_par *)info->par;
+
+	return sbusfb_mmap_helper(p9100_mmap_map,
+				  par->physbase, par->fbsize,
+				  par->sdev->reg_addrs[0].which_io,
+				  vma);
+}
+
+/*
+ *  Initialisation
+ */
+
+static void
+p9100_init_fix(struct fb_info *info, int linebytes)
+{
+	struct p9100_par *par = (struct p9100_par *)info->par;
+
+	strncpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id) - 1);
+	info->fix.id[sizeof(info->fix.id)-1] = 0;
+
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+	info->fix.line_length = linebytes;
+
+	info->fix.accel = FB_ACCEL_SUN_CGTHREE;
+}
+
+struct all_info {
+	struct fb_info info;
+	struct p9100_par par;
+	struct list_head list;
+};
+static LIST_HEAD(p9100_list);
+
+static void p9100_init_one(struct sbus_dev *sdev)
+{
+	struct all_info *all;
+	int linebytes;
+
+	all = kmalloc(sizeof(*all), GFP_KERNEL);
+	if (!all) {
+		printk(KERN_ERR "p9100: Cannot allocate memory.\n");
+		return;
+	}
+	memset(all, 0, sizeof(*all));
+
+	INIT_LIST_HEAD(&all->list);
+
+	spin_lock_init(&all->par.lock);
+	all->par.sdev = sdev;
+
+	/* This is the framebuffer and the only resource apps can mmap.  */
+	all->par.physbase = sdev->reg_addrs[2].phys_addr;
+
+	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+
+	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
+				       all->info.var.xres);
+	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+
+	all->par.regs = (struct p9100_regs *)
+		sbus_ioremap(&sdev->resource[0], 0,
+			     sizeof(struct p9100_regs), "p9100 regs");
+
+	all->info.node = NODEV;
+	all->info.flags = FBINFO_FLAG_DEFAULT;
+	all->info.fbops = &p9100_ops;
+#ifdef CONFIG_SPARC32
+	all->info.screen_base = (char *)
+		prom_getintdefault(sdev->prom_node, "address", 0);
+#endif
+	if (!all->info.screen_base)
+		all->info.screen_base = (char *)
+			sbus_ioremap(&sdev->resource[2], 0,
+				     all->par.fbsize, "p9100 ram");
+	all->info.currcon = -1;
+	all->info.par = &all->par;
+
+	p9100_blank(0, &all->info);
+
+	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+		printk(KERN_ERR "p9100: Could not allocate color map.\n");
+		kfree(all);
+		return;
+	}
+
+	p9100_set_par(&all->info);
+	p9100_init_fix(&all->info, linebytes);
+
+	if (register_framebuffer(&all->info) < 0) {
+		printk(KERN_ERR "p9100: Could not register framebuffer.\n");
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+		return;
+	}
+
+	list_add(&all->list, &p9100_list);
+
+	printk("p9100: %s at %lx:%lx\n",
+	       sdev->prom_name,
+	       (long) sdev->reg_addrs[0].which_io,
+	       (long) sdev->reg_addrs[0].phys_addr);
+}
+
+int __init p9100_init(void)
+{
+	struct sbus_bus *sbus;
+	struct sbus_dev *sdev;
+
+	for_all_sbusdev(sdev, sbus) {
+		if (!strcmp(sdev->prom_name, "p9100"))
+			p9100_init_one(sdev);
+	}
+
+	return 0;
+}
+
+void __exit p9100_exit(void)
+{
+	struct list_head *pos, *tmp;
+
+	list_for_each_safe(pos, tmp, &p9100_list) {
+		struct all_info *all = list_entry(pos, typeof(*all), list);
+
+		unregister_framebuffer(&all->info);
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+	}
+}
+
+int __init
+p9100_setup(char *arg)
+{
+	/* No cmdline options yet... */
+	return 0;
+}
+
+#ifdef MODULE
+module_init(p9100_init);
+module_exit(p9100_exit);
+#endif
+
+MODULE_DESCRIPTION("framebuffer driver for P9100 chipsets");
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/p9100.h b/drivers/video/p9100.h
--- a/drivers/video/p9100.h	Tue Mar  4 19:30:03 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,87 +0,0 @@
-/*
- * Register information for the Weitek P9100 as found
- * on the Tadpole Sparcbook 3 laptops.
- * 
- * From the technical specification document provided by Tadpole.
- *
- * Derrick J Brashear (shadow@dementia.org)
- */
-
-#ifndef _P9100_H_
-#define _P9100_H_
-
-/* P9100 control registers */
-#define P9100_SYSCTL_OFF	0x0UL
-#define P9100_VIDEOCTL_OFF	0x100UL
-#define P9100_VRAMCTL_OFF 	0x180UL
-#define P9100_RAMDAC_OFF 	0x200UL
-#define P9100_VIDEOCOPROC_OFF 	0x400UL
-
-/* P9100 command registers */
-#define P9100_CMD_OFF 0x0UL
-
-/* P9100 framebuffer memory */
-#define P9100_FB_OFF 0x0UL
-
-
-/* 3 bits: 2=8bpp 3=16bpp 5=32bpp 7=24bpp */
-#define SYS_CONFIG_PIXELSIZE_SHIFT 26 
-
-#define SCREENPAINT_TIMECTL1_ENABLE_VIDEO 0x20 /* 0 = off, 1 = on */
-
-struct p9100_ctrl {
-  /* Registers for the system control */
-  __volatile__ __u32 sys_base;
-  __volatile__ __u32 sys_config;
-  __volatile__ __u32 sys_intr;
-  __volatile__ __u32 sys_int_ena;
-  __volatile__ __u32 sys_alt_rd;
-  __volatile__ __u32 sys_alt_wr;
-  __volatile__ __u32 sys_xxx[58];
-  /* Registers for the video control */
-  __volatile__ __u32 vid_base;
-  __volatile__ __u32 vid_hcnt;
-  __volatile__ __u32 vid_htotal;
-  __volatile__ __u32 vid_hsync_rise;
-  __volatile__ __u32 vid_hblank_rise;
-  __volatile__ __u32 vid_hblank_fall;
-  __volatile__ __u32 vid_hcnt_preload;
-  __volatile__ __u32 vid_vcnt;
-  __volatile__ __u32 vid_vlen;
-  __volatile__ __u32 vid_vsync_rise;
-  __volatile__ __u32 vid_vblank_rise;
-  __volatile__ __u32 vid_vblank_fall;
-  __volatile__ __u32 vid_vcnt_preload;
-  __volatile__ __u32 vid_screenpaint_addr;
-  __volatile__ __u32 vid_screenpaint_timectl1;
-  __volatile__ __u32 vid_screenpaint_qsfcnt;
-  __volatile__ __u32 vid_screenpaint_timectl2;
-  __volatile__ __u32 vid_xxx[15];
-  /* Registers for the video control */
-  __volatile__ __u32 vram_base;
-  __volatile__ __u32 vram_memcfg;
-  __volatile__ __u32 vram_refresh_pd;
-  __volatile__ __u32 vram_refresh_cnt;
-  __volatile__ __u32 vram_raslo_max;
-  __volatile__ __u32 vram_raslo_cur;
-  __volatile__ __u32 pwrup_cfg;
-  __volatile__ __u32 vram_xxx[25];
-  /* Registers for IBM RGB528 Palette */
-  __volatile__ __u32 ramdac_cmap_wridx; 
-  __volatile__ __u32 ramdac_palette_data;
-  __volatile__ __u32 ramdac_pixel_mask;
-  __volatile__ __u32 ramdac_palette_rdaddr;
-  __volatile__ __u32 ramdac_idx_lo;
-  __volatile__ __u32 ramdac_idx_hi;
-  __volatile__ __u32 ramdac_idx_data;
-  __volatile__ __u32 ramdac_idx_ctl;
-  __volatile__ __u32 ramdac_xxx[1784];
-};
-
-struct p9100_cmd_parameng {
-  __volatile__ __u32 parameng_status;
-  __volatile__ __u32 parameng_bltcmd;
-  __volatile__ __u32 parameng_quadcmd;
-};
-
-#endif /* _P9100_H_ */
diff -Nru a/drivers/video/p9100fb.c b/drivers/video/p9100fb.c
--- a/drivers/video/p9100fb.c	Tue Mar  4 19:30:14 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,195 +0,0 @@
-/* $id: p9100fb.c,v 1.4 1999/08/18 10:55:01 shadow Exp $
- * p9100fb.c: P9100 frame buffer driver
- *
- * Copyright 1999 Derrick J Brashear (shadow@dementia.org)
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-
-#include <video/sbusfb.h>
-#include <asm/io.h>
-
-#include <video/fbcon-cfb8.h>
-
-#include "p9100.h"
-
-static struct sbus_mmap_map p9100_mmap_map[] = {
-#if 0 /* For now, play we're a dumb color fb */
-  { P9100_CTL_OFF, 0x38000000, 0x2000 },
-  { P9100_CMD_OFF, 0x38002000, 0x2000 },
-  { P9100_FB_OFF, 0x38800000, 0x200000 },
-  { CG3_MMAP_OFFSET, 0x38800000, SBUS_MMAP_FBSIZE(1) },
-#else
-  { CG3_MMAP_OFFSET, 0x0, SBUS_MMAP_FBSIZE(1) },
-#endif
-  { 0, 0, 0 }
-};
-
-#define _READCTL(member, out) \
-{ \
-  struct p9100_ctrl *actual; \
-  actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
-  out = sbus_readl(&actual-> ## member ); \
-}
-
-#define READCTL(member, out) \
-{ \
-  struct p9100_ctrl *enab, *actual; \
-  actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
-  enab = (struct p9100_ctrl *)fb->s.p9100.fbmem; \
-  out = sbus_readl(&enab-> ## member ); \
-  out = sbus_readl(&actual-> ## member ); \
-}
-
-#define WRITECTL(member, val) \
-{ \
-  u32 __writetmp; \
-  struct p9100_ctrl *enab, *actual; \
-  actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
-  enab = (struct p9100_ctrl *)fb->s.p9100.fbmem; \
-  __writetmp = sbus_readl(&enab-> ## member ); \
-  sbus_writel(val, &actual-> ## member ); \
-}
-
-static void p9100_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count)
-{
-	unsigned long flags;
-	u32 tmp;
-	int i;
-
-	spin_lock_irqsave(&fb->lock, flags);
-
-	_READCTL(pwrup_cfg, tmp);
-	WRITECTL(ramdac_cmap_wridx, (index << 16));
-
-	for (i = index; count--; i++){
-		_READCTL(pwrup_cfg, tmp);
-		WRITECTL(ramdac_palette_data, (fb->color_map CM(i,0) << 16));
-		_READCTL(pwrup_cfg, tmp);
-		WRITECTL(ramdac_palette_data, (fb->color_map CM(i,1) << 16));
-		_READCTL(pwrup_cfg, tmp);
-		WRITECTL(ramdac_palette_data, (fb->color_map CM(i,2) << 16));
-	}
-
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static int p9100_blank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u32 val;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	READCTL(vid_screenpaint_timectl1, val);
-	val &= ~ SCREENPAINT_TIMECTL1_ENABLE_VIDEO;
-	WRITECTL(vid_screenpaint_timectl1, val);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static int p9100_unblank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u32 val;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	READCTL(vid_screenpaint_timectl1, val);
-	val |= SCREENPAINT_TIMECTL1_ENABLE_VIDEO;
-	WRITECTL(vid_screenpaint_timectl1, val);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static void p9100_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
-{
-  fb->info.screen_base += (y_margin - fb->y_margin) * p->line_length + 
-    (x_margin - fb->x_margin);
-}
-
-static char idstring[60] __initdata = { 0 };
-
-char * __init p9100fb_init(struct fb_info_sbusfb *fb)
-{
-	struct fb_fix_screeninfo *fix = &fb->fix;
-	struct display *disp = &fb->disp;
-	struct fbtype *type = &fb->type;
-	struct sbus_dev *sdev = fb->sbdp;
-	unsigned long phys = sdev->reg_addrs[2].phys_addr;
-	int tmp;
-
-#ifndef FBCON_HAS_CFB8
-	return NULL;
-#endif
-
-	/* Control regs: fb->sbdp->reg_addrs[0].phys_addr 
-	 * Command regs: fb->sbdp->reg_addrs[1].phys_addr 
-	 * Frame buffer: fb->sbdp->reg_addrs[2].phys_addr 
-         */
-
-	if (!fb->s.p9100.ctrl) {
-		fb->s.p9100.ctrl = (struct p9100_ctrl *)
-			sbus_ioremap(&sdev->resource[0], 0,
-				     sdev->reg_addrs[0].reg_size, "p9100 ctrl");
-	}
-
-	strcpy(fb->info.modename, "p9100");
-	strcpy(fix->id, "p9100");
-	fix->accel = FB_ACCEL_SUN_CGTHREE;
-	fix->line_length = fb->var.xres_virtual;
-
-	disp->scrollmode = SCROLL_YREDRAW;
-	if (!fb->info.screen_base)
-		fb->info.screen_base = (char *)
-			sbus_ioremap(&sdev->resource[2], 0,
-				     type->fb_size, "p9100 ram");
-	fb->s.p9100.fbmem = (volatile u32 *)fb->info.screen_base;
-	fb->info.screen_base += fix->line_length * fb->y_margin + fb->x_margin;
-
-	READCTL(sys_config, tmp);
-        switch ((tmp >> SYS_CONFIG_PIXELSIZE_SHIFT) & 7) {
-	case 7: 
-	  type->fb_depth = 24; 
-	  break;
-	case 5: 
-	  type->fb_depth = 32;
-	  break;
-	case 3: 
-	  type->fb_depth = 16; 
-	  break;
-	case 2: 
-	  type->fb_depth = 8; 
-	  break;
-	default: 
-	  printk("p9100: screen depth unknown: 0x%x", tmp);
-	  return NULL;
-        }
-
-	fb->dispsw = fbcon_cfb8;
-
-	fb->margins = p9100_margins;
-	fb->loadcmap = p9100_loadcmap;
-	fb->blank = p9100_blank;
-	fb->unblank = p9100_unblank;
-	
-	fb->physbase = phys;
-	fb->mmap_map = p9100_mmap_map;
-	
-	sprintf(idstring, "%s at 0x%x", "p9100", 
-		(unsigned int)fb->info.screen_base);
-
-	return idstring;
-}
-
diff -Nru a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
--- a/drivers/video/pvr2fb.c	Tue Mar  4 19:30:04 2003
+++ b/drivers/video/pvr2fb.c	Tue Mar  4 19:30:04 2003
@@ -15,7 +15,7 @@
  * an odd scheme for converting hardware values to/from framebuffer values, here are
  * some hacked-up formulas:
  *
- *  The Dreamcast has screen offsets from each side of it's four borders and the start
+ *  The Dreamcast has screen offsets from each side of its four borders and the start
  *  offsets of the display window.  I used these values to calculate 'pseudo' values
  *  (think of them as placeholders) for the fb video mode, so that when it came time
  *  to convert these values back into their hardware values, I could just add mode-
diff -Nru a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
--- a/drivers/video/retz3fb.c	Tue Mar  4 19:30:13 2003
+++ b/drivers/video/retz3fb.c	Tue Mar  4 19:30:13 2003
@@ -1379,7 +1379,7 @@
 		zinfo->base = ioremap(board_addr, board_size);
 		zinfo->regs = zinfo->base;
 		zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET;
-		/* Get memory size - for now we asume its a 4MB board */
+		/* Get memory size - for now we asume it's a 4MB board */
 		zinfo->fbsize = 0x00400000; /* 4 MB */
 		zinfo->physregs = board_addr;
 		zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET;
diff -Nru a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
--- a/drivers/video/sa1100fb.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/video/sa1100fb.c	Tue Mar  4 19:30:05 2003
@@ -1370,7 +1370,7 @@
 #ifdef CONFIG_SA1100_HUW_WEBPANEL
 #error Move me into __sa1100fb_lcd_power and/or __sa1100fb_backlight_power
 	if (machine_is_huw_webpanel()) {
-		// dont forget to set the control lines to zero (?)
+		// don't forget to set the control lines to zero (?)
 		DPRINTK("ShutDown HuW LCD controller\n");
 		BCR_clear(BCR_TFT_ENA + BCR_CCFL_POW + BCR_PWM_BACKLIGHT);
 	}
diff -Nru a/drivers/video/sbusfb.c b/drivers/video/sbusfb.c
--- a/drivers/video/sbusfb.c	Tue Mar  4 19:30:12 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1165 +0,0 @@
-/*
- *  linux/drivers/video/sbusfb.c -- SBUS or UPA based frame buffer device
- *
- *	Copyright (C) 1998 Jakub Jelinek
- *
- *  This driver is partly based on the Open Firmware console driver
- *
- *	Copyright (C) 1997 Geert Uytterhoeven
- *
- *  and SPARC console subsystem
- *
- *      Copyright (C) 1995 Peter Zaitcev (zaitcev@yahoo.com)
- *      Copyright (C) 1995-1997 David S. Miller (davem@caip.rutgers.edu)
- *      Copyright (C) 1995-1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- *      Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
- *      Copyright (C) 1996-1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *      Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/selection.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kd.h>
-#include <linux/vt_kern.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>	/* io_remap_page_range() */
-
-#include <video/sbusfb.h>
-
-#define DEFAULT_CURSOR_BLINK_RATE       (2*HZ/5)
-
-#define CURSOR_SHAPE			1
-#define CURSOR_BLINK			2
-
-    /*
-     *  Interface used by the world
-     */
-
-int sbusfb_init(void);
-int sbusfb_setup(char*);
-
-static int defx_margin = -1, defy_margin = -1;
-static char fontname[40] __initdata = { 0 };
-static int curblink __initdata = 1;
-static struct {
-	int depth;
-	int xres, yres;
-	int x_margin, y_margin;
-} def_margins [] = {
-	{ 8, 1280, 1024, 64, 80 },
-	{ 8, 1152, 1024, 64, 80 },
-	{ 8, 1152, 900,  64, 18 },
-	{ 8, 1024, 768,  0,  0 },
-	{ 8, 800, 600, 16, 12 },
-	{ 8, 640, 480, 0, 0 },
-	{ 1, 1152, 900,  8,  18 },
-	{ 0 },
-};
-
-static int sbusfb_open(struct fb_info *info, int user);
-static int sbusfb_release(struct fb_info *info, int user);
-static int sbusfb_mmap(struct fb_info *info, struct file *file, 
-			struct vm_area_struct *vma);
-static int sbusfb_set_var(struct fb_var_screeninfo *var, int con,
-			struct fb_info *info);
-static int sbusfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			struct fb_info *info);
-static int sbusfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			struct fb_info *info);
-static int sbusfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			    u_int transp, struct fb_info *info);
-static int sbusfb_blank(int blank, struct fb_info *info);
-static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			    u_long arg, int con, struct fb_info *info);
-static void sbusfb_cursor(struct display *p, int mode, int x, int y);
-static void sbusfb_clear_margin(struct display *p, int s);
-			    
-
-    /*
-     *  Interface to the low level console driver
-     */
-
-static int sbusfbcon_switch(int con, struct fb_info *info);
-static int sbusfbcon_updatevar(int con, struct fb_info *info);
-
-    /*
-     *  Internal routines
-     */
-
-static int sbusfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			    u_int *transp, struct fb_info *info);
-
-static struct fb_ops sbusfb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_open =	sbusfb_open,
-	.fb_release =	sbusfb_release,
-	.fb_set_var =	sbusfb_set_var,
-	.fb_get_cmap =	sbusfb_get_cmap,
-	.fb_set_cmap =	sbusfb_set_cmap,
-	.fb_setcolreg =	sbusfb_setcolreg,
-	.fb_blank =	sbusfb_blank,
-	.fb_ioctl =	sbusfb_ioctl,
-	.fb_mmap =	sbusfb_mmap,
-};
-
-    /*
-     *  Open/Release the frame buffer device
-     */
-
-static int sbusfb_open(struct fb_info *info, int user)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(info);
-	
-	if (user) {
-		if (fb->open == 0) {
-			fb->mmaped = 0;
-			fb->vtconsole = -1;
-		}
-		fb->open++;
-	} else
-		fb->consolecnt++;
-	return 0;
-}
-
-static int sbusfb_release(struct fb_info *info, int user)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
-	if (user) {	
-		fb->open--;
-		if (fb->open == 0) {
-			if (fb->vtconsole != -1) {
-				vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
-				if (fb->mmaped) {
-					fb->graphmode--;
-					sbusfb_clear_margin(&fb_display[fb->vtconsole], 0);
-				}
-			}
-			if (fb->reset)
-				fb->reset(fb);
-		}
-	} else
-		fb->consolecnt--;
-	return 0;
-}
-
-static unsigned long sbusfb_mmapsize(struct fb_info_sbusfb *fb, long size)
-{
-	if (size == SBUS_MMAP_EMPTY) return 0;
-	if (size >= 0) return size;
-	return fb->type.fb_size * (-size);
-}
-
-static int sbusfb_mmap(struct fb_info *info, struct file *file, 
-			struct vm_area_struct *vma)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(info);
-	unsigned int size, page, r, map_size;
-	unsigned long map_offset = 0;
-	unsigned long off;
-	int i;
-                                        
-	size = vma->vm_end - vma->vm_start;
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-		return -EINVAL;
-
-	off = vma->vm_pgoff << PAGE_SHIFT;
-
-	/* To stop the swapper from even considering these pages */
-	vma->vm_flags |= (VM_SHM| VM_LOCKED);
-	
-
-	/* Each page, see which map applies */
-	for (page = 0; page < size; ){
-		map_size = 0;
-		for (i = 0; fb->mmap_map[i].size; i++)
-			if (fb->mmap_map[i].voff == off+page) {
-				map_size = sbusfb_mmapsize(fb,fb->mmap_map[i].size);
-#ifdef __sparc_v9__
-#define POFF_MASK	(PAGE_MASK|0x1UL)
-#else
-#define POFF_MASK	(PAGE_MASK)
-#endif				
-				map_offset = (fb->physbase + fb->mmap_map[i].poff) & POFF_MASK;
-				break;
-			}
-		if (!map_size){
-			page += PAGE_SIZE;
-			continue;
-		}
-		if (page + map_size > size)
-			map_size = size - page;
-		r = io_remap_page_range(vma, vma->vm_start+page, map_offset, map_size, vma->vm_page_prot, fb->iospace);
-		if (r)
-			return -EAGAIN;
-		page += map_size;
-	}
-	
-	vma->vm_flags |= VM_IO;
-	if (!fb->mmaped) {
-		int lastconsole = 0;
-		
-		if (info->display_fg)
-			lastconsole = info->display_fg->vc_num;
-		fb->mmaped = 1;
-		if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
-			fb->vtconsole = lastconsole;
-			fb->graphmode++;
-			vt_cons [lastconsole]->vc_mode = KD_GRAPHICS;
-			vc_cons[lastconsole].d->vc_sw->con_cursor(vc_cons[lastconsole].d,CM_ERASE);
-		} else if (fb->unblank && !fb->blanked)
-			(*fb->unblank)(fb);
-	}
-	return 0;
-}
-
-static void sbusfb_clear_margin(struct display *p, int s)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
-	if (fb->switch_from_graph)
-		(*fb->switch_from_graph)(fb);
-	if (fb->fill) {
-		unsigned short rects [16];
-
-		rects [0] = 0;
-		rects [1] = 0;
-		rects [2] = fb->info.var.xres_virtual;
-		rects [3] = fb->y_margin;
-		rects [4] = 0;
-		rects [5] = fb->y_margin;
-		rects [6] = fb->x_margin;
-		rects [7] = fb->info.var.yres_virtual;
-		rects [8] = fb->info.var.xres_virtual - fb->x_margin;
-		rects [9] = fb->y_margin;
-		rects [10] = fb->info.var.xres_virtual;
-		rects [11] = fb->info.var.yres_virtual;
-		rects [12] = fb->x_margin;
-		rects [13] = fb->info.var.yres_virtual - fb->y_margin;
-		rects [14] = fb->info.var.xres_virtual - fb->x_margin;
-		rects [15] = fb->info.var.yres_virtual;
-		(*fb->fill)(fb, p, s, 4, rects);
-	} else {
-		unsigned char *fb_base = fb->info.screen_base, *q;
-		int skip_bytes = fb->y_margin * fb->info.var.xres_virtual;
-		int scr_size = fb->info.var.xres_virtual
-			* fb->info.var.yres_virtual;
-		int h, he, incr, size;
-
-		he = fb->info.var.yres;
-		if (fb->info.var.bits_per_pixel == 1) {
-			fb_base -= (skip_bytes + fb->x_margin) / 8;
-			skip_bytes /= 8;
-			scr_size /= 8;
-			fb_memset255 (fb_base, skip_bytes - fb->x_margin / 8);
-			fb_memset255 (fb_base + scr_size - skip_bytes + fb->x_margin / 8, skip_bytes - fb->x_margin / 8);
-			incr = fb->info.var.xres_virtual / 8;
-			size = fb->x_margin / 8 * 2;
-			for (q = fb_base + skip_bytes - fb->x_margin / 8, h = 0;
-			     h <= he; q += incr, h++)
-				fb_memset255 (q, size);
-		} else {
-			fb_base -= (skip_bytes + fb->x_margin);
-			fb_memset (fb_base, attr_bgcol(p,s), skip_bytes - fb->x_margin);
-			fb_memset (fb_base + scr_size - skip_bytes + fb->x_margin, attr_bgcol(p,s), skip_bytes - fb->x_margin);
-			incr = fb->info.var.xres_virtual;
-			size = fb->x_margin * 2;
-			for (q = fb_base + skip_bytes - fb->x_margin, h = 0;
-			     h <= he; q += incr, h++)
-				fb_memset (q, attr_bgcol(p,s), size);
-		}
-	}
-}
-
-static void sbusfb_disp_setup(struct display *p)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
-	if (fb->setup)
-		fb->setup(p);	
-	sbusfb_clear_margin(p, 0);
-}
-
-
-    /*
-     *  Set the User Defined Part of the Display
-     */
-
-static int sbusfb_set_var(struct fb_var_screeninfo *var, int con,
-			  struct fb_info *info)
-{
-       struct display *display;
-       int activate = var->activate;
-
-       if(con >= 0)
-               display = &fb_display[con];
-       else
-               display = info->disp;
-
-       /* simple check for equality until fully implemented -E */
-       if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-               if (display->var.xres != var->xres ||
-                       display->var.yres != var->yres ||
-                       display->var.xres_virtual != var->xres_virtual ||
-                       display->var.yres_virtual != var->yres_virtual ||
-                       display->var.bits_per_pixel != var->bits_per_pixel ||
-                       display->var.accel_flags != var->accel_flags) {
-                       return -EINVAL;
-               }
-       }
-       return 0;
-
-}
-
-    /*
-     *  Hardware cursor
-     */
-     
-static int sbus_hw_scursor (struct fbcursor *cursor, struct fb_info_sbusfb *fb)
-{
-	int op;
-	int i, bytes = 0;
-	struct fbcursor f;
-	char red[2], green[2], blue[2];
-	
-	if (copy_from_user (&f, cursor, sizeof(struct fbcursor)))
-		return -EFAULT;
-	op = f.set;
-	if (op & FB_CUR_SETSHAPE){
-		if ((u32) f.size.fbx > fb->cursor.hwsize.fbx)
-			return -EINVAL;
-		if ((u32) f.size.fby > fb->cursor.hwsize.fby)
-			return -EINVAL;
-		if (f.size.fbx > 32)
-			bytes = f.size.fby << 3;
-		else
-			bytes = f.size.fby << 2;
-	}
-	if (op & FB_CUR_SETCMAP){
-		if (f.cmap.index || f.cmap.count != 2)
-			return -EINVAL;
-		if (copy_from_user (red, f.cmap.red, 2) ||
-		    copy_from_user (green, f.cmap.green, 2) ||
-		    copy_from_user (blue, f.cmap.blue, 2))
-			return -EFAULT;
-	}
-	if (op & FB_CUR_SETCMAP)
-		(*fb->setcursormap) (fb, red, green, blue);
-	if (op & FB_CUR_SETSHAPE){
-		u32 u;
-		
-		fb->cursor.size = f.size;
-		memset ((void *)&fb->cursor.bits, 0, sizeof (fb->cursor.bits));
-		if (copy_from_user (fb->cursor.bits [0], f.mask, bytes) ||
-		    copy_from_user (fb->cursor.bits [1], f.image, bytes))
-			return -EFAULT;
-		if (f.size.fbx <= 32) {
-			u = 0xffffffff << (32 - f.size.fbx);
-			for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
-				fb->cursor.bits [0][i] &= u;
-				fb->cursor.bits [1][i] &= fb->cursor.bits [0][i];
-			}
-		} else {
-			u = 0xffffffff << (64 - f.size.fbx);
-			for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
-				fb->cursor.bits [0][2*i+1] &= u;
-				fb->cursor.bits [1][2*i] &= fb->cursor.bits [0][2*i];
-				fb->cursor.bits [1][2*i+1] &= fb->cursor.bits [0][2*i+1];
-			}
-		}
-		(*fb->setcurshape) (fb);
-	}
-	if (op & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)){
-		if (op & FB_CUR_SETCUR)
-			fb->cursor.enable = f.enable;
-		if (op & FB_CUR_SETPOS)
-			fb->cursor.cpos = f.pos;
-		if (op & FB_CUR_SETHOT)
-			fb->cursor.chot = f.hot;
-		(*fb->setcursor) (fb);
-	}
-	return 0;
-}
-
-static unsigned char hw_cursor_cmap[2] = { 0, 0xff };
-
-static void
-sbusfb_cursor_timer_handler(unsigned long dev_addr)
-{
-	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)dev_addr;
-        
-	if (!fb->setcursor) return;
-                                
-	if (fb->cursor.mode & CURSOR_BLINK) {
-		fb->cursor.enable ^= 1;
-		fb->setcursor(fb);
-	}
-	
-	fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate;
-	add_timer(&fb->cursor.timer);
-}
-
-static void sbusfb_cursor(struct display *p, int mode, int x, int y)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfod(p);
-	
-	switch (mode) {
-	case CM_ERASE:
-		fb->cursor.mode &= ~CURSOR_BLINK;
-		fb->cursor.enable = 0;
-		(*fb->setcursor)(fb);
-		break;
-				  
-	case CM_MOVE:
-	case CM_DRAW:
-		if (fb->cursor.mode & CURSOR_SHAPE) {
-			fb->cursor.size.fbx = fontwidth(p);
-			fb->cursor.size.fby = fontheight(p);
-			fb->cursor.chot.fbx = 0;
-			fb->cursor.chot.fby = 0;
-			fb->cursor.enable = 1;
-			memset (fb->cursor.bits, 0, sizeof (fb->cursor.bits));
-			fb->cursor.bits[0][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p)));
-			fb->cursor.bits[1][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p)));
-			fb->cursor.bits[0][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p)));
-			fb->cursor.bits[1][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p)));
-			(*fb->setcursormap) (fb, hw_cursor_cmap, hw_cursor_cmap, hw_cursor_cmap);
-			(*fb->setcurshape) (fb);
-		}
-		fb->cursor.mode = CURSOR_BLINK;
-		if (fontwidthlog(p))
-			fb->cursor.cpos.fbx = (x << fontwidthlog(p)) + fb->x_margin;
-		else
-			fb->cursor.cpos.fbx = (x * fontwidth(p)) + fb->x_margin;
-		if (fontheightlog(p))
-			fb->cursor.cpos.fby = (y << fontheightlog(p)) + fb->y_margin;
-		else
-			fb->cursor.cpos.fby = (y * fontheight(p)) + fb->y_margin;
-		(*fb->setcursor)(fb);
-		break;
-	}
-}
-
-    /*
-     *  Get the Colormap
-     */
-
-static int sbusfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			 struct fb_info *info)
-{
-	if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
-		return fb_get_cmap(cmap, kspc, sbusfb_getcolreg, info);
-	else if (fb_display[con].cmap.len) /* non default colormap? */
-		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2);
-	return 0;
-}
-
-    /*
-     *  Set the Colormap
-     */
-
-static int sbusfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			 struct fb_info *info)
-{
-	int err;
-	struct display *disp;
-
-	if (con >= 0)
-		disp = &fb_display[con];
-	else
-		disp = info->disp;
-	if (!disp->cmap.len) {	/* no colormap allocated? */
-		if ((err = fb_alloc_cmap(&disp->cmap, 1<<disp->var.bits_per_pixel, 0)))
-			return err;
-	}
-	if (con == info->currcon) {			/* current console? */
-		err = fb_set_cmap(cmap, kspc, info);
-		if (!err) {
-			struct fb_info_sbusfb *fb = sbusfbinfo(info);
-			
-			if (fb->loadcmap)
-				(*fb->loadcmap)(fb, &fb_display[con], cmap->start, cmap->len);
-		}
-		return err;
-	} else
-		fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
-	return 0;
-}
-
-static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			u_long arg, int con, struct fb_info *info)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(info);
-	int i;
-	int lastconsole;
-	
-	switch (cmd){
-	case FBIOGTYPE:		/* return frame buffer type */
-		if (copy_to_user((struct fbtype *)arg, &fb->type, sizeof(struct fbtype)))
-			return -EFAULT;
-		break;
-	case FBIOGATTR: {
-		struct fbgattr *fba = (struct fbgattr *) arg;
-		
-		i = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct fbgattr));
-		if (i) return i;
-		if (__put_user(fb->emulations[0], &fba->real_type) ||
-		    __put_user(0, &fba->owner) ||
-		    __copy_to_user(&fba->fbtype, &fb->type,
-				   sizeof(struct fbtype)) ||
-		    __put_user(0, &fba->sattr.flags) ||
-		    __put_user(fb->type.fb_type, &fba->sattr.emu_type) ||
-		    __put_user(-1, &fba->sattr.dev_specific[0]))
-			return -EFAULT;
-		for (i = 0; i < 4; i++) {
-			if (put_user(fb->emulations[i], &fba->emu_types[i]))
-				return -EFAULT;
-		}
-		break;
-	}
-	case FBIOSATTR:
-		i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbsattr));
-		if (i) return i;
-		return -EINVAL;
-	case FBIOSVIDEO:
-		if (fb->consolecnt) {
-			lastconsole = info->display_fg->vc_num;
-			if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
- 				break;
- 		}
-		if (get_user(i, (int *)arg))
-			return -EFAULT;
-		if (i){
-			if (!fb->blanked || !fb->unblank)
-				break;
-			if (fb->consolecnt || (fb->open && fb->mmaped))
-				(*fb->unblank)(fb);
-			fb->blanked = 0;
-		} else {
-			if (fb->blanked || !fb->blank)
-				break;
-			(*fb->blank)(fb);
-			fb->blanked = 1;
-		}
-		break;
-	case FBIOGVIDEO:
-		if (put_user(fb->blanked, (int *) arg))
-			return -EFAULT;
-		break;
-	case FBIOGETCMAP_SPARC: {
-		char *rp, *gp, *bp;
-		int end, count, index;
-		struct fbcmap *cmap;
-
-		if (!fb->loadcmap)
-			return -EINVAL;
-		i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbcmap));
-		if (i) return i;
-		cmap = (struct fbcmap *) arg;
-		if (__get_user(count, &cmap->count) ||
-		    __get_user(index, &cmap->index))
-			return -EFAULT;
-		if ((index < 0) || (index > 255))
-			return -EINVAL;
-		if (index + count > 256)
-			count = 256 - index;
-		if (__get_user(rp, &cmap->red) ||
-		    __get_user(gp, &cmap->green) ||
-		    __get_user(bp, &cmap->blue))
-			return -EFAULT;
-		if (verify_area (VERIFY_WRITE, rp, count))
-			return -EFAULT;
-		if (verify_area (VERIFY_WRITE, gp, count))
-			return -EFAULT;
-		if (verify_area (VERIFY_WRITE, bp, count))
-			return -EFAULT;
-		end = index + count;
-		for (i = index; i < end; i++){
-			if (__put_user(fb->color_map CM(i,0), rp) ||
-			    __put_user(fb->color_map CM(i,1), gp) ||
-			    __put_user(fb->color_map CM(i,2), bp))
-				return -EFAULT;
-			rp++; gp++; bp++;
-		}
-		(*fb->loadcmap)(fb, NULL, index, count);
-		break;			
-	}
-	case FBIOPUTCMAP_SPARC: {	/* load color map entries */
-		char *rp, *gp, *bp;
-		int end, count, index;
-		struct fbcmap *cmap;
-		
-		if (!fb->loadcmap || !fb->color_map)
-			return -EINVAL;
-		i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbcmap));
-		if (i) return i;
-		cmap = (struct fbcmap *) arg;
-		if (__get_user(count, &cmap->count) ||
-		    __get_user(index, &cmap->index))
-			return -EFAULT;
-		if ((index < 0) || (index > 255))
-			return -EINVAL;
-		if (index + count > 256)
-			count = 256 - index;
-		if (__get_user(rp, &cmap->red) ||
-		    __get_user(gp, &cmap->green) ||
-		    __get_user(bp, &cmap->blue))
-			return -EFAULT;
-		if (verify_area (VERIFY_READ, rp, count))
-			return -EFAULT;
-		if (verify_area (VERIFY_READ, gp, count))
-			return -EFAULT;
-		if (verify_area (VERIFY_READ, bp, count))
-			return -EFAULT;
-
-		end = index + count;
-		for (i = index; i < end; i++){
-			if (__get_user(fb->color_map CM(i,0), rp))
-				return -EFAULT;
-			if (__get_user(fb->color_map CM(i,1), gp))
-				return -EFAULT;
-			if (__get_user(fb->color_map CM(i,2), bp))
-				return -EFAULT;
-			rp++; gp++; bp++;
-		}
-		(*fb->loadcmap)(fb, NULL, index, count);
-		break;			
-	}
-	case FBIOGCURMAX: {
-		struct fbcurpos *p = (struct fbcurpos *) arg;
-		if (!fb->setcursor) return -EINVAL;
-		if(verify_area (VERIFY_WRITE, p, sizeof (struct fbcurpos)))
-			return -EFAULT;
-		if (__put_user(fb->cursor.hwsize.fbx, &p->fbx) ||
-		    __put_user(fb->cursor.hwsize.fby, &p->fby))
-			return -EFAULT;
-		break;
-	}
-	case FBIOSCURSOR:
-		if (!fb->setcursor) return -EINVAL;
- 		if (fb->consolecnt) {
- 			lastconsole = info->display_fg->vc_num; 
- 			if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
- 				return -EINVAL; /* Don't let graphics programs hide our nice text cursor */
-			fb->cursor.mode = CURSOR_SHAPE; /* Forget state of our text cursor */
-		}
-		return sbus_hw_scursor ((struct fbcursor *) arg, fb);
-
-	case FBIOSCURPOS:
-		if (!fb->setcursor) return -EINVAL;
-		/* Don't let graphics programs move our nice text cursor */
- 		if (fb->consolecnt) {
- 			lastconsole = info->display_fg->vc_num; 
- 			if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
- 				return -EINVAL; /* Don't let graphics programs move our nice text cursor */
- 		}
-		if (copy_from_user(&fb->cursor.cpos, (void *)arg, sizeof(struct fbcurpos)))
-			return -EFAULT;
-		(*fb->setcursor) (fb);
-		break;
-	default:
-		if (fb->ioctl)
-			return fb->ioctl(fb, cmd, arg);
-		return -EINVAL;
-	}		
-	return 0;
-}
-
-    /*
-     *  Setup: parse used options
-     */
-
-int __init sbusfb_setup(char *options)
-{
-	char *p;
-	
-	for (p = options;;) {
-		if (!strncmp(p, "nomargins", 9)) {
-			defx_margin = 0; defy_margin = 0;
-		} else if (!strncmp(p, "margins=", 8)) {
-			int i, j;
-			char *q;
-			
-			i = simple_strtoul(p+8,&q,10);
-			if (i >= 0 && *q == 'x') {
-			    j = simple_strtoul(q+1,&q,10);
-			    if (j >= 0 && (*q == ' ' || !*q)) {
-			    	defx_margin = i; defy_margin = j;
-			    }
-			}
-		} else if (!strncmp(p, "font=", 5)) {
-			int i;
-			
-			for (i = 0; i < sizeof(fontname) - 1; i++)
-				if (p[i+5] == ' ' || !p[i+5])
-					break;
-			memcpy(fontname, p+5, i);
-			fontname[i] = 0;
-		} else if (!strncmp(p, "noblink", 7))
-			curblink = 0;
-		while (*p && *p != ' ' && *p != ',') p++;
-		if (*p != ',') break;
-		p++;
-	}
-	return 0;
-}
-
-static int sbusfbcon_switch(int con, struct fb_info *info)
-{
-	int x_margin, y_margin;
-	struct fb_info_sbusfb *fb = sbusfbinfo(info);
-	int lastconsole;
-    
-	/* Do we have to save the colormap? */
-	if (fb_display[info->currcon].cmap.len)
-		fb_get_cmap(&fb_display[info->currcon].cmap, 1, sbusfb_getcolreg, info);
-
-	if (info->display_fg) {
-		lastconsole = info->display_fg->vc_num;
-		if (lastconsole != con && 
-		    (fontwidth(&fb_display[lastconsole]) != fontwidth(&fb_display[con]) ||
-		     fontheight(&fb_display[lastconsole]) != fontheight(&fb_display[con])))
-			fb->cursor.mode |= CURSOR_SHAPE;
-	}
-	x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2;
-	y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2;
-	if (fb->margins)
-		fb->margins(fb, &fb_display[con], x_margin, y_margin);
-	if (fb->graphmode || fb->x_margin != x_margin || fb->y_margin != y_margin) {
-		fb->x_margin = x_margin; fb->y_margin = y_margin;
-		sbusfb_clear_margin(&fb_display[con], 0);
-	}
-	info->currcon = con;
-	/* Install new colormap */
-	do_install_cmap(con, info);
-	return 0;
-}
-
-    /*
-     *  Update the `var' structure (called by fbcon.c)
-     */
-
-static int sbusfbcon_updatevar(int con, struct fb_info *info)
-{
-	/* Nothing */
-	return 0;
-}
-
-    /*
-     *  Blank the display.
-     */
-
-static int sbusfb_blank(int blank, struct fb_info *info)
-{
-    struct fb_info_sbusfb *fb = sbusfbinfo(info);
-    
-    if (blank && fb->blank)
-	    return fb->blank(fb);
-    else if (!blank && fb->unblank)
-	    return fb->unblank(fb);
-    return 0;
-}
-
-    /*
-     *  Read a single color register and split it into
-     *  colors/transparent. Return != 0 for invalid regno.
-     */
-
-static int sbusfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			  u_int *transp, struct fb_info *info)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
-	if (!fb->color_map || regno > 255)
-		return 1;
-	*red = (fb->color_map CM(regno, 0)<<8) | fb->color_map CM(regno, 0);
-	*green = (fb->color_map CM(regno, 1)<<8) | fb->color_map CM(regno, 1);
-	*blue = (fb->color_map CM(regno, 2)<<8) | fb->color_map CM(regno, 2);
-	*transp = 0;
-	return 0;
-}
-
-
-    /*
-     *  Set a single color register. The values supplied are already
-     *  rounded down to the hardware's capabilities (according to the
-     *  entries in the var structure). Return != 0 for invalid regno.
-     */
-
-static int sbusfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			    u_int transp, struct fb_info *info)
-{
-	struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
-	if (!fb->color_map || regno > 255)
-		return 1;
-	red >>= 8;
-	green >>= 8;
-	blue >>= 8;
-	fb->color_map CM(regno, 0) = red;
-	fb->color_map CM(regno, 1) = green;
-	fb->color_map CM(regno, 2) = blue;
-	return 0;
-}
-
-static int sbusfb_set_font(struct display *p, int width, int height)
-{
-	int margin;
-	int w = p->var.xres_virtual, h = p->var.yres_virtual;
-	int depth = p->var.bits_per_pixel;
-	struct fb_info_sbusfb *fb = sbusfbinfod(p);
-	int x_margin, y_margin;
-	
-	if (depth > 8) depth = 8;
-	x_margin = 0;
-	y_margin = 0;
-	if (defx_margin < 0 || defy_margin < 0) {
-		for (margin = 0; def_margins[margin].depth; margin++)
-			if (w == def_margins[margin].xres &&
-			    h == def_margins[margin].yres &&
-			    depth == def_margins[margin].depth) {
-				x_margin = def_margins[margin].x_margin;
-				y_margin = def_margins[margin].y_margin;
-				break;
-			}
-	} else {
-		x_margin = defx_margin;
-		y_margin = defy_margin;
-	}
-	x_margin += ((w - 2*x_margin) % width) / 2;
-	y_margin += ((h - 2*y_margin) % height) / 2;
-
-	p->var.xres = w - 2*x_margin;
-	p->var.yres = h - 2*y_margin;
-	
-	fb->cursor.mode |= CURSOR_SHAPE;
-	
-	if (fb->margins)
-		fb->margins(fb, p, x_margin, y_margin);
-	if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
-		fb->x_margin = x_margin; fb->y_margin = y_margin;
-		sbusfb_clear_margin(p, 0);
-	}
-
-	return 1;
-}
-
-void sbusfb_palette(int enter)
-{
-	int i;
-	struct display *p;
-	
-	for (i = 0; i < MAX_NR_CONSOLES; i++) {
-		p = &fb_display[i];
-		if (p->dispsw && p->dispsw->setup == sbusfb_disp_setup &&
-		    p->fb_info->display_fg &&
-		    p->fb_info->display_fg->vc_num == i) {
-			struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
-			if (fb->restore_palette) {
-				if (enter)
-					fb->restore_palette(fb);
-				else if (vt_cons[i]->vc_mode != KD_GRAPHICS)
-				         vc_cons[i].d->vc_sw->con_set_palette(vc_cons[i].d, color_table);
-			}
-		}
-	}
-}
-
-    /*
-     *  Initialisation
-     */
-     
-extern void (*prom_palette)(int);
-
-static void __init sbusfb_init_fb(int node, int parent, int fbtype,
-				  struct sbus_dev *sbdp)
-{
-	struct fb_fix_screeninfo *fix;
-	struct fb_var_screeninfo *var;
-	struct display *disp;
-	struct fb_info_sbusfb *fb;
-	struct fbtype *type;
-	int linebytes, w, h, depth;
-	char *p = NULL;
-	int margin;
-
-	fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC);
-	if (!fb) {
-		prom_printf("Could not allocate sbusfb structure\n");
-		return;
-	}
-	
-	if (!prom_palette)
-		prom_palette = sbusfb_palette;
-	
-	memset(fb, 0, sizeof(struct fb_info_sbusfb));
-	fix = &fb->info.fix;
-	var = &fb->info.var;
-	disp = &fb->disp;
-	type = &fb->type;
-	
-	spin_lock_init(&fb->lock);
-	fb->prom_node = node;
-	fb->prom_parent = parent;
-	fb->sbdp = sbdp;
-	if (sbdp)
-		fb->iospace = sbdp->reg_addrs[0].which_io;
-
-	type->fb_type = fbtype;
-	memset(&fb->emulations, 0xff, sizeof(fb->emulations));
-	fb->emulations[0] = fbtype;
-	
-#ifdef CONFIG_SPARC32
-	fb->info.screen_base = (unsigned char *)prom_getintdefault(node, "address", 0);
-#endif
-	
-	type->fb_height = h = prom_getintdefault(node, "height", 900);
-	type->fb_width  = w = prom_getintdefault(node, "width", 1152);
-sizechange:
-	type->fb_depth  = depth = (fbtype == FBTYPE_SUN2BW) ? 1 : 8;
-	linebytes = prom_getintdefault(node, "linebytes", w * depth / 8);
-	type->fb_size   = PAGE_ALIGN((linebytes) * h);
-	
-	if (defx_margin < 0 || defy_margin < 0) {
-		for (margin = 0; def_margins[margin].depth; margin++)
-			if (w == def_margins[margin].xres &&
-			    h == def_margins[margin].yres &&
-			    depth == def_margins[margin].depth) {
-				fb->x_margin = def_margins[margin].x_margin;
-				fb->y_margin = def_margins[margin].y_margin;
-				break;
-			}
-	} else {
-		fb->x_margin = defx_margin;
-		fb->y_margin = defy_margin;
-	}
-	fb->x_margin += ((w - 2*fb->x_margin) & 7) / 2;
-	fb->y_margin += ((h - 2*fb->y_margin) & 15) / 2;
-
-	var->xres_virtual = w;
-	var->yres_virtual = h;
-	var->xres = w - 2*fb->x_margin;
-	var->yres = h - 2*fb->y_margin;
-	
-	var->bits_per_pixel = depth;
-	var->height = var->width = -1;
-	var->pixclock = 10000;
-	var->vmode = FB_VMODE_NONINTERLACED;
-	var->red.length = var->green.length = var->blue.length = 8;
-
-	fix->line_length = linebytes;
-	fix->smem_len = type->fb_size;
-	fix->type = FB_TYPE_PACKED_PIXELS;
-	fix->visual = FB_VISUAL_PSEUDOCOLOR;
-	
-	fb->info.node = NODEV;
-	fb->info.fbops = &sbusfb_ops;
-	fb->info.disp = disp;
-	fb->info.currcon = -1;
-	strcpy(fb->info.fontname, fontname);
-	fb->info.changevar = NULL;
-	fb->info.switch_con = &sbusfbcon_switch;
-	fb->info.updatevar = &sbusfbcon_updatevar;
-	fb->info.flags = FBINFO_FLAG_DEFAULT;
-	
-	fb->cursor.hwsize.fbx = 32;
-	fb->cursor.hwsize.fby = 32;
-	
-	if (depth > 1 && !fb->color_map)
-		fb->color_map = kmalloc(256 * 3, GFP_ATOMIC);
-		
-	switch(fbtype) {
-#ifdef CONFIG_FB_CREATOR
-	case FBTYPE_CREATOR:
-		p = creatorfb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_CGSIX
-	case FBTYPE_SUNFAST_COLOR:
-		p = cgsixfb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_CGTHREE
-	case FBTYPE_SUN3COLOR:
-		p = cgthreefb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_TCX
-	case FBTYPE_TCXCOLOR:
-		p = tcxfb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_LEO
-	case FBTYPE_SUNLEO:
-		p = leofb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_BWTWO
-	case FBTYPE_SUN2BW:
-		p = bwtwofb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_CGFOURTEEN
-	case FBTYPE_MDICOLOR:
-		p = cgfourteenfb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_P9100
-	case FBTYPE_P9100COLOR:
-		/* Temporary crock. For now we are a cg3 */
-		p = p9100fb_init(fb); type->fb_type = FBTYPE_SUN3COLOR; break;
-#endif
-	}
-	
-	if (!p) {
-		if (fb->color_map)
-			kfree(fb->color_map);
-		kfree(fb);
-		return;
-	}
-	
-	if (p == SBUSFBINIT_SIZECHANGE)
-		goto sizechange;
-
-	disp->dispsw = &fb->dispsw;
-	if (fb->setcursor) {
-		fb->dispsw.cursor = sbusfb_cursor;
-		if (curblink) {
-			fb->cursor.blink_rate = DEFAULT_CURSOR_BLINK_RATE;
-			init_timer(&fb->cursor.timer);
-			fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate;
-			fb->cursor.timer.data = (unsigned long)fb;
-			fb->cursor.timer.function = sbusfb_cursor_timer_handler;
-			add_timer(&fb->cursor.timer);
-		}
-	}
-	fb->cursor.mode = CURSOR_SHAPE;
-	fb->dispsw.set_font = sbusfb_set_font;
-	fb->setup = fb->dispsw.setup;
-	fb->dispsw.setup = sbusfb_disp_setup;
-	fb->dispsw.clear_margins = NULL;
-
-	disp->var = *var;
-	
-	if (fb->blank)
-		disp->can_soft_blank = 1;
-
-	sbusfb_set_var(var, -1, &fb->info);
-
-	if (register_framebuffer(&fb->info) < 0) {
-		if (fb->color_map)
-			kfree(fb->color_map);
-		kfree(fb);
-		return;
-	}
-	printk(KERN_INFO "fb%d: %s\n", minor(fb->info.node), p);
-}
-
-static inline int known_card(char *name)
-{
-	char *p;
-	for (p = name; *p && *p != ','; p++);
-	if (*p == ',') name = p + 1;
-	if (!strcmp(name, "cgsix") || !strcmp(name, "cgthree+"))
-		return FBTYPE_SUNFAST_COLOR;
-	if (!strcmp(name, "cgthree") || !strcmp(name, "cgRDI"))
-		return FBTYPE_SUN3COLOR;
-	if (!strcmp(name, "cgfourteen"))
-		return FBTYPE_MDICOLOR;
-	if (!strcmp(name, "leo"))
-		return FBTYPE_SUNLEO;
-	if (!strcmp(name, "bwtwo"))
-		return FBTYPE_SUN2BW;
-	if (!strcmp(name, "tcx"))
-		return FBTYPE_TCXCOLOR;
-	if (!strcmp(name, "p9100"))
-		return FBTYPE_P9100COLOR;
-	return FBTYPE_NOTYPE;
-}
-
-#ifdef CONFIG_FB_CREATOR
-static void creator_fb_scan_siblings(int root)
-{
-	int node, child;
-
-	child = prom_getchild(root);
-	for (node = prom_searchsiblings(child, "SUNW,ffb"); node;
-	     node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb"))
-		sbusfb_init_fb(node, root, FBTYPE_CREATOR, NULL);
-	for (node = prom_searchsiblings(child, "SUNW,afb"); node;
-	     node = prom_searchsiblings(prom_getsibling(node), "SUNW,afb"))
-		sbusfb_init_fb(node, root, FBTYPE_CREATOR, NULL);
-}
-
-static void creator_fb_scan(void)
-{
-	int root;
-
-	creator_fb_scan_siblings(prom_root_node);
-
-	root = prom_getchild(prom_root_node);
-	for (root = prom_searchsiblings(root, "upa"); root;
-	     root = prom_searchsiblings(prom_getsibling(root), "upa"))
-		creator_fb_scan_siblings(root);
-}
-#endif
-
-int __init sbusfb_init(void)
-{
-	int type;
-	struct sbus_dev *sbdp;
-	struct sbus_bus *sbus;
-	char prom_name[40];
-	extern int con_is_present(void);
-	
-	if (!con_is_present()) return -ENXIO;
-	
-#ifdef CONFIG_FB_CREATOR
-	creator_fb_scan();
-#endif
-#ifdef CONFIG_SUN4
-	sbusfb_init_fb(0, 0, FBTYPE_SUN2BW, NULL);
-#endif
-#if defined(CONFIG_FB_CGFOURTEEN) && !defined(__sparc_v9__)
-	{
-		int root, node;
-		root = prom_getchild(prom_root_node);
-		root = prom_searchsiblings(root, "obio");
-		if (root && 
-		    (node = prom_searchsiblings(prom_getchild(root), "cgfourteen"))) {
-			sbusfb_init_fb(node, root, FBTYPE_MDICOLOR, NULL);
-		}
-	}
-#endif
-	if (sbus_root == NULL)
-		return 0;
-	for_all_sbusdev(sbdp, sbus) {
-		type = known_card(sbdp->prom_name);
-		if (type == FBTYPE_NOTYPE)
-			continue;
-		if (prom_getproperty(sbdp->prom_node, "emulation",
-				     prom_name, sizeof(prom_name)) > 0) {
-			type = known_card(prom_name);
-			if (type == FBTYPE_NOTYPE)
-				type = known_card(sbdp->prom_name);
-		}
-		sbusfb_init_fb(sbdp->prom_node, sbdp->bus->prom_node, type, sbdp);
-	}
-	return 0;
-}
-
-MODULE_LICENSE("GPL");	
diff -Nru a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/sbuslib.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,85 @@
+/* sbuslib.c: Helper library for SBUS framebuffer drivers.
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+
+#include <asm/oplib.h>
+
+#include "sbuslib.h"
+
+void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp)
+{
+	memset(var, 0, sizeof(*var));
+
+	var->xres = prom_getintdefault(prom_node, "width", 1152);
+	var->yres = prom_getintdefault(prom_node, "height", 900);
+	var->xres_virtual = var->xres;
+	var->yres_virtual = var->yres;
+	var->bits_per_pixel = bpp;
+}
+
+EXPORT_SYMBOL(sbusfb_fill_var);
+
+static unsigned long sbusfb_mmapsize(long size, unsigned long fbsize)
+{
+	if (size == SBUS_MMAP_EMPTY) return 0;
+	if (size >= 0) return size;
+	return fbsize * (-size);
+}
+
+int sbusfb_mmap_helper(struct sbus_mmap_map *map,
+		       unsigned long physbase,
+		       unsigned long fbsize,
+		       unsigned long iospace,
+		       struct vm_area_struct *vma)
+{
+	unsigned int size, page, r, map_size;
+	unsigned long map_offset = 0;
+	unsigned long off;
+	int i;
+                                        
+	size = vma->vm_end - vma->vm_start;
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	/* To stop the swapper from even considering these pages */
+	vma->vm_flags |= (VM_SHM | VM_IO | VM_LOCKED);
+	
+	/* Each page, see which map applies */
+	for (page = 0; page < size; ){
+		map_size = 0;
+		for (i = 0; map[i].size; i++)
+			if (map[i].voff == off+page) {
+				map_size = sbusfb_mmapsize(map[i].size, fbsize);
+#ifdef __sparc_v9__
+#define POFF_MASK	(PAGE_MASK|0x1UL)
+#else
+#define POFF_MASK	(PAGE_MASK)
+#endif				
+				map_offset = (physbase + map[i].poff) & POFF_MASK;
+				break;
+			}
+		if (!map_size){
+			page += PAGE_SIZE;
+			continue;
+		}
+		if (page + map_size > size)
+			map_size = size - page;
+		r = io_remap_page_range(vma,
+					vma->vm_start + page,
+					map_offset, map_size,
+					vma->vm_page_prot, iospace);
+		if (r)
+			return -EAGAIN;
+		page += map_size;
+	}
+
+	return 0;
+}
diff -Nru a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/sbuslib.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,21 @@
+/* sbuslib.h: SBUS fb helper library interfaces */
+#ifndef _SBUSLIB_H
+#define _SBUSLIB_H
+
+struct sbus_mmap_map {
+	unsigned long voff;
+	unsigned long poff;
+	unsigned long size;
+};
+
+#define SBUS_MMAP_FBSIZE(n) (-n)
+#define SBUS_MMAP_EMPTY	0x80000000
+
+extern void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp);
+struct vm_area_struct;
+extern int sbusfb_mmap_helper(struct sbus_mmap_map *map,
+			      unsigned long physbase, unsigned long fbsize,
+			      unsigned long iospace,
+			      struct vm_area_struct *vma);
+
+#endif /* _SBUSLIB_H */
diff -Nru a/drivers/video/sstfb.c b/drivers/video/sstfb.c
--- a/drivers/video/sstfb.c	Tue Mar  4 19:30:10 2003
+++ b/drivers/video/sstfb.c	Tue Mar  4 19:30:10 2003
@@ -35,7 +35,7 @@
       wich one should i use ? is there any preferred one ? It seems ARGB is
       the one ...
 -TODO: in  set_var check the validity of timings (hsync vsync)...
--TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via
+-TODO: check and recheck the use of sst_wait_idle : we don't flush the fifo via
        a nop command. so it's ok as long as the commands we pass don't go
        through the fifo. warning: issuing a nop command seems to need pci_fifo
 -FIXME: in case of failure in the init sequence, be sure we return to a safe
diff -Nru a/drivers/video/tcx.c b/drivers/video/tcx.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/tcx.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,493 @@
+/* tcx.c: TCX frame buffer driver
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
+ *
+ * Driver layout based loosely on tgafb.c, see that file for credits.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/fbio.h>
+
+#include "sbuslib.h"
+
+/*
+ * Local functions.
+ */
+
+static int tcx_check_var(struct fb_var_screeninfo *, struct fb_info *);
+static int tcx_set_par(struct fb_info *);
+static int tcx_setcolreg(unsigned, unsigned, unsigned, unsigned,
+			 unsigned, struct fb_info *);
+static int tcx_blank(int, struct fb_info *);
+
+static int tcx_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+
+/*
+ *  Frame buffer operations
+ */
+
+static struct fb_ops tcx_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= tcx_check_var,
+	.fb_set_par		= tcx_set_par,
+	.fb_setcolreg		= tcx_setcolreg,
+	.fb_blank		= tcx_blank,
+	.fb_fillrect		= cfb_fillrect,
+	.fb_copyarea		= cfb_copyarea,
+	.fb_imageblit		= cfb_imageblit,
+	.fb_mmap		= tcx_mmap,
+	.fb_cursor		= soft_cursor,
+};
+
+/* THC definitions */
+#define TCX_THC_MISC_REV_SHIFT       16
+#define TCX_THC_MISC_REV_MASK        15
+#define TCX_THC_MISC_VSYNC_DIS       (1 << 25)
+#define TCX_THC_MISC_HSYNC_DIS       (1 << 24)
+#define TCX_THC_MISC_RESET           (1 << 12)
+#define TCX_THC_MISC_VIDEO           (1 << 10)
+#define TCX_THC_MISC_SYNC            (1 << 9)
+#define TCX_THC_MISC_VSYNC           (1 << 8)
+#define TCX_THC_MISC_SYNC_ENAB       (1 << 7)
+#define TCX_THC_MISC_CURS_RES        (1 << 6)
+#define TCX_THC_MISC_INT_ENAB        (1 << 5)
+#define TCX_THC_MISC_INT             (1 << 4)
+#define TCX_THC_MISC_INIT            0x9f
+#define TCX_THC_REV_REV_SHIFT        20
+#define TCX_THC_REV_REV_MASK         15
+#define TCX_THC_REV_MINREV_SHIFT     28
+#define TCX_THC_REV_MINREV_MASK      15
+
+/* The contents are unknown */
+struct tcx_tec {
+	volatile u32 tec_matrix;
+	volatile u32 tec_clip;
+	volatile u32 tec_vdc;
+};
+
+struct tcx_thc {
+	volatile u32 thc_rev;
+        u32 thc_pad0[511];
+	volatile u32 thc_hs;		/* hsync timing */
+	volatile u32 thc_hsdvs;
+	volatile u32 thc_hd;
+	volatile u32 thc_vs;		/* vsync timing */
+	volatile u32 thc_vd;
+	volatile u32 thc_refresh;
+	volatile u32 thc_misc;
+	u32 thc_pad1[56];
+	volatile u32 thc_cursxy;	/* cursor x,y position (16 bits each) */
+	volatile u32 thc_cursmask[32];	/* cursor mask bits */
+	volatile u32 thc_cursbits[32];	/* what to show where mask enabled */
+};
+
+struct bt_regs {
+	volatile u32 addr;
+	volatile u32 color_map;
+	volatile u32 control;
+	volatile u32 cursor;
+};
+
+#define TCX_MMAP_ENTRIES 14
+
+struct tcx_par {
+	spinlock_t		lock;
+	struct bt_regs		*bt;
+	struct tcx_thc		*thc;
+	struct tcx_tec		*tec;
+	volatile u32		*cplane;
+
+	u32			flags;
+#define TCX_FLAG_BLANKED	0x00000001
+
+	unsigned long		physbase;
+	unsigned long		fbsize;
+
+	struct sbus_mmap_map	mmap_map[TCX_MMAP_ENTRIES];
+	int			lowdepth;
+
+	struct sbus_dev		*sdev;
+	struct list_head	list;
+};
+
+/* Reset control plane so that WID is 8-bit plane. */
+static void __tcx_set_control_plane (struct tcx_par *par)
+{
+	volatile u32 *p, *pend;
+        
+	if (par->lowdepth)
+		return;
+
+	p = par->cplane;
+	if (p == NULL)
+		return;
+	for (pend = p + par->fbsize; p < pend; p++) {
+		u32 tmp = sbus_readl(p);
+
+		tmp &= 0xffffff;
+		sbus_writel(tmp, p);
+	}
+}
+                                                
+static void tcx_reset (struct fb_info *info)
+{
+	struct tcx_par *par = (struct tcx_par *) info->par;
+	unsigned long flags;
+
+	spin_lock_irqsave(&par->lock, flags);
+	__tcx_set_control_plane(par);
+	spin_unlock_irqrestore(&par->lock, flags);
+}
+
+/**
+ *      tcx_check_var - Optional function.  Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int tcx_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->bits_per_pixel != 8)
+		return -EINVAL;
+
+	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
+		return -EINVAL;
+	if (var->nonstd)
+		return -EINVAL;
+	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+
+	if (var->xres != info->var.xres || var->yres != info->var.yres)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ *      tcx_set_par - Optional function.  Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+tcx_set_par(struct fb_info *info)
+{
+	return 0;
+}
+
+/**
+ *      tcx_setcolreg - Optional function. Sets a color register.
+ *      @regno: boolean, 0 copy local, 1 get_user() function
+ *      @red: frame buffer colormap structure
+ *      @green: The green value which can be up to 16 bits wide
+ *      @blue:  The blue value which can be up to 16 bits wide.
+ *      @transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ */
+static int tcx_setcolreg(unsigned regno,
+			 unsigned red, unsigned green, unsigned blue,
+			 unsigned transp, struct fb_info *info)
+{
+	struct tcx_par *par = (struct tcx_par *) info->par;
+	struct bt_regs *bt = par->bt;
+	unsigned long flags;
+
+	if (regno >= 256)
+		return 1;
+
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	sbus_writel(regno << 24, &bt->addr);
+	sbus_writel(red << 24, &bt->color_map);
+	sbus_writel(green << 24, &bt->color_map);
+	sbus_writel(blue << 24, &bt->color_map);
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+/**
+ *      tcx_blank - Optional function.  Blanks the display.
+ *      @blank_mode: the blank mode we want.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
+static int
+tcx_blank(int blank, struct fb_info *info)
+{
+	struct tcx_par *par = (struct tcx_par *) info->par;
+	struct tcx_thc *thc = par->thc;
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&par->lock, flags);
+
+	val = sbus_readl(&thc->thc_misc);
+
+	switch (blank) {
+	case 0: /* Unblanking */
+		val &= ~(TCX_THC_MISC_VSYNC_DIS |
+			 TCX_THC_MISC_HSYNC_DIS);
+		val |= TCX_THC_MISC_VIDEO;
+		par->flags &= ~TCX_FLAG_BLANKED;
+		break;
+
+	case 1: /* Normal blanking */
+		val &= ~TCX_THC_MISC_VIDEO;
+		par->flags |= TCX_FLAG_BLANKED;
+		break;
+
+	case 2: /* VESA blank (vsync off) */
+		val |= TCX_THC_MISC_VSYNC_DIS;
+		break;
+	case 3: /* VESA blank (hsync off) */
+		val |= TCX_THC_MISC_HSYNC_DIS;
+		break;
+
+	case 4: /* Poweroff */
+		break;
+	};
+
+	sbus_writel(val, &thc->thc_misc);
+
+	spin_unlock_irqrestore(&par->lock, flags);
+
+	return 0;
+}
+
+static struct sbus_mmap_map __tcx_mmap_map[TCX_MMAP_ENTRIES] = {
+	{ TCX_RAM8BIT,		0,		SBUS_MMAP_FBSIZE(1) },
+	{ TCX_RAM24BIT,		0,		SBUS_MMAP_FBSIZE(4) },
+	{ TCX_UNK3,		0,		SBUS_MMAP_FBSIZE(8) },
+	{ TCX_UNK4,		0,		SBUS_MMAP_FBSIZE(8) },
+	{ TCX_CONTROLPLANE,	0,		SBUS_MMAP_FBSIZE(4) },
+	{ TCX_UNK6,		0,		SBUS_MMAP_FBSIZE(8) },
+	{ TCX_UNK7,		0,		SBUS_MMAP_FBSIZE(8) },
+	{ TCX_TEC,		0,		PAGE_SIZE	    },
+	{ TCX_BTREGS,		0,		PAGE_SIZE	    },
+	{ TCX_THC,		0,		PAGE_SIZE	    },
+	{ TCX_DHC,		0,		PAGE_SIZE	    },
+	{ TCX_ALT,		0,		PAGE_SIZE	    },
+	{ TCX_UNK2,		0,		0x20000		    },
+	{ 0,			0,		0		    }
+};
+
+static int tcx_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+{
+	struct tcx_par *par = (struct tcx_par *)info->par;
+
+	return sbusfb_mmap_helper(par->mmap_map,
+				  par->physbase, par->fbsize,
+				  par->sdev->reg_addrs[0].which_io,
+				  vma);
+}
+
+/*
+ *  Initialisation
+ */
+
+static void
+tcx_init_fix(struct fb_info *info, int linebytes)
+{
+	struct tcx_par *par = (struct tcx_par *)info->par;
+	const char *tcx_name;
+
+	if (par->lowdepth)
+		tcx_name = "TCX8";
+	else
+		tcx_name = "TCX24";
+
+	strncpy(info->fix.id, tcx_name, sizeof(info->fix.id) - 1);
+	info->fix.id[sizeof(info->fix.id)-1] = 0;
+
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+	info->fix.line_length = linebytes;
+
+	info->fix.accel = FB_ACCEL_SUN_TCX;
+}
+
+struct all_info {
+	struct fb_info info;
+	struct tcx_par par;
+	struct list_head list;
+};
+static LIST_HEAD(tcx_list);
+
+static void tcx_init_one(struct sbus_dev *sdev)
+{
+	struct all_info *all;
+	int linebytes, i;
+
+	all = kmalloc(sizeof(*all), GFP_KERNEL);
+	if (!all) {
+		printk(KERN_ERR "tcx: Cannot allocate memory.\n");
+		return;
+	}
+	memset(all, 0, sizeof(*all));
+
+	INIT_LIST_HEAD(&all->list);
+
+	spin_lock_init(&all->par.lock);
+	all->par.sdev = sdev;
+
+	all->par.lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit");
+
+	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+
+	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
+				       all->info.var.xres);
+	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+
+	all->par.tec = (struct tcx_tec *)
+		sbus_ioremap(&sdev->resource[7], 0,
+			     sizeof(struct tcx_tec), "tcx tec");
+	all->par.thc = (struct tcx_thc *)
+		sbus_ioremap(&sdev->resource[9], 0,
+			     sizeof(struct tcx_thc), "tcx thc");
+	all->par.bt = (struct bt_regs *)
+		sbus_ioremap(&sdev->resource[8], 0,
+			     sizeof(struct bt_regs), "tcx dac");
+	memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map));
+	if (!all->par.lowdepth) {
+		all->par.cplane = (volatile u32 *)
+			sbus_ioremap(&sdev->resource[4], 0,
+				     all->par.fbsize * sizeof(u32), "tcx cplane");
+	} else {
+		all->par.mmap_map[1].size = SBUS_MMAP_EMPTY;
+		all->par.mmap_map[4].size = SBUS_MMAP_EMPTY;
+		all->par.mmap_map[5].size = SBUS_MMAP_EMPTY;
+		all->par.mmap_map[6].size = SBUS_MMAP_EMPTY;
+	}
+
+	all->par.physbase = 0;
+	for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
+		int j;
+
+		switch (i) {
+		case 10:
+			j = 12;
+			break;
+
+		case 11: case 12:
+			j = i - 1;
+			break;
+
+		default:
+			j = i;
+			break;
+		};
+		all->par.mmap_map[i].poff = sdev->reg_addrs[j].phys_addr;
+	}
+
+	all->info.node = NODEV;
+	all->info.flags = FBINFO_FLAG_DEFAULT;
+	all->info.fbops = &tcx_ops;
+#ifdef CONFIG_SPARC32
+	all->info.screen_base = (char *)
+		prom_getintdefault(sdev->prom_node, "address", 0);
+#endif
+	if (!all->info.screen_base)
+		all->info.screen_base = (char *)
+			sbus_ioremap(&sdev->resource[0], 0,
+				     all->par.fbsize, "tcx ram");
+	all->info.currcon = -1;
+	all->info.par = &all->par;
+
+	/* Initialize brooktree DAC. */
+	sbus_writel(0x04 << 24, &all->par.bt->addr);         /* color planes */
+	sbus_writel(0xff << 24, &all->par.bt->control);
+	sbus_writel(0x05 << 24, &all->par.bt->addr);
+	sbus_writel(0x00 << 24, &all->par.bt->control);
+	sbus_writel(0x06 << 24, &all->par.bt->addr);         /* overlay plane */
+	sbus_writel(0x73 << 24, &all->par.bt->control);
+	sbus_writel(0x07 << 24, &all->par.bt->addr);
+	sbus_writel(0x00 << 24, &all->par.bt->control);
+
+	tcx_reset(&all->info);
+
+	tcx_blank(0, &all->info);
+
+	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+		printk(KERN_ERR "tcx: Could not allocate color map.\n");
+		kfree(all);
+		return;
+	}
+
+	tcx_set_par(&all->info);
+	tcx_init_fix(&all->info, linebytes);
+
+	if (register_framebuffer(&all->info) < 0) {
+		printk(KERN_ERR "tcx: Could not register framebuffer.\n");
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+		return;
+	}
+
+	list_add(&all->list, &tcx_list);
+
+	printk("tcx: %s at %lx:%lx, %s\n",
+	       sdev->prom_name,
+	       (long) sdev->reg_addrs[0].which_io,
+	       (long) sdev->reg_addrs[0].phys_addr,
+	       all->par.lowdepth ? "8-bit only" : "24-bit depth");
+}
+
+int __init tcx_init(void)
+{
+	struct sbus_bus *sbus;
+	struct sbus_dev *sdev;
+
+	for_all_sbusdev(sdev, sbus) {
+		if (!strcmp(sdev->prom_name, "tcx"))
+			tcx_init_one(sdev);
+	}
+
+	return 0;
+}
+
+void __exit tcx_exit(void)
+{
+	struct list_head *pos, *tmp;
+
+	list_for_each_safe(pos, tmp, &tcx_list) {
+		struct all_info *all = list_entry(pos, typeof(*all), list);
+
+		unregister_framebuffer(&all->info);
+		fb_dealloc_cmap(&all->info.cmap);
+		kfree(all);
+	}
+}
+
+int __init
+tcx_setup(char *arg)
+{
+	/* No cmdline options yet... */
+	return 0;
+}
+
+#ifdef MODULE
+module_init(tcx_init);
+module_exit(tcx_exit);
+#endif
+
+MODULE_DESCRIPTION("framebuffer driver for TCX chipsets");
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/tcxfb.c b/drivers/video/tcxfb.c
--- a/drivers/video/tcxfb.c	Tue Mar  4 19:30:04 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,368 +0,0 @@
-/* $Id: tcxfb.c,v 1.13 2001/09/19 00:04:33 davem Exp $
- * tcxfb.c: TCX 24/8bit frame buffer driver
- *
- * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
- * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-
-#include <video/sbusfb.h>
-#include <asm/io.h>
-#include <asm/sbus.h>
-
-#include <video/fbcon-cfb8.h>
-
-/* THC definitions */
-#define TCX_THC_MISC_REV_SHIFT       16
-#define TCX_THC_MISC_REV_MASK        15
-#define TCX_THC_MISC_VSYNC_DIS       (1 << 25)
-#define TCX_THC_MISC_HSYNC_DIS       (1 << 24)
-#define TCX_THC_MISC_RESET           (1 << 12)
-#define TCX_THC_MISC_VIDEO           (1 << 10)
-#define TCX_THC_MISC_SYNC            (1 << 9)
-#define TCX_THC_MISC_VSYNC           (1 << 8)
-#define TCX_THC_MISC_SYNC_ENAB       (1 << 7)
-#define TCX_THC_MISC_CURS_RES        (1 << 6)
-#define TCX_THC_MISC_INT_ENAB        (1 << 5)
-#define TCX_THC_MISC_INT             (1 << 4)
-#define TCX_THC_MISC_INIT            0x9f
-#define TCX_THC_REV_REV_SHIFT        20
-#define TCX_THC_REV_REV_MASK         15
-#define TCX_THC_REV_MINREV_SHIFT     28
-#define TCX_THC_REV_MINREV_MASK      15
-
-/* The contents are unknown */
-struct tcx_tec {
-	volatile u32 tec_matrix;
-	volatile u32 tec_clip;
-	volatile u32 tec_vdc;
-};
-
-struct tcx_thc {
-	volatile u32 thc_rev;
-        u32 thc_pad0[511];
-	volatile u32 thc_hs;		/* hsync timing */
-	volatile u32 thc_hsdvs;
-	volatile u32 thc_hd;
-	volatile u32 thc_vs;		/* vsync timing */
-	volatile u32 thc_vd;
-	volatile u32 thc_refresh;
-	volatile u32 thc_misc;
-	u32 thc_pad1[56];
-	volatile u32 thc_cursxy;	/* cursor x,y position (16 bits each) */
-	volatile u32 thc_cursmask[32];	/* cursor mask bits */
-	volatile u32 thc_cursbits[32];	/* what to show where mask enabled */
-};
-
-static struct sbus_mmap_map tcx_mmap_map[] = {
-	{ TCX_RAM8BIT,		0,		SBUS_MMAP_FBSIZE(1) },
-	{ TCX_RAM24BIT,		0,		SBUS_MMAP_FBSIZE(4) },
-	{ TCX_UNK3,		0,		SBUS_MMAP_FBSIZE(8) },
-	{ TCX_UNK4,		0,		SBUS_MMAP_FBSIZE(8) },
-	{ TCX_CONTROLPLANE,	0,		SBUS_MMAP_FBSIZE(4) },
-	{ TCX_UNK6,		0,		SBUS_MMAP_FBSIZE(8) },
-	{ TCX_UNK7,		0,		SBUS_MMAP_FBSIZE(8) },
-	{ TCX_TEC,		0,		PAGE_SIZE	    },
-	{ TCX_BTREGS,		0,		PAGE_SIZE	    },
-	{ TCX_THC,		0,		PAGE_SIZE	    },
-	{ TCX_DHC,		0,		PAGE_SIZE	    },
-	{ TCX_ALT,		0,		PAGE_SIZE	    },
-	{ TCX_UNK2,		0,		0x20000		    },
-	{ 0,			0,		0		    }
-};
-
-static void __tcx_set_control_plane (struct fb_info_sbusfb *fb)
-{
-	u32 *p, *pend;
-        
-	p = fb->s.tcx.cplane;
-	if (p == NULL)
-		return;
-	for (pend = p + fb->type.fb_size; p < pend; p++) {
-		u32 tmp = sbus_readl(p);
-
-		tmp &= 0xffffff;
-		sbus_writel(tmp, p);
-	}
-}
-                                                
-static void tcx_switch_from_graph (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&fb->lock, flags);
-
-	/* Reset control plane to 8bit mode if necessary */
-	if (fb->open && fb->mmaped)
-		__tcx_set_control_plane (fb);
-
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void tcx_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count)
-{
-	struct bt_regs *bt = fb->s.tcx.bt;
-	unsigned long flags;
-	int i;
-                
-	spin_lock_irqsave(&fb->lock, flags);
-	sbus_writel(index << 24, &bt->addr);
-	for (i = index; count--; i++){
-		sbus_writel(fb->color_map CM(i,0) << 24, &bt->color_map);
-		sbus_writel(fb->color_map CM(i,1) << 24, &bt->color_map);
-		sbus_writel(fb->color_map CM(i,2) << 24, &bt->color_map);
-	}
-	sbus_writel(0, &bt->addr);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void tcx_restore_palette (struct fb_info_sbusfb *fb)
-{
-	struct bt_regs *bt = fb->s.tcx.bt;
-	unsigned long flags;
-                
-	spin_lock_irqsave(&fb->lock, flags);
-	sbus_writel(0, &bt->addr);
-	sbus_writel(0xffffffff, &bt->color_map);
-	sbus_writel(0xffffffff, &bt->color_map);
-	sbus_writel(0xffffffff, &bt->color_map);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void tcx_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
-{
-        struct bt_regs *bt = fb->s.tcx.bt;
-	unsigned long flags;
-
-	spin_lock_irqsave(&fb->lock, flags);
-
-	/* Note the 2 << 24 is different from cg6's 1 << 24 */
-	sbus_writel(2 << 24, &bt->addr);
-	sbus_writel(red[0] << 24, &bt->cursor);
-	sbus_writel(green[0] << 24, &bt->cursor);
-	sbus_writel(blue[0] << 24, &bt->cursor);
-	sbus_writel(3 << 24, &bt->addr);
-	sbus_writel(red[1] << 24, &bt->cursor);
-	sbus_writel(green[1] << 24, &bt->cursor);
-	sbus_writel(blue[1] << 24, &bt->cursor);
-	sbus_writel(0, &bt->addr);
-
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-/* Set cursor shape */
-static void tcx_setcurshape (struct fb_info_sbusfb *fb)
-{
-	struct tcx_thc *thc = fb->s.tcx.thc;
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	for (i = 0; i < 32; i++){
-		sbus_writel(fb->cursor.bits[0][i], &thc->thc_cursmask[i]);
-		sbus_writel(fb->cursor.bits[1][i], &thc->thc_cursbits[i]);
-	}
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-/* Load cursor information */
-static void tcx_setcursor (struct fb_info_sbusfb *fb)
-{
-	struct cg_cursor *c = &fb->cursor;
-	unsigned long flags;
-	unsigned int v;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	if (c->enable)
-		v = ((c->cpos.fbx - c->chot.fbx) << 16)
-		    |((c->cpos.fby - c->chot.fby) & 0xffff);
-	else
-		/* Magic constant to turn off the cursor */
-		v = ((65536-32) << 16) | (65536-32);
-	sbus_writel(v, &fb->s.tcx.thc->thc_cursxy);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static int tcx_blank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u32 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readl(&fb->s.tcx.thc->thc_misc);
-	tmp &= ~TCX_THC_MISC_VIDEO;
-	/* This should put us in power-save */
-	tmp |= TCX_THC_MISC_VSYNC_DIS;
-        tmp |= TCX_THC_MISC_HSYNC_DIS;
-	sbus_writel(tmp, &fb->s.tcx.thc->thc_misc);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static int tcx_unblank (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u32 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	tmp = sbus_readl(&fb->s.tcx.thc->thc_misc);
-	tmp &= ~TCX_THC_MISC_VSYNC_DIS;
-	tmp &= ~TCX_THC_MISC_HSYNC_DIS;
-	tmp |= TCX_THC_MISC_VIDEO;
-	sbus_writel(tmp, &fb->s.tcx.thc->thc_misc);
-	spin_unlock_irqrestore(&fb->lock, flags);
-	return 0;
-}
-
-static void tcx_reset (struct fb_info_sbusfb *fb)
-{
-	unsigned long flags;
-	u32 tmp;
-
-	spin_lock_irqsave(&fb->lock, flags);
-	if (fb->open && fb->mmaped)
-		__tcx_set_control_plane(fb);
-	
-	/* Turn off stuff in the Transform Engine. */
-	sbus_writel(0, &fb->s.tcx.tec->tec_matrix);
-	sbus_writel(0, &fb->s.tcx.tec->tec_clip);
-	sbus_writel(0, &fb->s.tcx.tec->tec_vdc);
-
-	/* Enable cursor in Brooktree DAC. */
-	sbus_writel(0x06 << 24, &fb->s.tcx.bt->addr);
-	tmp = sbus_readl(&fb->s.tcx.bt->control);
-	tmp |= 0x03 << 24;
-	sbus_writel(tmp, &fb->s.tcx.bt->control);
-	spin_unlock_irqrestore(&fb->lock, flags);
-}
-
-static void tcx_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
-{
-	fb->info.screen_base += (y_margin - fb->y_margin) * p->fb_info->fix.line_length + (x_margin - fb->x_margin);
-}
-
-static char idstring[60] __initdata = { 0 };
-
-char __init *tcxfb_init(struct fb_info_sbusfb *fb)
-{
-	struct fb_fix_screeninfo *fix = &fb->info.fix;
-	struct display *disp = &fb->disp;
-	struct fbtype *type = &fb->type;
-	struct sbus_dev *sdev = fb->sbdp;
-	unsigned long phys = sdev->reg_addrs[0].phys_addr;
-	int lowdepth, i, j;
-
-#ifndef FBCON_HAS_CFB8
-	return NULL;
-#endif
-
-	lowdepth = prom_getbool (fb->prom_node, "tcx-8-bit");
-
-	if (lowdepth) {
-		strcpy(fb->info.modename, "TCX8");
-		strcpy(fix->id, "TCX8");
-	} else {
-		strcpy(fb->info.modename, "TCX24");
-		strcpy(fix->id, "TCX24");
-	}
-	fix->line_length = fb->info.var.xres_virtual;
-	fix->accel = FB_ACCEL_SUN_TCX;
-
-	disp->scrollmode = SCROLL_YREDRAW;
-	if (!fb->info.screen_base) {
-		fb->info.screen_base = (char *)
-			sbus_ioremap(&sdev->resource[0], 0,
-				     type->fb_size, "tcx ram");
-	}
-	fb->info.screen_base += fix->line_length * fb->y_margin + fb->x_margin;
-	fb->s.tcx.tec = (struct tcx_tec *)
-		sbus_ioremap(&sdev->resource[7], 0,
-			     sizeof(struct tcx_tec), "tcx tec");
-	fb->s.tcx.thc = (struct tcx_thc *)
-		sbus_ioremap(&sdev->resource[9], 0,
-			     sizeof(struct tcx_thc), "tcx thc");
-	fb->s.tcx.bt = (struct bt_regs *)
-		sbus_ioremap(&sdev->resource[8], 0, 
-			     sizeof(struct bt_regs), "tcx dac");
-	if (!lowdepth) {
-		fb->s.tcx.cplane = (u32 *)
-			sbus_ioremap(&sdev->resource[4], 0, 
-				     type->fb_size * sizeof(u32), "tcx cplane");
-		type->fb_depth = 24;
-		fb->switch_from_graph = tcx_switch_from_graph;
-	} else {
-		/* As there can be one tcx in a machine only, we can write directly into
-		   tcx_mmap_map */
-		tcx_mmap_map[1].size = SBUS_MMAP_EMPTY;
-		tcx_mmap_map[4].size = SBUS_MMAP_EMPTY;
-		tcx_mmap_map[5].size = SBUS_MMAP_EMPTY;
-		tcx_mmap_map[6].size = SBUS_MMAP_EMPTY;
-	}
-	fb->dispsw = fbcon_cfb8;
-
-	fb->margins = tcx_margins;
-	fb->loadcmap = tcx_loadcmap;
-	if (prom_getbool (fb->prom_node, "hw-cursor")) {
-		fb->setcursor = tcx_setcursor;
-		fb->setcursormap = tcx_setcursormap;
-		fb->setcurshape = tcx_setcurshape;
-	}
-	fb->restore_palette = tcx_restore_palette;
-	fb->blank = tcx_blank;
-	fb->unblank = tcx_unblank;
-	fb->reset = tcx_reset;
-
-	fb->physbase = 0;
-	for (i = 0; i < 13; i++) {
-		/* tcx_mmap_map has to be sorted by voff, while
-		   order of phys registers from PROM differs a little
-		   bit. Here is the correction */
-		switch (i) {
-		case 10: j = 12; break;
-		case 11:
-		case 12: j = i - 1; break;
-		default: j = i; break;
-		}
-		tcx_mmap_map[i].poff = fb->sbdp->reg_addrs[j].phys_addr;
-	}
-	fb->mmap_map = tcx_mmap_map;
-
-	/* Initialize Brooktree DAC */
-	sbus_writel(0x04 << 24, &fb->s.tcx.bt->addr);         /* color planes */
-	sbus_writel(0xff << 24, &fb->s.tcx.bt->control);
-	sbus_writel(0x05 << 24, &fb->s.tcx.bt->addr);
-	sbus_writel(0x00 << 24, &fb->s.tcx.bt->control);
-	sbus_writel(0x06 << 24, &fb->s.tcx.bt->addr);         /* overlay plane */
-	sbus_writel(0x73 << 24, &fb->s.tcx.bt->control);
-	sbus_writel(0x07 << 24, &fb->s.tcx.bt->addr);
-	sbus_writel(0x00 << 24, &fb->s.tcx.bt->control);
-
-	sprintf(idstring, "tcx at %x.%08lx Rev %d.%d %s",
-		fb->iospace, phys,
-		((sbus_readl(&fb->s.tcx.thc->thc_rev) >> TCX_THC_REV_REV_SHIFT) &
-		 TCX_THC_REV_REV_MASK),
-		((sbus_readl(&fb->s.tcx.thc->thc_rev) >> TCX_THC_REV_MINREV_SHIFT) &
-		 TCX_THC_REV_MINREV_MASK),
-		lowdepth ? "8-bit only" : "24-bit depth");
-		    
-	tcx_reset(fb);
-
-	return idstring;
-}
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/virgefb.c b/drivers/video/virgefb.c
--- a/drivers/video/virgefb.c	Tue Mar  4 19:30:05 2003
+++ b/drivers/video/virgefb.c	Tue Mar  4 19:30:05 2003
@@ -1752,7 +1752,7 @@
 
 	} else {
 
-		/* board running in Z3 space. Seperate video memory (3 apertures)
+		/* board running in Z3 space. Separate video memory (3 apertures)
 		   and S3 register set */
 
 		on_zorro2 = 0;
diff -Nru a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c
--- a/fs/adfs/dir_f.c	Tue Mar  4 19:30:11 2003
+++ b/fs/adfs/dir_f.c	Tue Mar  4 19:30:11 2003
@@ -259,7 +259,7 @@
 
 /*
  * get a directory entry.  Note that the caller is responsible
- * for holding the relevent locks.
+ * for holding the relevant locks.
  */
 int
 __adfs_dir_get(struct adfs_dir *dir, int pos, struct object_info *obj)
diff -Nru a/fs/afs/vnode.c b/fs/afs/vnode.c
--- a/fs/afs/vnode.c	Tue Mar  4 19:30:07 2003
+++ b/fs/afs/vnode.c	Tue Mar  4 19:30:07 2003
@@ -272,7 +272,7 @@
 /*****************************************************************************/
 /*
  * break any outstanding callback on a vnode
- * - only relevent to server that issued it
+ * - only relevant to server that issued it
  */
 int afs_vnode_give_up_callback(afs_vnode_t *vnode)
 {
diff -Nru a/fs/befs/ChangeLog b/fs/befs/ChangeLog
--- a/fs/befs/ChangeLog	Tue Mar  4 19:30:04 2003
+++ b/fs/befs/ChangeLog	Tue Mar  4 19:30:04 2003
@@ -117,7 +117,7 @@
 * Rewrote datastream positon lookups.
 	(datastream.c) [WD]
 
-* Moved the TODO list to it's own file.
+* Moved the TODO list to its own file.
 
 
 Version 0.50 (2001-11-13)
diff -Nru a/fs/befs/btree.c b/fs/befs/btree.c
--- a/fs/befs/btree.c	Tue Mar  4 19:30:03 2003
+++ b/fs/befs/btree.c	Tue Mar  4 19:30:03 2003
@@ -41,7 +41,7 @@
 /* Befs B+tree structure:
  * 
  * The first thing in the tree is the tree superblock. It tells you
- * all kinds of usefull things about the tree, like where the rootnode
+ * all kinds of useful things about the tree, like where the rootnode
  * is located, and the size of the nodes (always 1024 with current version
  * of BeOS).
  *
diff -Nru a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
--- a/fs/befs/linuxvfs.c	Tue Mar  4 19:30:08 2003
+++ b/fs/befs/linuxvfs.c	Tue Mar  4 19:30:08 2003
@@ -541,7 +541,7 @@
 	wchar_t uni;
 	int unilen, utflen;
 	char *result;
-	int maxlen = in_len; /* The utf8->nls conversion cant make more chars */
+	int maxlen = in_len; /* The utf8->nls conversion can't make more chars */
 
 	befs_debug(sb, "---> utf2nls()");
 
diff -Nru a/fs/bio.c b/fs/bio.c
--- a/fs/bio.c	Tue Mar  4 19:30:10 2003
+++ b/fs/bio.c	Tue Mar  4 19:30:10 2003
@@ -334,7 +334,7 @@
  *	@bdev:  I/O target
  *
  *	Return the approximate number of pages we can send to this target.
- *	There's no guarentee that you will be able to fit this number of pages
+ *	There's no guarantee that you will be able to fit this number of pages
  *	into a bio, it does not account for dynamic restrictions that vary
  *	on offset.
  */
@@ -383,7 +383,7 @@
 		return 0;
 
 	/*
-	 * we might loose a segment or two here, but rather that than
+	 * we might lose a segment or two here, but rather that than
 	 * make this too complex.
 	 */
 retry_segments:
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Tue Mar  4 19:30:09 2003
+++ b/fs/buffer.c	Tue Mar  4 19:30:09 2003
@@ -1403,10 +1403,7 @@
 	
 static void invalidate_bh_lrus(void)
 {
-	preempt_disable();
-	invalidate_bh_lru(NULL);
-	smp_call_function(invalidate_bh_lru, NULL, 1, 1);
-	preempt_enable();
+	on_each_cpu(invalidate_bh_lru, NULL, 1, 1);
 }
 
 void set_bh_page(struct buffer_head *bh,
@@ -2495,7 +2492,7 @@
 
 	/*
 	 * The page straddles i_size.  It must be zeroed out on each and every
-	 * writepage invokation because it may be mmapped.  "A file is mapped
+	 * writepage invocation because it may be mmapped.  "A file is mapped
 	 * in multiples of the page size.  For a file that is not a multiple of
 	 * the  page size, the remaining memory is zeroed when mapped, and
 	 * writes to that region are not written out to the file."
@@ -2584,7 +2581,7 @@
  * BH_Lock state bit), any buffer that appears to be clean when doing a
  * write request, and any buffer that appears to be up-to-date when doing
  * read request.  Further it marks as clean buffers that are processed for
- * writing (the buffer cache wont assume that they are actually clean until
+ * writing (the buffer cache won't assume that they are actually clean until
  * the buffer gets unlocked).
  *
  * ll_rw_block sets b_end_io to simple completion handler that marks
diff -Nru a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
--- a/fs/cifs/cifs_unicode.h	Tue Mar  4 19:30:14 2003
+++ b/fs/cifs/cifs_unicode.h	Tue Mar  4 19:30:14 2003
@@ -99,7 +99,7 @@
  * UniStrchr:  Find a character in a string
  *
  * Returns:
- *     Address of first occurance of character in string
+ *     Address of first occurrence of character in string
  *     or NULL if the character is not in the string
  */
 static inline wchar_t *
diff -Nru a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
--- a/fs/cifs/cifspdu.h	Tue Mar  4 19:30:13 2003
+++ b/fs/cifs/cifspdu.h	Tue Mar  4 19:30:13 2003
@@ -1245,7 +1245,7 @@
 	__u8 Reserved3;
 	__u16 SubCommand;	/* one setup word */
 	__u16 ByteCount;
-	__u8 Pad[3];		/* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesnt seem to matter though */
+	__u8 Pad[3];		/* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */
 	__u16 MaxReferralLevel;
 	char RequestFileName[1];
 } TRANSACTION2_GET_DFS_REFER_REQ;
diff -Nru a/fs/dcache.c b/fs/dcache.c
--- a/fs/dcache.c	Tue Mar  4 19:30:04 2003
+++ b/fs/dcache.c	Tue Mar  4 19:30:04 2003
@@ -47,16 +47,8 @@
 
 static unsigned int d_hash_mask;
 static unsigned int d_hash_shift;
-static struct list_head *dentry_hashtable;
+static struct hlist_head *dentry_hashtable;
 static LIST_HEAD(dentry_unused);
-static int max_dentries;
-static void * hashtable_end;
-
-static inline int is_bucket(void * addr)
-{
-	return ((addr < (void *)dentry_hashtable)
-			|| (addr > hashtable_end) ? 0 : 1);
-}	
 
 /* Statistics gathering. */
 struct dentry_stat_t dentry_stat = {
@@ -292,6 +284,7 @@
 	while (next != head) {
 		tmp = next;
 		next = tmp->next;
+		prefetch(next);
 		alias = list_entry(tmp, struct dentry, d_alias);
  		if (!d_unhashed(alias)) {
 			if (alias->d_flags & DCACHE_DISCONNECTED)
@@ -378,6 +371,7 @@
 		if (tmp == &dentry_unused)
 			break;
 		list_del_init(tmp);
+		prefetch(dentry_unused.prev);
  		dentry_stat.nr_unused--;
 		dentry = list_entry(tmp, struct dentry, d_lru);
 
@@ -603,15 +597,15 @@
  * done under dcache_lock.
  *
  */
-void shrink_dcache_anon(struct list_head *head)
+void shrink_dcache_anon(struct hlist_head *head)
 {
-	struct list_head *lp;
+	struct hlist_node *lp;
 	int found;
 	do {
 		found = 0;
 		spin_lock(&dcache_lock);
-		list_for_each(lp, head) {
-			struct dentry *this = list_entry(lp, struct dentry, d_hash);
+		hlist_for_each(lp, head) {
+			struct dentry *this = hlist_entry(lp, struct dentry, d_hash);
 			list_del(&this->d_lru);
 
 			/* don't add non zero d_count dentries 
@@ -727,7 +721,7 @@
 	dentry->d_mounted = 0;
 	dentry->d_cookie = NULL;
 	dentry->d_bucket = NULL;
-	INIT_LIST_HEAD(&dentry->d_hash);
+	INIT_HLIST_NODE(&dentry->d_hash);
 	INIT_LIST_HEAD(&dentry->d_lru);
 	INIT_LIST_HEAD(&dentry->d_subdirs);
 	INIT_LIST_HEAD(&dentry->d_alias);
@@ -797,7 +791,7 @@
 	return res;
 }
 
-static inline struct list_head * d_hash(struct dentry * parent, unsigned long hash)
+static inline struct hlist_head * d_hash(struct dentry * parent, unsigned long hash)
 {
 	hash += (unsigned long) parent / L1_CACHE_BYTES;
 	hash = hash ^ (hash >> D_HASHBITS);
@@ -860,7 +854,7 @@
 			res->d_flags |= DCACHE_DISCONNECTED;
 			res->d_vfs_flags &= ~DCACHE_UNHASHED;
 			list_add(&res->d_alias, &inode->i_dentry);
-			list_add(&res->d_hash, &inode->i_sb->s_anon);
+			hlist_add_head(&res->d_hash, &inode->i_sb->s_anon);
 			spin_unlock(&res->d_lock);
 		}
 		inode = NULL; /* don't drop reference */
@@ -947,21 +941,21 @@
 	unsigned int len = name->len;
 	unsigned int hash = name->hash;
 	const unsigned char *str = name->name;
-	struct list_head *head = d_hash(parent,hash);
+	struct hlist_head *head = d_hash(parent,hash);
 	struct dentry *found = NULL;
-	struct list_head *tmp;
-	int lookup_count = 0;
+	struct hlist_node *node;
 
 	rcu_read_lock();
 	
-	/* lookup is terminated when flow reaches any bucket head */
-	for(tmp = head->next; !is_bucket(tmp); tmp = tmp->next) {
+	hlist_for_each (node, head) { 
 		struct dentry *dentry; 
 		unsigned long move_count;
 		struct qstr * qstr;
 		
+		prefetch(node->next);
+
 		smp_read_barrier_depends();
-		dentry = list_entry(tmp, struct dentry, d_hash);
+		dentry = hlist_entry(node, struct dentry, d_hash);
 
 		/* if lookup ends up in a different bucket 
 		 * due to concurrent rename, fail it
@@ -969,12 +963,6 @@
 		if (unlikely(dentry->d_bucket != head))
 			break;
 
-		/* to avoid race if dentry keep coming back to original
-		 * bucket due to double moves
-		 */
-		if (unlikely(++lookup_count > max_dentries))
-			break;
-
 		/*
 		 * We must take a snapshot of d_move_count followed by
 		 * read memory barrier before any search key comparison 
@@ -1004,8 +992,11 @@
 		 */ 
 		if (unlikely(move_count != dentry->d_move_count)) 
 			break;
-		if (!d_unhashed(dentry))
-			found = dget(dentry);
+		if (!d_unhashed(dentry)) {
+			atomic_inc(&dentry->d_count);
+			dentry->d_vfs_flags |= DCACHE_REFERENCED;
+			found = dentry;
+		}
 		spin_unlock(&dentry->d_lock);
 		break;
  	}
@@ -1031,7 +1022,8 @@
 	unsigned long dent_addr = (unsigned long) dentry;
 	unsigned long min_addr = PAGE_OFFSET;
 	unsigned long align_mask = 0x0F;
-	struct list_head *base, *lhp;
+	struct hlist_head *base;
+	struct hlist_node *lhp;
 
 	if (dent_addr < min_addr)
 		goto out;
@@ -1047,13 +1039,14 @@
 		goto out;
 
 	spin_lock(&dcache_lock);
-	lhp = base = d_hash(dparent, dentry->d_name.hash);
-	while ((lhp = lhp->next) != base) {
+	base = d_hash(dparent, dentry->d_name.hash);
+	hlist_for_each(lhp,base) { 
+		prefetch(lhp->next);
 		/* read_barrier_depends() not required for d_hash list
 		 * as it is parsed under dcache_lock
 		 */
-		if (dentry == list_entry(lhp, struct dentry, d_hash)) {
-			dget(dentry);
+		if (dentry == hlist_entry(lhp, struct dentry, d_hash)) {
+			__dget_locked(dentry);
 			spin_unlock(&dcache_lock);
 			return 1;
 		}
@@ -1113,12 +1106,11 @@
  
 void d_rehash(struct dentry * entry)
 {
-	struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
+	struct hlist_head *list = d_hash(entry->d_parent, entry->d_name.hash);
 	spin_lock(&dcache_lock);
- 	if (!list_empty(&entry->d_hash) && !d_unhashed(entry)) BUG();
  	entry->d_vfs_flags &= ~DCACHE_UNHASHED;
 	entry->d_bucket = list;
- 	list_add_rcu(&entry->d_hash, list);
+ 	hlist_add_head_rcu(&entry->d_hash, list);
 	spin_unlock(&dcache_lock);
 }
 
@@ -1171,10 +1163,6 @@
  * We could be nicer about the deleted file, and let it show
  * up under the name it got deleted rather than the name that
  * deleted it.
- *
- * Careful with the hash switch. The hash switch depends on
- * the fact that any list-entry can be a head of the list.
- * Think about it.
  */
  
 /**
@@ -1197,8 +1185,8 @@
 	/* Move the dentry to the target hash queue, if on different bucket */
 	if (dentry->d_bucket != target->d_bucket) {
 		dentry->d_bucket = target->d_bucket;
-		list_del_rcu(&dentry->d_hash);
-		list_add_rcu(&dentry->d_hash, &target->d_hash);
+		hlist_del_rcu(&dentry->d_hash);
+		hlist_add_head_rcu(&dentry->d_hash, target->d_bucket);
 	}
 
 	/* Unhash the target: dput() will then get rid of it */
@@ -1281,6 +1269,7 @@
 			continue;
 		}
 		parent = dentry->d_parent;
+		prefetch(parent);
 		namelen = dentry->d_name.len;
 		buflen -= namelen + 1;
 		if (buflen < 0)
@@ -1500,7 +1489,7 @@
 
 static void __init dcache_init(unsigned long mempages)
 {
-	struct list_head *d;
+	struct hlist_head *d;
 	unsigned long order;
 	unsigned int nr_hash;
 	int i;
@@ -1521,15 +1510,12 @@
 	if (!dentry_cache)
 		panic("Cannot create dentry cache");
 	
-	/* approximate maximum number of dentries in one hash bucket */
-	max_dentries = (mempages * (PAGE_SIZE / sizeof(struct dentry)));
-
 	set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory);
 
 #if PAGE_SHIFT < 13
 	mempages >>= (13 - PAGE_SHIFT);
 #endif
-	mempages *= sizeof(struct list_head);
+	mempages *= sizeof(struct hlist_head);
 	for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
 		;
 
@@ -1537,7 +1523,7 @@
 		unsigned long tmp;
 
 		nr_hash = (1UL << order) * PAGE_SIZE /
-			sizeof(struct list_head);
+			sizeof(struct hlist_head);
 		d_hash_mask = (nr_hash - 1);
 
 		tmp = nr_hash;
@@ -1545,7 +1531,7 @@
 		while ((tmp >>= 1UL) != 0UL)
 			d_hash_shift++;
 
-		dentry_hashtable = (struct list_head *)
+		dentry_hashtable = (struct hlist_head *)
 			__get_free_pages(GFP_ATOMIC, order);
 	} while (dentry_hashtable == NULL && --order >= 0);
 
@@ -1555,12 +1541,10 @@
 	if (!dentry_hashtable)
 		panic("Failed to allocate dcache hash table\n");
 
-	hashtable_end = dentry_hashtable + nr_hash;
-
 	d = dentry_hashtable;
 	i = nr_hash;
 	do {
-		INIT_LIST_HEAD(d);
+		INIT_HLIST_HEAD(d);
 		d++;
 		i--;
 	} while (i);
diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c	Tue Mar  4 19:30:05 2003
+++ b/fs/devfs/base.c	Tue Mar  4 19:30:05 2003
@@ -1312,7 +1312,7 @@
  *	free_dentry - Free the dentry for a device entry and invalidate inode.
  *	@de: The entry.
  *
- *	This must only be called after the entry has been unhooked from it's
+ *	This must only be called after the entry has been unhooked from its
  *	 parent directory.
  */
 
@@ -1584,7 +1584,7 @@
 
 
 /**
- *	_devfs_unregister - Unregister a device entry from it's parent.
+ *	_devfs_unregister - Unregister a device entry from its parent.
  *	@dir: The parent directory.
  *	@de: The entry to unregister.
  *
@@ -2658,7 +2658,7 @@
     else de->u.dir.no_more_additions = TRUE;
     write_unlock (&de->u.dir.lock);
     if (err) return err;
-    /*  Now unhook the directory from it's parent  */
+    /*  Now unhook the directory from its parent  */
     write_lock (&de->parent->u.dir.lock);
     if ( !_devfs_unhook (de) ) err = -ENOENT;
     write_unlock (&de->parent->u.dir.lock);
diff -Nru a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c	Tue Mar  4 19:30:10 2003
+++ b/fs/direct-io.c	Tue Mar  4 19:30:10 2003
@@ -42,7 +42,7 @@
 /*
  * This code generally works in units of "dio_blocks".  A dio_block is
  * somewhere between the hard sector size and the filesystem block size.  it
- * is determined on a per-invokation basis.   When talking to the filesystem
+ * is determined on a per-invocation basis.   When talking to the filesystem
  * we need to convert dio_blocks to fs_blocks by scaling the dio_block quantity
  * down by dio->blkfactor.  Similarly, fs-blocksize quantities are converted
  * to bio_block quantities by shifting left by blkfactor.
diff -Nru a/fs/eventpoll.c b/fs/eventpoll.c
--- a/fs/eventpoll.c	Tue Mar  4 19:30:07 2003
+++ b/fs/eventpoll.c	Tue Mar  4 19:30:07 2003
@@ -97,7 +97,7 @@
 
 /*
  * Remove the item from the list and perform its initialization.
- * This is usefull for us because we can test if the item is linked
+ * This is useful for us because we can test if the item is linked
  * using "EP_IS_LINKED(p)".
  */
 #define EP_LIST_DEL(p) do { list_del(p); INIT_LIST_HEAD(p); } while (0)
@@ -950,7 +950,7 @@
 	}
 	else
 	{
-		/* We have to signal that an error occured */
+		/* We have to signal that an error occurred */
 		epi->nwait = -1;
 	}
 }
diff -Nru a/fs/ext2/acl.c b/fs/ext2/acl.c
--- a/fs/ext2/acl.c	Tue Mar  4 19:30:12 2003
+++ b/fs/ext2/acl.c	Tue Mar  4 19:30:12 2003
@@ -419,7 +419,7 @@
  */
 static size_t
 ext2_xattr_list_acl_access(char *list, struct inode *inode,
-			   const char *name, int name_len, int flags)
+			   const char *name, int name_len)
 {
 	const size_t size = sizeof(XATTR_NAME_ACL_ACCESS);
 
@@ -432,7 +432,7 @@
 
 static size_t
 ext2_xattr_list_acl_default(char *list, struct inode *inode,
-			    const char *name, int name_len, int flags)
+			    const char *name, int name_len)
 {
 	const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT);
 
@@ -465,7 +465,7 @@
 
 static int
 ext2_xattr_get_acl_access(struct inode *inode, const char *name,
-			  void *buffer, size_t size, int flags)
+			  void *buffer, size_t size)
 {
 	if (strcmp(name, "") != 0)
 		return -EINVAL;
@@ -474,7 +474,7 @@
 
 static int
 ext2_xattr_get_acl_default(struct inode *inode, const char *name,
-			   void *buffer, size_t size, int flags)
+			   void *buffer, size_t size)
 {
 	if (strcmp(name, "") != 0)
 		return -EINVAL;
diff -Nru a/fs/ext2/dir.c b/fs/ext2/dir.c
--- a/fs/ext2/dir.c	Tue Mar  4 19:30:09 2003
+++ b/fs/ext2/dir.c	Tue Mar  4 19:30:09 2003
@@ -420,6 +420,7 @@
 	err = ext2_commit_chunk(page, from, to);
 	ext2_put_page(page);
 	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(dir);
 }
 
@@ -509,6 +510,7 @@
 	ext2_set_de_type (de, inode);
 	err = ext2_commit_chunk(page, from, to);
 	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(dir);
 	/* OFFSET_CACHE */
 out_put:
@@ -556,6 +558,7 @@
 	dir->inode = 0;
 	err = ext2_commit_chunk(page, from, to);
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(inode);
 out:
 	ext2_put_page(page);
diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
--- a/fs/ext2/ialloc.c	Tue Mar  4 19:30:09 2003
+++ b/fs/ext2/ialloc.c	Tue Mar  4 19:30:09 2003
@@ -526,7 +526,7 @@
 	inode->i_blocks = 0;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	memset(ei->i_data, 0, sizeof(ei->i_data));
-	ei->i_flags = EXT2_I(dir)->i_flags;
+	ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
 	if (S_ISLNK(mode))
 		ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
 	/* dirsync is only applied to directories */
diff -Nru a/fs/ext2/xattr.c b/fs/ext2/xattr.c
--- a/fs/ext2/xattr.c	Tue Mar  4 19:30:10 2003
+++ b/fs/ext2/xattr.c	Tue Mar  4 19:30:10 2003
@@ -199,7 +199,7 @@
  */
 ssize_t
 ext2_getxattr(struct dentry *dentry, const char *name,
-	      void *buffer, size_t size, int flags)
+	      void *buffer, size_t size)
 {
 	struct ext2_xattr_handler *handler;
 	struct inode *inode = dentry->d_inode;
@@ -207,7 +207,7 @@
 	handler = ext2_xattr_resolve_name(&name);
 	if (!handler)
 		return -EOPNOTSUPP;
-	return handler->get(inode, name, buffer, size, flags);
+	return handler->get(inode, name, buffer, size);
 }
 
 /*
@@ -217,9 +217,9 @@
  * BKL held [before 2.5.x]
  */
 ssize_t
-ext2_listxattr(struct dentry *dentry, char *buffer, size_t size, int flags)
+ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
 {
-	return ext2_xattr_list(dentry->d_inode, buffer, size, flags);
+	return ext2_xattr_list(dentry->d_inode, buffer, size);
 }
 
 /*
@@ -250,7 +250,7 @@
  * BKL held [before 2.5.x]
  */
 int
-ext2_removexattr(struct dentry *dentry, const char *name, int flags)
+ext2_removexattr(struct dentry *dentry, const char *name)
 {
 	struct ext2_xattr_handler *handler;
 	struct inode *inode = dentry->d_inode;
@@ -258,7 +258,7 @@
 	handler = ext2_xattr_resolve_name(&name);
 	if (!handler)
 		return -EOPNOTSUPP;
-	return handler->set(inode, name, NULL, 0, flags | XATTR_REPLACE);
+	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
 }
 
 /*
@@ -371,8 +371,7 @@
  * used / required on success.
  */
 int
-ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size,
-		int flags)
+ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
 	struct buffer_head *bh = NULL;
 	struct ext2_xattr_entry *entry;
@@ -412,7 +411,7 @@
 		handler = ext2_xattr_handler(entry->e_name_index);
 		if (handler)
 			size += handler->list(NULL, inode, entry->e_name,
-					      entry->e_name_len, flags);
+					      entry->e_name_len);
 	}
 
 	if (ext2_xattr_cache_insert(bh))
@@ -435,7 +434,7 @@
 		handler = ext2_xattr_handler(entry->e_name_index);
 		if (handler)
 			buf += handler->list(buf, inode, entry->e_name,
-					     entry->e_name_len, flags);
+					     entry->e_name_len);
 	}
 	error = size;
 
diff -Nru a/fs/ext2/xattr.h b/fs/ext2/xattr.h
--- a/fs/ext2/xattr.h	Tue Mar  4 19:30:04 2003
+++ b/fs/ext2/xattr.h	Tue Mar  4 19:30:04 2003
@@ -58,9 +58,9 @@
 struct ext2_xattr_handler {
 	char *prefix;
 	size_t (*list)(char *list, struct inode *inode, const char *name,
-		       int name_len, int flags);
+		       int name_len);
 	int (*get)(struct inode *inode, const char *name, void *buffer,
-		   size_t size, int flags);
+		   size_t size);
 	int (*set)(struct inode *inode, const char *name, const void *buffer,
 		   size_t size, int flags);
 };
@@ -69,12 +69,12 @@
 extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *);
 
 extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int);
-extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t, int);
-extern ssize_t ext2_listxattr(struct dentry *, char *, size_t, int);
-extern int ext2_removexattr(struct dentry *, const char *, int);
+extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
+extern int ext2_removexattr(struct dentry *, const char *);
 
 extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t);
-extern int ext2_xattr_list(struct inode *, char *, size_t, int flags);
+extern int ext2_xattr_list(struct inode *, char *, size_t);
 extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
 
 extern void ext2_xattr_delete_inode(struct inode *);
diff -Nru a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
--- a/fs/ext2/xattr_trusted.c	Tue Mar  4 19:30:04 2003
+++ b/fs/ext2/xattr_trusted.c	Tue Mar  4 19:30:04 2003
@@ -16,11 +16,11 @@
 
 static size_t
 ext2_xattr_trusted_list(char *list, struct inode *inode,
-			const char *name, int name_len, int flags)
+			const char *name, int name_len)
 {
 	const int prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1;
 
-	if (!((flags & XATTR_KERNEL_CONTEXT) || capable(CAP_SYS_ADMIN)))
+	if (!capable(CAP_SYS_ADMIN))
 		return 0;
 
 	if (list) {
@@ -33,11 +33,11 @@
 
 static int
 ext2_xattr_trusted_get(struct inode *inode, const char *name,
-		       void *buffer, size_t size, int flags)
+		       void *buffer, size_t size)
 {
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
-	if (!((flags & XATTR_KERNEL_CONTEXT) || capable(CAP_SYS_ADMIN)))
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name,
 			      buffer, size);
@@ -49,7 +49,7 @@
 {
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
-	if (!((flags & XATTR_KERNEL_CONTEXT) || capable(CAP_SYS_ADMIN)))
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name,
 			      value, size, flags);
diff -Nru a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c
--- a/fs/ext2/xattr_user.c	Tue Mar  4 19:30:10 2003
+++ b/fs/ext2/xattr_user.c	Tue Mar  4 19:30:10 2003
@@ -19,12 +19,11 @@
 
 static size_t
 ext2_xattr_user_list(char *list, struct inode *inode,
-		     const char *name, int name_len, int flags)
+		     const char *name, int name_len)
 {
 	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
 
-	if (!(flags & XATTR_KERNEL_CONTEXT) &&
-	    !test_opt(inode->i_sb, XATTR_USER))
+	if (!test_opt(inode->i_sb, XATTR_USER))
 		return 0;
 
 	if (list) {
@@ -37,49 +36,46 @@
 
 static int
 ext2_xattr_user_get(struct inode *inode, const char *name,
-		    void *buffer, size_t size, int flags)
+		    void *buffer, size_t size)
 {
+	int error;
+
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
-	if (!(flags & XATTR_KERNEL_CONTEXT)) {
-		int error;
-
-		if (!test_opt(inode->i_sb, XATTR_USER))
-			return -EOPNOTSUPP;
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return -EOPNOTSUPP;
 #ifdef CONFIG_EXT2_FS_POSIX_ACL
-		error = ext2_permission_locked(inode, MAY_READ);
+	error = ext2_permission_locked(inode, MAY_READ);
 #else
-		error = permission(inode, MAY_READ);
+	error = permission(inode, MAY_READ);
 #endif
-		if (error)
-			return error;
-	}
-	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name,
-			      buffer, size);
+	if (error)
+		return error;
+
+	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, buffer, size);
 }
 
 static int
 ext2_xattr_user_set(struct inode *inode, const char *name,
 		    const void *value, size_t size, int flags)
 {
+	int error;
+
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return -EOPNOTSUPP;
 	if ( !S_ISREG(inode->i_mode) &&
 	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
 		return -EPERM;
-	if (!(flags & XATTR_KERNEL_CONTEXT)) {
-		int error;
-
-		if (!test_opt(inode->i_sb, XATTR_USER))
-			return -EOPNOTSUPP;
 #ifdef CONFIG_EXT2_FS_POSIX_ACL
-		error = ext2_permission_locked(inode, MAY_WRITE);
+	error = ext2_permission_locked(inode, MAY_WRITE);
 #else
-		error = permission(inode, MAY_WRITE);
+	error = permission(inode, MAY_WRITE);
 #endif
-		if (error)
-			return error;
-	}
+	if (error)
+		return error;
+
 	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
 			      value, size, flags);
 }
diff -Nru a/fs/ext3/acl.c b/fs/ext3/acl.c
--- a/fs/ext3/acl.c	Tue Mar  4 19:30:05 2003
+++ b/fs/ext3/acl.c	Tue Mar  4 19:30:05 2003
@@ -431,7 +431,7 @@
  */
 static size_t
 ext3_xattr_list_acl_access(char *list, struct inode *inode,
-			   const char *name, int name_len, int flags)
+			   const char *name, int name_len)
 {
 	const size_t size = sizeof(XATTR_NAME_ACL_ACCESS);
 
@@ -444,7 +444,7 @@
 
 static size_t
 ext3_xattr_list_acl_default(char *list, struct inode *inode,
-			    const char *name, int name_len, int flags)
+			    const char *name, int name_len)
 {
 	const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT);
 
@@ -477,7 +477,7 @@
 
 static int
 ext3_xattr_get_acl_access(struct inode *inode, const char *name,
-			  void *buffer, size_t size, int flags)
+			  void *buffer, size_t size)
 {
 	if (strcmp(name, "") != 0)
 		return -EINVAL;
@@ -486,7 +486,7 @@
 
 static int
 ext3_xattr_get_acl_default(struct inode *inode, const char *name,
-			   void *buffer, size_t size, int flags)
+			   void *buffer, size_t size)
 {
 	if (strcmp(name, "") != 0)
 		return -EINVAL;
diff -Nru a/fs/ext3/dir.c b/fs/ext3/dir.c
--- a/fs/ext3/dir.c	Tue Mar  4 19:30:09 2003
+++ b/fs/ext3/dir.c	Tue Mar  4 19:30:09 2003
@@ -33,12 +33,17 @@
 static int ext3_readdir(struct file *, void *, filldir_t);
 static int ext3_dx_readdir(struct file * filp,
 			   void * dirent, filldir_t filldir);
+static int ext3_release_dir (struct inode * inode,
+				struct file * filp);
 
 struct file_operations ext3_dir_operations = {
 	.read		= generic_read_dir,
 	.readdir	= ext3_readdir,		/* we take BKL. needed?*/
 	.ioctl		= ext3_ioctl,		/* BKL held */
 	.fsync		= ext3_sync_file,		/* BKL held */
+#ifdef CONFIG_EXT3_INDEX
+	.release	= ext3_release_dir,
+#endif
 };
 
 
@@ -275,7 +280,11 @@
 		 */
 		parent = n->rb_parent;
 		fname = rb_entry(n, struct fname, rb_hash);
-		kfree(fname);
+		while (fname) {
+			struct fname * old = fname;
+			fname = fname->next;
+			kfree (old);
+		}
 		if (!parent)
 			root->rb_node = 0;
 		else if (parent->rb_left == n)
@@ -481,4 +490,13 @@
 	UPDATE_ATIME(inode);
 	return 0;
 }
+
+static int ext3_release_dir (struct inode * inode, struct file * filp)
+{
+       if (is_dx(inode) && filp->private_data)
+		ext3_htree_free_dir_info(filp->private_data);
+
+	return 0;
+}
+
 #endif
diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c
--- a/fs/ext3/file.c	Tue Mar  4 19:30:14 2003
+++ b/fs/ext3/file.c	Tue Mar  4 19:30:14 2003
@@ -55,29 +55,61 @@
 	return 0;
 }
 
-/*
- * ext3_file_write().
- *
- * Most things are done in ext3_prepare_write() and ext3_commit_write().
- */
-
 static ssize_t
 ext3_file_write(struct kiocb *iocb, const char *buf, size_t count, loff_t pos)
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_dentry->d_inode;
+	int ret, err;
+
+	ret = generic_file_aio_write(iocb, buf, count, pos);
 
 	/*
-	 * Nasty: if the file is subject to synchronous writes then we need
-	 * to force generic_osync_inode() to call ext3_write_inode().
-	 * We do that by marking the inode dirty.  This adds much more
-	 * computational expense than we need, but we're going to sync
-	 * anyway.
+	 * Skip flushing if there was an error, or if nothing was written.
 	 */
-	if (IS_SYNC(inode) || (file->f_flags & O_SYNC))
-		mark_inode_dirty(inode);
+	if (ret <= 0)
+		return ret;
+	
+	/*
+	 * If the inode is IS_SYNC, or is O_SYNC and we are doing data
+	 * journalling then we need to make sure that we force the transaction
+	 * to disk to keep all metadata uptodate synchronously.
+	 */
+	if (file->f_flags & O_SYNC) {
+		/*
+		 * If we are non-data-journaled, then the dirty data has
+		 * already been flushed to backing store by generic_osync_inode,
+		 * and the inode has been flushed too if there have been any
+		 * modifications other than mere timestamp updates.
+		 *
+		 * Open question --- do we care about flushing timestamps too
+		 * if the inode is IS_SYNC?
+		 */
+		if (!ext3_should_journal_data(inode))
+			return ret;
+
+		goto force_commit;
+	}
 
-	return generic_file_aio_write(iocb, buf, count, pos);
+	/*
+	 * So we know that there has been no forced data flush.  If the inode
+	 * is marked IS_SYNC, we need to force one ourselves.
+	 */
+	if (!IS_SYNC(inode))
+		return ret;
+	
+	/*
+	 * Open question #2 --- should we force data to disk here too?  If we
+	 * don't, the only impact is that data=writeback filesystems won't
+	 * flush data to disk automatically on IS_SYNC, only metadata (but
+	 * historically, that is what ext2 has done.)
+	 */
+	
+force_commit:
+	err = ext3_force_commit(inode->i_sb);
+	if (err) 
+		return err;
+	return ret;
 }
 
 struct file_operations ext3_file_operations = {
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c	Tue Mar  4 19:30:10 2003
+++ b/fs/ext3/namei.c	Tue Mar  4 19:30:10 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 -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
--- a/fs/ext3/xattr.c	Tue Mar  4 19:30:09 2003
+++ b/fs/ext3/xattr.c	Tue Mar  4 19:30:09 2003
@@ -195,7 +195,7 @@
  */
 ssize_t
 ext3_getxattr(struct dentry *dentry, const char *name,
-	      void *buffer, size_t size, int flags)
+	      void *buffer, size_t size)
 {
 	struct ext3_xattr_handler *handler;
 	struct inode *inode = dentry->d_inode;
@@ -203,7 +203,7 @@
 	handler = ext3_xattr_resolve_name(&name);
 	if (!handler)
 		return -EOPNOTSUPP;
-	return handler->get(inode, name, buffer, size, flags);
+	return handler->get(inode, name, buffer, size);
 }
 
 /*
@@ -212,9 +212,9 @@
  * dentry->d_inode->i_sem down
  */
 ssize_t
-ext3_listxattr(struct dentry *dentry, char *buffer, size_t size, int flags)
+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
 {
-	return ext3_xattr_list(dentry->d_inode, buffer, size, flags);
+	return ext3_xattr_list(dentry->d_inode, buffer, size);
 }
 
 /*
@@ -243,7 +243,7 @@
  * dentry->d_inode->i_sem down
  */
 int
-ext3_removexattr(struct dentry *dentry, const char *name, int flags)
+ext3_removexattr(struct dentry *dentry, const char *name)
 {
 	struct ext3_xattr_handler *handler;
 	struct inode *inode = dentry->d_inode;
@@ -251,7 +251,7 @@
 	handler = ext3_xattr_resolve_name(&name);
 	if (!handler)
 		return -EOPNOTSUPP;
-	return handler->set(inode, name, NULL, 0, flags | XATTR_REPLACE);
+	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
 }
 
 /*
@@ -364,8 +364,7 @@
  * used / required on success.
  */
 int
-ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size,
-		int flags)
+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
 	struct buffer_head *bh = NULL;
 	struct ext3_xattr_entry *entry;
@@ -405,7 +404,7 @@
 		handler = ext3_xattr_handler(entry->e_name_index);
 		if (handler)
 			size += handler->list(NULL, inode, entry->e_name,
-					      entry->e_name_len, flags);
+					      entry->e_name_len);
 	}
 
 	if (ext3_xattr_cache_insert(bh))
@@ -428,7 +427,7 @@
 		handler = ext3_xattr_handler(entry->e_name_index);
 		if (handler)
 			buf += handler->list(buf, inode, entry->e_name,
-					     entry->e_name_len, flags);
+					     entry->e_name_len);
 	}
 	error = size;
 
diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h
--- a/fs/ext3/xattr.h	Tue Mar  4 19:30:13 2003
+++ b/fs/ext3/xattr.h	Tue Mar  4 19:30:13 2003
@@ -57,9 +57,9 @@
 struct ext3_xattr_handler {
 	char *prefix;
 	size_t (*list)(char *list, struct inode *inode, const char *name,
-		       int name_len, int flags);
+		       int name_len);
 	int (*get)(struct inode *inode, const char *name, void *buffer,
-		   size_t size, int flags);
+		   size_t size);
 	int (*set)(struct inode *inode, const char *name, const void *buffer,
 		   size_t size, int flags);
 };
@@ -68,12 +68,12 @@
 extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *);
 
 extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int);
-extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t, int);
-extern ssize_t ext3_listxattr(struct dentry *, char *, size_t, int);
-extern int ext3_removexattr(struct dentry *, const char *, int);
+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
+extern int ext3_removexattr(struct dentry *, const char *);
 
 extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
-extern int ext3_xattr_list(struct inode *, char *, size_t, int flags);
+extern int ext3_xattr_list(struct inode *, char *, size_t);
 extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
 extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
 
@@ -97,7 +97,7 @@
 }
 
 static inline int
-ext3_xattr_list(struct inode *inode, void *buffer, size_t size, int flags)
+ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
 {
 	return -EOPNOTSUPP;
 }
diff -Nru a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c
--- a/fs/ext3/xattr_trusted.c	Tue Mar  4 19:30:11 2003
+++ b/fs/ext3/xattr_trusted.c	Tue Mar  4 19:30:11 2003
@@ -17,11 +17,11 @@
 
 static size_t
 ext3_xattr_trusted_list(char *list, struct inode *inode,
-			const char *name, int name_len, int flags)
+			const char *name, int name_len)
 {
 	const int prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1;
 
-	if (!((flags & XATTR_KERNEL_CONTEXT) || capable(CAP_SYS_ADMIN)))
+	if (!capable(CAP_SYS_ADMIN))
 		return 0;
 
 	if (list) {
@@ -34,11 +34,11 @@
 
 static int
 ext3_xattr_trusted_get(struct inode *inode, const char *name,
-		       void *buffer, size_t size, int flags)
+		       void *buffer, size_t size)
 {
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
-	if (!((flags & XATTR_KERNEL_CONTEXT) || capable(CAP_SYS_ADMIN)))
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name,
 			      buffer, size);
@@ -50,7 +50,7 @@
 {
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
-	if (!((flags & XATTR_KERNEL_CONTEXT) || capable(CAP_SYS_ADMIN)))
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	return ext3_xattr_set(inode, EXT3_XATTR_INDEX_TRUSTED, name,
 			      value, size, flags);
diff -Nru a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c
--- a/fs/ext3/xattr_user.c	Tue Mar  4 19:30:04 2003
+++ b/fs/ext3/xattr_user.c	Tue Mar  4 19:30:04 2003
@@ -21,12 +21,11 @@
 
 static size_t
 ext3_xattr_user_list(char *list, struct inode *inode,
-		     const char *name, int name_len, int flags)
+		     const char *name, int name_len)
 {
 	const int prefix_len = sizeof(XATTR_USER_PREFIX)-1;
 
-	if (!(flags & XATTR_KERNEL_CONTEXT) &&
-	    !test_opt(inode->i_sb, XATTR_USER))
+	if (!test_opt(inode->i_sb, XATTR_USER))
 		return 0;
 
 	if (list) {
@@ -39,49 +38,46 @@
 
 static int
 ext3_xattr_user_get(struct inode *inode, const char *name,
-		    void *buffer, size_t size, int flags)
+		    void *buffer, size_t size)
 {
+	int error;
+
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
-	if (!(flags & XATTR_KERNEL_CONTEXT)) {
-		int error;
-
-		if (!test_opt(inode->i_sb, XATTR_USER))
-			return -EOPNOTSUPP;
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return -EOPNOTSUPP;
 #ifdef CONFIG_EXT3_FS_POSIX_ACL
-		error = ext3_permission_locked(inode, MAY_READ);
+	error = ext3_permission_locked(inode, MAY_READ);
 #else
-		error = permission(inode, MAY_READ);
+	error = permission(inode, MAY_READ);
 #endif
-		if (error)
-			return error;
-	}
-	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name,
-			      buffer, size);
+	if (error)
+		return error;
+
+	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, buffer, size);
 }
 
 static int
 ext3_xattr_user_set(struct inode *inode, const char *name,
 		    const void *value, size_t size, int flags)
 {
+	int error;
+
 	if (strcmp(name, "") == 0)
 		return -EINVAL;
+	if (!test_opt(inode->i_sb, XATTR_USER))
+		return -EOPNOTSUPP;
 	if ( !S_ISREG(inode->i_mode) &&
 	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
 		return -EPERM;
-	if (!(flags & XATTR_KERNEL_CONTEXT)) {
-		int error;
-
-		if (!test_opt(inode->i_sb, XATTR_USER))
-			return -EOPNOTSUPP;
 #ifdef CONFIG_EXT3_FS_POSIX_ACL
-		error = ext3_permission_locked(inode, MAY_WRITE);
+	error = ext3_permission_locked(inode, MAY_WRITE);
 #else
-		error = permission(inode, MAY_WRITE);
+	error = permission(inode, MAY_WRITE);
 #endif
-		if (error)
-			return error;
-	}
+	if (error)
+		return error;
+
 	return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name,
 			      value, size, flags);
 }
diff -Nru a/fs/filesystems.c b/fs/filesystems.c
--- a/fs/filesystems.c	Tue Mar  4 19:30:12 2003
+++ b/fs/filesystems.c	Tue Mar  4 19:30:12 2003
@@ -9,6 +9,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
+#include <linux/init.h>
 #include <linux/module.h>
 #include <asm/uaccess.h>
 
@@ -58,6 +59,38 @@
 	return p;
 }
 
+
+/* define fs_subsys */
+static decl_subsys(fs, NULL);
+
+static int register_fs_subsys(struct file_system_type * fs)
+{
+	struct subsystem *sub = &fs->subsys;
+
+	snprintf(sub->kset.kobj.name, KOBJ_NAME_LEN, "%s", fs->name);
+	subsys_set_kset(fs, fs_subsys);
+	return subsystem_register(sub);
+}
+
+static int unlink_fs(struct file_system_type * fs)
+{
+	struct file_system_type ** tmp;
+
+	write_lock(&file_systems_lock);
+	tmp = &file_systems;
+	while (*tmp) {
+		if (fs == *tmp) {
+			*tmp = fs->next;
+			fs->next = NULL;
+			write_unlock(&file_systems_lock);
+			return 0;
+		}
+		tmp = &(*tmp)->next;
+	}
+	write_unlock(&file_systems_lock);
+	return -EINVAL;
+}
+
 /**
  *	register_filesystem - register a new filesystem
  *	@fs: the file system structure
@@ -88,6 +121,14 @@
 	else
 		*p = fs;
 	write_unlock(&file_systems_lock);
+
+	if (!res) {
+		/* we implicitly possess reference to @fs during registration,
+		 * so it cannot be unregister from under us. */
+		if (register_fs_subsys(fs))
+			printk(KERN_WARNING "Failed to register '%s' in sysfs\n",
+			       fs->name);
+	}
 	return res;
 }
 
@@ -105,21 +146,44 @@
  
 int unregister_filesystem(struct file_system_type * fs)
 {
-	struct file_system_type ** tmp;
+	int res;
 
-	write_lock(&file_systems_lock);
-	tmp = &file_systems;
-	while (*tmp) {
-		if (fs == *tmp) {
-			*tmp = fs->next;
-			fs->next = NULL;
-			write_unlock(&file_systems_lock);
-			return 0;
-		}
-		tmp = &(*tmp)->next;
-	}
-	write_unlock(&file_systems_lock);
-	return -EINVAL;
+	res = unlink_fs(fs);
+	if (!res)
+		subsystem_unregister(&fs->subsys);
+	return res;
+}
+
+extern int sysfs_init(void);
+
+/**
+ *	fs_subsys_init - initialize sysfs and fs subsystem.
+ *
+ *	In order to register filesystems in sysfs, it has to be 
+ *	initialized. Also, we need the base fs filesystem, so the 
+ *	registered filesystems have a home.
+ *	
+ *	During sysfs_init(), the registration of sysfs into itself
+ *	will fail, since it's not mounted yet. To make sure that 
+ *	sysfs does show up, we re-register sysfs's embedded subsystem,
+ *	which will get added, since sysfs is now mounted.
+ */
+
+void __init fs_subsys_init(void)
+{
+	struct file_system_type ** p;
+
+	/* make sure sysfs is up and running */
+	sysfs_init();
+
+	/* register fs_subsys */
+	subsystem_register(&fs_subsys);
+
+	p = find_filesystem("sysfs");
+
+	if (p)
+		/* make sure it's registered */
+		register_fs_subsys(*p);
 }
 
 static int fs_index(const char * __name)
diff -Nru a/fs/fs-writeback.c b/fs/fs-writeback.c
--- a/fs/fs-writeback.c	Tue Mar  4 19:30:14 2003
+++ b/fs/fs-writeback.c	Tue Mar  4 19:30:14 2003
@@ -90,7 +90,7 @@
 		 * Only add valid (hashed) inodes to the superblock's
 		 * dirty list.  Add blockdev inodes as well.
 		 */
-		if (list_empty(&inode->i_hash) && !S_ISBLK(inode->i_mode))
+		if (hlist_unhashed(&inode->i_hash) && !S_ISBLK(inode->i_mode))
 			goto out;
 
 		/*
diff -Nru a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c
--- a/fs/hpfs/dnode.c	Tue Mar  4 19:30:08 2003
+++ b/fs/hpfs/dnode.c	Tue Mar  4 19:30:08 2003
@@ -188,7 +188,7 @@
 	return de;
 }
 
-/* Delete dirent and don't care about it's subtree */
+/* Delete dirent and don't care about its subtree */
 
 void hpfs_delete_de(struct super_block *s, struct dnode *d, struct hpfs_dirent *de)
 {
diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- a/fs/hugetlbfs/inode.c	Tue Mar  4 19:30:13 2003
+++ b/fs/hugetlbfs/inode.c	Tue Mar  4 19:30:13 2003
@@ -189,7 +189,7 @@
 
 static void hugetlbfs_delete_inode(struct inode *inode)
 {
-	list_del_init(&inode->i_hash);
+	hlist_del_init(&inode->i_hash);
 	list_del_init(&inode->i_list);
 	inode->i_state |= I_FREEING;
 	inodes_stat.nr_inodes--;
@@ -208,7 +208,7 @@
 {
 	struct super_block *super_block = inode->i_sb;
 
-	if (list_empty(&inode->i_hash))
+	if (hlist_unhashed(&inode->i_hash))
 		goto out_truncate;
 
 	if (!(inode->i_state & (I_DIRTY|I_LOCK))) {
@@ -223,7 +223,7 @@
 
 	/* write_inode_now() ? */
 	inodes_stat.nr_unused--;
-	list_del_init(&inode->i_hash);
+	hlist_del_init(&inode->i_hash);
 out_truncate:
 	list_del_init(&inode->i_list);
 	inode->i_state |= I_FREEING;
diff -Nru a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c	Tue Mar  4 19:30:14 2003
+++ b/fs/inode.c	Tue Mar  4 19:30:14 2003
@@ -69,8 +69,8 @@
 
 LIST_HEAD(inode_in_use);
 LIST_HEAD(inode_unused);
-static struct list_head *inode_hashtable;
-static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */
+static struct hlist_head *inode_hashtable;
+static HLIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */
 
 /*
  * A simple spinlock to protect the list manipulations.
@@ -81,6 +81,16 @@
 spinlock_t inode_lock = SPIN_LOCK_UNLOCKED;
 
 /*
+ * iprune_sem provides exclusion between the kswapd or try_to_free_pages
+ * icache shrinking path, and the umount path.  Without this exclusion,
+ * by the time prune_icache calls iput for the inode whose pages it has
+ * been invalidating, or by the time it calls clear_inode & destroy_inode
+ * from its final dispose_list, the struct super_block they refer to
+ * (for inode->i_sb->s_op) may already have been freed and reused.
+ */
+static DECLARE_MUTEX(iprune_sem);
+
+/*
  * Statistics gathering..
  */
 struct inodes_stat_t inodes_stat;
@@ -162,7 +172,7 @@
 void inode_init_once(struct inode *inode)
 {
 	memset(inode, 0, sizeof(*inode));
-	INIT_LIST_HEAD(&inode->i_hash);
+	INIT_HLIST_NODE(&inode->i_hash);
 	INIT_LIST_HEAD(&inode->i_data.clean_pages);
 	INIT_LIST_HEAD(&inode->i_data.dirty_pages);
 	INIT_LIST_HEAD(&inode->i_data.locked_pages);
@@ -284,7 +294,7 @@
 			continue;
 		invalidate_inode_buffers(inode);
 		if (!atomic_read(&inode->i_count)) {
-			list_del_init(&inode->i_hash);
+			hlist_del_init(&inode->i_hash);
 			list_del(&inode->i_list);
 			list_add(&inode->i_list, dispose);
 			inode->i_state |= I_FREEING;
@@ -320,6 +330,7 @@
 	int busy;
 	LIST_HEAD(throw_away);
 
+	down(&iprune_sem);
 	spin_lock(&inode_lock);
 	busy = invalidate_list(&inode_in_use, sb, &throw_away);
 	busy |= invalidate_list(&inode_unused, sb, &throw_away);
@@ -328,6 +339,7 @@
 	spin_unlock(&inode_lock);
 
 	dispose_list(&throw_away);
+	up(&iprune_sem);
 
 	return busy;
 }
@@ -395,6 +407,7 @@
 	int nr_scanned;
 	unsigned long reap = 0;
 
+	down(&iprune_sem);
 	spin_lock(&inode_lock);
 	for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) {
 		struct inode *inode;
@@ -422,14 +435,17 @@
 			if (!can_unuse(inode))
 				continue;
 		}
-		list_del_init(&inode->i_hash);
+		hlist_del_init(&inode->i_hash);
 		list_move(&inode->i_list, &freeable);
 		inode->i_state |= I_FREEING;
 		nr_pruned++;
 	}
 	inodes_stat.nr_unused -= nr_pruned;
 	spin_unlock(&inode_lock);
+
 	dispose_list(&freeable);
+	up(&iprune_sem);
+
 	if (current_is_kswapd)
 		mod_page_state(kswapd_inodesteal, reap);
 	else
@@ -460,50 +476,42 @@
  * by hand after calling find_inode now! This simplifies iunique and won't
  * add any additional branch in the common code.
  */
-static struct inode * find_inode(struct super_block * sb, struct list_head *head, int (*test)(struct inode *, void *), void *data)
+static struct inode * find_inode(struct super_block * sb, struct hlist_head *head, int (*test)(struct inode *, void *), void *data)
 {
-	struct list_head *tmp;
-	struct inode * inode;
+	struct hlist_node *node;
+	struct inode * inode = NULL;
 
-	tmp = head;
-	for (;;) {
-		tmp = tmp->next;
-		inode = NULL;
-		if (tmp == head)
-			break;
-		inode = list_entry(tmp, struct inode, i_hash);
+	hlist_for_each (node, head) { 
+		prefetch(node->next);
+		inode = hlist_entry(node, struct inode, i_hash);
 		if (inode->i_sb != sb)
 			continue;
 		if (!test(inode, data))
 			continue;
 		break;
 	}
-	return inode;
+	return node ? inode : NULL;
 }
 
 /*
  * find_inode_fast is the fast path version of find_inode, see the comment at
  * iget_locked for details.
  */
-static struct inode * find_inode_fast(struct super_block * sb, struct list_head *head, unsigned long ino)
+static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head *head, unsigned long ino)
 {
-	struct list_head *tmp;
-	struct inode * inode;
+	struct hlist_node *node;
+	struct inode * inode = NULL;
 
-	tmp = head;
-	for (;;) {
-		tmp = tmp->next;
-		inode = NULL;
-		if (tmp == head)
-			break;
-		inode = list_entry(tmp, struct inode, i_hash);
+	hlist_for_each (node, head) {
+		prefetch(node->next);
+		inode = list_entry(node, struct inode, i_hash);
 		if (inode->i_ino != ino)
 			continue;
 		if (inode->i_sb != sb)
 			continue;
 		break;
 	}
-	return inode;
+	return node ? inode : NULL;
 }
 
 /**
@@ -553,7 +561,7 @@
  * We no longer cache the sb_flags in i_flags - see fs.h
  *	-- rmk@arm.uk.linux.org
  */
-static struct inode * get_new_inode(struct super_block *sb, struct list_head *head, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data)
+static struct inode * get_new_inode(struct super_block *sb, struct hlist_head *head, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data)
 {
 	struct inode * inode;
 
@@ -570,7 +578,7 @@
 
 			inodes_stat.nr_inodes++;
 			list_add(&inode->i_list, &inode_in_use);
-			list_add(&inode->i_hash, head);
+			hlist_add_head(&inode->i_hash, head);
 			inode->i_state = I_LOCK|I_NEW;
 			spin_unlock(&inode_lock);
 
@@ -603,7 +611,7 @@
  * get_new_inode_fast is the fast path version of get_new_inode, see the
  * comment at iget_locked for details.
  */
-static struct inode * get_new_inode_fast(struct super_block *sb, struct list_head *head, unsigned long ino)
+static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_head *head, unsigned long ino)
 {
 	struct inode * inode;
 
@@ -618,7 +626,7 @@
 			inode->i_ino = ino;
 			inodes_stat.nr_inodes++;
 			list_add(&inode->i_list, &inode_in_use);
-			list_add(&inode->i_hash, head);
+			hlist_add_head(&inode->i_hash, head);
 			inode->i_state = I_LOCK|I_NEW;
 			spin_unlock(&inode_lock);
 
@@ -670,7 +678,7 @@
 {
 	static ino_t counter = 0;
 	struct inode *inode;
-	struct list_head * head;
+	struct hlist_head * head;
 	ino_t res;
 	spin_lock(&inode_lock);
 retry:
@@ -724,7 +732,7 @@
  * Note, @test is called with the inode_lock held, so can't sleep.
  */
 static inline struct inode *ifind(struct super_block *sb,
-		struct list_head *head, int (*test)(struct inode *, void *),
+		struct hlist_head *head, int (*test)(struct inode *, void *),
 		void *data)
 {
 	struct inode *inode;
@@ -756,7 +764,7 @@
  * Otherwise NULL is returned.
  */
 static inline struct inode *ifind_fast(struct super_block *sb,
-		struct list_head *head, unsigned long ino)
+		struct hlist_head *head, unsigned long ino)
 {
 	struct inode *inode;
 
@@ -794,7 +802,7 @@
 struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
 		int (*test)(struct inode *, void *), void *data)
 {
-	struct list_head *head = inode_hashtable + hash(sb, hashval);
+	struct hlist_head *head = inode_hashtable + hash(sb, hashval);
 
 	return ifind(sb, head, test, data);
 }
@@ -816,7 +824,7 @@
  */
 struct inode *ilookup(struct super_block *sb, unsigned long ino)
 {
-	struct list_head *head = inode_hashtable + hash(sb, ino);
+	struct hlist_head *head = inode_hashtable + hash(sb, ino);
 
 	return ifind_fast(sb, head, ino);
 }
@@ -848,7 +856,7 @@
 		int (*test)(struct inode *, void *),
 		int (*set)(struct inode *, void *), void *data)
 {
-	struct list_head *head = inode_hashtable + hash(sb, hashval);
+	struct hlist_head *head = inode_hashtable + hash(sb, hashval);
 	struct inode *inode;
 
 	inode = ifind(sb, head, test, data);
@@ -881,7 +889,7 @@
  */
 struct inode *iget_locked(struct super_block *sb, unsigned long ino)
 {
-	struct list_head *head = inode_hashtable + hash(sb, ino);
+	struct hlist_head *head = inode_hashtable + hash(sb, ino);
 	struct inode *inode;
 
 	inode = ifind_fast(sb, head, ino);
@@ -907,11 +915,11 @@
  
 void __insert_inode_hash(struct inode *inode, unsigned long hashval)
 {
-	struct list_head *head = &anon_hash_chain;
+	struct hlist_head *head = &anon_hash_chain;
 	if (inode->i_sb)
 		head = inode_hashtable + hash(inode->i_sb, hashval);
 	spin_lock(&inode_lock);
-	list_add(&inode->i_hash, head);
+	hlist_add_head(&inode->i_hash, head);
 	spin_unlock(&inode_lock);
 }
 
@@ -925,7 +933,7 @@
 void remove_inode_hash(struct inode *inode)
 {
 	spin_lock(&inode_lock);
-	list_del_init(&inode->i_hash);
+	hlist_del_init(&inode->i_hash);
 	spin_unlock(&inode_lock);
 }
 
@@ -933,7 +941,7 @@
 {
 	struct super_operations *op = inode->i_sb->s_op;
 
-	list_del_init(&inode->i_hash);
+	hlist_del_init(&inode->i_hash);
 	list_del_init(&inode->i_list);
 	inode->i_state|=I_FREEING;
 	inodes_stat.nr_inodes--;
@@ -962,7 +970,7 @@
 {
 	struct super_block *sb = inode->i_sb;
 
-	if (!list_empty(&inode->i_hash)) {
+	if (!hlist_unhashed(&inode->i_hash)) {
 		if (!(inode->i_state & (I_DIRTY|I_LOCK))) {
 			list_del(&inode->i_list);
 			list_add(&inode->i_list, &inode_unused);
@@ -974,7 +982,7 @@
 		write_inode_now(inode, 1);
 		spin_lock(&inode_lock);
 		inodes_stat.nr_unused--;
-		list_del_init(&inode->i_hash);
+		hlist_del_init(&inode->i_hash);
 	}
 	list_del_init(&inode->i_list);
 	inode->i_state|=I_FREEING;
@@ -1220,7 +1228,7 @@
  */
 void __init inode_init(unsigned long mempages)
 {
-	struct list_head *head;
+	struct hlist_head *head;
 	unsigned long order;
 	unsigned int nr_hash;
 	int i;
@@ -1237,7 +1245,7 @@
 		unsigned long tmp;
 
 		nr_hash = (1UL << order) * PAGE_SIZE /
-			sizeof(struct list_head);
+			sizeof(struct hlist_head);
 		i_hash_mask = (nr_hash - 1);
 
 		tmp = nr_hash;
@@ -1245,7 +1253,7 @@
 		while ((tmp >>= 1UL) != 0UL)
 			i_hash_shift++;
 
-		inode_hashtable = (struct list_head *)
+		inode_hashtable = (struct hlist_head *)
 			__get_free_pages(GFP_ATOMIC, order);
 	} while (inode_hashtable == NULL && --order >= 0);
 
@@ -1258,7 +1266,7 @@
 	head = inode_hashtable;
 	i = nr_hash;
 	do {
-		INIT_LIST_HEAD(head);
+		INIT_HLIST_HEAD(head);
 		head++;
 		i--;
 	} while (i);
diff -Nru a/fs/intermezzo/super.c b/fs/intermezzo/super.c
--- a/fs/intermezzo/super.c	Tue Mar  4 19:30:14 2003
+++ b/fs/intermezzo/super.c	Tue Mar  4 19:30:14 2003
@@ -318,7 +318,7 @@
 
         CDEBUG(D_MALLOC, "mount error exit: kmem %ld, vmem %ld\n",
                presto_kmemory, presto_vmemory);
-        return NULL;
+        return ERR_PTR(-EINVAL);
 }
 
 
diff -Nru a/fs/jbd/revoke.c b/fs/jbd/revoke.c
--- a/fs/jbd/revoke.c	Tue Mar  4 19:30:04 2003
+++ b/fs/jbd/revoke.c	Tue Mar  4 19:30:04 2003
@@ -577,7 +577,7 @@
 	
 	record = find_revoke_record(journal, blocknr);
 	if (record) {
-		/* If we have multiple occurences, only record the
+		/* If we have multiple occurrences, only record the
 		 * latest sequence number in the hashed record */
 		if (tid_gt(sequence, record->sequence))
 			record->sequence = sequence;
diff -Nru a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
--- a/fs/jffs2/compr_rtime.c	Tue Mar  4 19:30:04 2003
+++ b/fs/jffs2/compr_rtime.c	Tue Mar  4 19:30:04 2003
@@ -13,7 +13,7 @@
  * Very simple lz77-ish encoder.
  *
  * Theory of operation: Both encoder and decoder have a list of "last
- * occurances" for every possible source-value; after sending the
+ * occurrences" for every possible source-value; after sending the
  * first source-byte, the second byte indicated the "run" length of
  * matches
  *
diff -Nru a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
--- a/fs/jfs/jfs_dmap.c	Tue Mar  4 19:30:13 2003
+++ b/fs/jfs/jfs_dmap.c	Tue Mar  4 19:30:13 2003
@@ -1112,7 +1112,7 @@
 	 * current allocation in place if the number of additional blocks
 	 * can fit into a dmap, the last block of the current allocation
 	 * is not the last block of the file system, and the start of the
-	 * inplace extension is not on an allocation group boundry.
+	 * inplace extension is not on an allocation group boundary.
 	 */
 	if (addnblocks > BPERDMAP || extblkno >= bmp->db_mapsize ||
 	    (extblkno & (bmp->db_agsize - 1)) == 0) {
diff -Nru a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h
--- a/fs/jfs/jfs_xattr.h	Tue Mar  4 19:30:13 2003
+++ b/fs/jfs/jfs_xattr.h	Tue Mar  4 19:30:13 2003
@@ -57,8 +57,8 @@
 extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
 			int);
 extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
-extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t, int);
-extern ssize_t jfs_listxattr(struct dentry *, char *, size_t, int);
-extern int jfs_removexattr(struct dentry *, const char *, int);
+extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
+extern int jfs_removexattr(struct dentry *, const char *);
 
 #endif	/* H_JFS_XATTR */
diff -Nru a/fs/jfs/xattr.c b/fs/jfs/xattr.c
--- a/fs/jfs/xattr.c	Tue Mar  4 19:30:07 2003
+++ b/fs/jfs/xattr.c	Tue Mar  4 19:30:07 2003
@@ -962,13 +962,12 @@
 }
 
 ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data,
-		     size_t buf_size, int flags)
+		     size_t buf_size)
 {
 	return __jfs_getxattr(dentry->d_inode, name, data, buf_size);
 }
 
-ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size,
-		      int flags)
+ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
 {
 	struct inode *inode = dentry->d_inode;
 	char *buffer;
@@ -1014,7 +1013,7 @@
 	return size;
 }
 
-int jfs_removexattr(struct dentry *dentry, const char *name, int flags)
+int jfs_removexattr(struct dentry *dentry, const char *name)
 {
 	return __jfs_setxattr(dentry->d_inode, name, 0, 0, XATTR_REPLACE);
 }
diff -Nru a/fs/mpage.c b/fs/mpage.c
--- a/fs/mpage.c	Tue Mar  4 19:30:05 2003
+++ b/fs/mpage.c	Tue Mar  4 19:30:05 2003
@@ -598,7 +598,7 @@
  * If a page is already under I/O, generic_writepages() skips it, even
  * if it's dirty.  This is desirable behaviour for memory-cleaning writeback,
  * but it is INCORRECT for data-integrity system calls such as fsync().  fsync()
- * and msync() need to guarentee that all the data which was dirty at the time
+ * and msync() need to guarantee that all the data which was dirty at the time
  * the call was made get new I/O started against them.  So if called_for_sync()
  * is true, we must wait for existing IO to complete.
  *
diff -Nru a/fs/namespace.c b/fs/namespace.c
--- a/fs/namespace.c	Tue Mar  4 19:30:11 2003
+++ b/fs/namespace.c	Tue Mar  4 19:30:11 2003
@@ -26,6 +26,7 @@
 extern struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
 extern int do_remount_sb(struct super_block *sb, int flags, void * data);
 extern int __init init_rootfs(void);
+extern int __init fs_subsys_init(void);
 
 static struct list_head *mount_hashtable;
 static int hash_mask, hash_bits;
@@ -1132,6 +1133,7 @@
 		d++;
 		i--;
 	} while (i);
+	fs_subsys_init();
 	init_rootfs();
 	init_mount_tree();
 }
diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c
--- a/fs/nfsd/export.c	Tue Mar  4 19:30:10 2003
+++ b/fs/nfsd/export.c	Tue Mar  4 19:30:10 2003
@@ -626,7 +626,7 @@
 
 	exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL);
 
-	/* must make sure there wont be an ex_fsid clash */
+	/* must make sure there won't be an ex_fsid clash */
 	if ((nxp->ex_flags & NFSEXP_FSID) &&
 	    (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) &&
 	    !IS_ERR(fsid_key) &&
diff -Nru a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
--- a/fs/nfsd/nfs4xdr.c	Tue Mar  4 19:30:13 2003
+++ b/fs/nfsd/nfs4xdr.c	Tue Mar  4 19:30:13 2003
@@ -1770,7 +1770,7 @@
 	 * XXX: By default, the ->readlink() VFS op will truncate symlinks
 	 * if they would overflow the buffer.  Is this kosher in NFSv4?  If
 	 * not, one easy fix is: if ->readlink() precisely fills the buffer,
-	 * assume that truncation occured, and return NFS4ERR_RESOURCE.
+	 * assume that truncation occurred, and return NFS4ERR_RESOURCE.
 	 */
 	nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount);
 	if (nfserr)
diff -Nru a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
--- a/fs/nfsd/nfsctl.c	Tue Mar  4 19:30:05 2003
+++ b/fs/nfsd/nfsctl.c	Tue Mar  4 19:30:05 2003
@@ -77,7 +77,7 @@
 };
 
 /* an argresp is stored in an allocated page and holds the 
- * size of the argument or response, along with it's content
+ * size of the argument or response, along with its content
  */
 struct argresp {
 	ssize_t size;
diff -Nru a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c	Tue Mar  4 19:30:12 2003
+++ b/fs/ntfs/aops.c	Tue Mar  4 19:30:12 2003
@@ -942,7 +942,7 @@
 	 * the below memcpy() already takes care of the mmap-at-end-of-file
 	 * requirements. If the file is converted to a non-resident one, then
 	 * the code path use is switched to the non-resident one where the
-	 * zeroing happens on each ntfs_writepage() invokation.
+	 * zeroing happens on each ntfs_writepage() invocation.
 	 *
 	 * The above also applies nicely when i_size is decreased.
 	 *
@@ -1087,7 +1087,7 @@
 
 		if (block >= ablock) {
 			// TODO: block is above allocated_size, need to
-			// allocate it. Best done in one go to accomodate not
+			// allocate it. Best done in one go to accommodate not
 			// only block but all above blocks up to and including:
 			// ((page->index << PAGE_CACHE_SHIFT) + to + blocksize
 			// - 1) >> blobksize_bits. Obviously will need to round
diff -Nru a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
--- a/fs/ntfs/attrib.c	Tue Mar  4 19:30:14 2003
+++ b/fs/ntfs/attrib.c	Tue Mar  4 19:30:14 2003
@@ -830,7 +830,7 @@
 				goto io_error;
 			for (deltaxcn = (s8)buf[b--]; b > b2; b--)
 				deltaxcn = (deltaxcn << 8) + buf[b];
-			/* Change the current lcn to it's new value. */
+			/* Change the current lcn to its new value. */
 			lcn += deltaxcn;
 #ifdef DEBUG
 			/*
diff -Nru a/fs/ntfs/layout.h b/fs/ntfs/layout.h
--- a/fs/ntfs/layout.h	Tue Mar  4 19:30:09 2003
+++ b/fs/ntfs/layout.h	Tue Mar  4 19:30:09 2003
@@ -152,7 +152,7 @@
  * been written to disk. The values 0 and -1 (ie. 0xffff) are not used. All
  * last u16's of each sector have to be equal to the usn (during reading) or
  * are set to it (during writing). If they are not, an incomplete multi sector
- * transfer has occured when the data was written.
+ * transfer has occurred when the data was written.
  * The maximum size for the update sequence array is fixed to:
  * 	maximum size = usa_ofs + (usa_count * 2) = 510 bytes
  * The 510 bytes comes from the fact that the last u16 in the array has to
diff -Nru a/fs/ntfs/mft.c b/fs/ntfs/mft.c
--- a/fs/ntfs/mft.c	Tue Mar  4 19:30:11 2003
+++ b/fs/ntfs/mft.c	Tue Mar  4 19:30:11 2003
@@ -202,7 +202,7 @@
  * records/inodes present in the page before I/O can proceed. In that case we
  * wouldn't need to bother with PG_locked and PG_uptodate as nobody will be
  * accessing anything without owning the mrec_lock semaphore. But we do need
- * to use them because of the read_cache_page() invokation and the code becomes
+ * to use them because of the read_cache_page() invocation and the code becomes
  * so much simpler this way that it is well worth it.
  *
  * The mft record is now ours and we return a pointer to it. You need to check
diff -Nru a/fs/ntfs/namei.c b/fs/ntfs/namei.c
--- a/fs/ntfs/namei.c	Tue Mar  4 19:30:12 2003
+++ b/fs/ntfs/namei.c	Tue Mar  4 19:30:12 2003
@@ -233,7 +233,7 @@
 	m = NULL;
 	ctx = NULL;
 
-	/* Check if a conversion error occured. */
+	/* Check if a conversion error occurred. */
 	if ((signed)nls_name.len < 0) {
 		err = (signed)nls_name.len;
 		goto err_out;
diff -Nru a/fs/proc/array.c b/fs/proc/array.c
--- a/fs/proc/array.c	Tue Mar  4 19:30:10 2003
+++ b/fs/proc/array.c	Tue Mar  4 19:30:10 2003
@@ -358,7 +358,8 @@
 		nice,
 		0UL /* removed */,
 		jiffies_to_clock_t(task->it_real_value),
-		(unsigned long long) jiffies_64_to_clock_t(task->start_time),
+		(unsigned long long)
+		    jiffies_64_to_clock_t(task->start_time - INITIAL_JIFFIES),
 		vsize,
 		mm ? mm->rss : 0, /* you might want to shift this left 3 */
 		task->rlim[RLIMIT_RSS].rlim_cur,
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c	Tue Mar  4 19:30:04 2003
+++ b/fs/proc/proc_misc.c	Tue Mar  4 19:30:04 2003
@@ -104,7 +104,7 @@
 	unsigned long uptime_remainder;
 	int len;
 
-	uptime = get_jiffies_64();
+	uptime = get_jiffies_64() - INITIAL_JIFFIES;
 	uptime_remainder = (unsigned long) do_div(uptime, HZ);
 
 #if HZ!=100
@@ -320,7 +320,7 @@
 {
 	int i, len;
 	extern unsigned long total_forks;
-	u64 jif = get_jiffies_64();
+	u64 jif = get_jiffies_64() - INITIAL_JIFFIES;
 	unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0;
 
 	for (i = 0 ; i < NR_CPUS; i++) {
diff -Nru a/fs/quota_v2.c b/fs/quota_v2.c
--- a/fs/quota_v2.c	Tue Mar  4 19:30:12 2003
+++ b/fs/quota_v2.c	Tue Mar  4 19:30:12 2003
@@ -415,7 +415,7 @@
 
 	if (!dquot->dq_off)
 		if ((ret = dq_insert_tree(dquot)) < 0) {
-			printk(KERN_ERR "VFS: Error %Zd occured while creating quota.\n", ret);
+			printk(KERN_ERR "VFS: Error %Zd occurred while creating quota.\n", ret);
 			return ret;
 		}
 	filp = sb_dqopt(dquot->dq_sb)->files[type];
diff -Nru a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c
--- a/fs/reiserfs/do_balan.c	Tue Mar  4 19:30:04 2003
+++ b/fs/reiserfs/do_balan.c	Tue Mar  4 19:30:04 2003
@@ -1381,7 +1381,7 @@
   if ( cur_tb ) {
     reiserfs_panic (tb->tb_sb, "vs-12335: check_before_balancing: "
 		    "suspect that schedule occurred based on cur_tb not being null at this point in code. "
-		    "do_balance cannot properly handle schedule occuring while it runs.");
+		    "do_balance cannot properly handle schedule occurring while it runs.");
   }
   
   /* double check that buffers that we will modify are unlocked. (fix_nodes should already have
diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
--- a/fs/reiserfs/journal.c	Tue Mar  4 19:30:10 2003
+++ b/fs/reiserfs/journal.c	Tue Mar  4 19:30:10 2003
@@ -1629,7 +1629,7 @@
 /*
 ** read and replay the log
 ** on a clean unmount, the journal header's next unflushed pointer will be to an invalid
-** transaction.  This tests that before finding all the transactions in the log, whic makes normal mount times fast.
+** transaction.  This tests that before finding all the transactions in the log, which makes normal mount times fast.
 **
 ** After a crash, this starts with the next unflushed transaction, and replays until it finds one too old, or invalid.
 **
@@ -1913,7 +1913,7 @@
 			result = -ENOMEM;
 		if( result != 0 )
 			printk( "sh-458: journal_init_dev: cannot init journal device\n '%s': %i", 
-				kdevname( to_kdev_t(jdev) ), result );
+				bdevname(journal->j_dev_bd), result );
 
 		else if (jdev != super->s_dev) {
 			set_blocksize(journal->j_dev_bd, super->s_blocksize);
@@ -1931,7 +1931,7 @@
 			printk( "journal_init_dev: '%s' is not a block device", jdev_name );
 			result = -ENOTBLK;
 		} else if( jdev_inode -> i_bdev == NULL ) {
-			printk( "journal_init_dev: bdev unintialized for '%s'", jdev_name );
+			printk( "journal_init_dev: bdev uninitialized for '%s'", jdev_name );
 			result = -ENOMEM;
 		} else  {
 			/* ok */
@@ -1946,7 +1946,7 @@
 	if( result != 0 ) {
 		release_journal_dev( super, journal );
 	}
-	printk( "journal_init_dev: journal device: %s", kdevname(to_kdev_t(jdev)) );
+	printk( "journal_init_dev: journal device: %s", bdevname(journal->j_dev_bd));
 	return result;
 }
 
@@ -2523,7 +2523,7 @@
 ** haven't hit disk yet.  called from bitmap.c
 **
 ** if it starts flushing things, it ors SCHEDULE_OCCURRED into repeat.
-** note, this is just if schedule has a chance of occuring.  I need to 
+** note, this is just if schedule has a chance of occurring.  I need to 
 ** change flush_commit_lists to have a repeat parameter too.
 **
 */
diff -Nru a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c
--- a/fs/reiserfs/lbalance.c	Tue Mar  4 19:30:14 2003
+++ b/fs/reiserfs/lbalance.c	Tue Mar  4 19:30:14 2003
@@ -1192,7 +1192,7 @@
   }
 
 
-  /* change item key if neccessary (when we paste before 0-th entry */
+  /* change item key if necessary (when we paste before 0-th entry */
   if (!before)
     {
 	set_le_ih_k_offset (ih, deh_offset(new_dehs));
diff -Nru a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
--- a/fs/reiserfs/stree.c	Tue Mar  4 19:30:11 2003
+++ b/fs/reiserfs/stree.c	Tue Mar  4 19:30:11 2003
@@ -1495,7 +1495,7 @@
 
 
     /* Repeat this loop until we either cut the item without needing
-       to balance, or we fix_nodes without schedule occuring */
+       to balance, or we fix_nodes without schedule occurring */
     while ( 1 ) {
 	/* Determine the balance mode, position of the first byte to
 	   be cut, and size to be cut.  In case of the indirect item
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Tue Mar  4 19:30:08 2003
+++ b/fs/reiserfs/super.c	Tue Mar  4 19:30:08 2003
@@ -1356,7 +1356,7 @@
   buf->f_bavail  = buf->f_bfree;
   buf->f_blocks  = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
   buf->f_bsize   = s->s_blocksize;
-  /* changed to accomodate gcc folks.*/
+  /* changed to accommodate gcc folks.*/
   buf->f_type    =  REISERFS_SUPER_MAGIC;
   return 0;
 }
diff -Nru a/fs/seq_file.c b/fs/seq_file.c
--- a/fs/seq_file.c	Tue Mar  4 19:30:11 2003
+++ b/fs/seq_file.c	Tue Mar  4 19:30:11 2003
@@ -250,7 +250,7 @@
  *	@s:	string
  *	@esc:	set of characters that need escaping
  *
- *	Puts string into buffer, replacing each occurence of character from
+ *	Puts string into buffer, replacing each occurrence of character from
  *	@esc with usual octal escape.  Returns 0 in case of success, -1 - in
  *	case of overflow.
  */
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	Tue Mar  4 19:30:08 2003
+++ b/fs/super.c	Tue Mar  4 19:30:08 2003
@@ -63,7 +63,7 @@
 		INIT_LIST_HEAD(&s->s_io);
 		INIT_LIST_HEAD(&s->s_files);
 		INIT_LIST_HEAD(&s->s_instances);
-		INIT_LIST_HEAD(&s->s_anon);
+		INIT_HLIST_HEAD(&s->s_anon);
 		init_rwsem(&s->s_umount);
 		sema_init(&s->s_lock, 1);
 		down_write(&s->s_umount);
diff -Nru a/fs/sysfs/Makefile b/fs/sysfs/Makefile
--- a/fs/sysfs/Makefile	Tue Mar  4 19:30:03 2003
+++ b/fs/sysfs/Makefile	Tue Mar  4 19:30:03 2003
@@ -2,4 +2,4 @@
 # Makefile for the sysfs virtual filesystem
 #
 
-obj-y		:= inode.o
+obj-y		:= inode.o file.o dir.o symlink.o mount.o bin.o
diff -Nru a/fs/sysfs/bin.c b/fs/sysfs/bin.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/sysfs/bin.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,233 @@
+/*
+ * bin.c - binary file operations for sysfs.
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+
+#include "sysfs.h"
+
+static struct file_operations bin_fops;
+
+static int fill_read(struct file * file, struct sysfs_bin_buffer * buffer)
+{
+	struct bin_attribute * attr = file->f_dentry->d_fsdata;
+	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
+
+	if (!buffer->data)
+		attr->read(kobj,buffer);
+	return buffer->size ? 0 : -ENOENT;
+}
+
+static int flush_read(struct file * file, char * userbuf, 
+		      struct sysfs_bin_buffer * buffer)
+{
+	return copy_to_user(userbuf,buffer->data + buffer->offset,buffer->count) ? 
+		-EFAULT : 0;
+}
+
+static ssize_t
+read(struct file * file, char * userbuf, size_t count, loff_t * off)
+{
+	struct sysfs_bin_buffer * buffer = file->private_data;
+	int ret;
+
+	ret = fill_read(file,buffer);
+	if (ret) 
+		goto Done;
+
+	buffer->offset = *off;
+
+	if (count > (buffer->size - *off))
+		count = buffer->size - *off;
+
+	buffer->count = count;
+
+	ret = flush_read(file,userbuf,buffer);
+	if (!ret) {
+		*off += count;
+		ret = count;
+	}
+ Done:
+	return ret;
+}
+
+int alloc_buf_data(struct sysfs_bin_buffer * buffer)
+{
+	buffer->data = kmalloc(buffer->count,GFP_KERNEL);
+	if (buffer->data) {
+		memset(buffer->data,0,buffer->count);
+		return 0;
+	} else
+		return -ENOMEM;
+}
+
+static int fill_write(struct file * file, const char * userbuf, 
+		      struct sysfs_bin_buffer * buffer)
+{
+	return copy_from_user(buffer,userbuf,buffer->count) ?
+		-EFAULT : 0;
+}
+
+static int flush_write(struct file * file, const char * userbuf, 
+		       struct sysfs_bin_buffer * buffer)
+{
+	struct bin_attribute * attr = file->f_dentry->d_fsdata;
+	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
+
+	return attr->write(kobj,buffer);
+}
+
+static ssize_t write(struct file * file, const char * userbuf,
+		     size_t count, loff_t * off)
+{
+	struct sysfs_bin_buffer * buffer = file->private_data;
+	int ret;
+
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+	buffer->count = count;
+
+	ret = alloc_buf_data(buffer);
+	if (ret)
+		goto Done;
+
+	ret = fill_write(file,userbuf,buffer);
+	if (ret)
+		goto Done;
+
+	ret = flush_write(file,userbuf,buffer);
+	if (ret > 0)
+		*off += count;
+ Done:
+	if (buffer->data) {
+		kfree(buffer->data);
+		buffer->data = NULL;
+	}
+	return ret;
+}
+
+static int check_perm(struct inode * inode, struct file * file)
+{
+	struct kobject * kobj = kobject_get(file->f_dentry->d_parent->d_fsdata);
+	struct bin_attribute * attr = file->f_dentry->d_fsdata;
+	struct sysfs_bin_buffer * buffer;
+	int error = 0;
+
+	if (!kobj || !attr)
+		goto Einval;
+
+	/* File needs write support.
+	 * The inode's perms must say it's ok, 
+	 * and we must have a store method.
+	 */
+	if (file->f_mode & FMODE_WRITE) {
+		if (!(inode->i_mode & S_IWUGO) || !attr->write)
+			goto Eaccess;
+	}
+
+	/* File needs read support.
+	 * The inode's perms must say it's ok, and we there
+	 * must be a show method for it.
+	 */
+	if (file->f_mode & FMODE_READ) {
+		if (!(inode->i_mode & S_IRUGO) || !attr->read)
+			goto Eaccess;
+	}
+
+	buffer = kmalloc(sizeof(struct sysfs_bin_buffer),GFP_KERNEL);
+	if (buffer) {
+		memset(buffer,0,sizeof(struct sysfs_bin_buffer));
+		file->private_data = buffer;
+	} else
+		error = -ENOMEM;
+	goto Done;
+
+ Einval:
+	error = -EINVAL;
+	goto Done;
+ Eaccess:
+	error = -EACCES;
+ Done:
+	if (error && kobj)
+		kobject_put(kobj);
+	return error;
+}
+
+static int open(struct inode * inode, struct file * file)
+{
+	return check_perm(inode,file);
+}
+
+static int release(struct inode * inode, struct file * file)
+{
+	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
+	u8 * buffer = file->private_data;
+
+	if (kobj) 
+		kobject_put(kobj);
+	if (buffer)
+		kfree(buffer);
+	return 0;
+}
+
+static struct file_operations bin_fops = {
+	.read		= read,
+	.write		= write,
+	.llseek		= generic_file_llseek,
+	.open		= open,
+	.release	= release,
+};
+
+/**
+ *	sysfs_create_bin_file - create binary file for object.
+ *	@kobj:	object.
+ *	@attr:	attribute descriptor.
+ *
+ */
+
+int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr)
+{
+	struct dentry * dentry;
+	struct dentry * parent;
+	int error = 0;
+
+	if (!kobj || !attr)
+		return -EINVAL;
+
+	parent = kobj->dentry;
+
+	down(&parent->d_inode->i_sem);
+	dentry = sysfs_get_dentry(parent,attr->attr.name);
+	if (!IS_ERR(dentry)) {
+		dentry->d_fsdata = (void *)attr;
+		error = sysfs_create(dentry,
+				     (attr->attr.mode & S_IALLUGO) | S_IFREG,
+				     NULL);
+		if (!error) {
+			dentry->d_inode->i_size = attr->size;
+			dentry->d_inode->i_fop = &bin_fops;
+		}
+	} else
+		error = PTR_ERR(dentry);
+	up(&parent->d_inode->i_sem);
+	return error;
+}
+
+
+/**
+ *	sysfs_remove_bin_file - remove binary file for object.
+ *	@kobj:	object.
+ *	@attr:	attribute descriptor.
+ *
+ */
+
+int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
+{
+	sysfs_hash_and_remove(kobj->dentry,attr->attr.name);
+	return 0;
+}
+
+EXPORT_SYMBOL(sysfs_create_bin_file);
+EXPORT_SYMBOL(sysfs_remove_bin_file);
diff -Nru a/fs/sysfs/dir.c b/fs/sysfs/dir.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/sysfs/dir.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,136 @@
+/*
+ * dir.c - Operations for sysfs directories.
+ */
+
+#undef DEBUG
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include "sysfs.h"
+
+static int init_dir(struct inode * inode)
+{
+	inode->i_op = &simple_dir_inode_operations;
+	inode->i_fop = &simple_dir_operations;
+
+	/* directory inodes start off with i_nlink == 2 (for "." entry) */
+	inode->i_nlink++;
+	return 0;
+}
+
+/**
+ *	sysfs_create_dir - create a directory for an object.
+ *	@parent:	parent parent object.
+ *	@kobj:		object we're creating directory for. 
+ */
+
+int sysfs_create_dir(struct kobject * kobj)
+{
+	struct dentry * dentry = NULL;
+	struct dentry * parent;
+	int error = 0;
+
+	if (!kobj)
+		return -EINVAL;
+
+	if (kobj->parent)
+		parent = kobj->parent->dentry;
+	else if (sysfs_mount && sysfs_mount->mnt_sb)
+		parent = sysfs_mount->mnt_sb->s_root;
+	else
+		return -EFAULT;
+
+	down(&parent->d_inode->i_sem);
+	dentry = sysfs_get_dentry(parent,kobj->name);
+	if (!IS_ERR(dentry)) {
+		dentry->d_fsdata = (void *)kobj;
+		kobj->dentry = dentry;
+		error = sysfs_create(dentry,(S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO),
+				     init_dir);
+		if (!error)
+			parent->d_inode->i_nlink++;
+	} else
+		error = PTR_ERR(dentry);
+	up(&parent->d_inode->i_sem);
+
+	return error;
+}
+
+
+
+/**
+ *	sysfs_remove_dir - remove an object's directory.
+ *	@kobj:	object. 
+ *
+ *	The only thing special about this is that we remove any files in 
+ *	the directory before we remove the directory, and we've inlined
+ *	what used to be sysfs_rmdir() below, instead of calling separately.
+ */
+
+void sysfs_remove_dir(struct kobject * kobj)
+{
+	struct list_head * node, * next;
+	struct dentry * dentry = dget(kobj->dentry);
+	struct dentry * parent;
+
+	if (!dentry)
+		return;
+
+	pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
+	parent = dget(dentry->d_parent);
+	down(&parent->d_inode->i_sem);
+	down(&dentry->d_inode->i_sem);
+
+	list_for_each_safe(node,next,&dentry->d_subdirs) {
+		struct dentry * d = dget(list_entry(node,struct dentry,d_child));
+		/** 
+		 * Make sure dentry is still there 
+		 */
+		pr_debug(" o %s: ",d->d_name.name);
+		if (d->d_inode) {
+
+			pr_debug("removing");
+			/**
+			 * Unlink and unhash.
+			 */
+			simple_unlink(dentry->d_inode,d);
+			d_delete(d);
+
+			/**
+			 * Drop reference from initial sysfs_get_dentry().
+			 */
+			dput(d);
+		}
+		pr_debug(" done (%d)\n",atomic_read(&d->d_count));
+		/**
+		 * drop reference from dget() above.
+		 */
+		dput(d);
+	}
+
+	up(&dentry->d_inode->i_sem);
+	d_invalidate(dentry);
+	simple_rmdir(parent->d_inode,dentry);
+	d_delete(dentry);
+
+	pr_debug(" o %s removing done (%d)\n",dentry->d_name.name,
+		 atomic_read(&dentry->d_count));
+	/**
+	 * Drop reference from initial sysfs_get_dentry().
+	 */
+	dput(dentry);
+
+	/**
+	 * Drop reference from dget() on entrance.
+	 */
+	dput(dentry);
+	up(&parent->d_inode->i_sem);
+	dput(parent);
+}
+
+
+EXPORT_SYMBOL(sysfs_create_dir);
+EXPORT_SYMBOL(sysfs_remove_dir);
+
diff -Nru a/fs/sysfs/file.c b/fs/sysfs/file.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/sysfs/file.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,424 @@
+/*
+ * file.c - operations for regular (text) files.
+ */
+
+#include <linux/module.h>
+#include <linux/dnotify.h>
+#include <linux/kobject.h>
+
+#include "sysfs.h"
+
+static struct file_operations sysfs_file_operations;
+
+static int init_file(struct inode * inode)
+{
+	inode->i_size = PAGE_SIZE;
+	inode->i_fop = &sysfs_file_operations;
+	return 0;
+}
+
+#define to_subsys(k) container_of(k,struct subsystem,kset.kobj)
+#define to_sattr(a) container_of(a,struct subsys_attribute,attr)
+
+/**
+ * Subsystem file operations.
+ * These operations allow subsystems to have files that can be 
+ * read/written. 
+ */
+static ssize_t 
+subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page)
+{
+	struct subsystem * s = to_subsys(kobj);
+	struct subsys_attribute * sattr = to_sattr(attr);
+	ssize_t ret = 0;
+
+	if (sattr->show)
+		ret = sattr->show(s,page);
+	return ret;
+}
+
+static ssize_t 
+subsys_attr_store(struct kobject * kobj, struct attribute * attr, 
+		  const char * page, size_t count)
+{
+	struct subsystem * s = to_subsys(kobj);
+	struct subsys_attribute * sattr = to_sattr(attr);
+	ssize_t ret = 0;
+
+	if (sattr->store)
+		ret = sattr->store(s,page,count);
+	return ret;
+}
+
+static struct sysfs_ops subsys_sysfs_ops = {
+	.show	= subsys_attr_show,
+	.store	= subsys_attr_store,
+};
+
+
+struct sysfs_buffer {
+	size_t			count;
+	loff_t			pos;
+	char			* page;
+	struct sysfs_ops	* ops;
+};
+
+
+/**
+ *	fill_read_buffer - allocate and fill buffer from object.
+ *	@file:		file pointer.
+ *	@buffer:	data buffer for file.
+ *
+ *	Allocate @buffer->page, if it hasn't been already, then call the
+ *	kobject's show() method to fill the buffer with this attribute's 
+ *	data. 
+ *	This is called only once, on the file's first read. 
+ */
+static int fill_read_buffer(struct file * file, struct sysfs_buffer * buffer)
+{
+	struct attribute * attr = file->f_dentry->d_fsdata;
+	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
+	struct sysfs_ops * ops = buffer->ops;
+	int ret = 0;
+	size_t count;
+
+	if (!buffer->page)
+		buffer->page = (char *) __get_free_page(GFP_KERNEL);
+	if (!buffer->page)
+		return -ENOMEM;
+
+	count = ops->show(kobj,attr,buffer->page);
+	if (count >= 0)
+		buffer->count = count;
+	else
+		ret = count;
+	return ret;
+}
+
+
+/**
+ *	flush_read_buffer - push buffer to userspace.
+ *	@buffer:	data buffer for file.
+ *	@userbuf:	user-passed buffer.
+ *	@count:		number of bytes requested.
+ *	@ppos:		file position.
+ *
+ *	Copy the buffer we filled in fill_read_buffer() to userspace.
+ *	This is done at the reader's leisure, copying and advancing 
+ *	the amount they specify each time.
+ *	This may be called continuously until the buffer is empty.
+ */
+static int flush_read_buffer(struct sysfs_buffer * buffer, char * buf, 
+			     size_t count, loff_t * ppos)
+{
+	int error;
+
+	if (count > (buffer->count - *ppos))
+		count = buffer->count - *ppos;
+
+	error = copy_to_user(buf,buffer->page + *ppos,count);
+	if (!error)
+		*ppos += count;
+	return error ? -EFAULT : count;
+}
+
+/**
+ *	sysfs_read_file - read an attribute. 
+ *	@file:	file pointer.
+ *	@buf:	buffer to fill.
+ *	@count:	number of bytes to read.
+ *	@ppos:	starting offset in file.
+ *
+ *	Userspace wants to read an attribute file. The attribute descriptor
+ *	is in the file's ->d_fsdata. The target object is in the directory's
+ *	->d_fsdata.
+ *
+ *	We call fill_read_buffer() to allocate and fill the buffer from the
+ *	object's show() method exactly once (if the read is happening from
+ *	the beginning of the file). That should fill the entire buffer with
+ *	all the data the object has to offer for that attribute.
+ *	We then call flush_read_buffer() to copy the buffer to userspace
+ *	in the increments specified.
+ */
+
+static ssize_t
+sysfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+	struct sysfs_buffer * buffer = file->private_data;
+	ssize_t retval = 0;
+
+	if (!*ppos) {
+		if ((retval = fill_read_buffer(file,buffer)))
+			return retval;
+	}
+	pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
+		 __FUNCTION__,count,*ppos,buffer->page);
+	return flush_read_buffer(buffer,buf,count,ppos);
+}
+
+
+/**
+ *	fill_write_buffer - copy buffer from userspace.
+ *	@buffer:	data buffer for file.
+ *	@userbuf:	data from user.
+ *	@count:		number of bytes in @userbuf.
+ *
+ *	Allocate @buffer->page if it hasn't been already, then
+ *	copy the user-supplied buffer into it.
+ */
+
+static int 
+fill_write_buffer(struct sysfs_buffer * buffer, const char * buf, size_t count)
+{
+	int error;
+
+	if (!buffer->page)
+		buffer->page = (char *)__get_free_page(GFP_KERNEL);
+	if (!buffer->page)
+		return -ENOMEM;
+
+	if (count >= PAGE_SIZE)
+		count = PAGE_SIZE - 1;
+	error = copy_from_user(buffer->page,buf,count);
+	return error ? -EFAULT : count;
+}
+
+
+/**
+ *	flush_write_buffer - push buffer to kobject.
+ *	@file:		file pointer.
+ *	@buffer:	data buffer for file.
+ *
+ *	Get the correct pointers for the kobject and the attribute we're
+ *	dealing with, then call the store() method for the attribute, 
+ *	passing the buffer that we acquired in fill_write_buffer().
+ */
+
+static int 
+flush_write_buffer(struct file * file, struct sysfs_buffer * buffer, size_t count)
+{
+	struct attribute * attr = file->f_dentry->d_fsdata;
+	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
+	struct sysfs_ops * ops = buffer->ops;
+
+	return ops->store(kobj,attr,buffer->page,count);
+}
+
+
+/**
+ *	sysfs_write_file - write an attribute.
+ *	@file:	file pointer
+ *	@buf:	data to write
+ *	@count:	number of bytes
+ *	@ppos:	starting offset
+ *
+ *	Similar to sysfs_read_file(), though working in the opposite direction.
+ *	We allocate and fill the data from the user in fill_write_buffer(),
+ *	then push it to the kobject in flush_write_buffer().
+ *	There is no easy way for us to know if userspace is only doing a partial
+ *	write, so we don't support them. We expect the entire buffer to come
+ *	on the first write. 
+ *	Hint: if you're writing a value, first read the file, modify only the
+ *	the value you're changing, then write entire buffer back. 
+ */
+
+static ssize_t
+sysfs_write_file(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+	struct sysfs_buffer * buffer = file->private_data;
+
+	count = fill_write_buffer(buffer,buf,count);
+	if (count > 0)
+		count = flush_write_buffer(file,buffer,count);
+	if (count > 0)
+		*ppos += count;
+	return count;
+}
+
+static int check_perm(struct inode * inode, struct file * file)
+{
+	struct kobject * kobj = kobject_get(file->f_dentry->d_parent->d_fsdata);
+	struct attribute * attr = file->f_dentry->d_fsdata;
+	struct sysfs_buffer * buffer;
+	struct sysfs_ops * ops = NULL;
+	int error = 0;
+
+	if (!kobj || !attr)
+		goto Einval;
+
+	/* if the kobject has no ktype, then we assume that it is a subsystem
+	 * itself, and use ops for it.
+	 */
+	if (kobj->kset && kobj->kset->ktype)
+		ops = kobj->kset->ktype->sysfs_ops;
+	else if (kobj->ktype)
+		ops = kobj->ktype->sysfs_ops;
+	else
+		ops = &subsys_sysfs_ops;
+
+	/* No sysfs operations, either from having no subsystem,
+	 * or the subsystem have no operations.
+	 */
+	if (!ops)
+		goto Eaccess;
+
+	/* File needs write support.
+	 * The inode's perms must say it's ok, 
+	 * and we must have a store method.
+	 */
+	if (file->f_mode & FMODE_WRITE) {
+
+		if (!(inode->i_mode & S_IWUGO) || !ops->store)
+			goto Eaccess;
+
+	}
+
+	/* File needs read support.
+	 * The inode's perms must say it's ok, and we there
+	 * must be a show method for it.
+	 */
+	if (file->f_mode & FMODE_READ) {
+		if (!(inode->i_mode & S_IRUGO) || !ops->show)
+			goto Eaccess;
+	}
+
+	/* No error? Great, allocate a buffer for the file, and store it
+	 * it in file->private_data for easy access.
+	 */
+	buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL);
+	if (buffer) {
+		memset(buffer,0,sizeof(struct sysfs_buffer));
+		buffer->ops = ops;
+		file->private_data = buffer;
+	} else
+		error = -ENOMEM;
+	goto Done;
+
+ Einval:
+	error = -EINVAL;
+	goto Done;
+ Eaccess:
+	error = -EACCES;
+ Done:
+	if (error && kobj)
+		kobject_put(kobj);
+	return error;
+}
+
+static int sysfs_open_file(struct inode * inode, struct file * filp)
+{
+	return check_perm(inode,filp);
+}
+
+static int sysfs_release(struct inode * inode, struct file * filp)
+{
+	struct kobject * kobj = filp->f_dentry->d_parent->d_fsdata;
+	struct sysfs_buffer * buffer = filp->private_data;
+
+	if (kobj) 
+		kobject_put(kobj);
+
+	if (buffer) {
+		if (buffer->page)
+			free_page((unsigned long)buffer->page);
+		kfree(buffer);
+	}
+	return 0;
+}
+
+static struct file_operations sysfs_file_operations = {
+	.read		= sysfs_read_file,
+	.write		= sysfs_write_file,
+	.llseek		= generic_file_llseek,
+	.open		= sysfs_open_file,
+	.release	= sysfs_release,
+};
+
+/**
+ *	sysfs_create_file - create an attribute file for an object.
+ *	@kobj:	object we're creating for. 
+ *	@attr:	atrribute descriptor.
+ */
+
+int sysfs_create_file(struct kobject * kobj, struct attribute * attr)
+{
+	struct dentry * dentry;
+	struct dentry * parent;
+	int error = 0;
+
+	if (!kobj || !attr)
+		return -EINVAL;
+
+	parent = kobj->dentry;
+
+	down(&parent->d_inode->i_sem);
+	dentry = sysfs_get_dentry(parent,attr->name);
+	if (!IS_ERR(dentry)) {
+		dentry->d_fsdata = (void *)attr;
+		error = sysfs_create(dentry,(attr->mode & S_IALLUGO) | S_IFREG,init_file);
+	} else
+		error = PTR_ERR(dentry);
+	up(&parent->d_inode->i_sem);
+	return error;
+}
+
+
+/**
+ * sysfs_update_file - update the modified timestamp on an object attribute.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ *
+ * Also call dnotify for the dentry, which lots of userspace programs
+ * use.
+ */
+int sysfs_update_file(struct kobject * kobj, struct attribute * attr)
+{
+	struct dentry * dir = kobj->dentry;
+	struct dentry * victim;
+	int res = -ENOENT;
+
+	down(&dir->d_inode->i_sem);
+	victim = sysfs_get_dentry(dir, attr->name);
+	if (!IS_ERR(victim)) {
+		/* make sure dentry is really there */
+		if (victim->d_inode && 
+		    (victim->d_parent->d_inode == dir->d_inode)) {
+			victim->d_inode->i_mtime = CURRENT_TIME;
+			dnotify_parent(victim, DN_MODIFY);
+
+			/**
+			 * Drop reference from initial sysfs_get_dentry().
+			 */
+			dput(victim);
+			res = 0;
+		}
+		
+		/**
+		 * Drop the reference acquired from sysfs_get_dentry() above.
+		 */
+		dput(victim);
+	}
+	up(&dir->d_inode->i_sem);
+
+	return res;
+}
+
+
+/**
+ *	sysfs_remove_file - remove an object attribute.
+ *	@kobj:	object we're acting for.
+ *	@attr:	attribute descriptor.
+ *
+ *	Hash the attribute name and kill the victim.
+ */
+
+void sysfs_remove_file(struct kobject * kobj, struct attribute * attr)
+{
+	sysfs_hash_and_remove(kobj->dentry,attr->name);
+}
+
+
+EXPORT_SYMBOL(sysfs_create_file);
+EXPORT_SYMBOL(sysfs_remove_file);
+EXPORT_SYMBOL(sysfs_update_file);
+
diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c
--- a/fs/sysfs/inode.c	Tue Mar  4 19:30:13 2003
+++ b/fs/sysfs/inode.c	Tue Mar  4 19:30:13 2003
@@ -1,63 +1,32 @@
 /*
- * sysfs.c - The filesystem to export kernel objects.
+ * inode.c - basic inode and dentry operations.
  *
- * Copyright (c) 2001, 2002 Patrick Mochel
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * This is a simple, ramfs-based filesystem, designed to export kernel 
- * objects, their attributes, and the linkgaes between each other.
+ * sysfs is Copyright (c) 2001-3 Patrick Mochel
  *
  * Please see Documentation/filesystems/sysfs.txt for more information.
  */
 
 #undef DEBUG 
 
-#include <linux/list.h>
-#include <linux/init.h>
 #include <linux/pagemap.h>
-#include <linux/stat.h>
-#include <linux/fs.h>
-#include <linux/dcache.h>
 #include <linux/namei.h>
-#include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/backing-dev.h>
-#include <linux/kobject.h>
-#include <linux/mount.h>
-#include <linux/dnotify.h>
-#include <asm/uaccess.h>
-
-/* Random magic number */
-#define SYSFS_MAGIC 0x62656572
-
-static struct super_operations sysfs_ops;
-static struct file_operations sysfs_file_operations;
-static struct address_space_operations sysfs_aops;
+extern struct super_block * sysfs_sb;
 
-static struct vfsmount *sysfs_mount;
+static struct address_space_operations sysfs_aops = {
+	.readpage	= simple_readpage,
+	.prepare_write	= simple_prepare_write,
+	.commit_write	= simple_commit_write
+};
 
 static struct backing_dev_info sysfs_backing_dev_info = {
 	.ra_pages	= 0,	/* No readahead */
 	.memory_backed	= 1,	/* Does not contribute to dirty memory */
 };
 
-static struct inode *sysfs_get_inode(struct super_block *sb, int mode, int dev)
+struct inode * sysfs_new_inode(mode_t mode)
 {
-	struct inode *inode = new_inode(sb);
-
+	struct inode * inode = new_inode(sysfs_sb);
 	if (inode) {
 		inode->i_mode = mode;
 		inode->i_uid = current->fsuid;
@@ -68,472 +37,43 @@
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 		inode->i_mapping->a_ops = &sysfs_aops;
 		inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
-		switch (mode & S_IFMT) {
-		default:
-			init_special_inode(inode, mode, dev);
-			break;
-		case S_IFREG:
-			inode->i_size = PAGE_SIZE;
-			inode->i_fop = &sysfs_file_operations;
-			break;
-		case S_IFDIR:
-			inode->i_op = &simple_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
-
-			/* directory inodes start off with i_nlink == 2 (for "." entry) */
-			inode->i_nlink++;
-			break;
-		case S_IFLNK:
-			inode->i_op = &page_symlink_inode_operations;
-			break;
-		}
 	}
 	return inode;
 }
 
-static int sysfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
 {
-	struct inode *inode;
 	int error = 0;
-
-	if (!dentry->d_inode) {
-		inode = sysfs_get_inode(dir->i_sb, mode, dev);
-		if (inode) {
-			d_instantiate(dentry, inode);
-			dget(dentry);
-		} else
-			error = -ENOSPC;
-	} else
-		error = -EEXIST;
-	return error;
-}
-
-static int sysfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
-	int res;
-	mode = (mode & (S_IRWXUGO|S_ISVTX)) | S_IFDIR;
- 	res = sysfs_mknod(dir, dentry, mode, 0);
- 	if (!res)
- 		dir->i_nlink++;
-	return res;
-}
-
-static int sysfs_create(struct inode *dir, struct dentry *dentry, int mode)
-{
-	int res;
-	mode = (mode & S_IALLUGO) | S_IFREG;
- 	res = sysfs_mknod(dir, dentry, mode, 0);
-	return res;
-}
-
-static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
-{
-	struct inode *inode;
-	int error = -ENOSPC;
-
-	if (dentry->d_inode)
-		return -EEXIST;
-
-	inode = sysfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
-	if (inode) {
-		int l = strlen(symname)+1;
-		error = page_symlink(inode, symname, l);
-		if (!error) {
-			d_instantiate(dentry, inode);
-			dget(dentry);
+	struct inode * inode = NULL;
+	if (dentry) {
+		if (!dentry->d_inode) {
+			if ((inode = sysfs_new_inode(mode)))
+				goto Proceed;
+			else 
+				error = -ENOMEM;
 		} else
-			iput(inode);
-	}
-	return error;
-}
-
-#define to_subsys(k) container_of(k,struct subsystem,kset.kobj)
-#define to_sattr(a) container_of(a,struct subsys_attribute,attr)
-
-/**
- * Subsystem file operations.
- * These operations allow subsystems to have files that can be 
- * read/written. 
- */
-static ssize_t 
-subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page)
-{
-	struct subsystem * s = to_subsys(kobj);
-	struct subsys_attribute * sattr = to_sattr(attr);
-	ssize_t ret = 0;
-
-	if (sattr->show)
-		ret = sattr->show(s,page);
-	return ret;
-}
-
-static ssize_t 
-subsys_attr_store(struct kobject * kobj, struct attribute * attr, 
-		  const char * page, size_t count)
-{
-	struct subsystem * s = to_subsys(kobj);
-	struct subsys_attribute * sattr = to_sattr(attr);
-	ssize_t ret = 0;
-
-	if (sattr->store)
-		ret = sattr->store(s,page,count);
-	return ret;
-}
-
-static struct sysfs_ops subsys_sysfs_ops = {
-	.show	= subsys_attr_show,
-	.store	= subsys_attr_store,
-};
-
-
-struct sysfs_buffer {
-	size_t			count;
-	loff_t			pos;
-	char			* page;
-	struct sysfs_ops	* ops;
-};
-
-
-/**
- *	fill_read_buffer - allocate and fill buffer from object.
- *	@file:		file pointer.
- *	@buffer:	data buffer for file.
- *
- *	Allocate @buffer->page, if it hasn't been already, then call the
- *	kobject's show() method to fill the buffer with this attribute's 
- *	data. 
- *	This is called only once, on the file's first read. 
- */
-static int fill_read_buffer(struct file * file, struct sysfs_buffer * buffer)
-{
-	struct attribute * attr = file->f_dentry->d_fsdata;
-	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
-	struct sysfs_ops * ops = buffer->ops;
-	int ret = 0;
-	ssize_t count;
-
-	if (!buffer->page)
-		buffer->page = (char *) __get_free_page(GFP_KERNEL);
-	if (!buffer->page)
-		return -ENOMEM;
-
-	count = ops->show(kobj,attr,buffer->page);
-	if (count >= 0)
-		buffer->count = count;
-	else
-		ret = count;
-	return ret;
-}
-
-
-/**
- *	flush_read_buffer - push buffer to userspace.
- *	@buffer:	data buffer for file.
- *	@userbuf:	user-passed buffer.
- *	@count:		number of bytes requested.
- *	@ppos:		file position.
- *
- *	Copy the buffer we filled in fill_read_buffer() to userspace.
- *	This is done at the reader's leisure, copying and advancing 
- *	the amount they specify each time.
- *	This may be called continuously until the buffer is empty.
- */
-static int flush_read_buffer(struct sysfs_buffer * buffer, char * buf, 
-			     size_t count, loff_t * ppos)
-{
-	int error;
-
-	if (count > (buffer->count - *ppos))
-		count = buffer->count - *ppos;
+			error = -EEXIST;
+	} else 
+		error = -ENOENT;
+	goto Done;
 
-	error = copy_to_user(buf,buffer->page + *ppos,count);
+ Proceed:
+	if (init)
+		error = init(inode);
 	if (!error)
-		*ppos += count;
-	return error ? -EFAULT : count;
-}
-
-/**
- *	sysfs_read_file - read an attribute. 
- *	@file:	file pointer.
- *	@buf:	buffer to fill.
- *	@count:	number of bytes to read.
- *	@ppos:	starting offset in file.
- *
- *	Userspace wants to read an attribute file. The attribute descriptor
- *	is in the file's ->d_fsdata. The target object is in the directory's
- *	->d_fsdata.
- *
- *	We call fill_read_buffer() to allocate and fill the buffer from the
- *	object's show() method exactly once (if the read is happening from
- *	the beginning of the file). That should fill the entire buffer with
- *	all the data the object has to offer for that attribute.
- *	We then call flush_read_buffer() to copy the buffer to userspace
- *	in the increments specified.
- */
-
-static ssize_t
-sysfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos)
-{
-	struct sysfs_buffer * buffer = file->private_data;
-	ssize_t retval = 0;
-
-	if (!*ppos) {
-		if ((retval = fill_read_buffer(file,buffer)))
-			return retval;
-	}
-	pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
-		 __FUNCTION__,count,*ppos,buffer->page);
-	return flush_read_buffer(buffer,buf,count,ppos);
-}
-
-
-/**
- *	fill_write_buffer - copy buffer from userspace.
- *	@buffer:	data buffer for file.
- *	@userbuf:	data from user.
- *	@count:		number of bytes in @userbuf.
- *
- *	Allocate @buffer->page if it hasn't been already, then
- *	copy the user-supplied buffer into it.
- */
-
-static int 
-fill_write_buffer(struct sysfs_buffer * buffer, const char * buf, size_t count)
-{
-	int error;
-
-	if (!buffer->page)
-		buffer->page = (char *)__get_free_page(GFP_KERNEL);
-	if (!buffer->page)
-		return -ENOMEM;
-
-	if (count >= PAGE_SIZE)
-		count = PAGE_SIZE - 1;
-	error = copy_from_user(buffer->page,buf,count);
-	return error ? -EFAULT : count;
-}
-
-
-/**
- *	flush_write_buffer - push buffer to kobject.
- *	@file:		file pointer.
- *	@buffer:	data buffer for file.
- *
- *	Get the correct pointers for the kobject and the attribute we're
- *	dealing with, then call the store() method for the attribute, 
- *	passing the buffer that we acquired in fill_write_buffer().
- */
-
-static int 
-flush_write_buffer(struct file * file, struct sysfs_buffer * buffer, size_t count)
-{
-	struct attribute * attr = file->f_dentry->d_fsdata;
-	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
-	struct sysfs_ops * ops = buffer->ops;
-
-	return ops->store(kobj,attr,buffer->page,count);
-}
-
-
-/**
- *	sysfs_write_file - write an attribute.
- *	@file:	file pointer
- *	@buf:	data to write
- *	@count:	number of bytes
- *	@ppos:	starting offset
- *
- *	Similar to sysfs_read_file(), though working in the opposite direction.
- *	We allocate and fill the data from the user in fill_write_buffer(),
- *	then push it to the kobject in flush_write_buffer().
- *	There is no easy way for us to know if userspace is only doing a partial
- *	write, so we don't support them. We expect the entire buffer to come
- *	on the first write. 
- *	Hint: if you're writing a value, first read the file, modify only the
- *	the value you're changing, then write entire buffer back. 
- */
-
-static ssize_t
-sysfs_write_file(struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-	struct sysfs_buffer * buffer = file->private_data;
-
-	count = fill_write_buffer(buffer,buf,count);
-	if (count > 0)
-		count = flush_write_buffer(file,buffer,count);
-	if (count > 0)
-		*ppos += count;
-	return count;
-}
-
-static int check_perm(struct inode * inode, struct file * file)
-{
-	struct kobject * kobj = kobject_get(file->f_dentry->d_parent->d_fsdata);
-	struct attribute * attr = file->f_dentry->d_fsdata;
-	struct sysfs_buffer * buffer;
-	struct sysfs_ops * ops = NULL;
-	int error = 0;
-
-	if (!kobj || !attr)
-		goto Einval;
-
-	/* if the kobject has no ktype, then we assume that it is a subsystem
-	 * itself, and use ops for it.
-	 */
-	if (kobj->kset && kobj->kset->ktype)
-		ops = kobj->kset->ktype->sysfs_ops;
-	else if (kobj->ktype)
-		ops = kobj->ktype->sysfs_ops;
+		d_instantiate(dentry, inode);
 	else
-		ops = &subsys_sysfs_ops;
-
-	/* No sysfs operations, either from having no subsystem,
-	 * or the subsystem have no operations.
-	 */
-	if (!ops)
-		goto Eaccess;
-
-	/* File needs write support.
-	 * The inode's perms must say it's ok, 
-	 * and we must have a store method.
-	 */
-	if (file->f_mode & FMODE_WRITE) {
-
-		if (!(inode->i_mode & S_IWUGO) || !ops->store)
-			goto Eaccess;
-
-	}
-
-	/* File needs read support.
-	 * The inode's perms must say it's ok, and we there
-	 * must be a show method for it.
-	 */
-	if (file->f_mode & FMODE_READ) {
-		if (!(inode->i_mode & S_IRUGO) || !ops->show)
-			goto Eaccess;
-	}
-
-	/* No error? Great, allocate a buffer for the file, and store it
-	 * it in file->private_data for easy access.
-	 */
-	buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL);
-	if (buffer) {
-		memset(buffer,0,sizeof(struct sysfs_buffer));
-		buffer->ops = ops;
-		file->private_data = buffer;
-	} else
-		error = -ENOMEM;
-	goto Done;
-
- Einval:
-	error = -EINVAL;
-	goto Done;
- Eaccess:
-	error = -EACCES;
+		iput(inode);
  Done:
-	if (error && kobj)
-		kobject_put(kobj);
 	return error;
 }
 
-static int sysfs_open_file(struct inode * inode, struct file * filp)
-{
-	return check_perm(inode,filp);
-}
-
-static int sysfs_release(struct inode * inode, struct file * filp)
-{
-	struct kobject * kobj = filp->f_dentry->d_parent->d_fsdata;
-	struct sysfs_buffer * buffer = filp->private_data;
-
-	if (kobj) 
-		kobject_put(kobj);
-
-	if (buffer) {
-		if (buffer->page)
-			free_page((unsigned long)buffer->page);
-		kfree(buffer);
-	}
-	return 0;
-}
-
-static struct file_operations sysfs_file_operations = {
-	.read		= sysfs_read_file,
-	.write		= sysfs_write_file,
-	.llseek		= generic_file_llseek,
-	.open		= sysfs_open_file,
-	.release	= sysfs_release,
-};
-
-static struct address_space_operations sysfs_aops = {
-	.readpage	= simple_readpage,
-	.prepare_write	= simple_prepare_write,
-	.commit_write	= simple_commit_write
-};
-
-static struct super_operations sysfs_ops = {
-	.statfs		= simple_statfs,
-	.drop_inode	= generic_delete_inode,
-};
-
-static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *inode;
-	struct dentry *root;
-
-	sb->s_blocksize = PAGE_CACHE_SIZE;
-	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-	sb->s_magic = SYSFS_MAGIC;
-	sb->s_op = &sysfs_ops;
-	inode = sysfs_get_inode(sb, S_IFDIR | 0755, 0);
-
-	if (!inode) {
-		pr_debug("%s: could not get inode!\n",__FUNCTION__);
-		return -ENOMEM;
-	}
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		pr_debug("%s: could not get root dentry!\n",__FUNCTION__);
-		iput(inode);
-		return -ENOMEM;
-	}
-	sb->s_root = root;
-	return 0;
-}
-
-static struct super_block *sysfs_get_sb(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
-{
-	return get_sb_single(fs_type, flags, data, sysfs_fill_super);
-}
-
-static struct file_system_type sysfs_fs_type = {
-	.owner		= THIS_MODULE,
-	.name		= "sysfs",
-	.get_sb		= sysfs_get_sb,
-	.kill_sb	= kill_litter_super,
-};
-
-static int __init sysfs_init(void)
+int sysfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
 {
-	int err;
-
-	err = register_filesystem(&sysfs_fs_type);
-	if (!err) {
-		sysfs_mount = kern_mount(&sysfs_fs_type);
-		if (IS_ERR(sysfs_mount)) {
-			printk(KERN_ERR "sysfs: could not mount!\n");
-			err = PTR_ERR(sysfs_mount);
-			sysfs_mount = NULL;
-		}
-	}
-	return err;
+	return sysfs_create(dentry, mode, NULL);
 }
 
-core_initcall(sysfs_init);
-
-
-static struct dentry * get_dentry(struct dentry * parent, const char * name)
+struct dentry * sysfs_get_dentry(struct dentry * parent, const char * name)
 {
 	struct qstr qstr;
 
@@ -543,157 +83,12 @@
 	return lookup_hash(&qstr,parent);
 }
 
-
-/**
- *	sysfs_create_dir - create a directory for an object.
- *	@parent:	parent parent object.
- *	@kobj:		object we're creating directory for. 
- */
-
-int sysfs_create_dir(struct kobject * kobj)
-{
-	struct dentry * dentry = NULL;
-	struct dentry * parent;
-	int error = 0;
-
-	if (!kobj)
-		return -EINVAL;
-
-	if (kobj->parent)
-		parent = kobj->parent->dentry;
-	else if (sysfs_mount && sysfs_mount->mnt_sb)
-		parent = sysfs_mount->mnt_sb->s_root;
-	else
-		return -EFAULT;
-
-	down(&parent->d_inode->i_sem);
-	dentry = get_dentry(parent,kobj->name);
-	if (!IS_ERR(dentry)) {
-		dentry->d_fsdata = (void *)kobj;
-		kobj->dentry = dentry;
-		error = sysfs_mkdir(parent->d_inode,dentry,
-				    (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO));
-	} else
-		error = PTR_ERR(dentry);
-	up(&parent->d_inode->i_sem);
-
-	return error;
-}
-
-
-/**
- *	sysfs_create_file - create an attribute file for an object.
- *	@kobj:	object we're creating for. 
- *	@attr:	atrribute descriptor.
- */
-
-int sysfs_create_file(struct kobject * kobj, struct attribute * attr)
-{
-	struct dentry * dentry;
-	struct dentry * parent;
-	int error = 0;
-
-	if (!kobj || !attr)
-		return -EINVAL;
-
-	parent = kobj->dentry;
-
-	down(&parent->d_inode->i_sem);
-	dentry = get_dentry(parent,attr->name);
-	if (!IS_ERR(dentry)) {
-		dentry->d_fsdata = (void *)attr;
-		error = sysfs_create(parent->d_inode,dentry,attr->mode);
-	} else
-		error = PTR_ERR(dentry);
-	up(&parent->d_inode->i_sem);
-	return error;
-}
-
-
-static int object_depth(struct kobject * kobj)
-{
-	struct kobject * p = kobj;
-	int depth = 0;
-	do { depth++; } while ((p = p->parent));
-	return depth;
-}
-
-static int object_path_length(struct kobject * kobj)
-{
-	struct kobject * p = kobj;
-	int length = 1;
-	do {
-		length += strlen(p->name) + 1;
-		p = p->parent;
-	} while (p);
-	return length;
-}
-
-static void fill_object_path(struct kobject * kobj, char * buffer, int length)
-{
-	struct kobject * p;
-
-	--length;
-	for (p = kobj; p; p = p->parent) {
-		int cur = strlen(p->name);
-
-		/* back up enough to print this bus id with '/' */
-		length -= cur;
-		strncpy(buffer + length,p->name,cur);
-		*(buffer + --length) = '/';
-	}
-}
-
-/**
- *	sysfs_create_link - create symlink between two objects.
- *	@kobj:	object whose directory we're creating the link in.
- *	@target:	object we're pointing to.
- *	@name:		name of the symlink.
- */
-int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name)
-{
-	struct dentry * dentry = kobj->dentry;
-	struct dentry * d;
-	int error = 0;
-	int size;
-	int depth;
-	char * path;
-	char * s;
-
-	depth = object_depth(kobj);
-	size = object_path_length(target) + depth * 3 - 1;
-	if (size > PATH_MAX)
-		return -ENAMETOOLONG;
-	pr_debug("%s: depth = %d, size = %d\n",__FUNCTION__,depth,size);
-
-	path = kmalloc(size,GFP_KERNEL);
-	if (!path)
-		return -ENOMEM;
-	memset(path,0,size);
-
-	for (s = path; depth--; s += 3)
-		strcpy(s,"../");
-
-	fill_object_path(target,path,size);
-	pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
-
-	down(&dentry->d_inode->i_sem);
-	d = get_dentry(dentry,name);
-	if (!IS_ERR(d))
-		error = sysfs_symlink(dentry->d_inode,d,path);
-	else
-		error = PTR_ERR(d);
-	up(&dentry->d_inode->i_sem);
-	kfree(path);
-	return error;
-}
-
-static void hash_and_remove(struct dentry * dir, const char * name)
+void sysfs_hash_and_remove(struct dentry * dir, const char * name)
 {
 	struct dentry * victim;
 
 	down(&dir->d_inode->i_sem);
-	victim = get_dentry(dir,name);
+	victim = sysfs_get_dentry(dir,name);
 	if (!IS_ERR(victim)) {
 		/* make sure dentry is really there */
 		if (victim->d_inode && 
@@ -703,161 +98,18 @@
 
 			pr_debug("sysfs: Removing %s (%d)\n", victim->d_name.name,
 				 atomic_read(&victim->d_count));
-			/**
-			 * Drop reference from initial get_dentry().
-			 */
-			dput(victim);
-		}
-		
-		/**
-		 * Drop the reference acquired from get_dentry() above.
-		 */
-		dput(victim);
-	}
-	up(&dir->d_inode->i_sem);
-}
-
-/**
- * sysfs_update_file - update the modified timestamp on an object attribute.
- * @kobj: object we're acting for.
- * @attr: attribute descriptor.
- *
- * Also call dnotify for the dentry, which lots of userspace programs
- * use.
- */
-int sysfs_update_file(struct kobject * kobj, struct attribute * attr)
-{
-	struct dentry * dir = kobj->dentry;
-	struct dentry * victim;
-	int res = -ENOENT;
-
-	down(&dir->d_inode->i_sem);
-	victim = get_dentry(dir, attr->name);
-	if (!IS_ERR(victim)) {
-		/* make sure dentry is really there */
-		if (victim->d_inode && 
-		    (victim->d_parent->d_inode == dir->d_inode)) {
-			victim->d_inode->i_mtime = CURRENT_TIME;
-			dnotify_parent(victim, DN_MODIFY);
-
-			/**
-			 * Drop reference from initial get_dentry().
+			/*
+			 * Drop reference from initial sysfs_get_dentry().
 			 */
 			dput(victim);
-			res = 0;
 		}
 		
 		/**
-		 * Drop the reference acquired from get_dentry() above.
+		 * Drop the reference acquired from sysfs_get_dentry() above.
 		 */
 		dput(victim);
 	}
 	up(&dir->d_inode->i_sem);
-
-	return res;
 }
 
 
-/**
- *	sysfs_remove_file - remove an object attribute.
- *	@kobj:	object we're acting for.
- *	@attr:	attribute descriptor.
- *
- *	Hash the attribute name and kill the victim.
- */
-
-void sysfs_remove_file(struct kobject * kobj, struct attribute * attr)
-{
-	hash_and_remove(kobj->dentry,attr->name);
-}
-
-
-/**
- *	sysfs_remove_link - remove symlink in object's directory.
- *	@kobj:	object we're acting for.
- *	@name:	name of the symlink to remove.
- */
-
-void sysfs_remove_link(struct kobject * kobj, char * name)
-{
-	hash_and_remove(kobj->dentry,name);
-}
-
-
-/**
- *	sysfs_remove_dir - remove an object's directory.
- *	@kobj:	object. 
- *
- *	The only thing special about this is that we remove any files in 
- *	the directory before we remove the directory, and we've inlined
- *	what used to be sysfs_rmdir() below, instead of calling separately.
- */
-
-void sysfs_remove_dir(struct kobject * kobj)
-{
-	struct list_head * node, * next;
-	struct dentry * dentry = dget(kobj->dentry);
-	struct dentry * parent;
-
-	if (!dentry)
-		return;
-
-	pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
-	parent = dget(dentry->d_parent);
-	down(&parent->d_inode->i_sem);
-	down(&dentry->d_inode->i_sem);
-
-	list_for_each_safe(node,next,&dentry->d_subdirs) {
-		struct dentry * d = dget(list_entry(node,struct dentry,d_child));
-		/** 
-		 * Make sure dentry is still there 
-		 */
-		pr_debug(" o %s: ",d->d_name.name);
-		if (d->d_inode) {
-
-			pr_debug("removing");
-			/**
-			 * Unlink and unhash.
-			 */
-			simple_unlink(dentry->d_inode,d);
-			d_delete(d);
-
-			/**
-			 * Drop reference from initial get_dentry().
-			 */
-			dput(d);
-		}
-		pr_debug(" done (%d)\n",atomic_read(&d->d_count));
-		/**
-		 * drop reference from dget() above.
-		 */
-		dput(d);
-	}
-
-	up(&dentry->d_inode->i_sem);
-	d_invalidate(dentry);
-	simple_rmdir(parent->d_inode,dentry);
-	d_delete(dentry);
-
-	pr_debug(" o %s removing done (%d)\n",dentry->d_name.name,
-		 atomic_read(&dentry->d_count));
-	/**
-	 * Drop reference from initial get_dentry().
-	 */
-	dput(dentry);
-
-	/**
-	 * Drop reference from dget() on entrance.
-	 */
-	dput(dentry);
-	up(&parent->d_inode->i_sem);
-	dput(parent);
-}
-
-EXPORT_SYMBOL(sysfs_create_file);
-EXPORT_SYMBOL(sysfs_update_file);
-EXPORT_SYMBOL(sysfs_remove_file);
-EXPORT_SYMBOL(sysfs_create_link);
-EXPORT_SYMBOL(sysfs_remove_link);
-EXPORT_SYMBOL(sysfs_create_dir);
-EXPORT_SYMBOL(sysfs_remove_dir);
diff -Nru a/fs/sysfs/mount.c b/fs/sysfs/mount.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/sysfs/mount.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,83 @@
+/*
+ * mount.c - operations for initializing and mounting sysfs.
+ */
+
+#define DEBUG 
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+
+#include "sysfs.h"
+
+/* Random magic number */
+#define SYSFS_MAGIC 0x62656572
+
+struct vfsmount *sysfs_mount;
+struct super_block * sysfs_sb = NULL;
+
+static struct super_operations sysfs_ops = {
+	.statfs		= simple_statfs,
+	.drop_inode	= generic_delete_inode,
+};
+
+static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct inode *inode;
+	struct dentry *root;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = SYSFS_MAGIC;
+	sb->s_op = &sysfs_ops;
+	sysfs_sb = sb;
+
+	inode = sysfs_new_inode(S_IFDIR | S_IRUGO | S_IWUSR);
+	if (inode) {
+		inode->i_op = &simple_dir_inode_operations;
+		inode->i_fop = &simple_dir_operations;
+		/* directory inodes start off with i_nlink == 2 (for "." entry) */
+		inode->i_nlink++;	
+	} else {
+		pr_debug("sysfs: could not get root inode\n");
+		return -ENOMEM;
+	}
+
+	root = d_alloc_root(inode);
+	if (!root) {
+		pr_debug("%s: could not get root dentry!\n",__FUNCTION__);
+		iput(inode);
+		return -ENOMEM;
+	}
+	sb->s_root = root;
+	return 0;
+}
+
+static struct super_block *sysfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, sysfs_fill_super);
+}
+
+static struct file_system_type sysfs_fs_type = {
+	.name		= "sysfs",
+	.get_sb		= sysfs_get_sb,
+	.kill_sb	= kill_litter_super,
+};
+
+int __init sysfs_init(void)
+{
+	int err;
+
+	err = register_filesystem(&sysfs_fs_type);
+	if (!err) {
+		sysfs_mount = kern_mount(&sysfs_fs_type);
+		if (IS_ERR(sysfs_mount)) {
+			printk(KERN_ERR "sysfs: could not mount!\n");
+			err = PTR_ERR(sysfs_mount);
+			sysfs_mount = NULL;
+		}
+	}
+	return err;
+}
diff -Nru a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/sysfs/symlink.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,125 @@
+/*
+ * symlink.c - operations for sysfs symlinks.
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+
+#include "sysfs.h"
+
+
+static int init_symlink(struct inode * inode)
+{
+	inode->i_op = &page_symlink_inode_operations;
+	return 0;
+}
+
+static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
+{
+	int error;
+
+	error = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
+	if (!error) {
+		int l = strlen(symname)+1;
+		error = page_symlink(dentry->d_inode, symname, l);
+		if (error)
+			iput(dentry->d_inode);
+	}
+	return error;
+}
+
+static int object_depth(struct kobject * kobj)
+{
+	struct kobject * p = kobj;
+	int depth = 0;
+	do { depth++; } while ((p = p->parent));
+	return depth;
+}
+
+static int object_path_length(struct kobject * kobj)
+{
+	struct kobject * p = kobj;
+	int length = 1;
+	do {
+		length += strlen(p->name) + 1;
+		p = p->parent;
+	} while (p);
+	return length;
+}
+
+static void fill_object_path(struct kobject * kobj, char * buffer, int length)
+{
+	struct kobject * p;
+
+	--length;
+	for (p = kobj; p; p = p->parent) {
+		int cur = strlen(p->name);
+
+		/* back up enough to print this bus id with '/' */
+		length -= cur;
+		strncpy(buffer + length,p->name,cur);
+		*(buffer + --length) = '/';
+	}
+}
+
+/**
+ *	sysfs_create_link - create symlink between two objects.
+ *	@kobj:	object whose directory we're creating the link in.
+ *	@target:	object we're pointing to.
+ *	@name:		name of the symlink.
+ */
+int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name)
+{
+	struct dentry * dentry = kobj->dentry;
+	struct dentry * d;
+	int error = 0;
+	int size;
+	int depth;
+	char * path;
+	char * s;
+
+	depth = object_depth(kobj);
+	size = object_path_length(target) + depth * 3 - 1;
+	if (size > PATH_MAX)
+		return -ENAMETOOLONG;
+	pr_debug("%s: depth = %d, size = %d\n",__FUNCTION__,depth,size);
+
+	path = kmalloc(size,GFP_KERNEL);
+	if (!path)
+		return -ENOMEM;
+	memset(path,0,size);
+
+	for (s = path; depth--; s += 3)
+		strcpy(s,"../");
+
+	fill_object_path(target,path,size);
+	pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
+
+	down(&dentry->d_inode->i_sem);
+	d = sysfs_get_dentry(dentry,name);
+	if (!IS_ERR(d))
+		error = sysfs_symlink(dentry->d_inode,d,path);
+	else
+		error = PTR_ERR(d);
+	up(&dentry->d_inode->i_sem);
+	kfree(path);
+	return error;
+}
+
+
+/**
+ *	sysfs_remove_link - remove symlink in object's directory.
+ *	@kobj:	object we're acting for.
+ *	@name:	name of the symlink to remove.
+ */
+
+void sysfs_remove_link(struct kobject * kobj, char * name)
+{
+	sysfs_hash_and_remove(kobj->dentry,name);
+}
+
+
+EXPORT_SYMBOL(sysfs_create_link);
+EXPORT_SYMBOL(sysfs_remove_link);
+
diff -Nru a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/sysfs/sysfs.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,10 @@
+
+extern struct vfsmount * sysfs_mount;
+
+extern struct inode * sysfs_new_inode(mode_t mode);
+extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
+
+extern struct dentry * sysfs_get_dentry(struct dentry *, char *);
+
+extern void sysfs_hash_and_remove(struct dentry * dir, const char * name);
+
diff -Nru a/fs/udf/dir.c b/fs/udf/dir.c
--- a/fs/udf/dir.c	Tue Mar  4 19:30:05 2003
+++ b/fs/udf/dir.c	Tue Mar  4 19:30:05 2003
@@ -19,7 +19,7 @@
  *
  * HISTORY
  *
- *  10/05/98 dgb  Split directory operations into it's own file
+ *  10/05/98 dgb  Split directory operations into its own file
  *                Implemented directory reads via do_udf_readdir
  *  10/06/98      Made directory operations work!
  *  11/17/98      Rewrote directory to support ICBTAG_FLAG_AD_LONG
diff -Nru a/fs/ufs/util.h b/fs/ufs/util.h
--- a/fs/ufs/util.h	Tue Mar  4 19:30:09 2003
+++ b/fs/ufs/util.h	Tue Mar  4 19:30:09 2003
@@ -25,7 +25,7 @@
 
 
 /*
- * macros used for accesing structures
+ * macros used for accessing structures
  */
 static inline s32
 ufs_get_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1,
diff -Nru a/fs/xattr.c b/fs/xattr.c
--- a/fs/xattr.c	Tue Mar  4 19:30:08 2003
+++ b/fs/xattr.c	Tue Mar  4 19:30:08 2003
@@ -160,7 +160,7 @@
 		if (error)
 			goto out;
 		down(&d->d_inode->i_sem);
-		error = d->d_inode->i_op->getxattr(d, kname, kvalue, size, 0);
+		error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
 		up(&d->d_inode->i_sem);
 	}
 
@@ -233,7 +233,7 @@
 		if (error)
 			goto out;
 		down(&d->d_inode->i_sem);
-		error = d->d_inode->i_op->listxattr(d, klist, size, 0);
+		error = d->d_inode->i_op->listxattr(d, klist, size);
 		up(&d->d_inode->i_sem);
 	}
 
@@ -308,7 +308,7 @@
 		if (error)
 			goto out;
 		down(&d->d_inode->i_sem);
-		error = d->d_inode->i_op->removexattr(d, kname, 0);
+		error = d->d_inode->i_op->removexattr(d, kname);
 		up(&d->d_inode->i_sem);
 	}
 out:
diff -Nru a/fs/xfs/linux/xfs_globals.c b/fs/xfs/linux/xfs_globals.c
--- a/fs/xfs/linux/xfs_globals.c	Tue Mar  4 19:30:10 2003
+++ b/fs/xfs/linux/xfs_globals.c	Tue Mar  4 19:30:10 2003
@@ -37,7 +37,16 @@
 
 #include <xfs.h>
 
+/*
+ * System memory size - used to scale certain data structures in XFS.
+ */
 unsigned long	xfs_physmem;
+
+/*
+ * Tunable XFS parameters.  xfs_params is required even when CONFIG_SYSCTL=n,
+ * other XFS code uses these values.
+ */
+xfs_param_t xfs_params = { 0, 1, 0, 0, 0 };
 
 /*
  * Used to serialize atomicIncWithWrap.
diff -Nru a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c
--- a/fs/xfs/linux/xfs_iops.c	Tue Mar  4 19:30:05 2003
+++ b/fs/xfs/linux/xfs_iops.c	Tue Mar  4 19:30:05 2003
@@ -523,7 +523,7 @@
  */
 
 #define SYSTEM_NAME	"system."	/* VFS shared names/values */
-#define ROOT_NAME	"xfsroot."	/* XFS ondisk names/values */
+#define ROOT_NAME	"trusted."	/* root's own names/values */
 #define USER_NAME	"user."		/* user's own names/values */
 STATIC xattr_namespace_t xfs_namespace_array[] = {
 	{ .name= SYSTEM_NAME,	.namelen= sizeof(SYSTEM_NAME)-1,.exists= NULL },
@@ -590,7 +590,7 @@
 		error = -EINVAL;
 		if (flags & XATTR_CREATE)
 			 return error;
-		error = -ENOATTR;
+		error = -EOPNOTSUPP;
 		p += xfs_namespaces[SYSTEM_NAMES].namelen;
 		if (strcmp(p, POSIXACL_ACCESS) == 0) {
 			error = xfs_acl_vset(vp, (void *) data, size,
@@ -632,7 +632,7 @@
 		VOP_ATTR_SET(vp, p, (void *) data, size, xflags, NULL, error);
 		return -error;
 	}
-	return -ENOATTR;
+	return -EOPNOTSUPP;
 }
 
 STATIC ssize_t
@@ -640,8 +640,7 @@
 	struct dentry	*dentry,
 	const char	*name,
 	void		*data,
-	size_t		size,
-	int		flags)
+	size_t		size)
 {
 	ssize_t		error;
 	int		xflags = 0;
@@ -651,7 +650,7 @@
 
 	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
 			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
-		error = -ENOATTR;
+		error = -EOPNOTSUPP;
 		p += xfs_namespaces[SYSTEM_NAMES].namelen;
 		if (strcmp(p, POSIXACL_ACCESS) == 0) {
 			error = xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
@@ -690,7 +689,7 @@
 			error = -size;
 		return -error;
 	}
-	return -ENOATTR;
+	return -EOPNOTSUPP;
 }
 
 
@@ -698,8 +697,7 @@
 linvfs_listxattr(
 	struct dentry		*dentry,
 	char			*data,
-	size_t			size,
-	int			flags)
+	size_t			size)
 {
 	ssize_t			error;
 	int			result = 0;
@@ -743,8 +741,7 @@
 STATIC int
 linvfs_removexattr(
 	struct dentry	*dentry,
-	const char	*name,
-	int		flags)
+	const char	*name)
 {
 	int		error;
 	int		xflags = 0;
@@ -754,7 +751,7 @@
 
 	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
 			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
-		error = -ENOATTR;
+		error = -EOPNOTSUPP;
 		p += xfs_namespaces[SYSTEM_NAMES].namelen;
 		if (strcmp(p, POSIXACL_ACCESS) == 0)
 			error = xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
@@ -782,7 +779,7 @@
 		VOP_ATTR_REMOVE(vp, p, xflags, NULL, error);
 		return -error;
 	}
-	return -ENOATTR;
+	return -EOPNOTSUPP;
 }
 
 
diff -Nru a/fs/xfs/linux/xfs_sysctl.c b/fs/xfs/linux/xfs_sysctl.c
--- a/fs/xfs/linux/xfs_sysctl.c	Tue Mar  4 19:30:14 2003
+++ b/fs/xfs/linux/xfs_sysctl.c	Tue Mar  4 19:30:14 2003
@@ -34,16 +34,9 @@
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 
-/*
- * Tunable XFS parameters
- */
-
-extern struct xfsstats xfsstats;
 
 STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0, 0 };
 STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 1, 127 };
-
-xfs_param_t xfs_params = { 0, 1, 0, 0, 0 };
 
 static struct ctl_table_header *xfs_table_header;
 
diff -Nru a/fs/xfs/linux/xfs_sysctl.h b/fs/xfs/linux/xfs_sysctl.h
--- a/fs/xfs/linux/xfs_sysctl.h	Tue Mar  4 19:30:03 2003
+++ b/fs/xfs/linux/xfs_sysctl.h	Tue Mar  4 19:30:03 2003
@@ -64,8 +64,8 @@
 extern void xfs_sysctl_register(void);
 extern void xfs_sysctl_unregister(void);
 #else
-static __inline void xfs_sysctl_register(void) { };
-static __inline void xfs_sysctl_unregister(void) { };
-#endif
+# define xfs_sysctl_register()		do { } while (0)
+# define xfs_sysctl_unregister()	do { } while (0)
+#endif /* CONFIG_SYSCTL */
 
 #endif /* __XFS_SYSCTL_H__ */
diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
--- a/fs/xfs/pagebuf/page_buf.c	Tue Mar  4 19:30:04 2003
+++ b/fs/xfs/pagebuf/page_buf.c	Tue Mar  4 19:30:04 2003
@@ -57,6 +57,7 @@
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <linux/workqueue.h>
+#include <linux/suspend.h>
 
 #include <support/debug.h>
 #include <support/kmem.h>
@@ -155,37 +156,35 @@
  * Pagebuf hashing
  */
 
-/* This structure must be a power of 2 long for the hash to work */
+#define NBITS	8
+#define NHASH	(1<<NBITS)
+
 typedef struct {
 	struct list_head	pb_hash;
 	int			pb_count;
 	spinlock_t		pb_hash_lock;
 } pb_hash_t;
 
-static pb_hash_t	*pbhash;
-static unsigned int	pb_hash_mask;
-static unsigned int	pb_hash_shift;
-static unsigned int	pb_order;
+STATIC pb_hash_t	pbhash[NHASH];
 #define pb_hash(pb)	&pbhash[pb->pb_hash_index]
 
-/*
- * This hash is the same one as used on the Linux buffer cache,
- * see fs/buffer.c
- */
-
-#define _hashfn(dev,block)      \
-        ((((dev)<<(pb_hash_shift - 6)) ^ ((dev)<<(pb_hash_shift - 9))) ^ \
-         (((block)<<(pb_hash_shift - 6)) ^ ((block) >> 13) ^ \
-          ((block) << (pb_hash_shift - 12))))
-
-static inline int
+STATIC int
 _bhash(
 	dev_t		dev,
 	loff_t		base)
 {
+	int		bit, hval;
+
 	base >>= 9;
-	
-	return (_hashfn(dev, base) & pb_hash_mask);
+	/*
+	 * dev_t is 16 bits, loff_t is always 64 bits
+	 */
+	base ^= dev;
+	for (bit = hval = 0; base != 0 && bit < sizeof(base) * 8; bit += NBITS) {
+		hval ^= (int)base & (NHASH-1);
+		base >>= NBITS;
+	}
+	return hval;
 }
 
 /*
@@ -703,8 +702,7 @@
  *	are in memory.	The buffer may have unallocated holes, if
  *	some, but not all, of the blocks are in memory.	 Even where
  *	pages are present in the buffer, not all of every page may be
- *	valid.	The file system may use pagebuf_segment to visit the
- *	various segments of the buffer.
+ *	valid.
  */
 page_buf_t *
 pagebuf_find(				/* find buffer for block	*/
@@ -721,11 +719,10 @@
  *	pagebuf_get
  *
  *	pagebuf_get assembles a buffer covering the specified range.
- *	Some or all of the blocks in the range may be valid.  The file
- *	system may use pagebuf_segment to visit the various segments
- *	of the buffer.	Storage in memory for all portions of the
- *	buffer will be allocated, although backing storage may not be.
- *	If PBF_READ is set in flags, pagebuf_read
+ *	Some or all of the blocks in the range may be valid.  Storage
+ *	in memory for all portions of the buffer will be allocated,
+ *	although backing storage may not be.  If PBF_READ is set in
+ *	flags, pagebuf_iostart is called also.
  */
 page_buf_t *
 pagebuf_get(				/* allocate a buffer		*/
@@ -1200,8 +1197,10 @@
 		return status;
 	}
 
-	pb->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_DELWRI|PBF_READ_AHEAD);
-	pb->pb_flags |= flags & (PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_SYNC|PBF_READ_AHEAD);
+	pb->pb_flags &=
+		~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_DELWRI|PBF_READ_AHEAD);
+	pb->pb_flags |= flags &
+		(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_SYNC|PBF_READ_AHEAD);
 
 	BUG_ON(pb->pb_bn == PAGE_BUF_DADDR_NULL);
 
@@ -1298,7 +1297,6 @@
 pagebuf_iorequest(			/* start real I/O		*/
 	page_buf_t		*pb)	/* buffer to convey to device	*/
 {
-	int			status = 0;
 	int			i, map_i, total_nr_pages, nr_pages;
 	struct bio		*bio;
 	int			offset = pb->pb_offset;
@@ -1313,7 +1311,7 @@
 
 	if (pb->pb_flags & PBF_DELWRI) {
 		pagebuf_delwri_queue(pb, 1);
-		return status;
+		return 0;
 	}
 
 	/* Set the count to 1 initially, this will stop an I/O
@@ -1413,10 +1411,11 @@
 io_submitted:
 
 	if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
+		pb->pb_locked = 0;
 		pagebuf_iodone(pb, 0);
 	}
 
-	return status < 0 ? status : 0;
+	return 0;
 }
 
 /*
@@ -1459,7 +1458,7 @@
 caddr_t
 pagebuf_offset(
 	page_buf_t		*pb,
-	off_t			offset)
+	size_t			offset)
 {
 	struct page		*page;
 
@@ -1586,6 +1585,10 @@
 
 	INIT_LIST_HEAD(&tmp);
 	do {
+		/* swsusp */
+		if (current->flags & PF_FREEZE)
+			refrigerator(PF_IOTHREAD);
+
 		if (pbd_active == 1) {
 			del_timer(&pb_daemon_timer);
 			pb_daemon_timer.expires = jiffies +
@@ -1864,39 +1867,7 @@
 int __init
 pagebuf_init(void)
 {
-	int		order, mempages, i;
-	unsigned int	nr_hash;
-	extern int	xfs_physmem;
-
-	mempages = xfs_physmem >>= 16;
-	mempages *= sizeof(pb_hash_t);
-	for (order = 0; (1 << order) < mempages; order++)
-		;
-
-	if (order > 3) order = 3;	/* cap us at 2K buckets */
-
-	do {
-		unsigned long tmp;
-
-		nr_hash = (PAGE_SIZE << order) / sizeof(pb_hash_t);	
-		nr_hash = 1 << (ffs(nr_hash) - 1);
-		pb_hash_mask =  (nr_hash - 1);
-		tmp = nr_hash;
-		pb_hash_shift = 0;
-		while((tmp >>= 1UL) != 0UL)
-			pb_hash_shift++;
-
-		pbhash = (pb_hash_t *)
-			__get_free_pages(GFP_KERNEL, order);
-		pb_order = order;
-	} while (pbhash == NULL && --order > 0);
-	printk("pagebuf cache hash table entries: %d (order: %d, %ld bytes)\n",
-		nr_hash, order, (PAGE_SIZE << order));
-
-	for(i = 0; i < nr_hash; i++) {
-		spin_lock_init(&pbhash[i].pb_hash_lock);
-		INIT_LIST_HEAD(&pbhash[i].pb_hash);
-	} 
+	int			i;
 
 	pagebuf_table_header = register_sysctl_table(pagebuf_root_table, 1);
 
@@ -1914,6 +1885,11 @@
 		return -ENOMEM;
 	}
 
+	for (i = 0; i < NHASH; i++) {
+		spin_lock_init(&pbhash[i].pb_hash_lock);
+		INIT_LIST_HEAD(&pbhash[i].pb_hash);
+	}
+
 #ifdef PAGEBUF_TRACE
 	pb_trace.buf = (pagebuf_trace_t *)kmalloc(
 			PB_TRACE_BUFSIZE * sizeof(pagebuf_trace_t), GFP_KERNEL);
@@ -1940,7 +1916,6 @@
 
 	kmem_cache_destroy(pagebuf_cache);
 	kmem_shake_deregister(pagebuf_shaker);
-	free_pages((unsigned long)pbhash, pb_order);
 
 	unregister_sysctl_table(pagebuf_table_header);
 #ifdef	CONFIG_PROC_FS
diff -Nru a/fs/xfs/pagebuf/page_buf.h b/fs/xfs/pagebuf/page_buf.h
--- a/fs/xfs/pagebuf/page_buf.h	Tue Mar  4 19:30:10 2003
+++ b/fs/xfs/pagebuf/page_buf.h	Tue Mar  4 19:30:10 2003
@@ -215,8 +215,8 @@
 	unsigned short		pb_error;	/* error code on I/O */
 	unsigned short		pb_page_count;	/* size of page array */
 	unsigned short		pb_offset;	/* page offset in first page */
-	unsigned short		pb_hash_index;	/* hash table index	*/
 	unsigned char		pb_locked;	/* page array is locked */
+	unsigned char		pb_hash_index;	/* hash table index	*/
 	struct page		**pb_pages;	/* array of page pointers */
 	struct page		*pb_page_array[PB_PAGES]; /* inline pages */
 #ifdef PAGEBUF_LOCK_TRACKING
@@ -329,7 +329,7 @@
 extern int pagebuf_iowait(		/* wait for buffer I/O done	*/
 		page_buf_t *);		/* buffer to wait on		*/
 
-extern caddr_t	pagebuf_offset(page_buf_t *, off_t);
+extern caddr_t	pagebuf_offset(page_buf_t *, size_t);
 
 extern void pagebuf_iomove(		/* move data in/out of pagebuf	*/
 		page_buf_t *,		/* buffer to manipulate		*/
diff -Nru a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
--- a/fs/xfs/support/debug.c	Tue Mar  4 19:30:04 2003
+++ b/fs/xfs/support/debug.c	Tue Mar  4 19:30:04 2003
@@ -85,8 +85,8 @@
 cmn_err(register int level, char *fmt, ...)
 {
 	char	*fp = fmt;
+	ulong	flags;
 	int	len;
-	unsigned long flags;
 	va_list	ap;
 
 	level &= XFS_ERR_MASK;
@@ -110,8 +110,8 @@
 void
 icmn_err(register int level, char *fmt, va_list ap)
 {
+	ulong	flags;
 	int	len;
-	int	flags;
 
 	level &= XFS_ERR_MASK;
 	if(level > XFS_MAX_ERR_LEVEL)
diff -Nru a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
--- a/fs/xfs/xfs_attr.h	Tue Mar  4 19:30:05 2003
+++ b/fs/xfs/xfs_attr.h	Tue Mar  4 19:30:05 2003
@@ -69,7 +69,7 @@
 /*
  * The maximum size (into the kernel or returned from the kernel) of an
  * attribute value or the buffer used for an attr_list() call.	Larger
- * sizes will result in an E2BIG return code.
+ * sizes will result in an ERANGE return code.
  */
 #define ATTR_MAX_VALUELEN	(64*1024)	/* max length of a value */
 
diff -Nru a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
--- a/fs/xfs/xfs_attr_leaf.c	Tue Mar  4 19:30:08 2003
+++ b/fs/xfs/xfs_attr_leaf.c	Tue Mar  4 19:30:08 2003
@@ -1374,7 +1374,7 @@
 		count * sizeof(xfs_attr_leaf_entry_t) +
 		INT_GET(leaf->hdr.usedbytes, ARCH_CONVERT);
 	if (bytes > (state->blocksize >> 1)) {
-		*action = 0;	/* blk over 50%, dont try to join */
+		*action = 0;	/* blk over 50%, don't try to join */
 		return(0);
 	}
 
diff -Nru a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
--- a/fs/xfs/xfs_buf.h	Tue Mar  4 19:30:14 2003
+++ b/fs/xfs/xfs_buf.h	Tue Mar  4 19:30:14 2003
@@ -153,7 +153,7 @@
 
 #define XFS_BUF_PTR(bp)		(xfs_caddr_t)((bp)->pb_addr)
 
-extern inline xfs_caddr_t xfs_buf_offset(page_buf_t *bp, off_t offset)
+extern inline xfs_caddr_t xfs_buf_offset(page_buf_t *bp, size_t offset)
 {
 	if (bp->pb_flags & PBF_MAPPED)
 		return XFS_BUF_PTR(bp) + offset;
diff -Nru a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
--- a/fs/xfs/xfs_buf_item.c	Tue Mar  4 19:30:04 2003
+++ b/fs/xfs/xfs_buf_item.c	Tue Mar  4 19:30:04 2003
@@ -924,7 +924,7 @@
 
 
 /*
- * Add the given log item with it's callback to the list of callbacks
+ * Add the given log item with its callback to the list of callbacks
  * to be called when the buffer's I/O completes.  If it is not set
  * already, set the buffer's b_iodone() routine to be
  * xfs_buf_iodone_callbacks() and link the log item into the list of
diff -Nru a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
--- a/fs/xfs/xfs_da_btree.c	Tue Mar  4 19:30:12 2003
+++ b/fs/xfs/xfs_da_btree.c	Tue Mar  4 19:30:12 2003
@@ -830,8 +830,8 @@
 	node = (xfs_da_intnode_t *)info;
 	count = INT_GET(node->hdr.count, ARCH_CONVERT);
 	if (count > (state->node_ents >> 1)) {
-		*action = 0;	/* blk over 50%, dont try to join */
-		return(0);	/* blk over 50%, dont try to join */
+		*action = 0;	/* blk over 50%, don't try to join */
+		return(0);	/* blk over 50%, don't try to join */
 	}
 
 	/*
diff -Nru a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
--- a/fs/xfs/xfs_dir_leaf.c	Tue Mar  4 19:30:13 2003
+++ b/fs/xfs/xfs_dir_leaf.c	Tue Mar  4 19:30:13 2003
@@ -1341,7 +1341,7 @@
 		count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) +
 		INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
 	if (bytes > (state->blocksize >> 1)) {
-		*action = 0;	/* blk over 50%, dont try to join */
+		*action = 0;	/* blk over 50%, don't try to join */
 		return(0);
 	}
 
diff -Nru a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
--- a/fs/xfs/xfs_dquot.c	Tue Mar  4 19:30:08 2003
+++ b/fs/xfs/xfs_dquot.c	Tue Mar  4 19:30:08 2003
@@ -840,7 +840,7 @@
  * Given the file system, inode OR id, and type (UDQUOT/GDQUOT), return a
  * a locked dquot, doing an allocation (if requested) as needed.
  * When both an inode and an id are given, the inode's id takes precedence.
- * That is, if the id changes while we dont hold the ilock inside this
+ * That is, if the id changes while we don't hold the ilock inside this
  * function, the new dquot is returned, not necessarily the one requested
  * in the id argument.
  */
@@ -1449,7 +1449,7 @@
 		xfs_dqtrace_entry(dqp, "DQPURGE ->DQFLUSH: DQDIRTY");
 		/* dqflush unlocks dqflock */
 		/*
-		 * Given that dqpurge is a very rare occurence, it is OK
+		 * Given that dqpurge is a very rare occurrence, it is OK
 		 * that we're holding the hashlist and mplist locks
 		 * across the disk write. But, ... XXXsup
 		 *
diff -Nru a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
--- a/fs/xfs/xfs_inode.c	Tue Mar  4 19:30:14 2003
+++ b/fs/xfs/xfs_inode.c	Tue Mar  4 19:30:14 2003
@@ -1001,7 +1001,7 @@
 }
 
 /*
- * Allocate an inode on disk and return a copy of it's in-core version.
+ * Allocate an inode on disk and return a copy of its in-core version.
  * The in-core inode is locked exclusively.  Set mode, nlink, and rdev
  * appropriately within the inode.  The uid and gid for the inode are
  * set according to the contents of the given cred structure.
diff -Nru a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
--- a/fs/xfs/xfs_log.h	Tue Mar  4 19:30:14 2003
+++ b/fs/xfs/xfs_log.h	Tue Mar  4 19:30:14 2003
@@ -53,10 +53,10 @@
  * endian issues in treating two 32 bit numbers as one 64 bit number
  */
 static
-#ifdef __GNUC__
-# if !((__GNUC__ == 2) && (__GNUC_MINOR__ == 95))
+#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95)
+__attribute__((unused))	/* gcc 2.95 miscompiles this when inlined */
+#else
 __inline__
-#endif
 #endif
 xfs_lsn_t	_lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2, xfs_arch_t arch)
 {
diff -Nru a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
--- a/fs/xfs/xfs_mount.c	Tue Mar  4 19:30:07 2003
+++ b/fs/xfs/xfs_mount.c	Tue Mar  4 19:30:07 2003
@@ -1023,7 +1023,7 @@
 			/*
 			 * If the xfs quota code isn't installed,
 			 * we have to reset the quotachk'd bit.
-			 * If an error occured, qm_mount_quotas code
+			 * If an error occurred, qm_mount_quotas code
 			 * has already disabled quotas. So, just finish
 			 * mounting, and get on with the boring life
 			 * without disk quotas.
diff -Nru a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
--- a/fs/xfs/xfs_trans_dquot.c	Tue Mar  4 19:30:05 2003
+++ b/fs/xfs/xfs_trans_dquot.c	Tue Mar  4 19:30:05 2003
@@ -755,7 +755,7 @@
 
 /*
  * Lock the dquot and change the reservation if we can.
- * This doesnt change the actual usage, just the reservation.
+ * This doesn't change the actual usage, just the reservation.
  * The inode sent in is locked.
  *
  * Returns 0 on success, EDQUOT or other errors otherwise
diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h
--- a/include/acpi/acconfig.h	Tue Mar  4 19:30:12 2003
+++ b/include/acpi/acconfig.h	Tue Mar  4 19:30:12 2003
@@ -72,7 +72,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20030122
+#define ACPI_CA_VERSION                 0x20030228
 
 /* Version of ACPI supported */
 
diff -Nru a/include/acpi/acdebug.h b/include/acpi/acdebug.h
--- a/include/acpi/acdebug.h	Tue Mar  4 19:30:04 2003
+++ b/include/acpi/acdebug.h	Tue Mar  4 19:30:05 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 -Nru a/include/acpi/acevents.h b/include/acpi/acevents.h
--- a/include/acpi/acevents.h	Tue Mar  4 19:30:10 2003
+++ b/include/acpi/acevents.h	Tue Mar  4 19:30:10 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 -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h
--- a/include/acpi/acglobal.h	Tue Mar  4 19:30:03 2003
+++ b/include/acpi/acglobal.h	Tue Mar  4 19:30:03 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 -Nru a/include/acpi/achware.h b/include/acpi/achware.h
--- a/include/acpi/achware.h	Tue Mar  4 19:30:10 2003
+++ b/include/acpi/achware.h	Tue Mar  4 19:30:10 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 -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h
--- a/include/acpi/aclocal.h	Tue Mar  4 19:30:10 2003
+++ b/include/acpi/aclocal.h	Tue Mar  4 19:30:10 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,22 +337,20 @@
 #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 */
 
diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h
--- a/include/acpi/acpixf.h	Tue Mar  4 19:30:03 2003
+++ b/include/acpi/acpixf.h	Tue Mar  4 19:30:03 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
@@ -397,6 +414,10 @@
 acpi_status
 acpi_enter_sleep_state (
 	u8                              sleep_state);
+
+acpi_status
+acpi_enter_sleep_state_s4bios (
+	void);
 
 acpi_status
 acpi_leave_sleep_state (
diff -Nru a/include/acpi/acresrc.h b/include/acpi/acresrc.h
--- a/include/acpi/acresrc.h	Tue Mar  4 19:30:04 2003
+++ b/include/acpi/acresrc.h	Tue Mar  4 19:30:04 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 -Nru a/include/acpi/acutils.h b/include/acpi/acutils.h
--- a/include/acpi/acutils.h	Tue Mar  4 19:30:03 2003
+++ b/include/acpi/acutils.h	Tue Mar  4 19:30:03 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 -Nru a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
--- a/include/asm-alpha/bitops.h	Tue Mar  4 19:30:08 2003
+++ b/include/asm-alpha/bitops.h	Tue Mar  4 19:30:08 2003
@@ -288,7 +288,7 @@
 #else
 	unsigned long bits, qofs, bofs;
 
-	bits = __kernel_cmpbge(word, 0);
+	bits = __kernel_cmpbge(0, word);
 	qofs = ffz_b(bits);
 	bits = __kernel_extbl(word, qofs);
 	bofs = ffz_b(~bits);
diff -Nru a/include/asm-alpha/mman.h b/include/asm-alpha/mman.h
--- a/include/asm-alpha/mman.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-alpha/mman.h	Tue Mar  4 19:30:04 2003
@@ -39,7 +39,7 @@
 #define MADV_SEQUENTIAL	2		/* expect sequential page references */
 #define MADV_WILLNEED	3		/* will need these pages */
 #define	MADV_SPACEAVAIL	5		/* ensure resources are available */
-#define MADV_DONTNEED	6		/* dont need these pages */
+#define MADV_DONTNEED	6		/* don't need these pages */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff -Nru a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
--- a/include/asm-alpha/pci.h	Tue Mar  4 19:30:03 2003
+++ b/include/asm-alpha/pci.h	Tue Mar  4 19:30:03 2003
@@ -97,7 +97,7 @@
 /* Unmap a single streaming mode DMA translation.  The DMA_ADDR and
    SIZE must match what was provided for in a previous pci_map_single
    call.  All other usages are undefined.  After this call, reads by
-   the cpu to the buffer are guarenteed to see whatever the device
+   the cpu to the buffer are guaranteed to see whatever the device
    wrote there.  */
 
 extern void pci_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
diff -Nru a/include/asm-alpha/rwsem.h b/include/asm-alpha/rwsem.h
--- a/include/asm-alpha/rwsem.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-alpha/rwsem.h	Tue Mar  4 19:30:13 2003
@@ -7,7 +7,7 @@
  */
 
 #ifndef _LINUX_RWSEM_H
-#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
+#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
 #endif
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-alpha/thread_info.h b/include/asm-alpha/thread_info.h
--- a/include/asm-alpha/thread_info.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-alpha/thread_info.h	Tue Mar  4 19:30:13 2003
@@ -34,9 +34,9 @@
  */
 #define INIT_THREAD_INFO(tsk)			\
 {						\
-	task:		&tsk,			\
-	exec_domain:	&default_exec_domain,	\
-	addr_limit:	KERNEL_DS,		\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
+	.addr_limit	= KERNEL_DS,		\
 	.restart_block = {			\
 		.fn = do_no_restart_syscall,	\
 	},					\
diff -Nru a/include/asm-arm/arch-pxa/bitfield.h b/include/asm-arm/arch-pxa/bitfield.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-arm/arch-pxa/bitfield.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,113 @@
+/*
+ *	FILE    	bitfield.h
+ *
+ *	Version 	1.1
+ *	Author  	Copyright (c) Marc A. Viredaz, 1998
+ *	        	DEC Western Research Laboratory, Palo Alto, CA
+ *	Date    	April 1998 (April 1997)
+ *	System  	Advanced RISC Machine (ARM)
+ *	Language	C or ARM Assembly
+ *	Purpose 	Definition of macros to operate on bit fields.
+ */
+
+
+
+#ifndef __BITFIELD_H
+#define __BITFIELD_H
+
+#ifndef __ASSEMBLY__
+#define UData(Data)	((unsigned long) (Data))
+#else
+#define UData(Data)	(Data)
+#endif
+
+
+/*
+ * MACRO: Fld
+ *
+ * Purpose
+ *    The macro "Fld" encodes a bit field, given its size and its shift value
+ *    with respect to bit 0.
+ *
+ * Note
+ *    A more intuitive way to encode bit fields would have been to use their
+ *    mask. However, extracting size and shift value information from a bit
+ *    field's mask is cumbersome and might break the assembler (255-character
+ *    line-size limit).
+ *
+ * Input
+ *    Size      	Size of the bit field, in number of bits.
+ *    Shft      	Shift value of the bit field with respect to bit 0.
+ *
+ * Output
+ *    Fld       	Encoded bit field.
+ */
+
+#define Fld(Size, Shft)	(((Size) << 16) + (Shft))
+
+
+/*
+ * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit
+ *
+ * Purpose
+ *    The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return
+ *    the size, shift value, mask, aligned mask, and first bit of a
+ *    bit field.
+ *
+ * Input
+ *    Field     	Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ *    FSize     	Size of the bit field, in number of bits.
+ *    FShft     	Shift value of the bit field with respect to bit 0.
+ *    FMsk      	Mask for the bit field.
+ *    FAlnMsk   	Mask for the bit field, aligned on bit 0.
+ *    F1stBit   	First bit of the bit field.
+ */
+
+#define FSize(Field)	((Field) >> 16)
+#define FShft(Field)	((Field) & 0x0000FFFF)
+#define FMsk(Field)	(((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field)	((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field)	(UData (1) << FShft (Field))
+
+
+/*
+ * MACRO: FInsrt
+ *
+ * Purpose
+ *    The macro "FInsrt" inserts a value into a bit field by shifting the
+ *    former appropriately.
+ *
+ * Input
+ *    Value     	Bit-field value.
+ *    Field     	Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ *    FInsrt    	Bit-field value positioned appropriately.
+ */
+
+#define FInsrt(Value, Field) \
+                	(UData (Value) << FShft (Field))
+
+
+/*
+ * MACRO: FExtr
+ *
+ * Purpose
+ *    The macro "FExtr" extracts the value of a bit field by masking and
+ *    shifting it appropriately.
+ *
+ * Input
+ *    Data      	Data containing the bit-field to be extracted.
+ *    Field     	Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ *    FExtr     	Bit-field value.
+ */
+
+#define FExtr(Data, Field) \
+                	((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
+
+
+#endif /* __BITFIELD_H */
diff -Nru a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h
--- a/include/asm-arm/arch-pxa/hardware.h	Tue Mar  4 19:30:03 2003
+++ b/include/asm-arm/arch-pxa/hardware.h	Tue Mar  4 19:30:03 2003
@@ -103,6 +103,5 @@
 
 #include "lubbock.h"
 #include "idp.h"
-#include "cerf.h"
 
 #endif  /* _ASM_ARCH_HARDWARE_H */
diff -Nru a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
--- a/include/asm-arm/arch-pxa/irqs.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-arm/arch-pxa/irqs.h	Tue Mar  4 19:30:04 2003
@@ -44,89 +44,90 @@
 			((i) - PXA_IRQ(32) + 2)
 #define IRQ_TO_GPIO(i)	((i) - (((i) > IRQ_GPIO1) ? IRQ_GPIO(2) : IRQ_GPIO(0)))
 
-#define	NR_IRQS		(IRQ_GPIO(80) + 1)
-
-#if defined(CONFIG_SA1111)
-
-#define IRQ_SA1111_START	(IRQ_GPIO(80) + 1)
-#define SA1111_IRQ(x)		(IRQ_SA1111_START + (x))
-
-#define IRQ_GPAIN0		SA1111_IRQ(0)
-#define IRQ_GPAIN1		SA1111_IRQ(1)
-#define IRQ_GPAIN2		SA1111_IRQ(2)
-#define IRQ_GPAIN3		SA1111_IRQ(3)
-#define IRQ_GPBIN0		SA1111_IRQ(4)
-#define IRQ_GPBIN1		SA1111_IRQ(5)
-#define IRQ_GPBIN2		SA1111_IRQ(6)
-#define IRQ_GPBIN3		SA1111_IRQ(7)
-#define IRQ_GPBIN4		SA1111_IRQ(8)
-#define IRQ_GPBIN5		SA1111_IRQ(9)
-#define IRQ_GPCIN0		SA1111_IRQ(10)
-#define IRQ_GPCIN1		SA1111_IRQ(11)
-#define IRQ_GPCIN2		SA1111_IRQ(12)
-#define IRQ_GPCIN3		SA1111_IRQ(13)
-#define IRQ_GPCIN4		SA1111_IRQ(14)
-#define IRQ_GPCIN5		SA1111_IRQ(15)
-#define IRQ_GPCIN6		SA1111_IRQ(16)
-#define IRQ_GPCIN7		SA1111_IRQ(17)
-#define IRQ_MSTXINT		SA1111_IRQ(18)
-#define IRQ_MSRXINT		SA1111_IRQ(19)
-#define IRQ_MSSTOPERRINT	SA1111_IRQ(20)
-#define IRQ_TPTXINT		SA1111_IRQ(21)
-#define IRQ_TPRXINT		SA1111_IRQ(22)
-#define IRQ_TPSTOPERRINT	SA1111_IRQ(23)
-#define SSPXMTINT	SA1111_IRQ(24)
-#define SSPRCVINT	SA1111_IRQ(25)
-#define SSPROR		SA1111_IRQ(26)
-#define AUDXMTDMADONEA	SA1111_IRQ(32)
-#define AUDRCVDMADONEA	SA1111_IRQ(33)
-#define AUDXMTDMADONEB	SA1111_IRQ(34)
-#define AUDRCVDMADONEB	SA1111_IRQ(35)
-#define AUDTFSR		SA1111_IRQ(36)
-#define AUDRFSR		SA1111_IRQ(37)
-#define AUDTUR		SA1111_IRQ(38)
-#define AUDROR		SA1111_IRQ(39)
-#define AUDDTS		SA1111_IRQ(40)
-#define AUDRDD		SA1111_IRQ(41)
-#define AUDSTO		SA1111_IRQ(42)
-#define USBPWR		SA1111_IRQ(43)
-#define NIRQHCIM	SA1111_IRQ(44)
-#define HCIBUFFACC	SA1111_IRQ(45)
-#define HCIRMTWKP	SA1111_IRQ(46)
-#define NHCIMFCIR	SA1111_IRQ(47)
-#define PORT_RESUME	SA1111_IRQ(48)
-#define S0_READY_NINT	SA1111_IRQ(49)
-#define S1_READY_NINT	SA1111_IRQ(50)
-#define S0_CD_VALID	SA1111_IRQ(51)
-#define S1_CD_VALID	SA1111_IRQ(52)
-#define S0_BVD1_STSCHG	SA1111_IRQ(53)
-#define S1_BVD1_STSCHG	SA1111_IRQ(54)
-
-#define SA1111_IRQ_MAX	SA1111_IRQ(54)
-
-#undef NR_IRQS
-#define NR_IRQS		(SA1111_IRQ_MAX + 1)
-
-#endif	// defined(CONFIG_SA1111)
-
-#if defined(CONFIG_ARCH_LUBBOCK) || defined(CONFIG_ARCH_PXA_IDP)
-#if CONFIG_SA1111
-#define LUBBOCK_IRQ(x)	(SA1111_IRQ_MAX + 1 + (x))
+/*
+ * The next 16 interrupts are for board specific purposes.  Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these.  If you need more, increase IRQ_BOARD_END, but keep it
+ * within sensible limits.
+ */
+#define IRQ_BOARD_START		(IRQ_GPIO(80) + 1)
+#define IRQ_BOARD_END		(IRQ_BOARD_START + 16)
+
+#define IRQ_SA1111_START	(IRQ_BOARD_END)
+#define IRQ_GPAIN0		(IRQ_BOARD_END + 0)
+#define IRQ_GPAIN1		(IRQ_BOARD_END + 1)
+#define IRQ_GPAIN2		(IRQ_BOARD_END + 2)
+#define IRQ_GPAIN3		(IRQ_BOARD_END + 3)
+#define IRQ_GPBIN0		(IRQ_BOARD_END + 4)
+#define IRQ_GPBIN1		(IRQ_BOARD_END + 5)
+#define IRQ_GPBIN2		(IRQ_BOARD_END + 6)
+#define IRQ_GPBIN3		(IRQ_BOARD_END + 7)
+#define IRQ_GPBIN4		(IRQ_BOARD_END + 8)
+#define IRQ_GPBIN5		(IRQ_BOARD_END + 9)
+#define IRQ_GPCIN0		(IRQ_BOARD_END + 10)
+#define IRQ_GPCIN1		(IRQ_BOARD_END + 11)
+#define IRQ_GPCIN2		(IRQ_BOARD_END + 12)
+#define IRQ_GPCIN3		(IRQ_BOARD_END + 13)
+#define IRQ_GPCIN4		(IRQ_BOARD_END + 14)
+#define IRQ_GPCIN5		(IRQ_BOARD_END + 15)
+#define IRQ_GPCIN6		(IRQ_BOARD_END + 16)
+#define IRQ_GPCIN7		(IRQ_BOARD_END + 17)
+#define IRQ_MSTXINT		(IRQ_BOARD_END + 18)
+#define IRQ_MSRXINT		(IRQ_BOARD_END + 19)
+#define IRQ_MSSTOPERRINT	(IRQ_BOARD_END + 20)
+#define IRQ_TPTXINT		(IRQ_BOARD_END + 21)
+#define IRQ_TPRXINT		(IRQ_BOARD_END + 22)
+#define IRQ_TPSTOPERRINT	(IRQ_BOARD_END + 23)
+#define SSPXMTINT		(IRQ_BOARD_END + 24)
+#define SSPRCVINT		(IRQ_BOARD_END + 25)
+#define SSPROR			(IRQ_BOARD_END + 26)
+#define AUDXMTDMADONEA		(IRQ_BOARD_END + 32)
+#define AUDRCVDMADONEA		(IRQ_BOARD_END + 33)
+#define AUDXMTDMADONEB		(IRQ_BOARD_END + 34)
+#define AUDRCVDMADONEB		(IRQ_BOARD_END + 35)
+#define AUDTFSR			(IRQ_BOARD_END + 36)
+#define AUDRFSR			(IRQ_BOARD_END + 37)
+#define AUDTUR			(IRQ_BOARD_END + 38)
+#define AUDROR			(IRQ_BOARD_END + 39)
+#define AUDDTS			(IRQ_BOARD_END + 40)
+#define AUDRDD			(IRQ_BOARD_END + 41)
+#define AUDSTO			(IRQ_BOARD_END + 42)
+#define IRQ_USBPWR		(IRQ_BOARD_END + 43)
+#define IRQ_HCIM		(IRQ_BOARD_END + 44)
+#define IRQ_HCIBUFFACC		(IRQ_BOARD_END + 45)
+#define IRQ_HCIRMTWKP		(IRQ_BOARD_END + 46)
+#define IRQ_NHCIMFCIR		(IRQ_BOARD_END + 47)
+#define IRQ_USB_PORT_RESUME	(IRQ_BOARD_END + 48)
+#define IRQ_S0_READY_NINT	(IRQ_BOARD_END + 49)
+#define IRQ_S1_READY_NINT	(IRQ_BOARD_END + 50)
+#define IRQ_S0_CD_VALID		(IRQ_BOARD_END + 51)
+#define IRQ_S1_CD_VALID		(IRQ_BOARD_END + 52)
+#define IRQ_S0_BVD1_STSCHG	(IRQ_BOARD_END + 53)
+#define IRQ_S1_BVD1_STSCHG	(IRQ_BOARD_END + 54)
+
+/*
+ * Figure out the MAX IRQ number.
+ *
+ * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
+ * Otherwise, we have the standard IRQs only.
+ */
+#ifdef CONFIG_SA1111
+#define NR_IRQS			(IRQ_S1_BVD1_STSCHG + 1)
+#elif defined(CONFIG_ARCH_LUBBOCK)
+#define NR_IRQS			(IRQ_BOARD_END)
 #else
-#define LUBBOCK_IRQ(x)	(IRQ_GPIO(80) + 1 + (x))
+#define NR_IRQS			(IRQ_BOARD_START)
 #endif
 
+/*
+ * Board specific IRQs.  Define them here.
+ * Do not surround them with ifdefs.
+ */
+#define LUBBOCK_IRQ(x)		(IRQ_BOARD_START + (x))
 #define LUBBOCK_SD_IRQ		LUBBOCK_IRQ(0)
 #define LUBBOCK_SA1111_IRQ	LUBBOCK_IRQ(1)
 #define LUBBOCK_USB_IRQ		LUBBOCK_IRQ(2)
 #define LUBBOCK_ETH_IRQ		LUBBOCK_IRQ(3)
 #define LUBBOCK_UCB1400_IRQ	LUBBOCK_IRQ(4)
 #define LUBBOCK_BB_IRQ		LUBBOCK_IRQ(5)
-
-#undef NR_IRQS
-#define NR_IRQS		(LUBBOCK_IRQ(5) + 1)
-
-#endif	// CONFIG_ARCH_LUBBOCK
-
-
 
diff -Nru a/include/asm-arm/arch-pxa/lubbock.h b/include/asm-arm/arch-pxa/lubbock.h
--- a/include/asm-arm/arch-pxa/lubbock.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-arm/arch-pxa/lubbock.h	Tue Mar  4 19:30:05 2003
@@ -13,7 +13,6 @@
 #define LUBBOCK_FPGA_PHYS	PXA_CS2_PHYS
 #define LUBBOCK_FPGA_VIRT	(0xf0000000)	/* phys 0x08000000 */
 #define LUBBOCK_ETH_BASE	(0xf1000000)	/* phys 0x0c000000 */
-#define LUBBOCK_SA1111_BASE	(0xf4000000)	/* phys 0x10000000 */
 
 #define LUB_P2V(x)		((x) - LUBBOCK_FPGA_PHYS + LUBBOCK_FPGA_VIRT)
 #define LUB_V2P(x)		((x) - LUBBOCK_FPGA_VIRT + LUBBOCK_FPGA_PHYS)
diff -Nru a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
--- a/include/asm-arm/arch-pxa/pxa-regs.h	Tue Mar  4 19:30:10 2003
+++ b/include/asm-arm/arch-pxa/pxa-regs.h	Tue Mar  4 19:30:10 2003
@@ -380,32 +380,12 @@
 /*
  * IrSR (Infrared Selection Register)
  */
-#define IrSR_OFFSET 0x20
+#define STISR_RXPL      (1 << 4)        /* Receive Data Polarity */
+#define STISR_TXPL      (1 << 3)        /* Transmit Data Polarity */
+#define STISR_XMODE     (1 << 2)        /* Transmit Pulse Width Select */
+#define STISR_RCVEIR    (1 << 1)        /* Receiver SIR Enable */
+#define STISR_XMITIR    (1 << 0)        /* Transmitter SIR Enable */
 
-#define IrSR_RXPL_NEG_IS_ZERO (1<<4)
-#define IrSR_RXPL_POS_IS_ZERO 0x0
-#define IrSR_TXPL_NEG_IS_ZERO (1<<3)
-#define IrSR_TXPL_POS_IS_ZERO 0x0
-#define IrSR_XMODE_PULSE_1_6  (1<<2)
-#define IrSR_XMODE_PULSE_3_16 0x0
-#define IrSR_RCVEIR_IR_MODE   (1<<1)
-#define IrSR_RCVEIR_UART_MODE 0x0
-#define IrSR_XMITIR_IR_MODE   (1<<0)
-#define IrSR_XMITIR_UART_MODE 0x0
-
-#define IrSR_IR_RECEIVE_ON (\
-                IrSR_RXPL_NEG_IS_ZERO | \
-                IrSR_TXPL_POS_IS_ZERO | \
-                IrSR_XMODE_PULSE_3_16 | \
-                IrSR_RCVEIR_IR_MODE   | \
-                IrSR_XMITIR_UART_MODE)
-
-#define IrSR_IR_TRANSMIT_ON (\
-                IrSR_RXPL_NEG_IS_ZERO | \
-                IrSR_TXPL_POS_IS_ZERO | \
-                IrSR_XMODE_PULSE_3_16 | \
-                IrSR_RCVEIR_UART_MODE | \
-                IrSR_XMITIR_IR_MODE)
 
 /*
  * I2C registers
@@ -417,53 +397,49 @@
 #define ISR		__REG(0x40301698)  /* I2C Status Register - ISR */
 #define ISAR		__REG(0x403016A0)  /* I2C Slave Address Register - ISAR */
 
-/* ----- Control register bits ---------------------------------------- */
+#define ICR_START	(1 << 0)	   /* start bit */
+#define ICR_STOP	(1 << 1)	   /* stop bit */
+#define ICR_ACKNAK	(1 << 2)	   /* send ACK(0) or NAK(1) */
+#define ICR_TB		(1 << 3)	   /* transfer byte bit */
+#define ICR_MA		(1 << 4)	   /* master abort */
+#define ICR_SCLE	(1 << 5)	   /* master clock enable */
+#define ICR_IUE		(1 << 6)	   /* unit enable */
+#define ICR_GCD		(1 << 7)	   /* general call disable */
+#define ICR_ITEIE	(1 << 8)	   /* enable tx interrupts */
+#define ICR_IRFIE	(1 << 9)	   /* enable rx interrupts */
+#define ICR_BEIE	(1 << 10)	   /* enable bus error ints */
+#define ICR_SSDIE	(1 << 11)	   /* slave STOP detected int enable */
+#define ICR_ALDIE	(1 << 12)	   /* enable arbitration interrupt */
+#define ICR_SADIE	(1 << 13)	   /* slave address detected int enable */
+#define ICR_UR		(1 << 14)	   /* unit reset */
+
+#define ISR_RWM		(1 << 0)	   /* read/write mode */
+#define ISR_ACKNAK	(1 << 1)	   /* ack/nak status */
+#define ISR_UB		(1 << 2)	   /* unit busy */
+#define ISR_IBB		(1 << 3)	   /* bus busy */
+#define ISR_SSD		(1 << 4)	   /* slave stop detected */
+#define ISR_ALD		(1 << 5)	   /* arbitration loss detected */
+#define ISR_ITE		(1 << 6)	   /* tx buffer empty */
+#define ISR_IRF		(1 << 7)	   /* rx buffer full */
+#define ISR_GCAD	(1 << 8)	   /* general call address detected */
+#define ISR_SAD		(1 << 9)	   /* slave address detected */
+#define ISR_BED		(1 << 10)	   /* bus error no ACK/NAK */
 
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8 		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000  	/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM         0x1		/* read/write mode */
-#define ISR_ACKNAK      0x2		/* ack/nak status */
-#define ISR_UB          0x4		/* unit busy */
-#define ISR_IBB         0x8		/* bus busy */
-#define ISR_SSD         0x10		/* slave stop detected */
-#define ISR_ALD         0x20		/* arbitration loss detected */
-#define ISR_ITE         0x40            /* tx buffer empty */
-#define ISR_IRF         0x80            /* rx buffer full */
-#define ISR_GCAD        0x100		/* general call address detected */
-#define ISR_SAD         0x200		/* slave address detected */
-#define ISR_BED         0x400           /* bus error no ACK/NAK */
 
 /*
  * Serial Audio Controller
  */
 
-
-/* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
- * short defines because there is too much chance of namespace collision */
-
-//#define SACR0		__REG(0x40400000)  /* Global Control Register */
-//#define SACR1		__REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
-//#define SASR0		__REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
-//#define SAIMR		__REG(0x40400014)  /* Serial Audio Interrupt Mask Register */
-//#define SAICR		__REG(0x40400018)  /* Serial Audio Interrupt Clear Register */
-//#define SADIV		__REG(0x40400060)  /* Audio Clock Divider Register. */
-//#define SADR		__REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
+/* FIXME: This clash with SA1111 defines */
+#ifndef CONFIG_SA1111
+#define SACR0		__REG(0x40400000)  /* Global Control Register */
+#define SACR1		__REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
+#define SASR0		__REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
+#define SAIMR		__REG(0x40400014)  /* Serial Audio Interrupt Mask Register */
+#define SAICR		__REG(0x40400018)  /* Serial Audio Interrupt Clear Register */
+#define SADIV		__REG(0x40400060)  /* Audio Clock Divider Register. */
+#define SADR		__REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
+#endif
 
 
 /*
@@ -714,6 +690,30 @@
 #define ICSR0		__REG(0x40800014)  /* ICP Status Register 0 */
 #define ICSR1		__REG(0x40800018)  /* ICP Status Register 1 */
 
+#define ICCR0_AME       (1 << 7)           /* Adress match enable */
+#define ICCR0_TIE       (1 << 6)           /* Transmit FIFO interrupt enable */
+#define ICCR0_RIE       (1 << 5)           /* Recieve FIFO interrupt enable */
+#define ICCR0_RXE       (1 << 4)           /* Receive enable */
+#define ICCR0_TXE       (1 << 3)           /* Transmit enable */
+#define ICCR0_TUS       (1 << 2)           /* Transmit FIFO underrun select */
+#define ICCR0_LBM       (1 << 1)           /* Loopback mode */
+#define ICCR0_ITR       (1 << 0)           /* IrDA transmission */
+
+#define ICSR0_FRE       (1 << 5)           /* Framing error */
+#define ICSR0_RFS       (1 << 4)           /* Receive FIFO service request */
+#define ICSR0_TFS       (1 << 3)           /* Transnit FIFO service request */
+#define ICSR0_RAB       (1 << 2)           /* Receiver abort */
+#define ICSR0_TUR       (1 << 1)           /* Trunsmit FIFO underun */
+#define ICSR0_EIF       (1 << 0)           /* End/Error in FIFO */
+
+#define ICSR1_ROR       (1 << 6)           /* Receiver FIFO underrun  */
+#define ICSR1_CRE       (1 << 5)           /* CRC error */
+#define ICSR1_EOF       (1 << 4)           /* End of frame */
+#define ICSR1_TNF       (1 << 3)           /* Transmit FIFO not full */
+#define ICSR1_RNE       (1 << 2)           /* Receive FIFO not empty */
+#define ICSR1_TBY       (1 << 1)           /* Tramsmiter busy flag */
+#define ICSR1_RSY       (1 << 0)           /* Recevier synchronized flag */
+
 
 /*
  * Real Time Clock
@@ -1171,18 +1171,104 @@
 #define LCCR0_BM	(1 << 20) 	/* Branch mask */
 #define LCCR0_OUM	(1 << 21)	/* Output FIFO underrun mask */
 
+#define LCCR1_PPL       Fld (10, 0)      /* Pixels Per Line - 1 */
+#define LCCR1_DisWdth(Pixel)            /* Display Width [1..800 pix.]  */ \
+                        (((Pixel) - 1) << FShft (LCCR1_PPL))
+
+#define LCCR1_HSW       Fld (6, 10)     /* Horizontal Synchronization     */
+#define LCCR1_HorSnchWdth(Tpix)         /* Horizontal Synchronization     */ \
+                                        /* pulse Width [1..64 Tpix]       */ \
+                        (((Tpix) - 1) << FShft (LCCR1_HSW))
+
+#define LCCR1_ELW       Fld (8, 16)     /* End-of-Line pixel clock Wait    */
+                                        /* count - 1 [Tpix]                */
+#define LCCR1_EndLnDel(Tpix)            /*  End-of-Line Delay              */ \
+                                        /*  [1..256 Tpix]                  */ \
+                        (((Tpix) - 1) << FShft (LCCR1_ELW))
+
+#define LCCR1_BLW       Fld (8, 24)     /* Beginning-of-Line pixel clock   */
+                                        /* Wait count - 1 [Tpix]           */
+#define LCCR1_BegLnDel(Tpix)            /*  Beginning-of-Line Delay        */ \
+                                        /*  [1..256 Tpix]                  */ \
+                        (((Tpix) - 1) << FShft (LCCR1_BLW))
+
+
+#define LCCR2_LPP       Fld (10, 0)     /* Line Per Panel - 1              */
+#define LCCR2_DisHght(Line)             /*  Display Height [1..1024 lines] */ \
+                        (((Line) - 1) << FShft (LCCR2_LPP))
+
+#define LCCR2_VSW       Fld (6, 10)     /* Vertical Synchronization pulse  */
+                                        /* Width - 1 [Tln] (L_FCLK)        */
+#define LCCR2_VrtSnchWdth(Tln)          /*  Vertical Synchronization pulse */ \
+                                        /*  Width [1..64 Tln]              */ \
+                        (((Tln) - 1) << FShft (LCCR2_VSW))
+
+#define LCCR2_EFW       Fld (8, 16)     /* End-of-Frame line clock Wait    */
+                                        /* count [Tln]                     */
+#define LCCR2_EndFrmDel(Tln)            /*  End-of-Frame Delay             */ \
+                                        /*  [0..255 Tln]                   */ \
+                        ((Tln) << FShft (LCCR2_EFW))
+
+#define LCCR2_BFW       Fld (8, 24)     /* Beginning-of-Frame line clock   */
+                                        /* Wait count [Tln]                */
+#define LCCR2_BegFrmDel(Tln)            /*  Beginning-of-Frame Delay       */ \
+                                        /*  [0..255 Tln]                   */ \
+                        ((Tln) << FShft (LCCR2_BFW))
+
+#if 0
 #define LCCR3_PCD	(0xff)		/* Pixel clock divisor */
 #define LCCR3_ACB	(0xff << 8)	/* AC Bias pin frequency */
 #define LCCR3_ACB_S	8
+#endif
+
 #define LCCR3_API	(0xf << 16)	/* AC Bias pin trasitions per interrupt */
 #define LCCR3_API_S	16
 #define LCCR3_VSP	(1 << 20)	/* vertical sync polarity */
 #define LCCR3_HSP	(1 << 21)	/* horizontal sync polarity */
 #define LCCR3_PCP	(1 << 22)	/* pixel clock polarity */
 #define LCCR3_OEP	(1 << 23)	/* output enable polarity */
+#if 0
 #define LCCR3_BPP	(7 << 24)	/* bits per pixel */
 #define LCCR3_BPP_S	24
+#endif
 #define LCCR3_DPC	(1 << 27)	/* double pixel clock mode */
+
+
+#define LCCR3_PCD       Fld (8, 0)      /* Pixel Clock Divisor */
+#define LCCR3_PixClkDiv(Div)            /* Pixel Clock Divisor */ \
+                        (((Div) << FShft (LCCR3_PCD)))
+
+
+#define LCCR3_BPP       Fld (3, 24)     /* Bit Per Pixel */
+#define LCCR3_Bpp(Bpp)                  /* Bit Per Pixel */ \
+                        (((Bpp) << FShft (LCCR3_BPP)))
+
+#define LCCR3_ACB       Fld (8, 8)      /* AC Bias */
+#define LCCR3_Acb(Acb)                  /* BAC Bias */ \
+                        (((Acb) << FShft (LCCR3_ACB)))
+
+#define LCCR3_HorSnchH  (LCCR3_HSP*0)   /*  Horizontal Synchronization     */
+                                        /*  pulse active High              */
+#define LCCR3_HorSnchL  (LCCR3_HSP*1)   /*  Horizontal Synchronization     */
+
+#define LCCR3_VrtSnchH  (LCCR3_VSP*0)   /*  Vertical Synchronization pulse */
+                                        /*  active High                    */
+#define LCCR3_VrtSnchL  (LCCR3_VSP*1)   /*  Vertical Synchronization pulse */
+                                        /*  active Low                     */
+
+#define LCSR_LDD	(1 << 0)	/* LCD Disable Done */
+#define LCSR_SOF	(1 << 1)	/* Start of frame */
+#define LCSR_BER	(1 << 2)	/* Bus error */
+#define LCSR_ABC	(1 << 3)	/* AC Bias count */
+#define LCSR_IUL	(1 << 4)	/* input FIFO underrun Lower panel */
+#define LCSR_IUU	(1 << 5)	/* input FIFO underrun Upper panel */
+#define LCSR_OU		(1 << 6)	/* output FIFO underrun */
+#define LCSR_QD		(1 << 7)	/* quick disable */
+#define LCSR_EOF	(1 << 8)	/* end of frame */
+#define LCSR_BS		(1 << 9)	/* branch status */
+#define LCSR_SINT	(1 << 10)	/* subsequent interrupt */
+
+#define LDCMD_PAL	(1 << 26)	/* instructs DMA to load palette buffer */
 
 #define LCSR_LDD	(1 << 0)	/* LCD Disable Done */
 #define LCSR_SOF	(1 << 1)	/* Start of frame */
diff -Nru a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h
--- a/include/asm-arm/arch-pxa/system.h	Tue Mar  4 19:30:07 2003
+++ b/include/asm-arm/arch-pxa/system.h	Tue Mar  4 19:30:07 2003
@@ -27,7 +27,7 @@
 		/* Initialize the watchdog and let it fire */
 		OWER = OWER_WME;
 		OSSR = OSSR_M3;
-		OSMR3 = OSCR + 36864;	/* ... in 10 ms */
+		OSMR3 = OSCR + 368640;	/* ... in 100 ms */
 	}
 }
 
diff -Nru a/include/asm-arm/arch-pxa/time.h b/include/asm-arm/arch-pxa/time.h
--- a/include/asm-arm/arch-pxa/time.h	Tue Mar  4 19:30:08 2003
+++ b/include/asm-arm/arch-pxa/time.h	Tue Mar  4 19:30:08 2003
@@ -42,7 +42,7 @@
 	elapsed = LATCH - ticks_to_match;
 
 	/* Now convert them to usec */
-	usec = (unsigned long)(elapsed*tick)/LATCH;
+	usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
 
 	return usec;
 }
@@ -51,6 +51,8 @@
 {
 	long flags;
 	int next_match;
+
+	do_profile(regs);
 
 	/* Loop until we get ahead of the free running timer.
 	 * This ensures an exact clock tick count and time accuracy.
diff -Nru a/include/asm-arm/arch-sa1100/simpad.h b/include/asm-arm/arch-sa1100/simpad.h
--- a/include/asm-arm/arch-sa1100/simpad.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-arm/arch-sa1100/simpad.h	Tue Mar  4 19:30:05 2003
@@ -46,7 +46,7 @@
 #define IRQ_GPIO_CF_IRQ         IRQ_GPIO1
 #define IRQ_GPIO_CF_CD          IRQ_GPIO24      
 
-// CS3 Latch is write only, a shadow is neccessary 
+// CS3 Latch is write only, a shadow is necessary 
 
 #define CS3BUSTYPE unsigned volatile long           
 #define CS3_BASE        0xf1000000
diff -Nru a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
--- a/include/asm-arm/bitops.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-arm/bitops.h	Tue Mar  4 19:30:04 2003
@@ -9,7 +9,7 @@
  *
  * Please note that the code in this file should never be included
  * from user space.  Many of these are not implemented in assembler
- * since they would be too costly.  Also, they require priviledged
+ * since they would be too costly.  Also, they require privileged
  * instructions (which are not available from user mode) to ensure
  * that they are atomic.
  */
diff -Nru a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h
--- a/include/asm-arm/proc-fns.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-arm/proc-fns.h	Tue Mar  4 19:30:09 2003
@@ -125,7 +125,7 @@
 
 #if 0
  * The following is to fool mkdep into generating the correct
- * dependencies.  Without this, it cant figure out that this
+ * dependencies.  Without this, it can't figure out that this
  * file does indeed depend on the cpu-*.h files.
 #include <asm/cpu-single.h>
 #include <asm/cpu-multi26.h>
diff -Nru a/include/asm-cris/namei.h b/include/asm-cris/namei.h
--- a/include/asm-cris/namei.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-cris/namei.h	Tue Mar  4 19:30:09 2003
@@ -9,7 +9,7 @@
 
 /* used to find file-system prefixes for doing emulations
  * see for example asm-sparc/namei.h
- * we dont use it...
+ * we don't use it...
  */
 
 #define __emul_prefix() NULL
diff -Nru a/include/asm-cris/processor.h b/include/asm-cris/processor.h
--- a/include/asm-cris/processor.h	Tue Mar  4 19:30:08 2003
+++ b/include/asm-cris/processor.h	Tue Mar  4 19:30:08 2003
@@ -65,7 +65,7 @@
 /*
  * At user->kernel entry, the pt_regs struct is stacked on the top of the kernel-stack.
  * This macro allows us to find those regs for a task.
- * Notice that subsequent pt_regs stackings, like recursive interrupts occuring while
+ * Notice that subsequent pt_regs stackings, like recursive interrupts occurring while
  * we're in the kernel, won't affect this - only the first user->kernel transition
  * registers are reached by this.
  */
diff -Nru a/include/asm-cris/uaccess.h b/include/asm-cris/uaccess.h
--- a/include/asm-cris/uaccess.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-cris/uaccess.h	Tue Mar  4 19:30:04 2003
@@ -126,7 +126,7 @@
  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  * and yet we don't want to do any pointers, because that is too much
  * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the uglyness from the user.
+ * and hide all the ugliness from the user.
  *
  * The "__xxx" versions of the user access functions are versions that
  * do not verify the address space, that must have been done previously
diff -Nru a/include/asm-generic/topology.h b/include/asm-generic/topology.h
--- a/include/asm-generic/topology.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-generic/topology.h	Tue Mar  4 19:30:04 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 -Nru a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h
--- a/include/asm-i386/mach-bigsmp/mach_apic.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-i386/mach-bigsmp/mach_apic.h	Tue Mar  4 19:30:13 2003
@@ -10,7 +10,7 @@
 		((phys_apic) & (~0xf)) )
 #endif
 
-#define no_balance_irq (1)
+#define NO_BALANCE_IRQ (1)
 #define esr_disable (1)
 
 static inline int apic_id_registered(void)
@@ -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 -Nru a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h
--- a/include/asm-i386/mach-default/do_timer.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-i386/mach-default/do_timer.h	Tue Mar  4 19:30:13 2003
@@ -67,7 +67,7 @@
 #ifdef BUGGY_NEPTUN_TIMER
 		/*
 		 * for the Neptun bug we know that the 'latch'
-		 * command doesnt latch the high and low value
+		 * command doesn't latch the high and low value
 		 * of the counter atomically. Thus we have to 
 		 * substract 256 from the counter 
 		 * ... funny, isnt it? :)
diff -Nru a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h
--- a/include/asm-i386/mach-default/mach_apic.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-i386/mach-default/mach_apic.h	Tue Mar  4 19:30:14 2003
@@ -9,7 +9,7 @@
  #define TARGET_CPUS 0x01
 #endif
 
-#define no_balance_irq (0)
+#define NO_BALANCE_IRQ (0)
 #define esr_disable (0)
 
 #define INT_DELIVERY_MODE dest_LowestPrio
@@ -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 -Nru a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h
--- a/include/asm-i386/mach-numaq/mach_apic.h	Tue Mar  4 19:30:08 2003
+++ b/include/asm-i386/mach-numaq/mach_apic.h	Tue Mar  4 19:30:08 2003
@@ -5,7 +5,7 @@
 
 #define TARGET_CPUS (0xf)
 
-#define no_balance_irq (1)
+#define NO_BALANCE_IRQ (1)
 #define esr_disable (1)
 
 #define INT_DELIVERY_MODE dest_LowestPrio
@@ -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 -Nru a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
--- a/include/asm-i386/mach-summit/mach_apic.h	Tue Mar  4 19:30:10 2003
+++ b/include/asm-i386/mach-summit/mach_apic.h	Tue Mar  4 19:30:10 2003
@@ -4,7 +4,7 @@
 extern int x86_summit;
 
 #define esr_disable (x86_summit ? 1 : 0)
-#define no_balance_irq (0)
+#define NO_BALANCE_IRQ (0)
 
 #define XAPIC_DEST_CPUS_MASK    0x0Fu
 #define XAPIC_DEST_CLUSTER_MASK 0xF0u
@@ -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 -Nru a/include/asm-i386/mach-visws/cobalt.h b/include/asm-i386/mach-visws/cobalt.h
--- a/include/asm-i386/mach-visws/cobalt.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-i386/mach-visws/cobalt.h	Tue Mar  4 19:30:04 2003
@@ -60,7 +60,7 @@
 #define	CO_APIC_PCIA_BASE0	0 /* and 1 */	/* slot 0, line 0 */
 #define	CO_APIC_PCIA_BASE123	5 /* and 6 */	/* slot 0, line 1 */
 
-#define	CO_APIC_PIIX4_USB	7		/* this one is wierd */
+#define	CO_APIC_PIIX4_USB	7		/* this one is weird */
 
 /* Lithium PCI Bridge B -- "the one with PIIX4" */
 #define	CO_APIC_PCIB_BASE0	8 /* and 9-12 *//* slot 0, line 0 */
diff -Nru a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
--- a/include/asm-i386/mmzone.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-i386/mmzone.h	Tue Mar  4 19:30:09 2003
@@ -12,6 +12,8 @@
 
 #ifdef CONFIG_X86_NUMAQ
 #include <asm/numaq.h>
+#elif CONFIG_X86_SUMMIT
+#include <asm/srat.h>
 #else
 #define pfn_to_nid(pfn)		(0)
 #endif /* CONFIG_X86_NUMAQ */
diff -Nru a/include/asm-i386/numaq.h b/include/asm-i386/numaq.h
--- a/include/asm-i386/numaq.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-i386/numaq.h	Tue Mar  4 19:30:09 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()
 
@@ -168,6 +169,10 @@
         struct	eachquadmem eq[MAX_NUMNODES];	/* indexed by quad id */
 };
 
+static inline unsigned long get_zholes_size(int nid)
+{
+	return 0;
+}
 #endif /* CONFIG_X86_NUMAQ */
 #endif /* NUMAQ_H */
 
diff -Nru a/include/asm-i386/numnodes.h b/include/asm-i386/numnodes.h
--- a/include/asm-i386/numnodes.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-i386/numnodes.h	Tue Mar  4 19:30:05 2003
@@ -5,6 +5,8 @@
 
 #ifdef CONFIG_X86_NUMAQ
 #include <asm/numaq.h>
+#elif CONFIG_X86_SUMMIT
+#include <asm/srat.h>
 #else
 #define MAX_NUMNODES	1
 #endif /* CONFIG_X86_NUMAQ */
diff -Nru a/include/asm-i386/page.h b/include/asm-i386/page.h
--- a/include/asm-i386/page.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-i386/page.h	Tue Mar  4 19:30:05 2003
@@ -24,7 +24,7 @@
 #else
 
 /*
- *	On older X86 processors its not a win to use MMX here it seems.
+ *	On older X86 processors it's not a win to use MMX here it seems.
  *	Maybe the K6-III ?
  */
  
@@ -49,6 +49,7 @@
 typedef struct { unsigned long pte_low; } pte_t;
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
+#define boot_pte_t pte_t /* or would you rather have a typedef */
 #define pte_val(x)	((x).pte_low)
 #define HPAGE_SHIFT	22
 #endif
diff -Nru a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
--- a/include/asm-i386/pgtable-2level.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-i386/pgtable-2level.h	Tue Mar  4 19:30:09 2003
@@ -42,7 +42,7 @@
 #define set_pte(pteptr, pteval) (*(pteptr) = pteval)
 #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
 /*
- * (pmds are folded into pgds so this doesnt get actually called,
+ * (pmds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
  */
 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
diff -Nru a/include/asm-i386/rwsem.h b/include/asm-i386/rwsem.h
--- a/include/asm-i386/rwsem.h	Tue Mar  4 19:30:08 2003
+++ b/include/asm-i386/rwsem.h	Tue Mar  4 19:30:08 2003
@@ -33,7 +33,7 @@
 #define _I386_RWSEM_H
 
 #ifndef _LINUX_RWSEM_H
-#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
+#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
 #endif
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h
--- a/include/asm-i386/semaphore.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-i386/semaphore.h	Tue Mar  4 19:30:05 2003
@@ -76,7 +76,7 @@
  *	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
  *
  * i'd rather use the more flexible initialization above, but sadly
- * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
+ * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
  */
 	atomic_set(&sem->count, val);
 	sem->sleepers = 0;
diff -Nru a/include/asm-i386/sigcontext.h b/include/asm-i386/sigcontext.h
--- a/include/asm-i386/sigcontext.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-i386/sigcontext.h	Tue Mar  4 19:30:05 2003
@@ -11,7 +11,7 @@
  * Pentium III FXSR, SSE support
  *	Gareth Hughes <gareth@valinux.com>, May 2000
  *
- * The FPU state data structure has had to grow to accomodate the
+ * The FPU state data structure has had to grow to accommodate the
  * extended FPU state required by the Streaming SIMD Extensions.
  * There is no documented standard to accomplish this at the moment.
  */
diff -Nru a/include/asm-i386/srat.h b/include/asm-i386/srat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/srat.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,46 @@
+/*
+ * Some of the code in this file has been gleaned from the 64 bit 
+ * discontigmem support code base.
+ *
+ * Copyright (C) 2002, IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to Pat Gaughen <gone@us.ibm.com>
+ */
+
+#ifndef _ASM_SRAT_H_
+#define _ASM_SRAT_H_
+
+/*
+ * each element in pfnnode_map represents 256 MB (2^28) of pages.
+ * so, to represent 64GB we need 256 elements.
+ */
+#define MAX_ELEMENTS 256
+#define PFN_TO_ELEMENT(pfn) ((pfn)>>(28 - PAGE_SHIFT))
+
+extern int pfnnode_map[];
+#define pfn_to_nid(pfn) ({ pfnnode_map[PFN_TO_ELEMENT(pfn)]; })
+#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 void get_memcfg_from_srat(void);
+extern unsigned long *get_zholes_size(int);
+#define get_memcfg_numa() get_memcfg_from_srat()
+
+#endif /* _ASM_SRAT_H_ */
diff -Nru a/include/asm-i386/topology.h b/include/asm-i386/topology.h
--- a/include/asm-i386/topology.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-i386/topology.h	Tue Mar  4 19:30:05 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[];
@@ -60,6 +62,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 -Nru a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
--- a/include/asm-i386/uaccess.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-i386/uaccess.h	Tue Mar  4 19:30:04 2003
@@ -101,7 +101,7 @@
  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  * and yet we don't want to do any pointers, because that is too much
  * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the uglyness from the user.
+ * and hide all the ugliness from the user.
  *
  * The "__xxx" versions of the user access functions are versions that
  * do not verify the address space, that must have been done previously
@@ -258,7 +258,7 @@
 unsigned long __copy_from_user_ll(void *to, const void *from, unsigned long n);
 
 /*
- * Here we special-case 1, 2 and 4-byte copy_*_user invokations.  On a fault
+ * Here we special-case 1, 2 and 4-byte copy_*_user invocations.  On a fault
  * we return the initial request size (1, 2 or 4), as copy_*_user should do.
  * If a store crosses a page boundary and gets a fault, the x86 will not write
  * anything, so this is accurate.
diff -Nru a/include/asm-ia64/mmzone.h b/include/asm-ia64/mmzone.h
--- a/include/asm-ia64/mmzone.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-ia64/mmzone.h	Tue Mar  4 19:30:14 2003
@@ -44,7 +44,7 @@
  * Note that IO addresses are NOT considered valid addresses.
  *
  * Note, many platforms can simply check if kaddr exceeds a specific size.  
- *	(However, this wont work on SGI platforms since IO space is embedded 
+ *	(However, this won't work on SGI platforms since IO space is embedded 
  * 	within the range of valid memory addresses & nodes have holes in the 
  *	address range between banks). 
  */
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
--- a/include/asm-ia64/page.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-ia64/page.h	Tue Mar  4 19:30:04 2003
@@ -57,6 +57,16 @@
 # define REGION_SHIFT	61
 # define HPAGE_SIZE	(__IA64_UL_CONST(1) << HPAGE_SHIFT)
 # define HPAGE_MASK	(~(HPAGE_SIZE - 1))
+static inline int
+check_valid_hugepage_range(unsigned long addr, unsigned long len)
+{
+	if (REGION_NUMBER(addr) == REGION_HPAGE)
+		return -EINVAL;
+	if (REGION_NUMBER(addr+len) == REGION_HPAGE)
+		return -EINVAL;
+	return 0;
+}
+#define ARCH_HAS_VALID_HUGEPAGE_RANGE
 #endif /* CONFIG_HUGETLB_PAGE */
 
 #ifdef __ASSEMBLY__
diff -Nru a/include/asm-ia64/sn/klconfig.h b/include/asm-ia64/sn/klconfig.h
--- a/include/asm-ia64/sn/klconfig.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-ia64/sn/klconfig.h	Tue Mar  4 19:30:05 2003
@@ -273,7 +273,7 @@
  * Each BOARD consists of COMPONENTs and the BOARD structure has 
  * pointers (offsets) to its COMPONENT structure.
  * The COMPONENT structure has version info, size and speed info, revision,
- * error info and the NIC info. This structure can accomodate any
+ * error info and the NIC info. This structure can accommodate any
  * BOARD with arbitrary COMPONENT composition.
  *
  * The ERRORINFO part of each BOARD has error information
diff -Nru a/include/asm-ia64/sn/pci/bridge.h b/include/asm-ia64/sn/pci/bridge.h
--- a/include/asm-ia64/sn/pci/bridge.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-ia64/sn/pci/bridge.h	Tue Mar  4 19:30:05 2003
@@ -14,7 +14,7 @@
  * bridge.h - header file for bridge chip and bridge portion of xbridge chip
  *
  * Also including offsets for unique PIC registers.
- * The PIC asic is a follow-on to Xbridge and most of it's registers are
+ * The PIC asic is a follow-on to Xbridge and most of its registers are
  * identical to those of Xbridge.  PIC is different than Xbridge in that
  * it will accept 64 bit register access and that, in some cases, data
  * is kept in bits 63:32.   PIC registers that are identical to Xbridge
@@ -1684,7 +1684,7 @@
 /* RRB clear register */
 #define	BRIDGE_RRB_CLEAR(r)	(0x00000001<<(r))
 
-/* Defines for the virtual channels so we dont hardcode 0-3 within code */
+/* Defines for the virtual channels so we don't hardcode 0-3 within code */
 #define VCHAN0	0	/* virtual channel 0 (ie. the "normal" channel) */
 #define VCHAN1	1	/* virtual channel 1 */
 #define VCHAN2	2	/* virtual channel 2 - PIC only */
diff -Nru a/include/asm-ia64/sn/pci/pcibr_private.h b/include/asm-ia64/sn/pci/pcibr_private.h
--- a/include/asm-ia64/sn/pci/pcibr_private.h	Tue Mar  4 19:30:03 2003
+++ b/include/asm-ia64/sn/pci/pcibr_private.h	Tue Mar  4 19:30:03 2003
@@ -578,7 +578,7 @@
 #ifdef LATER
 	toid_t                  bserr_toutid;	/* Timeout started by errintr */
 #endif	/* LATER */
-	iopaddr_t               bserr_addr;	/* Address where error occured */
+	iopaddr_t               bserr_addr;	/* Address where error occurred */
 	uint64_t		bserr_intstat;	/* interrupts active at error dump */
     } bs_errinfo;
 
diff -Nru a/include/asm-ia64/sn/pda.h b/include/asm-ia64/sn/pda.h
--- a/include/asm-ia64/sn/pda.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-ia64/sn/pda.h	Tue Mar  4 19:30:13 2003
@@ -84,10 +84,10 @@
  * the IA64 cpu_data area. A full page is allocated for the cp_data area for each
  * cpu but only a small amout of the page is actually used. We put the SNIA PDA
  * in the same page as the cpu_data area. Note that there is a check in the setup
- * code to verify that we dont overflow the page.
+ * code to verify that we don't overflow the page.
  *
  * Seems like we should should cache-line align the pda so that any changes in the
- * size of the cpu_data area dont change cache layout. Should we align to 32, 64, 128
+ * size of the cpu_data area don't change cache layout. Should we align to 32, 64, 128
  * or 512 boundary. Each has merits. For now, pick 128 but should be revisited later.
  */
 DECLARE_PER_CPU(struct pda_s, pda_percpu);
diff -Nru a/include/asm-ia64/sn/sn1/mmzone_sn1.h b/include/asm-ia64/sn/sn1/mmzone_sn1.h
--- a/include/asm-ia64/sn/sn1/mmzone_sn1.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-ia64/sn/sn1/mmzone_sn1.h	Tue Mar  4 19:30:14 2003
@@ -130,7 +130,7 @@
 
 /*
  * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
- * nodes so that they dont alias to the same line in the cache as the previous allocated structure.
+ * nodes so that they don't alias to the same line in the cache as the previous allocated structure.
  * This macro takes an address of the end of previous allocation, rounds it to a page boundary & 
  * changes the node number.
  */
diff -Nru a/include/asm-ia64/sn/sn2/mmzone_sn2.h b/include/asm-ia64/sn/sn2/mmzone_sn2.h
--- a/include/asm-ia64/sn/sn2/mmzone_sn2.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-ia64/sn/sn2/mmzone_sn2.h	Tue Mar  4 19:30:13 2003
@@ -137,7 +137,7 @@
 
 /*
  * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
- * nodes so that they dont alias to the same line in the cache as the previous allocated structure.
+ * nodes so that they don't alias to the same line in the cache as the previous allocated structure.
  * This macro takes an address of the end of previous allocation, rounds it to a page boundary & 
  * changes the node number.
  */
diff -Nru a/include/asm-ia64/sn/sn2/shub_mmr.h b/include/asm-ia64/sn/sn2/shub_mmr.h
--- a/include/asm-ia64/sn/sn2/shub_mmr.h	Tue Mar  4 19:30:11 2003
+++ b/include/asm-ia64/sn/sn2/shub_mmr.h	Tue Mar  4 19:30:11 2003
@@ -2720,7 +2720,7 @@
 #define SH_NI0_LLP_ERR_RETRY_COUNT_MASK          0x0000000000ff0000
 
 /*   SH_NI0_LLP_ERR_RETRY_TIMEOUT                                       */
-/*   Description:  Indicates a retry timeout has occured                */
+/*   Description:  Indicates a retry timeout has occurred               */
 #define SH_NI0_LLP_ERR_RETRY_TIMEOUT_SHFT        24
 #define SH_NI0_LLP_ERR_RETRY_TIMEOUT_MASK        0x0000000001000000
 
@@ -3017,7 +3017,7 @@
 #define SH_NI1_LLP_ERR_RETRY_COUNT_MASK          0x0000000000ff0000
 
 /*   SH_NI1_LLP_ERR_RETRY_TIMEOUT                                       */
-/*   Description:  Indicates a retry timeout has occured                */
+/*   Description:  Indicates a retry timeout has occurred               */
 #define SH_NI1_LLP_ERR_RETRY_TIMEOUT_SHFT        24
 #define SH_NI1_LLP_ERR_RETRY_TIMEOUT_MASK        0x0000000001000000
 
@@ -26034,7 +26034,7 @@
 #define SH_PIO_WRITE_STATUS_0_INIT               0x8000000000000000
 
 /*   SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR                            */
-/*   Description:  More than one PIO write error occured                */
+/*   Description:  More than one PIO write error occurred               */
 #define SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR_SHFT 0
 #define SH_PIO_WRITE_STATUS_0_MULTI_WRITE_ERROR_MASK 0x0000000000000001
 
@@ -26073,7 +26073,7 @@
 #define SH_PIO_WRITE_STATUS_1_INIT               0x8000000000000000
 
 /*   SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR                            */
-/*   Description:  More than one PIO write error occured                */
+/*   Description:  More than one PIO write error occurred               */
 #define SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR_SHFT 0
 #define SH_PIO_WRITE_STATUS_1_MULTI_WRITE_ERROR_MASK 0x0000000000000001
 
diff -Nru a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
--- a/include/asm-ia64/sn/sn_cpuid.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-ia64/sn/sn_cpuid.h	Tue Mar  4 19:30:04 2003
@@ -47,7 +47,7 @@
  *			hard_smp_processor_id()- cpu_physical_id of current processor
  *			cpu_physical_id(cpuid) - convert a <cpuid> to a <physical_cpuid>
  *			cpu_logical_id(phy_id) - convert a <physical_cpuid> to a <cpuid> 
- *				* not real efficient - dont use in perf critical code
+ *				* not real efficient - don't use in perf critical code
  *
  *         LID - processor defined register (see PRM V2).
  *
diff -Nru a/include/asm-m68k/dvma.h b/include/asm-m68k/dvma.h
--- a/include/asm-m68k/dvma.h	Tue Mar  4 19:30:10 2003
+++ b/include/asm-m68k/dvma.h	Tue Mar  4 19:30:10 2003
@@ -45,7 +45,7 @@
 #define IOMMU_ENTRIES 120
 
 /* empirical kludge -- dvma regions only seem to work right on 0x10000 
-   byte boundries */
+   byte boundaries */
 #define DVMA_REGION_SIZE 0x10000
 #define DVMA_ALIGN(addr) (((addr)+DVMA_REGION_SIZE-1) & \
                          ~(DVMA_REGION_SIZE-1))
diff -Nru a/include/asm-m68k/io.h b/include/asm-m68k/io.h
--- a/include/asm-m68k/io.h	Tue Mar  4 19:30:10 2003
+++ b/include/asm-m68k/io.h	Tue Mar  4 19:30:10 2003
@@ -250,7 +250,7 @@
 #define readl(addr)      in_le32(addr)
 #define writel(val,addr) out_le32((addr),(val))
 
-/* those can be defined for both ISA and PCI - it wont work though */
+/* those can be defined for both ISA and PCI - it won't work though */
 #define readb(addr)       in_8(addr)
 #define readw(addr)       in_le16(addr)
 #define writeb(val,addr)  out_8((addr),(val))
diff -Nru a/include/asm-m68k/page.h b/include/asm-m68k/page.h
--- a/include/asm-m68k/page.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-m68k/page.h	Tue Mar  4 19:30:14 2003
@@ -164,7 +164,7 @@
  * NOTE: virtual isn't really correct, actually it should be the offset into the
  * memory node, but we have no highmem, so that works for now.
  * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots
- * of the shifts unneccessary.
+ * of the shifts unnecessary.
  */
 #define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
diff -Nru a/include/asm-m68k/posix_types.h b/include/asm-m68k/posix_types.h
--- a/include/asm-m68k/posix_types.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-m68k/posix_types.h	Tue Mar  4 19:30:04 2003
@@ -22,6 +22,8 @@
 typedef long		__kernel_time_t;
 typedef long		__kernel_suseconds_t;
 typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
 typedef int		__kernel_daddr_t;
 typedef char *		__kernel_caddr_t;
 typedef unsigned short	__kernel_uid16_t;
diff -Nru a/include/asm-m68k/swim_iop.h b/include/asm-m68k/swim_iop.h
--- a/include/asm-m68k/swim_iop.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-m68k/swim_iop.h	Tue Mar  4 19:30:04 2003
@@ -60,7 +60,7 @@
 
 #define	gcrOnMFMErr	-400	/* GCR (400/800K) on HD media */
 #define	verErr		-84	/* verify failed */
-#define	fmt2Err		-83	/* cant get enough sync during format */
+#define	fmt2Err		-83	/* can't get enough sync during format */
 #define	fmt1Err		-82	/* can't find sector 0 after track format */
 #define	sectNFErr	-81	/* can't find sector */
 #define	seekErr		-80	/* drive error during seek */
diff -Nru a/include/asm-m68knommu/MC68328.h b/include/asm-m68knommu/MC68328.h
--- a/include/asm-m68knommu/MC68328.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-m68knommu/MC68328.h	Tue Mar  4 19:30:05 2003
@@ -1237,10 +1237,10 @@
 #define RTCISR		WORD_REF(RTCISR_ADDR)
 
 #define RTCISR_SW	0x0001	/* Stopwatch timed out */
-#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
-#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
-#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
-#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occurred */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occurred */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occurred */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occurred */
 
 /*
  * RTC Interrupt Enable Register
diff -Nru a/include/asm-m68knommu/MC68EZ328.h b/include/asm-m68knommu/MC68EZ328.h
--- a/include/asm-m68knommu/MC68EZ328.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-m68knommu/MC68EZ328.h	Tue Mar  4 19:30:14 2003
@@ -1071,19 +1071,19 @@
 #define RTCISR		WORD_REF(RTCISR_ADDR)
 
 #define RTCISR_SW	0x0001	/* Stopwatch timed out */
-#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
-#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
-#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
-#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
-#define RTCISR_HR	0x0020	/* 1-hour interrupt has occured */
-#define RTCISR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt has occured */ 
-#define RTCISR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt has occured */ 
-#define RTCISR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt has occured */ 
-#define RTCISR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt has occured */ 
-#define RTCISR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt has occured */ 
-#define RTCISR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt has occured */ 
-#define RTCISR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt has occured */ 
-#define RTCISR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt has occured */ 
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occurred */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occurred */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occurred */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occurred */
+#define RTCISR_HR	0x0020	/* 1-hour interrupt has occurred */
+#define RTCISR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt has occurred */ 
+#define RTCISR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt has occurred */ 
+#define RTCISR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt has occurred */ 
+#define RTCISR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt has occurred */ 
+#define RTCISR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt has occurred */ 
+#define RTCISR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt has occurred */ 
+#define RTCISR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt has occurred */ 
+#define RTCISR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt has occurred */ 
 
 /*
  * RTC Interrupt Enable Register
diff -Nru a/include/asm-m68knommu/MC68VZ328.h b/include/asm-m68knommu/MC68VZ328.h
--- a/include/asm-m68knommu/MC68VZ328.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-m68knommu/MC68VZ328.h	Tue Mar  4 19:30:05 2003
@@ -1167,19 +1167,19 @@
 #define RTCISR		WORD_REF(RTCISR_ADDR)
 
 #define RTCISR_SW	0x0001	/* Stopwatch timed out */
-#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occured */
-#define RTCISR_ALM	0x0004	/* Alarm interrupt has occured */
-#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occured */
-#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occured */
-#define RTCISR_HR	0x0020	/* 1-hour interrupt has occured */
-#define RTCISR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt has occured */ 
-#define RTCISR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt has occured */ 
-#define RTCISR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt has occured */ 
-#define RTCISR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt has occured */ 
-#define RTCISR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt has occured */ 
-#define RTCISR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt has occured */ 
-#define RTCISR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt has occured */ 
-#define RTCISR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt has occured */ 
+#define RTCISR_MIN	0x0002	/* 1-minute interrupt has occurred */
+#define RTCISR_ALM	0x0004	/* Alarm interrupt has occurred */
+#define RTCISR_DAY	0x0008	/* 24-hour rollover interrupt has occurred */
+#define RTCISR_1HZ	0x0010	/* 1Hz interrupt has occurred */
+#define RTCISR_HR	0x0020	/* 1-hour interrupt has occurred */
+#define RTCISR_SAM0	0x0100	/*   4Hz /   4.6875Hz interrupt has occurred */ 
+#define RTCISR_SAM1	0x0200	/*   8Hz /   9.3750Hz interrupt has occurred */ 
+#define RTCISR_SAM2	0x0400	/*  16Hz /  18.7500Hz interrupt has occurred */ 
+#define RTCISR_SAM3	0x0800	/*  32Hz /  37.5000Hz interrupt has occurred */ 
+#define RTCISR_SAM4	0x1000	/*  64Hz /  75.0000Hz interrupt has occurred */ 
+#define RTCISR_SAM5	0x2000	/* 128Hz / 150.0000Hz interrupt has occurred */ 
+#define RTCISR_SAM6	0x4000	/* 256Hz / 300.0000Hz interrupt has occurred */ 
+#define RTCISR_SAM7	0x8000	/* 512Hz / 600.0000Hz interrupt has occurred */ 
 
 /*
  * RTC Interrupt Enable Register
diff -Nru a/include/asm-m68knommu/mcftimer.h b/include/asm-m68knommu/mcftimer.h
--- a/include/asm-m68knommu/mcftimer.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-m68knommu/mcftimer.h	Tue Mar  4 19:30:09 2003
@@ -40,6 +40,18 @@
 #define	MCFTIMER_TCN		0x06		/* Timer Counter reg (r/w) */
 #define	MCFTIMER_TER		0x11		/* Timer Event reg (r/w) */
 
+struct mcftimer {
+	unsigned short	tmr;			/* Timer Mode reg (r/w) */
+	unsigned short	reserved1;
+	unsigned short	trr;			/* Timer Reference (r/w) */
+	unsigned short	reserved2;
+	unsigned short	tcr;			/* Timer Capture reg (r/w) */
+	unsigned short	reserved3;
+	unsigned short	tcn;			/* Timer Counter reg (r/w) */
+	unsigned short	reserved4;
+	unsigned char	reserved5;
+	unsigned char	ter;			/* Timer Event reg (r/w) */
+} __attribute__((packed));
 
 /*
  *	Bit definitions for the Timer Mode Register (TMR).
diff -Nru a/include/asm-m68knommu/siginfo.h b/include/asm-m68knommu/siginfo.h
--- a/include/asm-m68knommu/siginfo.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-m68knommu/siginfo.h	Tue Mar  4 19:30:05 2003
@@ -1 +1,6 @@
-#include <asm-m68k/siginfo.h>
+#ifndef _M68KNOMMU_SIGINFO_H
+#define _M68KNOMMU_SIGINFO_H
+
+#include <asm-generic/siginfo.h>
+
+#endif
diff -Nru a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h
--- a/include/asm-m68knommu/unistd.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-m68knommu/unistd.h	Tue Mar  4 19:30:09 2003
@@ -221,6 +221,8 @@
 #define __NR_setfsuid32		215
 #define __NR_setfsgid32		216
 
+#define	NR_syscalls		256
+
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
 
diff -Nru a/include/asm-mips/ddb5xxx/ddb5xxx.h b/include/asm-mips/ddb5xxx/ddb5xxx.h
--- a/include/asm-mips/ddb5xxx/ddb5xxx.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-mips/ddb5xxx/ddb5xxx.h	Tue Mar  4 19:30:09 2003
@@ -34,7 +34,7 @@
  * that are true for all DDB 5xxx boards.  The modification is based on
  *
  *	uPD31577(VRC5477) VR5432-SDRAM/PCI Bridge (Luke)
- *	Preliminary Specification Decoment, Rev 1.1, 27 Dec, 2000
+ *	Preliminary Specification Document, Rev 1.1, 27 Dec, 2000
  *  
  */
 
diff -Nru a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
--- a/include/asm-mips/mipsregs.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-mips/mipsregs.h	Tue Mar  4 19:30:09 2003
@@ -528,7 +528,7 @@
 #define CE1_SP_HINT_TO_SHARED_SC_BLOCKS	15
 
 /*
- * These flags define in which priviledge mode the counters count events
+ * These flags define in which privilege mode the counters count events
  */
 #define CEB_USER	8	/* Count events in user mode, EXL = ERL = 0 */
 #define CEB_SUPERVISOR	4	/* Count events in supvervisor mode EXL = ERL = 0 */
diff -Nru a/include/asm-mips/pci.h b/include/asm-mips/pci.h
--- a/include/asm-mips/pci.h	Tue Mar  4 19:30:11 2003
+++ b/include/asm-mips/pci.h	Tue Mar  4 19:30:11 2003
@@ -102,7 +102,7 @@
  * must match what was provided for in a previous pci_map_single call.  All
  * other usages are undefined.
  *
- * After this call, reads by the cpu to the buffer are guarenteed to see
+ * After this call, reads by the cpu to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
 extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
diff -Nru a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
--- a/include/asm-mips/pgtable.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-mips/pgtable.h	Tue Mar  4 19:30:05 2003
@@ -291,7 +291,7 @@
 }
 
 /*
- * (pmds are folded into pgds so this doesnt get actually called,
+ * (pmds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
  */
 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
diff -Nru a/include/asm-mips/processor.h b/include/asm-mips/processor.h
--- a/include/asm-mips/processor.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-mips/processor.h	Tue Mar  4 19:30:04 2003
@@ -228,7 +228,7 @@
  * Do necessary setup to start up a newly executed thread.
  */
 #define start_thread(regs, new_pc, new_sp) do {				\
-	/* New thread looses kernel privileges. */			\
+	/* New thread loses kernel privileges. */			\
 	regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KU_USER;\
 	regs->cp0_epc = new_pc;						\
 	regs->regs[29] = new_sp;					\
diff -Nru a/include/asm-mips64/mipsregs.h b/include/asm-mips64/mipsregs.h
--- a/include/asm-mips64/mipsregs.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-mips64/mipsregs.h	Tue Mar  4 19:30:13 2003
@@ -310,7 +310,7 @@
 #define CE1_SP_HINT_TO_SHARED_SC_BLOCKS	15
 
 /*
- * These flags define in which priviledge mode the counters count events
+ * These flags define in which privilege mode the counters count events
  */
 #define CEB_USER	8	/* Count events in user mode, EXL = ERL = 0 */
 #define CEB_SUPERVISOR	4	/* Count events in supvervisor mode EXL = ERL = 0 */
diff -Nru a/include/asm-mips64/pci.h b/include/asm-mips64/pci.h
--- a/include/asm-mips64/pci.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-mips64/pci.h	Tue Mar  4 19:30:04 2003
@@ -126,7 +126,7 @@
  * must match what was provided for in a previous pci_map_single call.  All
  * other usages are undefined.
  *
- * After this call, reads by the cpu to the buffer are guarenteed to see
+ * After this call, reads by the cpu to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
 static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
diff -Nru a/include/asm-mips64/pgtable.h b/include/asm-mips64/pgtable.h
--- a/include/asm-mips64/pgtable.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-mips64/pgtable.h	Tue Mar  4 19:30:14 2003
@@ -318,7 +318,7 @@
 }
 
 /*
- * (pmds are folded into pgds so this doesnt get actually called,
+ * (pmds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
  */
 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
diff -Nru a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h
--- a/include/asm-mips64/processor.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-mips64/processor.h	Tue Mar  4 19:30:09 2003
@@ -256,7 +256,7 @@
 do {									\
 	unsigned long __status;						\
 									\
-	/* New thread looses kernel privileges. */			\
+	/* New thread loses kernel privileges. */			\
 	__status = regs->cp0_status & ~(ST0_CU0|ST0_FR|ST0_KSU);	\
 	__status |= KSU_USER;						\
 	__status |= (current->thread.mflags & MF_32BIT) ? 0 : ST0_FR;	\
diff -Nru a/include/asm-mips64/sn/klconfig.h b/include/asm-mips64/sn/klconfig.h
--- a/include/asm-mips64/sn/klconfig.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-mips64/sn/klconfig.h	Tue Mar  4 19:30:09 2003
@@ -293,7 +293,7 @@
  * Each BOARD consists of COMPONENTs and the BOARD structure has 
  * pointers (offsets) to its COMPONENT structure.
  * The COMPONENT structure has version info, size and speed info, revision,
- * error info and the NIC info. This structure can accomodate any
+ * error info and the NIC info. This structure can accommodate any
  * BOARD with arbitrary COMPONENT composition.
  *
  * The ERRORINFO part of each BOARD has error information
diff -Nru a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h
--- a/include/asm-parisc/assembly.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-parisc/assembly.h	Tue Mar  4 19:30:09 2003
@@ -381,7 +381,7 @@
 	/* cr11 (sar) is a funny one.  5 bits on PA1.1 and 6 bit on PA2.0
 	 * For PA2.0 mtsar or mtctl always write 6 bits, but mfctl only
 	 * reads 5 bits.  Use mfctl,w to read all six bits.  Otherwise
-	 * we loose the 6th bit on a save/restore over interrupt.
+	 * we lose the 6th bit on a save/restore over interrupt.
 	 */
 	mfctl,w  %cr11, %r1
 	STREG    %r1, PT_SAR (\regs)
diff -Nru a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
--- a/include/asm-parisc/cacheflush.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-parisc/cacheflush.h	Tue Mar  4 19:30:14 2003
@@ -25,16 +25,10 @@
 
 extern void flush_cache_all_local(void);
 
-#ifdef CONFIG_SMP
 static inline void flush_cache_all(void)
 {
-	smp_call_function((void (*)(void *))flush_cache_all_local, NULL, 1, 1);
-	flush_cache_all_local();
+	on_each_cpu((void (*)(void *))flush_cache_all_local, NULL, 1, 1);
 }
-#else
-#define flush_cache_all flush_cache_all_local
-#endif
-
 
 /* The following value needs to be tuned and probably scaled with the
  * cache size.
diff -Nru a/include/asm-parisc/eisa_eeprom.h b/include/asm-parisc/eisa_eeprom.h
--- a/include/asm-parisc/eisa_eeprom.h	Tue Mar  4 19:30:10 2003
+++ b/include/asm-parisc/eisa_eeprom.h	Tue Mar  4 19:30:10 2003
@@ -25,7 +25,7 @@
 	u_int8_t  ver_maj;
 	u_int8_t  ver_min;
 	u_int8_t  num_slots;        /* number of EISA slots in system */
-	u_int16_t csum;             /* checksum, I dont know how to calulate this */
+	u_int16_t csum;             /* checksum, I don't know how to calulate this */
 	u_int8_t  pad[10];
 } __attribute__ ((packed));
 
diff -Nru a/include/asm-parisc/mman.h b/include/asm-parisc/mman.h
--- a/include/asm-parisc/mman.h	Tue Mar  4 19:30:10 2003
+++ b/include/asm-parisc/mman.h	Tue Mar  4 19:30:10 2003
@@ -32,7 +32,7 @@
 #define MADV_RANDOM     1               /* expect random page references */
 #define MADV_SEQUENTIAL 2               /* expect sequential page references */
 #define MADV_WILLNEED   3               /* will need these pages */
-#define MADV_DONTNEED   4               /* dont need these pages */
+#define MADV_DONTNEED   4               /* don't need these pages */
 #define MADV_SPACEAVAIL 5               /* insure that resources are reserved */
 #define MADV_VPS_PURGE  6               /* Purge pages from VM page cache */
 #define MADV_VPS_INHERIT 7              /* Inherit parents page size */
diff -Nru a/include/asm-parisc/pdc_chassis.h b/include/asm-parisc/pdc_chassis.h
--- a/include/asm-parisc/pdc_chassis.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-parisc/pdc_chassis.h	Tue Mar  4 19:30:04 2003
@@ -116,7 +116,7 @@
 					 PDC_CHASSIS_LED_ATTN_OFF	| \
 					 PDC_CHASSIS_LED_FAULT_ON	| \
 					 PDC_CHASSIS_LED_VALID		)
-/* Unexpected reboot occured - Executing non-OS code */
+/* Unexpected reboot occurred - Executing non-OS code */
 #define PDC_CHASSIS_LSTATE_NONOS_UNEXP	(PDC_CHASSIS_LED_RUN_FLASH	| \
 					 PDC_CHASSIS_LED_ATTN_OFF	| \
 					 PDC_CHASSIS_LED_FAULT_FLASH	| \
diff -Nru a/include/asm-ppc/page.h b/include/asm-ppc/page.h
--- a/include/asm-ppc/page.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-ppc/page.h	Tue Mar  4 19:30:05 2003
@@ -58,7 +58,7 @@
 #endif
 
 
-/* align addr on a size boundry - adjust address up if needed -- Cort */
+/* align addr on a size boundary - adjust address up if needed -- Cort */
 #define _ALIGN(addr,size)	(((addr)+(size)-1)&(~((size)-1)))
 
 /* to align the pointer to the (next) page boundary */
diff -Nru a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h
--- a/include/asm-ppc/uaccess.h	Tue Mar  4 19:30:04 2003
+++ b/include/asm-ppc/uaccess.h	Tue Mar  4 19:30:04 2003
@@ -65,7 +65,7 @@
  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  * and yet we don't want to do any pointers, because that is too much
  * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the uglyness from the user.
+ * and hide all the ugliness from the user.
  *
  * The "__xxx" versions of the user access functions are versions that
  * do not verify the address space, that must have been done previously
diff -Nru a/include/asm-ppc/uninorth.h b/include/asm-ppc/uninorth.h
--- a/include/asm-ppc/uninorth.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-ppc/uninorth.h	Tue Mar  4 19:30:13 2003
@@ -111,7 +111,7 @@
 #define UNI_N_ARB_CTRL_QACK_DELAY105	0x00
 
 /* This one _might_ return the CPU number of the CPU reading it;
- * the bootROM decides wether to boot or to sleep/spinloop depending
+ * the bootROM decides whether to boot or to sleep/spinloop depending
  * on this register beeing 0 or not
  */
 #define UNI_N_CPU_NUMBER		0x0050
diff -Nru a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
--- a/include/asm-ppc64/page.h	Tue Mar  4 19:30:03 2003
+++ b/include/asm-ppc64/page.h	Tue Mar  4 19:30:03 2003
@@ -114,11 +114,11 @@
 
 #endif /* __ASSEMBLY__ */
 
-/* align addr on a size boundry - adjust address up/down if needed */
+/* align addr on a size boundary - adjust address up/down if needed */
 #define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1)))
 #define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1)))
 
-/* align addr on a size boundry - adjust address up if needed */
+/* align addr on a size boundary - adjust address up if needed */
 #define _ALIGN(addr,size)     _ALIGN_UP(addr,size)
 
 /* to align the pointer to the (next) double word boundary */
diff -Nru a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
--- a/include/asm-ppc64/pgtable.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-ppc64/pgtable.h	Tue Mar  4 19:30:13 2003
@@ -198,7 +198,7 @@
  * Find an entry in a page-table-directory.  We combine the address region 
  * (the high order N bits) and the pgd portion of the address.
  */
-/* to avoid overflow in free_pgtables we dont use PTRS_PER_PGD here */
+/* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */
 #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x7ff)
 
 #define pgd_offset(mm, address)	 ((mm)->pgd + pgd_index(address))
diff -Nru a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h
--- a/include/asm-ppc64/uaccess.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-ppc64/uaccess.h	Tue Mar  4 19:30:09 2003
@@ -73,7 +73,7 @@
  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  * and yet we don't want to do any pointers, because that is too much
  * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the uglyness from the user.
+ * and hide all the ugliness from the user.
  *
  * The "__xxx" versions of the user access functions are versions that
  * do not verify the address space, that must have been done previously
diff -Nru a/include/asm-s390/ccwdev.h b/include/asm-s390/ccwdev.h
--- a/include/asm-s390/ccwdev.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-s390/ccwdev.h	Tue Mar  4 19:30:13 2003
@@ -120,7 +120,7 @@
 					/* device is no longer available     */
 	int (*set_online) (struct ccw_device *);
 	int (*set_offline) (struct ccw_device *);
-	struct device_driver driver;	/* higher level structure, dont init
+	struct device_driver driver;	/* higher level structure, don't init
 					   this from your driver	     */
 	char *name;
 };
diff -Nru a/include/asm-s390/processor.h b/include/asm-s390/processor.h
--- a/include/asm-s390/processor.h	Tue Mar  4 19:30:08 2003
+++ b/include/asm-s390/processor.h	Tue Mar  4 19:30:08 2003
@@ -154,7 +154,7 @@
 }
  
 /*
- * Function to stop a processor until an interruption occured
+ * Function to stop a processor until an interruption occurred
  */
 static inline void enabled_wait(void)
 {
diff -Nru a/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h
--- a/include/asm-s390/rwsem.h	Tue Mar  4 19:30:08 2003
+++ b/include/asm-s390/rwsem.h	Tue Mar  4 19:30:08 2003
@@ -38,7 +38,7 @@
  */
 
 #ifndef _LINUX_RWSEM_H
-#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
+#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
 #endif
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-s390/types.h b/include/asm-s390/types.h
--- a/include/asm-s390/types.h	Tue Mar  4 19:30:09 2003
+++ b/include/asm-s390/types.h	Tue Mar  4 19:30:09 2003
@@ -32,7 +32,7 @@
 typedef unsigned long long __u64;
 #endif
 /* A address type so that arithmetic can be done on it & it can be upgraded to
-   64 bit when neccessary 
+   64 bit when necessary 
 */
 typedef __u32  addr_t; 
 typedef __s32  saddr_t;
diff -Nru a/include/asm-s390x/ccwdev.h b/include/asm-s390x/ccwdev.h
--- a/include/asm-s390x/ccwdev.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-s390x/ccwdev.h	Tue Mar  4 19:30:13 2003
@@ -120,7 +120,7 @@
 					/* device is no longer available     */
 	int (*set_online) (struct ccw_device *);
 	int (*set_offline) (struct ccw_device *);
-	struct device_driver driver;	/* higher level structure, dont init
+	struct device_driver driver;	/* higher level structure, don't init
 					   this from your driver	     */
 	char *name;
 };
diff -Nru a/include/asm-s390x/processor.h b/include/asm-s390x/processor.h
--- a/include/asm-s390x/processor.h	Tue Mar  4 19:30:12 2003
+++ b/include/asm-s390x/processor.h	Tue Mar  4 19:30:12 2003
@@ -168,7 +168,7 @@
 }
 
 /*
- * Function to stop a processor until an interruption occured
+ * Function to stop a processor until an interruption occurred
  */
 static inline void enabled_wait(void)
 {
diff -Nru a/include/asm-s390x/rwsem.h b/include/asm-s390x/rwsem.h
--- a/include/asm-s390x/rwsem.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-s390x/rwsem.h	Tue Mar  4 19:30:05 2003
@@ -38,7 +38,7 @@
  */
 
 #ifndef _LINUX_RWSEM_H
-#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
+#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
 #endif
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-s390x/types.h b/include/asm-s390x/types.h
--- a/include/asm-s390x/types.h	Tue Mar  4 19:30:07 2003
+++ b/include/asm-s390x/types.h	Tue Mar  4 19:30:07 2003
@@ -32,7 +32,7 @@
 
 /* 
  * A address type so that arithmetic can be done on it & it can be upgraded to
- * 64 bit when neccessary 
+ * 64 bit when necessary 
  */
 
 typedef unsigned long  addr_t; 
diff -Nru a/include/asm-sh/pci.h b/include/asm-sh/pci.h
--- a/include/asm-sh/pci.h	Tue Mar  4 19:30:11 2003
+++ b/include/asm-sh/pci.h	Tue Mar  4 19:30:11 2003
@@ -118,7 +118,7 @@
  * must match what was provided for in a previous pci_map_single call.  All
  * other usages are undefined.
  *
- * After this call, reads by the cpu to the buffer are guarenteed to see
+ * After this call, reads by the cpu to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
 static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
diff -Nru a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h
--- a/include/asm-sh/semaphore.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-sh/semaphore.h	Tue Mar  4 19:30:14 2003
@@ -54,7 +54,7 @@
  *	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
  *
  * i'd rather use the more flexible initialization above, but sadly
- * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
+ * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
  */
 	atomic_set(&sem->count, val);
 	sem->sleepers = 0;
diff -Nru a/include/asm-sparc/ioctl.h b/include/asm-sparc/ioctl.h
--- a/include/asm-sparc/ioctl.h	Tue Mar  4 19:30:12 2003
+++ b/include/asm-sparc/ioctl.h	Tue Mar  4 19:30:12 2003
@@ -2,23 +2,35 @@
 #ifndef _SPARC_IOCTL_H
 #define _SPARC_IOCTL_H
 
+/*
+ * Our DIR and SIZE overlap in order to simulteneously provide
+ * a non-zero _IOC_NONE (for binary compatibility) and
+ * 14 bits of size as on i386. Here's the layout:
+ *
+ *   0xE0000000   DIR
+ *   0x80000000     DIR = WRITE
+ *   0x40000000     DIR = READ
+ *   0x20000000     DIR = NONE
+ *   0x3FFF0000   SIZE (overlaps NONE bit)
+ *   0x0000FF00   TYPE
+ *   0x000000FF   NR (CMD)
+ */
+
 #define _IOC_NRBITS      8
 #define _IOC_TYPEBITS    8
-#define _IOC_SIZEBITS    8
-#define _IOC_RESVBITS    5
+#define _IOC_SIZEBITS   13	/* Actually 14, see below. */
 #define _IOC_DIRBITS     3
 
 #define _IOC_NRMASK      ((1 << _IOC_NRBITS)-1)
 #define _IOC_TYPEMASK    ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_RESVMASK    ((1 << _IOC_RESVBITS)-1)
 #define _IOC_SIZEMASK    ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_XSIZEMASK   ((1 << (_IOC_SIZEBITS+1))-1)
 #define _IOC_DIRMASK     ((1 << _IOC_DIRBITS)-1)
 
 #define _IOC_NRSHIFT     0
 #define _IOC_TYPESHIFT   (_IOC_NRSHIFT + _IOC_NRBITS)
 #define _IOC_SIZESHIFT   (_IOC_TYPESHIFT + _IOC_TYPEBITS)
-#define _IOC_RESVSHIFT   (_IOC_SIZESHIFT + _IOC_SIZEBITS)
-#define _IOC_DIRSHIFT    (_IOC_RESVSHIFT + _IOC_RESVBITS)
+#define _IOC_DIRSHIFT    (_IOC_SIZESHIFT + _IOC_SIZEBITS)
 
 #define _IOC_NONE        1U
 #define _IOC_READ        2U
@@ -35,17 +47,20 @@
 #define _IOW(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
 #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
 
-#define _IOC_DIR(nr)        (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+/* Used to decode ioctl numbers in drivers despite the leading underscore... */
+#define _IOC_DIR(nr)    \
+ ( (((((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) & (_IOC_WRITE|_IOC_READ)) != 0)?   \
+                            (((nr) >> _IOC_DIRSHIFT) & (_IOC_WRITE|_IOC_READ)):  \
+                            (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) )
 #define _IOC_TYPE(nr)       (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
 #define _IOC_NR(nr)         (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the PCMCIA... */
+#define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_XSIZEMASK)
 
+/* ...and for the PCMCIA and sound. */
 #define IOC_IN          (_IOC_WRITE << _IOC_DIRSHIFT)
 #define IOC_OUT         (_IOC_READ << _IOC_DIRSHIFT)
 #define IOC_INOUT       ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK    (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_MASK    (_IOC_XSIZEMASK << _IOC_SIZESHIFT)
 #define IOCSIZE_SHIFT   (_IOC_SIZESHIFT)
 
 #endif /* !(_SPARC_IOCTL_H) */
diff -Nru a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h
--- a/include/asm-sparc/pci.h	Tue Mar  4 19:30:12 2003
+++ b/include/asm-sparc/pci.h	Tue Mar  4 19:30:12 2003
@@ -59,7 +59,7 @@
  * must match what was provided for in a previous pci_map_single call.  All
  * other usages are undefined.
  *
- * After this call, reads by the cpu to the buffer are guarenteed to see
+ * After this call, reads by the cpu to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
 extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction);
diff -Nru a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h
--- a/include/asm-sparc/uaccess.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-sparc/uaccess.h	Tue Mar  4 19:30:13 2003
@@ -89,7 +89,7 @@
  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  * and yet we don't want to do any pointers, because that is too much
  * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the uglyness from the user.
+ * and hide all the ugliness from the user.
  */
 #define put_user(x,ptr) ({ \
 unsigned long __pu_addr = (unsigned long)(ptr); \
diff -Nru a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h
--- a/include/asm-sparc64/hardirq.h	Tue Mar  4 19:30:11 2003
+++ b/include/asm-sparc64/hardirq.h	Tue Mar  4 19:30:11 2003
@@ -10,6 +10,7 @@
 #include <linux/threads.h>
 #include <linux/brlock.h>
 #include <linux/spinlock.h>
+#include <linux/cache.h>
 
 /* entry.S is sensitive to the offsets of these fields */
 /* rtrap.S is sensitive to the size of this structure */
diff -Nru a/include/asm-sparc64/ioctl.h b/include/asm-sparc64/ioctl.h
--- a/include/asm-sparc64/ioctl.h	Tue Mar  4 19:30:13 2003
+++ b/include/asm-sparc64/ioctl.h	Tue Mar  4 19:30:13 2003
@@ -2,23 +2,35 @@
 #ifndef _SPARC64_IOCTL_H
 #define _SPARC64_IOCTL_H
 
+/*
+ * Our DIR and SIZE overlap in order to simulteneously provide
+ * a non-zero _IOC_NONE (for binary compatibility) and
+ * 14 bits of size as on i386. Here's the layout:
+ *
+ *   0xE0000000   DIR
+ *   0x80000000     DIR = WRITE
+ *   0x40000000     DIR = READ
+ *   0x20000000     DIR = NONE
+ *   0x3FFF0000   SIZE (overlaps NONE bit)
+ *   0x0000FF00   TYPE
+ *   0x000000FF   NR (CMD)
+ */
+
 #define _IOC_NRBITS      8
 #define _IOC_TYPEBITS    8
-#define _IOC_SIZEBITS    8
-#define _IOC_RESVBITS    5
+#define _IOC_SIZEBITS   13	/* Actually 14, see below. */
 #define _IOC_DIRBITS     3
 
 #define _IOC_NRMASK      ((1 << _IOC_NRBITS)-1)
 #define _IOC_TYPEMASK    ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_RESVMASK    ((1 << _IOC_RESVBITS)-1)
 #define _IOC_SIZEMASK    ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_XSIZEMASK   ((1 << (_IOC_SIZEBITS+1))-1)
 #define _IOC_DIRMASK     ((1 << _IOC_DIRBITS)-1)
 
 #define _IOC_NRSHIFT     0
 #define _IOC_TYPESHIFT   (_IOC_NRSHIFT + _IOC_NRBITS)
 #define _IOC_SIZESHIFT   (_IOC_TYPESHIFT + _IOC_TYPEBITS)
-#define _IOC_RESVSHIFT   (_IOC_SIZESHIFT + _IOC_SIZEBITS)
-#define _IOC_DIRSHIFT    (_IOC_RESVSHIFT + _IOC_RESVBITS)
+#define _IOC_DIRSHIFT    (_IOC_SIZESHIFT + _IOC_SIZEBITS)
 
 #define _IOC_NONE        1U
 #define _IOC_READ        2U
@@ -35,17 +47,20 @@
 #define _IOW(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
 #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
 
-#define _IOC_DIR(nr)        (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+/* Used to decode ioctl numbers in drivers despite the leading underscore... */
+#define _IOC_DIR(nr)    \
+ ( (((((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) & (_IOC_WRITE|_IOC_READ)) != 0)?   \
+                            (((nr) >> _IOC_DIRSHIFT) & (_IOC_WRITE|_IOC_READ)):  \
+                            (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) )
 #define _IOC_TYPE(nr)       (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
 #define _IOC_NR(nr)         (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the PCMCIA... */
+#define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_XSIZEMASK)
 
+/* ...and for the PCMCIA and sound. */
 #define IOC_IN          (_IOC_WRITE << _IOC_DIRSHIFT)
 #define IOC_OUT         (_IOC_READ << _IOC_DIRSHIFT)
 #define IOC_INOUT       ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK    (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_MASK    (_IOC_XSIZEMASK << _IOC_SIZESHIFT)
 #define IOCSIZE_SHIFT   (_IOC_SIZESHIFT)
 
 #endif /* !(_SPARC64_IOCTL_H) */
diff -Nru a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
--- a/include/asm-sparc64/pbm.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-sparc64/pbm.h	Tue Mar  4 19:30:14 2003
@@ -59,7 +59,7 @@
 	unsigned long	iommu_ctxflush;		/* IOMMU context flush register */
 
 	/* This is a register in the PCI controller, which if
-	 * read will have no side-effects but will guarentee
+	 * read will have no side-effects but will guarantee
 	 * completion of all previous writes into IOMMU/STC.
 	 */
 	unsigned long	write_complete_reg;
diff -Nru a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
--- a/include/asm-sparc64/pci.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-sparc64/pci.h	Tue Mar  4 19:30:05 2003
@@ -67,7 +67,7 @@
  * must match what was provided for in a previous pci_map_single call.  All
  * other usages are undefined.
  *
- * After this call, reads by the cpu to the buffer are guarenteed to see
+ * After this call, reads by the cpu to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
 extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction);
diff -Nru a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h
--- a/include/asm-sparc64/rwsem.h	Tue Mar  4 19:30:11 2003
+++ b/include/asm-sparc64/rwsem.h	Tue Mar  4 19:30:11 2003
@@ -8,7 +8,7 @@
 #define _SPARC64_RWSEM_H
 
 #ifndef _LINUX_RWSEM_H
-#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
+#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
 #endif
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h
--- a/include/asm-sparc64/uaccess.h	Tue Mar  4 19:30:08 2003
+++ b/include/asm-sparc64/uaccess.h	Tue Mar  4 19:30:08 2003
@@ -96,7 +96,7 @@
  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  * and yet we don't want to do any pointers, because that is too much
  * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the uglyness from the user.
+ * and hide all the ugliness from the user.
  */
 #define put_user(x,ptr) ({ \
 unsigned long __pu_addr = (unsigned long)(ptr); \
diff -Nru a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
--- a/include/asm-um/pgtable.h	Tue Mar  4 19:30:14 2003
+++ b/include/asm-um/pgtable.h	Tue Mar  4 19:30:14 2003
@@ -226,7 +226,7 @@
 }
 
 /*
- * (pmds are folded into pgds so this doesnt get actually called,
+ * (pmds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
  */
 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
diff -Nru a/include/asm-v850/sim.h b/include/asm-v850/sim.h
--- a/include/asm-v850/sim.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-v850/sim.h	Tue Mar  4 19:30:05 2003
@@ -22,7 +22,7 @@
 #define PLATFORM_LONG		"GDB V850E simulator"
 
 
-/* We use a wierd value for RAM, not just 0, for testing purposes.
+/* We use a weird value for RAM, not just 0, for testing purposes.
    These must match the values used in the linker script.  */
 #define RAM_ADDR		0x8F000000
 #define RAM_SIZE		0x01000000
diff -Nru a/include/asm-x86_64/rwsem.h b/include/asm-x86_64/rwsem.h
--- a/include/asm-x86_64/rwsem.h	Tue Mar  4 19:30:12 2003
+++ b/include/asm-x86_64/rwsem.h	Tue Mar  4 19:30:12 2003
@@ -34,7 +34,7 @@
 #define _X8664_RWSEM_H
 
 #ifndef _LINUX_RWSEM_H
-#error please dont include asm/rwsem.h directly, use linux/rwsem.h instead
+#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
 #endif
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-x86_64/semaphore.h b/include/asm-x86_64/semaphore.h
--- a/include/asm-x86_64/semaphore.h	Tue Mar  4 19:30:03 2003
+++ b/include/asm-x86_64/semaphore.h	Tue Mar  4 19:30:03 2003
@@ -78,7 +78,7 @@
  *	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
  *
  * i'd rather use the more flexible initialization above, but sadly
- * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
+ * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
  */
 	atomic_set(&sem->count, val);
 	sem->sleepers = 0;
diff -Nru a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
--- a/include/asm-x86_64/uaccess.h	Tue Mar  4 19:30:05 2003
+++ b/include/asm-x86_64/uaccess.h	Tue Mar  4 19:30:05 2003
@@ -79,7 +79,7 @@
  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  * and yet we don't want to do any pointers, because that is too much
  * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the uglyness from the user.
+ * and hide all the ugliness from the user.
  *
  * The "__xxx" versions of the user access functions are versions that
  * do not verify the address space, that must have been done previously
diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h
--- a/include/linux/acpi.h	Tue Mar  4 19:30:03 2003
+++ b/include/linux/acpi.h	Tue Mar  4 19:30:03 2003
@@ -79,7 +79,7 @@
 
 struct acpi_table_rsdt {
 	struct acpi_table_header header;
-	u32			entry[1];
+	u32			entry[8];
 } __attribute__ ((packed));
 
 /* Extended System Description Table (XSDT) */
diff -Nru a/include/linux/agp_backend.h b/include/linux/agp_backend.h
--- a/include/linux/agp_backend.h	Tue Mar  4 19:30:12 2003
+++ b/include/linux/agp_backend.h	Tue Mar  4 19:30:12 2003
@@ -46,6 +46,8 @@
 	INTEL_I820,
 	INTEL_I830_M,
 	INTEL_I845_G,
+	INTEL_I855_PM,
+	INTEL_I865_G,
 	INTEL_I840,
 	INTEL_I845,
 	INTEL_I850,
diff -Nru a/include/linux/cciss_ioctl.h b/include/linux/cciss_ioctl.h
--- a/include/linux/cciss_ioctl.h	Tue Mar  4 19:30:08 2003
+++ b/include/linux/cciss_ioctl.h	Tue Mar  4 19:30:08 2003
@@ -33,6 +33,18 @@
 typedef char FirmwareVer_type[4];
 typedef __u32 DriverVer_type;
 
+#define MAX_KMALLOC_SIZE 128000
+
+typedef struct _BIG_IOCTL_Command_struct {
+  LUNAddr_struct	   LUN_info;
+  RequestBlock_struct      Request;
+  ErrorInfo_struct  	   error_info; 
+  DWORD			   malloc_size; /* < MAX_KMALLOC_SIZE in cciss.c */
+  DWORD			   buf_size;    /* size in bytes of the buf */
+  				        /* < malloc_size * MAXSGENTRIES */
+  BYTE			   *buf;
+} BIG_IOCTL_Command_struct;
+
 
 #ifndef CCISS_CMD_H
 // This defines are duplicated in cciss_cmd.h in the driver directory 
@@ -169,6 +181,11 @@
   BYTE			   *buf;
 } IOCTL_Command_struct;
 
+typedef struct _LogvolInfo_struct{
+	__u32	LunID;
+	int	num_opens;  /* number of opens on the logical volume */
+	int	num_parts;  /* number of partitions configured on logvol */
+} LogvolInfo_struct;
 
 #define CCISS_GETPCIINFO _IOR(CCISS_IOC_MAGIC, 1, cciss_pci_info_struct)
 
@@ -190,5 +207,7 @@
 #define CCISS_REGNEWDISK  _IOW(CCISS_IOC_MAGIC, 13, int)
 
 #define CCISS_REGNEWD	   _IO(CCISS_IOC_MAGIC, 14)
+#define CCISS_GETLUNINFO   _IOR(CCISS_IOC_MAGIC, 17, LogvolInfo_struct)
+#define CCISS_BIG_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL_Command_struct)
 
 #endif  
diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h	Tue Mar  4 19:30:10 2003
+++ b/include/linux/cpufreq.h	Tue Mar  4 19:30:10 2003
@@ -62,10 +62,13 @@
 	unsigned int            cpu;    /* cpu nr or CPUFREQ_ALL_CPUS */
 	unsigned int            min;    /* in kHz */
 	unsigned int            max;    /* in kHz */
+	unsigned int            cur;    /* in kHz, only needed if cpufreq
+					 * governors are used */
         unsigned int            policy; /* see above */
 	struct cpufreq_governor *governor; /* see below */
 	struct cpufreq_cpuinfo  cpuinfo;     /* see above */
-	struct intf_data        intf;   /* interface data */
+	struct device		* dev;
+	struct kobject		kobj;
 };
 
 #define CPUFREQ_ADJUST          (0)
@@ -164,10 +167,6 @@
 	/* optional, for the moment */
 	int	(*init)		(struct cpufreq_policy *policy);
 	int	(*exit)		(struct cpufreq_policy *policy);
-	/* 2.4. compatible API */
-#ifdef CONFIG_CPU_FREQ_24_API
-	unsigned int		cpu_cur_freq[NR_CPUS];
-#endif
 };
 
 int cpufreq_register_driver(struct cpufreq_driver *driver_data);
@@ -208,14 +207,19 @@
 /* the proc_intf.c needs this */
 int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
 
-#ifdef CONFIG_CPU_FREQ_24_API
+#if defined(CONFIG_CPU_FREQ_GOV_USERSPACE) || defined(CONFIG_CPU_FREQ_GOV_USERSPACE_MODULE)
 /*********************************************************************
- *                        CPUFREQ 2.4. INTERFACE                     *
+ *                      CPUFREQ USERSPACE GOVERNOR                   *
  *********************************************************************/
+extern struct cpufreq_governor cpufreq_gov_userspace;
+int cpufreq_gov_userspace_init(void);
+
 int cpufreq_setmax(unsigned int cpu);
 int cpufreq_set(unsigned int kHz, unsigned int cpu);
 unsigned int cpufreq_get(unsigned int cpu);
 
+#ifdef CONFIG_CPU_FREQ_24_API
+
 /* /proc/sys/cpu */
 enum {
 	CPU_NR   = 1,           /* compatibilty reasons */
@@ -260,44 +264,9 @@
 	CPU_NR_FREQ = 3,
 };
 
-#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MAX, \
-                .data		= &cpu_max_freq[cpunr], \
-                .procname	= "speed-max", \
-                .maxlen		= sizeof(cpu_max_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MIN, \
-                .data		= &cpu_min_freq[cpunr], \
-                .procname	= "speed-min", \
-                .maxlen		= sizeof(cpu_min_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ, \
-                .procname	= "speed", \
-                .mode		= 0644, \
-                .proc_handler	= cpufreq_procctl, \
-                .strategy	= cpufreq_sysctl, \
-                .extra1		= (void*) (cpunr), }
-
-#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
-                CTL_CPU_VARS_SPEED_MAX(cpunr), \
-                CTL_CPU_VARS_SPEED_MIN(cpunr), \
-                CTL_CPU_VARS_SPEED(cpunr),  \
-                { .ctl_name = 0, }, }
-
-/* the ctl_table entry for each CPU */
-#define CPU_ENUM(s) { \
-                .ctl_name	= (CPU_NR + s), \
-                .procname	= #s, \
-                .mode		= 0555, \
-                .child		= ctl_cpu_vars_##s }
-
 #endif /* CONFIG_CPU_FREQ_24_API */
+
+#endif /* CONFIG_CPU_FREQ_GOV_USERSPACE */
 
 
 /*********************************************************************
diff -Nru a/include/linux/cyclades.h b/include/linux/cyclades.h
--- a/include/linux/cyclades.h	Tue Mar  4 19:30:14 2003
+++ b/include/linux/cyclades.h	Tue Mar  4 19:30:14 2003
@@ -141,7 +141,7 @@
 /****************** ****************** *******************/
 /*
  *	The data types defined below are used in all ZFIRM interface
- *	data structures. They accomodate differences between HW
+ *	data structures. They accommodate differences between HW
  *	architectures and compilers.
  */
 
diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h
--- a/include/linux/dcache.h	Tue Mar  4 19:30:14 2003
+++ b/include/linux/dcache.h	Tue Mar  4 19:30:14 2003
@@ -76,25 +76,25 @@
 	atomic_t d_count;
 	unsigned long d_vfs_flags;	/* moved here to be on same cacheline */
 	spinlock_t d_lock;		/* per dentry lock */
-	unsigned int d_flags;
-	unsigned long d_move_count;	/* to indicated moved dentry while lockless lookup */
 	struct inode  * d_inode;	/* Where the name belongs to - NULL is negative */
-	struct dentry * d_parent;	/* parent directory */
-	struct list_head * d_bucket;	/* lookup hash bucket */
-	struct list_head d_hash;	/* lookup hash list */
 	struct list_head d_lru;		/* LRU list */
 	struct list_head d_child;	/* child of parent list */
 	struct list_head d_subdirs;	/* our children */
 	struct list_head d_alias;	/* inode alias list */
-	int d_mounted;
-	struct qstr d_name;
-	struct qstr * d_qstr;		/* quick str ptr used in lockless lookup and concurrent d_move */
 	unsigned long d_time;		/* used by d_revalidate */
 	struct dentry_operations  *d_op;
 	struct super_block * d_sb;	/* The root of the dentry tree */
+	unsigned int d_flags;
+	int d_mounted;
 	void * d_fsdata;		/* fs-specific data */
  	struct rcu_head d_rcu;
 	struct dcookie_struct * d_cookie; /* cookie, if any */
+	unsigned long d_move_count;	/* to indicated moved dentry while lockless lookup */
+	struct qstr * d_qstr;		/* quick str ptr used in lockless lookup and concurrent d_move */
+	struct dentry * d_parent;	/* parent directory */
+	struct qstr d_name;
+	struct hlist_node d_hash;	/* lookup hash list */	
+	struct hlist_head * d_bucket;	/* lookup hash bucket */
 	unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
 } ____cacheline_aligned;
 
@@ -171,7 +171,7 @@
 static __inline__ void __d_drop(struct dentry * dentry)
 {
 	dentry->d_vfs_flags |= DCACHE_UNHASHED;
-	list_del_rcu(&dentry->d_hash);
+	hlist_del_rcu(&dentry->d_hash);
 }
 
 static __inline__ void d_drop(struct dentry * dentry)
@@ -198,7 +198,7 @@
 extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
 extern void shrink_dcache_sb(struct super_block *);
 extern void shrink_dcache_parent(struct dentry *);
-extern void shrink_dcache_anon(struct list_head *);
+extern void shrink_dcache_anon(struct hlist_head *);
 extern int d_invalidate(struct dentry *);
 
 /* only used at mount-time */
@@ -262,6 +262,8 @@
 static __inline__ struct dentry * dget(struct dentry *dentry)
 {
 	if (dentry) {
+		if (!atomic_read(&dentry->d_count))
+			BUG();
 		atomic_inc(&dentry->d_count);
 		dentry->d_vfs_flags |= DCACHE_REFERENCED;
 	}
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	Tue Mar  4 19:30:13 2003
+++ b/include/linux/device.h	Tue Mar  4 19:30:13 2003
@@ -27,9 +27,9 @@
 #include <linux/ioport.h>
 #include <linux/kobject.h>
 #include <linux/list.h>
-#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <asm/semaphore.h>
 #include <asm/atomic.h>
 
 #define DEVICE_NAME_SIZE	50
@@ -207,8 +207,6 @@
  * it supports the device.
  */
 
-struct intf_data;
-
 struct device_interface {
 	char			* name;
 	struct device_class	* devclass;
@@ -217,41 +215,19 @@
 	u32			devnum;
 
 	int (*add_device)	(struct device *);
-	int (*remove_device)	(struct intf_data *);
+	int (*remove_device)	(struct device *);
 };
 
 extern int interface_register(struct device_interface *);
 extern void interface_unregister(struct device_interface *);
 
 
-/*
- * intf_data - per-device data for an interface
- * Each interface typically has a per-device data structure 
- * that it allocates. It should embed one of these structures 
- * in that structure and call interface_add_data() to add it
- * to the device's list.
- * That will also enumerate the device within the interface
- * and create a driverfs symlink for it.
- */
-struct intf_data {
-	struct device_interface	* intf;
-	struct device		* dev;
-	u32			intf_num;
-	struct list_head	dev_entry;
-	struct kobject		kobj;
-};
-
-extern int interface_add_data(struct intf_data *);
-
-
-
 struct device {
 	struct list_head node;		/* node in sibling list */
 	struct list_head bus_list;	/* node in bus's list */
 	struct list_head class_list;
 	struct list_head driver_list;
 	struct list_head children;
-	struct list_head intf_list;
 	struct device 	* parent;
 
 	struct kobject kobj;
diff -Nru a/include/linux/ethtool.h b/include/linux/ethtool.h
--- a/include/linux/ethtool.h	Tue Mar  4 19:30:05 2003
+++ b/include/linux/ethtool.h	Tue Mar  4 19:30:05 2003
@@ -22,7 +22,7 @@
 	u8	duplex;		/* Duplex, half or full */
 	u8	port;		/* Which connector port */
 	u8	phy_address;
-	u8	transceiver;	/* Which tranceiver to use */
+	u8	transceiver;	/* Which transceiver to use */
 	u8	autoneg;	/* Enable or disable autonegotiation */
 	u32	maxtxpkt;	/* Tx pkts before generating tx int */
 	u32	maxrxpkt;	/* Rx pkts before generating rx int */
@@ -336,7 +336,7 @@
 #define PORT_FIBRE		0x03
 #define PORT_BNC		0x04
 
-/* Which tranceiver to use. */
+/* Which transceiver to use. */
 #define XCVR_INTERNAL		0x00
 #define XCVR_EXTERNAL		0x01
 #define XCVR_DUMMY1		0x02
diff -Nru a/include/linux/fcdevice.h b/include/linux/fcdevice.h
--- a/include/linux/fcdevice.h	Tue Mar  4 19:30:05 2003
+++ b/include/linux/fcdevice.h	Tue Mar  4 19:30:05 2003
@@ -31,7 +31,7 @@
 				   unsigned short type, void *daddr,
 				   void *saddr, unsigned len);
 extern int		fc_rebuild_header(struct sk_buff *skb);
-//extern unsigned short	fc_type_trans(struct sk_buff *skb, struct net_device *dev); 
+extern unsigned short	fc_type_trans(struct sk_buff *skb, struct net_device *dev); 
 
 extern struct net_device *init_fcdev(struct net_device *dev, int sizeof_priv);
 extern struct net_device *alloc_fcdev(int sizeof_priv);
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Tue Mar  4 19:30:05 2003
+++ b/include/linux/fs.h	Tue Mar  4 19:30:05 2003
@@ -18,6 +18,7 @@
 #include <linux/stat.h>
 #include <linux/cache.h>
 #include <linux/radix-tree.h>
+#include <linux/kobject.h>
 #include <asm/atomic.h>
 
 struct iovec;
@@ -353,7 +354,7 @@
 };
 
 struct inode {
-	struct list_head	i_hash;
+	struct hlist_node	i_hash;
 	struct list_head	i_list;
 	struct list_head	i_dentry;
 	unsigned long		i_ino;
@@ -601,7 +602,7 @@
 
 	struct list_head	s_dirty;	/* dirty inodes */
 	struct list_head	s_io;		/* parked for writeback */
-	struct list_head	s_anon;		/* anonymous dentries for (nfs) exporting */
+	struct hlist_head	s_anon;		/* anonymous dentries for (nfs) exporting */
 	struct list_head	s_files;
 
 	struct block_device	*s_bdev;
@@ -610,6 +611,7 @@
 
 	char s_id[32];				/* Informational name */
 
+	struct kobject           kobj;          /* anchor for sysfs */
 	void 			*s_fs_info;	/* Filesystem private info */
 
 	/*
@@ -743,9 +745,9 @@
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
-	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t,int);
-	ssize_t (*listxattr) (struct dentry *, char *, size_t, int);
-	int (*removexattr) (struct dentry *, const char *, int);
+	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+	ssize_t (*listxattr) (struct dentry *, char *, size_t);
+	int (*removexattr) (struct dentry *, const char *);
 };
 
 struct seq_file;
@@ -913,6 +915,7 @@
 
 struct file_system_type {
 	const char *name;
+	struct subsystem subsys;
 	int fs_flags;
 	struct super_block *(*get_sb) (struct file_system_type *, int, char *, void *);
 	void (*kill_sb) (struct super_block *);
diff -Nru a/include/linux/gfp.h b/include/linux/gfp.h
--- a/include/linux/gfp.h	Tue Mar  4 19:30:05 2003
+++ b/include/linux/gfp.h	Tue Mar  4 19:30:05 2003
@@ -49,24 +49,16 @@
 extern struct page * FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *));
 static inline struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order)
 {
-	struct pglist_data *pgdat = NODE_DATA(nid);
-	unsigned int idx = (gfp_mask & GFP_ZONEMASK);
-
 	if (unlikely(order >= MAX_ORDER))
 		return NULL;
-	return __alloc_pages(gfp_mask, order, pgdat->node_zonelists + idx);
-}
-static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
-{
-	struct pglist_data *pgdat = NODE_DATA(numa_node_id());
-	unsigned int idx = (gfp_mask & GFP_ZONEMASK);
 
-	if (unlikely(order >= MAX_ORDER))
-		return NULL;
-	return __alloc_pages(gfp_mask, order, pgdat->node_zonelists + idx);
+	return __alloc_pages(gfp_mask, order, NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK));
 }
 
-#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
+#define alloc_pages(gfp_mask, order) \
+		alloc_pages_node(numa_node_id(), gfp_mask, order)
+#define alloc_page(gfp_mask) \
+		alloc_pages_node(numa_node_id(), gfp_mask, 0)
 
 extern unsigned long FASTCALL(__get_free_pages(unsigned int gfp_mask, unsigned int order));
 extern unsigned long FASTCALL(get_zeroed_page(unsigned int gfp_mask));
diff -Nru a/include/linux/ghash.h b/include/linux/ghash.h
--- a/include/linux/ghash.h	Tue Mar  4 19:30:14 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,218 +0,0 @@
-/*
- * include/linux/ghash.h -- generic hashing with fuzzy retrieval
- *
- * (C) 1997 Thomas Schoebel-Theuer
- *
- * The algorithms implemented here seem to be a completely new invention,
- * and I'll publish the fundamentals in a paper.
- */
-
-#ifndef _GHASH_H
-#define _GHASH_H
-/* HASHSIZE _must_ be a power of two!!! */
-
-
-#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
-\
-struct NAME##_table {\
-	TYPE * hashtable[HASHSIZE];\
-	TYPE * sorted_list;\
-	int nr_entries;\
-};\
-\
-struct NAME##_ptrs {\
-	TYPE * next_hash;\
-	TYPE * prev_hash;\
-	TYPE * next_sorted;\
-	TYPE * prev_sorted;\
-};
-
-#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
-\
-LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
-{\
-	int ix = HASHFN(elem->KEY);\
-	TYPE ** base = &tbl->hashtable[ix];\
-	TYPE * ptr = *base;\
-	TYPE * prev = NULL;\
-\
-	tbl->nr_entries++;\
-	while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
-		base = &ptr->PTRS.next_hash;\
-		prev = ptr;\
-		ptr = *base;\
-	}\
-	elem->PTRS.next_hash = ptr;\
-	elem->PTRS.prev_hash = prev;\
-	if(ptr) {\
-		ptr->PTRS.prev_hash = elem;\
-	}\
-	*base = elem;\
-\
-	ptr = prev;\
-	if(!ptr) {\
-		ptr = tbl->sorted_list;\
-		prev = NULL;\
-	} else {\
-		prev = ptr->PTRS.prev_sorted;\
-	}\
-	while(ptr) {\
-		TYPE * next = ptr->PTRS.next_hash;\
-		if(next && KEYCMP(next->KEY, elem->KEY)) {\
-			prev = ptr;\
-			ptr = next;\
-		} else if(KEYCMP(ptr->KEY, elem->KEY)) {\
-			prev = ptr;\
-			ptr = ptr->PTRS.next_sorted;\
-		} else\
-			break;\
-	}\
-	elem->PTRS.next_sorted = ptr;\
-	elem->PTRS.prev_sorted = prev;\
-	if(ptr) {\
-		ptr->PTRS.prev_sorted = elem;\
-	}\
-	if(prev) {\
-		prev->PTRS.next_sorted = elem;\
-	} else {\
-		tbl->sorted_list = elem;\
-	}\
-}\
-\
-LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
-{\
-	TYPE * next = elem->PTRS.next_hash;\
-	TYPE * prev = elem->PTRS.prev_hash;\
-\
-	tbl->nr_entries--;\
-	if(next)\
-		next->PTRS.prev_hash = prev;\
-	if(prev)\
-		prev->PTRS.next_hash = next;\
-	else {\
-		int ix = HASHFN(elem->KEY);\
-		tbl->hashtable[ix] = next;\
-	}\
-\
-	next = elem->PTRS.next_sorted;\
-	prev = elem->PTRS.prev_sorted;\
-	if(next)\
-		next->PTRS.prev_sorted = prev;\
-	if(prev)\
-		prev->PTRS.next_sorted = next;\
-	else\
-		tbl->sorted_list = next;\
-}\
-\
-LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
-{\
-	int ix = hashfn(pos);\
-	TYPE * ptr = tbl->hashtable[ix];\
-	while(ptr && KEYCMP(ptr->KEY, pos))\
-		ptr = ptr->PTRS.next_hash;\
-	if(ptr && !KEYEQ(ptr->KEY, pos))\
-		ptr = NULL;\
-	return ptr;\
-}\
-\
-LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
-{\
-	int ix;\
-	int offset;\
-	TYPE * ptr;\
-	TYPE * next;\
-\
-	ptr = tbl->sorted_list;\
-	if(!ptr || KEYCMP(pos, ptr->KEY))\
-		return NULL;\
-	ix = HASHFN(pos);\
-	offset = HASHSIZE;\
-	do {\
-		offset >>= 1;\
-		next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\
-		if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\
-		   && KEYCMP(ptr->KEY, next->KEY))\
-			ptr = next;\
-	} while(offset);\
-\
-	for(;;) {\
-		next = ptr->PTRS.next_hash;\
-		if(next) {\
-			if(KEYCMP(next->KEY, pos)) {\
-				ptr = next;\
-				continue;\
-			}\
-		}\
-		next = ptr->PTRS.next_sorted;\
-		if(next && KEYCMP(next->KEY, pos)) {\
-			ptr = next;\
-			continue;\
-		}\
-		return ptr;\
-	}\
-	return NULL;\
-}
-
-#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
-\
-struct NAME##_table {\
-	TYPE * hashtable[HASHSIZE];\
-	int nr_entries;\
-};\
-\
-struct NAME##_ptrs {\
-	TYPE * next_hash;\
-	TYPE * prev_hash;\
-};
-
-#define DEF_HASH(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
-\
-LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
-{\
-	int ix = HASHFN(elem->KEY);\
-	TYPE ** base = &tbl->hashtable[ix];\
-	TYPE * ptr = *base;\
-	TYPE * prev = NULL;\
-\
-	tbl->nr_entries++;\
-	while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
-		base = &ptr->PTRS.next_hash;\
-		prev = ptr;\
-		ptr = *base;\
-	}\
-	elem->PTRS.next_hash = ptr;\
-	elem->PTRS.prev_hash = prev;\
-	if(ptr) {\
-		ptr->PTRS.prev_hash = elem;\
-	}\
-	*base = elem;\
-}\
-\
-LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
-{\
-	TYPE * next = elem->PTRS.next_hash;\
-	TYPE * prev = elem->PTRS.prev_hash;\
-\
-	tbl->nr_entries--;\
-	if(next)\
-		next->PTRS.prev_hash = prev;\
-	if(prev)\
-		prev->PTRS.next_hash = next;\
-	else {\
-		int ix = HASHFN(elem->KEY);\
-		tbl->hashtable[ix] = next;\
-	}\
-}\
-\
-LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
-{\
-	int ix = hashfn(pos);\
-	TYPE * ptr = tbl->hashtable[ix];\
-	while(ptr && KEYCMP(ptr->KEY, pos))\
-		ptr = ptr->PTRS.next_hash;\
-	if(ptr && !KEYEQ(ptr->KEY, pos))\
-		ptr = NULL;\
-	return ptr;\
-}
-
-#endif
diff -Nru a/include/linux/hugetlb.h b/include/linux/hugetlb.h
--- a/include/linux/hugetlb.h	Tue Mar  4 19:30:08 2003
+++ b/include/linux/hugetlb.h	Tue Mar  4 19:30:08 2003
@@ -4,7 +4,6 @@
 #ifdef CONFIG_HUGETLB_PAGE
 
 struct ctl_table;
-struct hugetlb_key;
 
 static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
 {
@@ -38,6 +37,10 @@
 		mm->used_hugetlb = 1;
 }
 
+#ifndef ARCH_HAS_VALID_HUGEPAGE_RANGE
+#define check_valid_hugepage_range(addr, len)	0
+#endif
+
 #else /* !CONFIG_HUGETLB_PAGE */
 
 static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
@@ -59,6 +62,7 @@
 #define follow_huge_pmd(mm, addr, pmd, write)	0
 #define is_aligned_hugepage_range(addr, len)	0
 #define pmd_huge(x)	0
+#define check_valid_hugepage_range(addr, len)	0
 
 #ifndef HPAGE_MASK
 #define HPAGE_MASK	0		/* Keep the compiler happy */
diff -Nru a/include/linux/i2c-proc.h b/include/linux/i2c-proc.h
--- a/include/linux/i2c-proc.h	Tue Mar  4 19:30:10 2003
+++ b/include/linux/i2c-proc.h	Tue Mar  4 19:30:10 2003
@@ -69,8 +69,7 @@
    these functions must be updated! */
 extern int i2c_register_entry(struct i2c_client *client,
 				  const char *prefix,
-				  ctl_table * ctl_template,
-				  struct module *controlling_mod);
+				  ctl_table * ctl_template);
 
 extern void i2c_deregister_entry(int id);
 
diff -Nru a/include/linux/if.h b/include/linux/if.h
--- a/include/linux/if.h	Tue Mar  4 19:30:08 2003
+++ b/include/linux/if.h	Tue Mar  4 19:30:08 2003
@@ -59,7 +59,7 @@
 #define IF_IFACE_X21	0x1002		/* X.21 serial interface	*/
 #define IF_IFACE_T1	0x1003		/* T1 telco serial interface	*/
 #define IF_IFACE_E1	0x1004		/* E1 telco serial interface	*/
-#define IF_IFACE_SYNC_SERIAL 0x1005	/* cant'b be set by software	*/
+#define IF_IFACE_SYNC_SERIAL 0x1005	/* can't be set by software	*/
 
 /* For definitions see hdlc.h */
 #define IF_PROTO_HDLC	0x2000		/* raw HDLC protocol		*/
diff -Nru a/include/linux/ipmi.h b/include/linux/ipmi.h
--- a/include/linux/ipmi.h	Tue Mar  4 19:30:14 2003
+++ b/include/linux/ipmi.h	Tue Mar  4 19:30:14 2003
@@ -166,7 +166,7 @@
 typedef struct ipmi_user *ipmi_user_t;
 
 /*
- * Stuff coming from the recieve interface comes as one of these.
+ * Stuff coming from the receive interface comes as one of these.
  * They are allocated, the receiver must free them with
  * ipmi_free_recv_msg() when done with the message.  The link is not
  * used after the message is delivered, so the upper layer may use the
diff -Nru a/include/linux/jiffies.h b/include/linux/jiffies.h
--- a/include/linux/jiffies.h	Tue Mar  4 19:30:04 2003
+++ b/include/linux/jiffies.h	Tue Mar  4 19:30:04 2003
@@ -28,7 +28,7 @@
  *	These inlines deal with timer wrapping correctly. You are 
  *	strongly encouraged to use them
  *	1. Because people otherwise forget
- *	2. Because if the timer wrap changes in future you wont have to
+ *	2. Because if the timer wrap changes in future you won't have to
  *	   alter your driver code.
  *
  * time_after(a,b) returns true if the time a is after time b.
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h	Tue Mar  4 19:30:04 2003
+++ b/include/linux/kobject.h	Tue Mar  4 19:30:04 2003
@@ -73,7 +73,7 @@
 
 static inline struct kset * to_kset(struct kobject * kobj)
 {
-	return container_of(kobj,struct kset,kobj);
+	return kobj ? container_of(kobj,struct kset,kobj) : NULL;
 }
 
 static inline struct kset * kset_get(struct kset * k)
diff -Nru a/include/linux/list.h b/include/linux/list.h
--- a/include/linux/list.h	Tue Mar  4 19:30:09 2003
+++ b/include/linux/list.h	Tue Mar  4 19:30:09 2003
@@ -319,6 +319,98 @@
 	for (pos = (head)->next, n = pos->next; pos != (head); \
 		pos = n, ({ read_barrier_depends(); 0;}), n = pos->next)
 
+/* 
+ * Double linked lists with a single pointer list head. 
+ * Mostly useful for hash tables where the two pointer list head is 
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */ 
+
+struct hlist_head { 
+	struct hlist_node *first; 
+}; 
+
+struct hlist_node { 
+	struct hlist_node *next, **pprev; 
+}; 
+
+#define HLIST_HEAD_INIT { .first = NULL } 
+#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) 
+#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
+
+static __inline__ int hlist_unhashed(struct hlist_node *h) 
+{ 
+	return !h->pprev;
+} 
+
+static __inline__ int hlist_empty(struct hlist_head *h) 
+{ 
+	return !h->first;
+} 
+
+static __inline__ void __hlist_del(struct hlist_node *n) 
+{
+	struct hlist_node *next = n->next;
+	struct hlist_node **pprev = n->pprev;
+	*pprev = next;  
+	if (next) 
+		next->pprev = pprev;
+}  
+
+static __inline__ void hlist_del(struct hlist_node *n)
+{
+	if (n->pprev)
+		__hlist_del(n);
+}
+
+#define hlist_del_rcu hlist_del  /* list_del_rcu is identical too? */
+
+static __inline__ void hlist_del_init(struct hlist_node *n) 
+{
+	if (n->pprev)  {
+		__hlist_del(n);
+		INIT_HLIST_NODE(n);
+	}
+}  
+
+static __inline__ void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 
+{ 
+	struct hlist_node *first = h->first;
+	n->next = first; 
+	if (first) 
+		first->pprev = &n->next;
+	h->first = n; 
+	n->pprev = &h->first; 
+} 
+
+static __inline__ void hlist_add_head_rcu(struct hlist_node *n, struct hlist_head *h) 
+{ 
+	struct hlist_node *first = h->first;
+	n->next = first;
+	n->pprev = &h->first; 
+	smp_wmb();
+	if (first) 
+		first->pprev = &n->next;
+	h->first = n; 
+} 
+
+/* next must be != NULL */
+static __inline__ void hlist_add_before(struct hlist_node *n, struct hlist_node *next)
+{
+	n->pprev = next->pprev;
+	n->next = next; 
+	next->pprev = &n->next; 
+	*(n->pprev) = n;
+}
+
+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+
+/* Cannot easily do prefetch unfortunately */
+#define hlist_for_each(pos, head) \
+	for (pos = (head)->first; pos; \
+	     pos = pos->next) 
+
 #else
 #warning "don't include kernel headers in userspace"
 #endif /* __KERNEL__ */
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h	Tue Mar  4 19:30:04 2003
+++ b/include/linux/mm.h	Tue Mar  4 19:30:04 2003
@@ -232,11 +232,15 @@
 static inline void put_page(struct page *page)
 {
 	if (PageCompound(page)) {
-		page = (struct page *)page->lru.next;
-		if (page->lru.prev) {	/* destructor? */
-			(*(void (*)(struct page *))page->lru.prev)(page);
-			return;
+		if (put_page_testzero(page)) {
+			page = (struct page *)page->lru.next;
+			if (page->lru.prev) {	/* destructor? */
+				(*(void (*)(struct page *))page->lru.prev)(page);
+			} else {
+				__page_cache_release(page);
+			}
 		}
+		return;
 	}
 	if (!PageReserved(page) && put_page_testzero(page))
 		__page_cache_release(page);
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h	Tue Mar  4 19:30:12 2003
+++ b/include/linux/module.h	Tue Mar  4 19:30:12 2003
@@ -150,13 +150,7 @@
 void *__symbol_get_gpl(const char *symbol);
 #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
 
-#ifdef __GENKSYMS__
-
-/* genksyms doesn't handle GPL-only symbols yet */
-#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
-	
-#else
-
+#ifndef __GENKSYMS__
 #ifdef CONFIG_MODVERSIONS
 /* Mark the CRC weak since genksyms apparently decides not to
  * generate a checksums for some symbols */
@@ -188,7 +182,7 @@
 #endif
 
 /* We don't mangle the actual symbol anymore, so no need for
- * special casing EXPORT_SYMBOL_NOVERS */
+ * special casing EXPORT_SYMBOL_NOVERS.  FIXME: Deprecated */
 #define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
 
 struct module_ref
diff -Nru a/include/linux/n_r3964.h b/include/linux/n_r3964.h
--- a/include/linux/n_r3964.h	Tue Mar  4 19:30:12 2003
+++ b/include/linux/n_r3964.h	Tue Mar  4 19:30:12 2003
@@ -165,7 +165,7 @@
 {
 	unsigned int length;             /* length in chars without header */
 	unsigned char *data;             /* usually data is located 
-                                        immediatly behind this struct */
+                                        immediately behind this struct */
 	unsigned int locks;              /* only used in rx_buffer */
 	  
     struct r3964_block_header *next;
diff -Nru a/include/linux/net.h b/include/linux/net.h
--- a/include/linux/net.h	Tue Mar  4 19:30:07 2003
+++ b/include/linux/net.h	Tue Mar  4 19:30:07 2003
@@ -210,23 +210,23 @@
 	      (file, sock, vma)) \
 	      \
 static struct proto_ops name##_ops = {			\
-	family:		fam,				\
+	.family		= fam,				\
 							\
-	release:	__lock_##name##_release,	\
-	bind:		__lock_##name##_bind,		\
-	connect:	__lock_##name##_connect,	\
-	socketpair:	__lock_##name##_socketpair,	\
-	accept:		__lock_##name##_accept,		\
-	getname:	__lock_##name##_getname,	\
-	poll:		__lock_##name##_poll,		\
-	ioctl:		__lock_##name##_ioctl,		\
-	listen:		__lock_##name##_listen,		\
-	shutdown:	__lock_##name##_shutdown,	\
-	setsockopt:	__lock_##name##_setsockopt,	\
-	getsockopt:	__lock_##name##_getsockopt,	\
-	sendmsg:	__lock_##name##_sendmsg,	\
-	recvmsg:	__lock_##name##_recvmsg,	\
-	mmap:		__lock_##name##_mmap,		\
+	.release	= __lock_##name##_release,	\
+	.bind		= __lock_##name##_bind,		\
+	.connect	= __lock_##name##_connect,	\
+	.socketpair	= __lock_##name##_socketpair,	\
+	.accept		= __lock_##name##_accept,	\
+	.getname	= __lock_##name##_getname,	\
+	.poll		= __lock_##name##_poll,		\
+	.ioctl		= __lock_##name##_ioctl,	\
+	.listen		= __lock_##name##_listen,	\
+	.shutdown	= __lock_##name##_shutdown,	\
+	.setsockopt	= __lock_##name##_setsockopt,	\
+	.getsockopt	= __lock_##name##_getsockopt,	\
+	.sendmsg	= __lock_##name##_sendmsg,	\
+	.recvmsg	= __lock_##name##_recvmsg,	\
+	.mmap		= __lock_##name##_mmap,		\
 };
 #endif
 
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
--- a/include/linux/netfilter_ipv4/ip_conntrack.h	Tue Mar  4 19:30:13 2003
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h	Tue Mar  4 19:30:13 2003
@@ -6,6 +6,7 @@
 
 #include <linux/config.h>
 #include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
+#include <linux/bitops.h>
 #include <asm/atomic.h>
 
 enum ip_conntrack_info
@@ -41,6 +42,10 @@
 	/* Conntrack should never be early-expired. */
 	IPS_ASSURED_BIT = 2,
 	IPS_ASSURED = (1 << IPS_ASSURED_BIT),
+
+	/* Connection is confirmed: originating packet has left box */
+	IPS_CONFIRMED_BIT = 3,
+	IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
 };
 
 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
@@ -159,7 +164,7 @@
 	struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
 
 	/* Have we seen traffic both ways yet? (bitset) */
-	volatile unsigned long status;
+	unsigned long status;
 
 	/* Timer function; drops refcnt when it goes off. */
 	struct timer_list timeout;
@@ -229,7 +234,8 @@
 /* decrement reference count on an expectation */
 void ip_conntrack_expect_put(struct ip_conntrack_expect *exp);
 
-extern struct module *ip_conntrack_module;
+/* call to create an explicit dependency on ip_conntrack. */
+extern void need_ip_conntrack(void);
 
 extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
 			  const struct ip_conntrack_tuple *orig);
@@ -254,7 +260,7 @@
 /* It's confirmed if it is, or has been in the hash table. */
 static inline int is_confirmed(struct ip_conntrack *ct)
 {
-	return ct->tuplehash[IP_CT_DIR_ORIGINAL].list.next != NULL;
+	return test_bit(IPS_CONFIRMED_BIT, &ct->status);
 }
 
 extern unsigned int ip_conntrack_htable_size;
diff -Nru a/include/linux/netfilter_ipv6/ip6t_ah.h b/include/linux/netfilter_ipv6/ip6t_ah.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_ipv6/ip6t_ah.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,30 @@
+#ifndef _IP6T_AH_H
+#define _IP6T_AH_H
+
+struct ip6t_ah
+{
+	u_int32_t spis[2];			/* Security Parameter Index */
+	u_int32_t hdrlen;			/* Header Length */
+	u_int8_t  hdrres;			/* Test of the Reserved Filed */
+	u_int8_t  invflags;			/* Inverse flags */
+};
+
+#define IP6T_AH_SPI 0x01
+#define IP6T_AH_LEN 0x02
+#define IP6T_AH_RES 0x04
+
+/* Values for "invflags" field in struct ip6t_ah. */
+#define IP6T_AH_INV_SPI		0x01	/* Invert the sense of spi. */
+#define IP6T_AH_INV_LEN		0x02	/* Invert the sense of length. */
+#define IP6T_AH_INV_MASK	0x03	/* All possible flags. */
+
+#define MASK_HOPOPTS    128
+#define MASK_DSTOPTS    64
+#define MASK_ROUTING    32
+#define MASK_FRAGMENT   16
+#define MASK_AH         8
+#define MASK_ESP        4
+#define MASK_NONE       2
+#define MASK_PROTO      1
+
+#endif /*_IP6T_AH_H*/
diff -Nru a/include/linux/netfilter_ipv6/ip6t_esp.h b/include/linux/netfilter_ipv6/ip6t_esp.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_ipv6/ip6t_esp.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,23 @@
+#ifndef _IP6T_ESP_H
+#define _IP6T_ESP_H
+
+struct ip6t_esp
+{
+	u_int32_t spis[2];			/* Security Parameter Index */
+	u_int8_t  invflags;			/* Inverse flags */
+};
+
+#define MASK_HOPOPTS    128
+#define MASK_DSTOPTS    64
+#define MASK_ROUTING    32
+#define MASK_FRAGMENT   16
+#define MASK_AH         8
+#define MASK_ESP        4
+#define MASK_NONE       2
+#define MASK_PROTO      1
+
+/* Values for "invflags" field in struct ip6t_esp. */
+#define IP6T_ESP_INV_SPI		0x01	/* Invert the sense of spi. */
+#define IP6T_ESP_INV_MASK	0x01	/* All possible flags. */
+
+#endif /*_IP6T_ESP_H*/
diff -Nru a/include/linux/netfilter_ipv6/ip6t_frag.h b/include/linux/netfilter_ipv6/ip6t_frag.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_ipv6/ip6t_frag.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,33 @@
+#ifndef _IP6T_FRAG_H
+#define _IP6T_FRAG_H
+
+struct ip6t_frag
+{
+	u_int32_t ids[2];			/* Security Parameter Index */
+	u_int32_t hdrlen;			/* Header Length */
+	u_int8_t  flags;			/*  */
+	u_int8_t  invflags;			/* Inverse flags */
+};
+
+#define IP6T_FRAG_IDS 		0x01
+#define IP6T_FRAG_LEN 		0x02
+#define IP6T_FRAG_RES 		0x04
+#define IP6T_FRAG_FST 		0x08
+#define IP6T_FRAG_MF  		0x10
+#define IP6T_FRAG_NMF  		0x20
+
+/* Values for "invflags" field in struct ip6t_frag. */
+#define IP6T_FRAG_INV_IDS	0x01	/* Invert the sense of ids. */
+#define IP6T_FRAG_INV_LEN	0x02	/* Invert the sense of length. */
+#define IP6T_FRAG_INV_MASK	0x03	/* All possible flags. */
+
+#define MASK_HOPOPTS    128
+#define MASK_DSTOPTS    64
+#define MASK_ROUTING    32
+#define MASK_FRAGMENT   16
+#define MASK_AH         8
+#define MASK_ESP        4
+#define MASK_NONE       2
+#define MASK_PROTO      1
+
+#endif /*_IP6T_FRAG_H*/
diff -Nru a/include/linux/netfilter_ipv6/ip6t_hl.h b/include/linux/netfilter_ipv6/ip6t_hl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_ipv6/ip6t_hl.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,22 @@
+/* ip6tables module for matching the Hop Limit value
+ * Maciej Soltysiak <solt@dns.toxicfilms.tv>
+ * Based on HW's ttl module */
+
+#ifndef _IP6T_HL_H
+#define _IP6T_HL_H
+
+enum {
+	IP6T_HL_EQ = 0,		/* equals */
+	IP6T_HL_NE,		/* not equals */
+	IP6T_HL_LT,		/* less than */
+	IP6T_HL_GT,		/* greater than */
+};
+
+
+struct ip6t_hl_info {
+	u_int8_t	mode;
+	u_int8_t	hop_limit;
+};
+
+
+#endif
diff -Nru a/include/linux/netfilter_ipv6/ip6t_ipv6header.h b/include/linux/netfilter_ipv6/ip6t_ipv6header.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_ipv6/ip6t_ipv6header.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,27 @@
+/* ipv6header match - matches IPv6 packets based
+on whether they contain certain headers */
+
+/* Original idea: Brad Chapman 
+ * Rewritten by: Andras Kis-Szabo <kisza@sch.bme.hu> */
+
+
+#ifndef __IPV6HEADER_H
+#define __IPV6HEADER_H
+
+struct ip6t_ipv6header_info
+{
+	u_int8_t matchflags;
+	u_int8_t invflags;
+	u_int8_t modeflag;
+};
+
+#define MASK_HOPOPTS    128
+#define MASK_DSTOPTS    64
+#define MASK_ROUTING    32
+#define MASK_FRAGMENT   16
+#define MASK_AH         8
+#define MASK_ESP        4
+#define MASK_NONE       2
+#define MASK_PROTO      1
+
+#endif /* __IPV6HEADER_H */
diff -Nru a/include/linux/netfilter_ipv6/ip6t_opts.h b/include/linux/netfilter_ipv6/ip6t_opts.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_ipv6/ip6t_opts.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,32 @@
+#ifndef _IP6T_OPTS_H
+#define _IP6T_OPTS_H
+
+#define IP6T_OPTS_OPTSNR 16
+
+struct ip6t_opts
+{
+	u_int32_t hdrlen;			/* Header Length */
+	u_int8_t flags;				/*  */
+	u_int8_t invflags;			/* Inverse flags */
+	u_int16_t opts[IP6T_OPTS_OPTSNR];	/* opts */
+	u_int8_t optsnr;			/* Nr of OPts */
+};
+
+#define IP6T_OPTS_LEN 		0x01
+#define IP6T_OPTS_OPTS 		0x02
+#define IP6T_OPTS_NSTRICT	0x04
+
+/* Values for "invflags" field in struct ip6t_rt. */
+#define IP6T_OPTS_INV_LEN	0x01	/* Invert the sense of length. */
+#define IP6T_OPTS_INV_MASK	0x01	/* All possible flags. */
+
+#define MASK_HOPOPTS    128
+#define MASK_DSTOPTS    64
+#define MASK_ROUTING    32
+#define MASK_FRAGMENT   16
+#define MASK_AH         8
+#define MASK_ESP        4
+#define MASK_NONE       2
+#define MASK_PROTO      1
+
+#endif /*_IP6T_OPTS_H*/
diff -Nru a/include/linux/netfilter_ipv6/ip6t_rt.h b/include/linux/netfilter_ipv6/ip6t_rt.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_ipv6/ip6t_rt.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,42 @@
+#ifndef _IP6T_RT_H
+#define _IP6T_RT_H
+
+/*#include <linux/in6.h>*/
+
+#define IP6T_RT_HOPS 16
+
+struct ip6t_rt
+{
+	u_int32_t rt_type;			/* Routing Type */
+	u_int32_t segsleft[2];			/* Segments Left */
+	u_int32_t hdrlen;			/* Header Length */
+	u_int8_t  flags;			/*  */
+	u_int8_t  invflags;			/* Inverse flags */
+	struct in6_addr addrs[IP6T_RT_HOPS];	/* Hops */
+	u_int8_t addrnr;			/* Nr of Addresses */
+};
+
+#define IP6T_RT_TYP 		0x01
+#define IP6T_RT_SGS 		0x02
+#define IP6T_RT_LEN 		0x04
+#define IP6T_RT_RES 		0x08
+#define IP6T_RT_FST_MASK	0x30
+#define IP6T_RT_FST 		0x10
+#define IP6T_RT_FST_NSTRICT	0x20
+
+/* Values for "invflags" field in struct ip6t_rt. */
+#define IP6T_RT_INV_TYP		0x01	/* Invert the sense of type. */
+#define IP6T_RT_INV_SGS		0x02	/* Invert the sense of Segments. */
+#define IP6T_RT_INV_LEN		0x04	/* Invert the sense of length. */
+#define IP6T_RT_INV_MASK	0x07	/* All possible flags. */
+
+#define MASK_HOPOPTS    128
+#define MASK_DSTOPTS    64
+#define MASK_ROUTING    32
+#define MASK_FRAGMENT   16
+#define MASK_AH         8
+#define MASK_ESP        4
+#define MASK_NONE       2
+#define MASK_PROTO      1
+
+#endif /*_IP6T_RT_H*/
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h	Tue Mar  4 19:30:08 2003
+++ b/include/linux/pci.h	Tue Mar  4 19:30:08 2003
@@ -645,7 +645,8 @@
 int pci_register_driver(struct pci_driver *);
 void pci_unregister_driver(struct pci_driver *);
 void pci_insert_device(struct pci_dev *, struct pci_bus *);
-void pci_remove_device(struct pci_dev *);
+void pci_remove_bus_device(struct pci_dev *);
+void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
 const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
 unsigned int pci_do_scan_bus(struct pci_bus *bus);
@@ -692,7 +693,6 @@
 extern int pci_visit_dev(struct pci_visit *fn,
 			 struct pci_dev_wrapped *wrapped_dev,
 			 struct pci_bus_wrapped *wrapped_parent);
-extern int pci_is_dev_in_use(struct pci_dev *dev);
 extern int pci_remove_device_safe(struct pci_dev *dev);
 
 #endif /* CONFIG_PCI */
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Tue Mar  4 19:30:07 2003
+++ b/include/linux/pci_ids.h	Tue Mar  4 19:30:07 2003
@@ -1861,8 +1861,12 @@
 #define PCI_DEVICE_ID_INTEL_82860_HB	0x2531
 #define PCI_DEVICE_ID_INTEL_82845G_HB	0x2560
 #define PCI_DEVICE_ID_INTEL_82845G_IG	0x2562
+#define PCI_DEVICE_ID_INTEL_82865_HB	0x2570
+#define PCI_DEVICE_ID_INTEL_82865_IG	0x2572
 #define PCI_DEVICE_ID_INTEL_82830_HB	0x3575
 #define PCI_DEVICE_ID_INTEL_82830_CGC	0x3577
+#define PCI_DEVICE_ID_INTEL_82855_HB	0x3580
+#define PCI_DEVICE_ID_INTEL_82855_IG	0x3582
 #define PCI_DEVICE_ID_INTEL_80310	0x530d
 #define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
 #define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010
diff -Nru a/include/linux/pnpbios.h b/include/linux/pnpbios.h
--- a/include/linux/pnpbios.h	Tue Mar  4 19:30:07 2003
+++ b/include/linux/pnpbios.h	Tue Mar  4 19:30:07 2003
@@ -85,8 +85,8 @@
 #define PNPBIOS_BOOTABLE		0x0010
 #define PNPBIOS_DOCK			0x0020
 #define PNPBIOS_REMOVABLE		0x0040
-#define pnpbios_is_static(x) ((x)->flags & 0x0100) == 0x0000
-#define pnpbios_is_dynamic(x) (x)->flags & 0x0080
+#define pnpbios_is_static(x) (((x)->flags & 0x0100) == 0x0000)
+#define pnpbios_is_dynamic(x) ((x)->flags & 0x0080)
 
 /* 0x8000 through 0xffff are OEM defined */
 
diff -Nru a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h
--- a/include/linux/rwsem-spinlock.h	Tue Mar  4 19:30:09 2003
+++ b/include/linux/rwsem-spinlock.h	Tue Mar  4 19:30:09 2003
@@ -9,7 +9,7 @@
 #define _LINUX_RWSEM_SPINLOCK_H
 
 #ifndef _LINUX_RWSEM_H
-#error please dont include linux/rwsem-spinlock.h directly, use linux/rwsem.h instead
+#error "please don't include linux/rwsem-spinlock.h directly, use linux/rwsem.h instead"
 #endif
 
 #include <linux/spinlock.h>
diff -Nru a/include/linux/sdla_x25.h b/include/linux/sdla_x25.h
--- a/include/linux/sdla_x25.h	Tue Mar  4 19:30:08 2003
+++ b/include/linux/sdla_x25.h	Tue Mar  4 19:30:08 2003
@@ -154,7 +154,7 @@
 #define X25RES_INVAL_CALL_ARG	0x3A	/* errorneous call arguments */
 #define X25RES_INVAL_CALL_DATA	0x3B	/* errorneous call user data */
 #define X25RES_ASYNC_PACKET	0x40	/* asynchronous packet received */
-#define X25RES_PROTO_VIOLATION	0x41	/* protocol violation occured */
+#define X25RES_PROTO_VIOLATION	0x41	/* protocol violation occurred */
 #define X25RES_PKT_TIMEOUT	0x42	/* X.25 packet time out */
 #define X25RES_PKT_RETRY_LIMIT	0x43	/* X.25 packet retry limit exceeded */
 /*----- Command-dependent results -----*/
diff -Nru a/include/linux/serial.h b/include/linux/serial.h
--- a/include/linux/serial.h	Tue Mar  4 19:30:05 2003
+++ b/include/linux/serial.h	Tue Mar  4 19:30:05 2003
@@ -91,6 +91,7 @@
 #define UART_CLEAR_FIFO		0x01
 #define UART_USE_FIFO		0x02
 #define UART_STARTECH		0x04
+#define UART_NATSEMI		0x08
 
 /*
  * Definitions for async_struct (and serial_struct) flags field
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h	Tue Mar  4 19:30:04 2003
+++ b/include/linux/serial_core.h	Tue Mar  4 19:30:04 2003
@@ -37,7 +37,8 @@
 #define PORT_16654	11
 #define PORT_16850	12
 #define PORT_RSA	13
-#define PORT_MAX_8250	13	/* max port ID */
+#define PORT_NS16550A	14
+#define PORT_MAX_8250	14	/* max port ID */
 
 /*
  * ARM specific type numbers.  These are not currently guaranteed
@@ -172,6 +173,7 @@
 #define UPF_LOW_LATENCY		(1 << 13)
 #define UPF_BUGGY_UART		(1 << 14)
 #define UPF_AUTOPROBE		(1 << 15)
+#define UPF_MAGIC_MULTIPLIER	(1 << 16)
 #define UPF_BOOT_ONLYMCA	(1 << 22)
 #define UPF_CONS_FLOW		(1 << 23)
 #define UPF_SHARE_IRQ		(1 << 24)
@@ -179,7 +181,7 @@
 #define UPF_RESOURCES		(1 << 30)
 #define UPF_IOREMAP		(1 << 31)
 
-#define UPF_CHANGE_MASK		(0x7fff)
+#define UPF_CHANGE_MASK		(0x17fff)
 #define UPF_USR_MASK		(UPF_SPD_MASK|UPF_LOW_LATENCY)
 
 	unsigned int		mctrl;			/* current modem ctrl settings */
@@ -279,12 +281,11 @@
  * Baud rate helpers.
  */
 void uart_update_timeout(struct uart_port *port, unsigned int cflag,
-			 unsigned int quot);
+			 unsigned int baud);
 unsigned int uart_get_baud_rate(struct uart_port *port, struct termios *termios,
 				struct termios *old, unsigned int min,
 				unsigned int max);
-unsigned int uart_get_divisor(struct uart_port *port, struct termios *termios,
-			      struct termios *old_termios);
+unsigned int uart_get_divisor(struct uart_port *port, unsigned int baud);
 
 /*
  * Console helpers.
diff -Nru a/include/linux/smp.h b/include/linux/smp.h
--- a/include/linux/smp.h	Tue Mar  4 19:30:09 2003
+++ b/include/linux/smp.h	Tue Mar  4 19:30:09 2003
@@ -10,9 +10,10 @@
 
 #ifdef CONFIG_SMP
 
+#include <linux/preempt.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
-#include <linux/threads.h>
+#include <linux/thread_info.h>
 #include <asm/smp.h>
 #include <asm/bug.h>
 
@@ -54,6 +55,21 @@
 			      int retry, int wait);
 
 /*
+ * Call a function on all processors
+ */
+static inline int on_each_cpu(void (*func) (void *info), void *info,
+			      int retry, int wait)
+{
+	int ret = 0;
+
+	preempt_disable();
+	ret = smp_call_function(func, info, retry, wait);
+	func(info);
+	preempt_enable();
+	return ret;
+}
+
+/*
  * True once the per process idle is forked
  */
 extern int smp_threads_ready;
@@ -96,6 +112,7 @@
 #define hard_smp_processor_id()			0
 #define smp_threads_ready			1
 #define smp_call_function(func,info,retry,wait)	({ 0; })
+#define on_each_cpu(func,info,retry,wait)	({ func(info); 0; })
 static inline void smp_send_reschedule(int cpu) { }
 static inline void smp_send_reschedule_all(void) { }
 #define cpu_online_map				1
diff -Nru a/include/linux/suspend.h b/include/linux/suspend.h
--- a/include/linux/suspend.h	Tue Mar  4 19:30:05 2003
+++ b/include/linux/suspend.h	Tue Mar  4 19:30:05 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 -Nru a/include/linux/swap.h b/include/linux/swap.h
--- a/include/linux/swap.h	Tue Mar  4 19:30:04 2003
+++ b/include/linux/swap.h	Tue Mar  4 19:30:04 2003
@@ -68,10 +68,11 @@
 
 #ifdef __KERNEL__
 
-struct sysinfo;
 struct address_space;
-struct zone;
+struct pte_chain;
+struct sysinfo;
 struct writeback_control;
+struct zone;
 
 /*
  * A swap extent maps a range of a swapfile's PAGE_SIZE pages onto a range of
@@ -140,6 +141,9 @@
 /* Swap 50% full? Release swapcache more aggressively.. */
 #define vm_swap_full() (nr_swap_pages*2 < total_swap_pages)
 
+/* linux/mm/oom_kill.c */
+extern void out_of_memory(void);
+
 /* linux/mm/page_alloc.c */
 extern unsigned long totalram_pages;
 extern unsigned long totalhigh_pages;
@@ -149,13 +153,11 @@
 extern unsigned int nr_free_buffer_pages(void);
 extern unsigned int nr_free_pagecache_pages(void);
 
-/* linux/mm/filemap.c */
-extern void FASTCALL(mark_page_accessed(struct page *));
-
 /* linux/mm/swap.c */
 extern void FASTCALL(lru_cache_add(struct page *));
 extern void FASTCALL(lru_cache_add_active(struct page *));
 extern void FASTCALL(activate_page(struct page *));
+extern void FASTCALL(mark_page_accessed(struct page *));
 extern void lru_add_drain(void);
 extern int rotate_reclaimable_page(struct page *page);
 extern void swap_setup(void);
@@ -165,11 +167,8 @@
 extern int shrink_all_memory(int);
 extern int vm_swappiness;
 
-/* linux/mm/oom_kill.c */
-extern void out_of_memory(void);
-
 /* linux/mm/rmap.c */
-struct pte_chain;
+#ifdef CONFIG_MMU
 int FASTCALL(page_referenced(struct page *));
 struct pte_chain *FASTCALL(page_add_rmap(struct page *, pte_t *,
 					struct pte_chain *));
@@ -186,6 +185,11 @@
 /* linux/mm/shmem.c */
 extern int shmem_unuse(swp_entry_t entry, struct page *page);
 
+#else
+#define page_referenced(page) \
+	TestClearPageReferenced(page)
+#endif /* CONFIG_MMU */
+
 #ifdef CONFIG_SWAP
 /* linux/mm/page_io.c */
 extern int swap_readpage(struct file *, struct page *);
@@ -242,8 +246,6 @@
 	page_cache_release(page)
 #define free_pages_and_swap_cache(pages, nr) \
 	release_pages((pages), (nr), 0);
-#define page_referenced(page) \
-	TestClearPageReferenced(page)
 
 #define show_swap_cache_info()			/*NOTHING*/
 #define free_swap_and_cache(swp)		/*NOTHING*/
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h	Tue Mar  4 19:30:07 2003
+++ b/include/linux/sysfs.h	Tue Mar  4 19:30:07 2003
@@ -16,6 +16,20 @@
 	mode_t			mode;
 };
 
+struct sysfs_bin_buffer {
+	u8 * 	data;
+	size_t	size;
+	size_t	count;
+	loff_t	offset;
+};
+
+struct bin_attribute {
+	struct attribute	attr;
+	size_t			size;
+	ssize_t (*read)(struct kobject *, struct sysfs_bin_buffer *);
+	ssize_t (*write)(struct kobject *, struct sysfs_bin_buffer *);
+};
+
 struct sysfs_ops {
 	ssize_t	(*show)(struct kobject *, struct attribute *,char *);
 	ssize_t	(*store)(struct kobject *,struct attribute *,const char *, size_t);
diff -Nru a/include/linux/telephony.h b/include/linux/telephony.h
--- a/include/linux/telephony.h	Tue Mar  4 19:30:09 2003
+++ b/include/linux/telephony.h	Tue Mar  4 19:30:09 2003
@@ -68,7 +68,7 @@
 * device installed in your system.  The PHONECTL_CAPABILITIES ioctl
 * returns an integer value indicating the number of capabilities the   
 * device has.  The PHONECTL_CAPABILITIES_LIST will fill an array of 
-* capability structs with all of it's capabilities.  The
+* capability structs with all of its capabilities.  The
 * PHONECTL_CAPABILITIES_CHECK takes a single capability struct and returns
 * a TRUE if the device has that capability, otherwise it returns false.
 * 
diff -Nru a/include/linux/time.h b/include/linux/time.h
--- a/include/linux/time.h	Tue Mar  4 19:30:10 2003
+++ b/include/linux/time.h	Tue Mar  4 19:30:10 2003
@@ -28,6 +28,12 @@
 #include <linux/seqlock.h>
 
 /*
+ * Have the 32 bit jiffies value wrap 5 minutes after boot
+ * so jiffies wrap bugs show up earlier.
+ */
+#define INITIAL_JIFFIES ((unsigned int) (-300*HZ))
+
+/*
  * Change timeval to jiffies, trying to avoid the
  * most obvious overflows..
  *
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Tue Mar  4 19:30:08 2003
+++ b/include/linux/usb.h	Tue Mar  4 19:30:08 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 -Nru a/include/linux/xattr.h b/include/linux/xattr.h
--- a/include/linux/xattr.h	Tue Mar  4 19:30:11 2003
+++ b/include/linux/xattr.h	Tue Mar  4 19:30:11 2003
@@ -9,8 +9,7 @@
 #ifndef _LINUX_XATTR_H
 #define _LINUX_XATTR_H
 
-#define XATTR_CREATE		0x1	/* fail if attr already exists */
-#define XATTR_REPLACE		0x2	/* fail if attr does not exist */
-#define XATTR_KERNEL_CONTEXT	0x4	/* called from kernel context */
+#define XATTR_CREATE	0x1	/* set value, fail if attr already exists */
+#define XATTR_REPLACE	0x2	/* set value, fail if attr does not exist */
 
 #endif	/* _LINUX_XATTR_H */
diff -Nru a/include/net/dn_dev.h b/include/net/dn_dev.h
--- a/include/net/dn_dev.h	Tue Mar  4 19:30:03 2003
+++ b/include/net/dn_dev.h	Tue Mar  4 19:30:03 2003
@@ -45,7 +45,7 @@
  * device will come up. In the dn_dev structure, it is the actual
  * state.
  *
- * Things have changed here. I've killed timer1 since its a user space
+ * Things have changed here. I've killed timer1 since it's a user space
  * issue for a user space routing deamon to sort out. The kernel does
  * not need to be bothered with it.
  *
diff -Nru a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h
--- a/include/net/irda/irda_device.h	Tue Mar  4 19:30:14 2003
+++ b/include/net/irda/irda_device.h	Tue Mar  4 19:30:14 2003
@@ -195,7 +195,7 @@
 
 /* The SIR unwrapper async_unwrap_char() will use a Rx-copy-break mechanism
  * when using the optional ZeroCopy Rx, where only small frames are memcpy
- * to a smaller skb to save memory. This is the thresold under which copy
+ * to a smaller skb to save memory. This is the threshold under which copy
  * will happen (and over which it won't happen).
  * Some FIR drivers may use this #define as well...
  * This is the same value as various Ethernet drivers. - Jean II */
diff -Nru a/include/net/irda/vlsi_ir.h b/include/net/irda/vlsi_ir.h
--- a/include/net/irda/vlsi_ir.h	Tue Mar  4 19:30:10 2003
+++ b/include/net/irda/vlsi_ir.h	Tue Mar  4 19:30:10 2003
@@ -382,7 +382,7 @@
  *		PLSWID = (pulsetime * freq / (BAUD+1)) - 1
  *			where pulsetime is the requested IrPHY pulse width
  *			and freq is 8(16)MHz for 40(48)MHz primary input clock
- *		PREAMB: dont care for SIR
+ *		PREAMB: don't care for SIR
  *
  *		The nominal SIR pulse width is 3/16 bit time so we have PLSWID=12
  *		fixed for all SIR speeds at 40MHz input clock (PLSWID=24 at 48MHz).
@@ -401,7 +401,7 @@
  *		PREAMB = 1
  *
  * FIR-mode:	BAUD = 0
- *		PLSWID: dont care
+ *		PLSWID: don't care
  *		PREAMB = 15
  */
 
diff -Nru a/include/net/iw_handler.h b/include/net/iw_handler.h
--- a/include/net/iw_handler.h	Tue Mar  4 19:30:04 2003
+++ b/include/net/iw_handler.h	Tue Mar  4 19:30:04 2003
@@ -92,7 +92,7 @@
  * The implementation goals were as follow :
  *	o Obvious : you should not need a PhD to understand what's happening,
  *		the benefit is easier maintainance.
- *	o Flexible : it should accomodate a wide variety of driver
+ *	o Flexible : it should accommodate a wide variety of driver
  *		implementations and be as flexible as the old API.
  *	o Lean : it should be efficient memory wise to minimise the impact
  *		on kernel footprint.
diff -Nru a/include/net/llc_conn.h b/include/net/llc_conn.h
--- a/include/net/llc_conn.h	Tue Mar  4 19:30:13 2003
+++ b/include/net/llc_conn.h	Tue Mar  4 19:30:13 2003
@@ -61,7 +61,7 @@
 	u8		    inc_cntr;
 	u8		    dec_cntr;
 	u8		    connect_step;
-	u8		    last_nr;	   /* NR of last pdu recieved */
+	u8		    last_nr;	   /* NR of last pdu received */
 	u32		    rx_pdu_hdr;	   /* used for saving header of last pdu
 					      received and caused sending FRMR.
 					      Used for resending FRMR */
diff -Nru a/include/net/sctp/command.h b/include/net/sctp/command.h
--- a/include/net/sctp/command.h	Tue Mar  4 19:30:14 2003
+++ b/include/net/sctp/command.h	Tue Mar  4 19:30:14 2003
@@ -68,7 +68,6 @@
 	SCTP_CMD_INIT_RESTART,  /* High level, do init timer work. */
 	SCTP_CMD_INIT_FAILED,   /* High level, do init failure work. */
 	SCTP_CMD_REPORT_DUP,	/* Report a duplicate TSN.  */
-	SCTP_CMD_REPORT_BIGGAP, /* Narc on a TSN (it was too high).  */
 	SCTP_CMD_STRIKE,	/* Mark a strike against a transport.  */
 	SCTP_CMD_TRANSMIT,      /* Transmit the outqueue. */
 	SCTP_CMD_HB_TIMERS_START,    /* Start the heartbeat timers. */
@@ -86,7 +85,8 @@
 	SCTP_CMD_PURGE_OUTQUEUE, /* Purge all data waiting to be sent. */
 	SCTP_CMD_SETUP_T2,       /* Hi-level, setup T2-shutdown parms.  */
 	SCTP_CMD_RTO_PENDING,	 /* Set transport's rto_pending. */
-
+	SCTP_CMD_PART_DELIVER,	 /* Partial data delivery considerations. */
+	SCTP_CMD_RENEGE,         /* Renege data on an association. */
 	SCTP_CMD_LAST
 } sctp_verb_t;
 
@@ -115,7 +115,7 @@
 	struct sctp_transport *transport;
 	sctp_bind_addr_t  *bp;
 	sctp_init_chunk_t *init;
-	sctp_ulpevent_t *ulpevent;
+	struct sctp_ulpevent *ulpevent;
 	sctp_packet_t *packet;
 	sctp_sackhdr_t *sackh;
 } sctp_arg_t;
@@ -163,7 +163,7 @@
 SCTP_ARG_CONSTRUCTOR(TRANSPORT,	struct sctp_transport *, transport)
 SCTP_ARG_CONSTRUCTOR(BA,	sctp_bind_addr_t *, bp)
 SCTP_ARG_CONSTRUCTOR(PEER_INIT,	sctp_init_chunk_t *, init)
-SCTP_ARG_CONSTRUCTOR(ULPEVENT,  sctp_ulpevent_t *, ulpevent)
+SCTP_ARG_CONSTRUCTOR(ULPEVENT,  struct sctp_ulpevent *, ulpevent)
 SCTP_ARG_CONSTRUCTOR(PACKET,	sctp_packet_t *, packet)
 SCTP_ARG_CONSTRUCTOR(SACKH,	sctp_sackhdr_t *, sackh)
 
diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h	Tue Mar  4 19:30:05 2003
+++ b/include/net/sctp/sctp.h	Tue Mar  4 19:30:05 2003
@@ -214,6 +214,7 @@
 #define SCTP_INC_STATS(field)		SNMP_INC_STATS(sctp_statistics, field)
 #define SCTP_INC_STATS_BH(field)	SNMP_INC_STATS_BH(sctp_statistics, field)
 #define SCTP_INC_STATS_USER(field)	SNMP_INC_STATS_USER(sctp_statistics, field)
+#define SCTP_DEC_STATS(field)		SNMP_DEC_STATS(sctp_statistics, field)
 
 /* Determine if this is a valid kernel address.  */
 static inline int sctp_is_valid_kaddr(unsigned long addr)
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h	Tue Mar  4 19:30:14 2003
+++ b/include/net/sctp/structs.h	Tue Mar  4 19:30:14 2003
@@ -2,7 +2,7 @@
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001 Intel Corp.
- * Copyright (c) 2001-2002 International Business Machines Corp.
+ * Copyright (c) 2001-2003 International Business Machines Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
  *
@@ -73,27 +73,25 @@
 
 /* Forward declarations for data structures. */
 struct sctp_protocol;
-struct SCTP_endpoint;
-struct SCTP_association;
+struct sctp_endpoint;
+struct sctp_association;
 struct sctp_transport;
-struct SCTP_packet;
-struct SCTP_chunk;
-struct SCTP_inqueue;
+struct sctp_packet;
+struct sctp_chunk;
+struct sctp_inq;
 struct sctp_outq;
-struct SCTP_bind_addr;
+struct sctp_bind_addr;
 struct sctp_ulpq;
 struct sctp_opt;
 struct sctp_endpoint_common;
 struct sctp_ssnmap;
 
 typedef struct sctp_protocol sctp_protocol_t;
-typedef struct SCTP_endpoint sctp_endpoint_t;
-typedef struct SCTP_association sctp_association_t;
-typedef struct SCTP_packet sctp_packet_t;
-typedef struct SCTP_chunk sctp_chunk_t;
-typedef struct SCTP_inqueue sctp_inqueue_t;
-typedef struct SCTP_bind_addr sctp_bind_addr_t;
-typedef struct sctp_opt sctp_opt_t;
+typedef struct sctp_endpoint sctp_endpoint_t;
+typedef struct sctp_association sctp_association_t;
+typedef struct sctp_packet sctp_packet_t;
+typedef struct sctp_chunk sctp_chunk_t;
+typedef struct sctp_bind_addr sctp_bind_addr_t;
 typedef struct sctp_endpoint_common sctp_endpoint_common_t;
 
 #include <net/sctp/tsnmap.h>
@@ -218,10 +216,10 @@
 					 int optname,
 					 char *optval,
 					 int *optlen);
-	struct dst_entry *(*get_dst)	(sctp_association_t *asoc,
+	struct dst_entry *(*get_dst)	(struct sctp_association *asoc,
 					 union sctp_addr *daddr,
 					 union sctp_addr *saddr);
-	void 		(*get_saddr)	(sctp_association_t *asoc,
+	void 		(*get_saddr)	(struct sctp_association *asoc,
 					 struct dst_entry *dst,
 					 union sctp_addr *daddr,
 				 	 union sctp_addr *saddr);	 
@@ -257,7 +255,7 @@
 
 /* Protocol family functions. */
 struct sctp_pf {
-	void (*event_msgname)(sctp_ulpevent_t *, char *, int *);
+	void (*event_msgname)(struct sctp_ulpevent *, char *, int *);
 	void (*skb_msgname)  (struct sk_buff *, char *, int *);
 	int  (*af_supported) (sa_family_t);
 	int  (*cmp_addr) (const union sctp_addr *,
@@ -279,6 +277,9 @@
 	/* What kind of a socket is this? */
 	sctp_socket_type_t type;
 
+	/* PF_ family specific functions.  */
+	struct sctp_pf *pf;
+
 	/* What is our base endpointer? */
 	sctp_endpoint_t *ep;
 
@@ -292,7 +293,10 @@
 	__u32 autoclose;
 	__u8 nodelay;
 	__u8 disable_fragments;
-	struct sctp_pf *pf;
+	__u8 pd_mode;
+
+	/* Receive to here while partial delivery is in effect. */
+	struct sk_buff_head pd_lobby;
 };
 
 
@@ -452,7 +456,7 @@
  * As a matter of convenience, we remember the SCTP common header for
  * each chunk as well as a few other header pointers...
  */
-struct SCTP_chunk {
+struct sctp_chunk {
 	/* These first three elements MUST PRECISELY match the first
 	 * three elements of struct sk_buff.  This allows us to reuse
 	 * all the skb_* queue management functions.
@@ -562,7 +566,7 @@
 /* This structure holds lists of chunks as we are assembling for
  * transmission.
  */
-struct SCTP_packet {
+struct sctp_packet {
 	/* These are the SCTP header values (host order) for the packet. */
 	__u16 source_port;
 	__u16 destination_port;
@@ -814,8 +818,8 @@
 /* This is the structure we use to queue packets as they come into
  * SCTP.  We write packets to it and read chunks from it.
  */
-struct SCTP_inqueue {
-	/* This is actually a queue of sctp_chunk_t each
+struct sctp_inq {
+	/* This is actually a queue of sctp_chunk each
 	 * containing a partially decoded packet.
 	 */
 	struct sk_buff_head in;
@@ -832,13 +836,12 @@
 	int malloced;        /* Is this structure kfree()able?  */
 };
 
-sctp_inqueue_t *sctp_inqueue_new(void);
-void sctp_inqueue_init(sctp_inqueue_t *);
-void sctp_inqueue_free(sctp_inqueue_t *);
-void sctp_push_inqueue(sctp_inqueue_t *, sctp_chunk_t *packet);
-sctp_chunk_t *sctp_pop_inqueue(sctp_inqueue_t *);
-void sctp_inqueue_set_th_handler(sctp_inqueue_t *,
-                                 void (*)(void *), void *);
+struct sctp_inq *sctp_inq_new(void);
+void sctp_inq_init(struct sctp_inq *);
+void sctp_inq_free(struct sctp_inq *);
+void sctp_inq_push(struct sctp_inq *, sctp_chunk_t *packet);
+struct sctp_chunk *sctp_inq_pop(struct sctp_inq *);
+void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *);
 
 /* This is the structure we use to hold outbound chunks.  You push
  * chunks in and they automatically pop out the other end as bundled
@@ -922,7 +925,7 @@
 
 
 /* These bind address data fields common between endpoints and associations */
-struct SCTP_bind_addr {
+struct sctp_bind_addr {
 
 	/* RFC 2960 12.1 Parameters necessary for the SCTP instance
 	 *
@@ -1011,7 +1014,7 @@
 	struct sock *sk;
 
 	/* This is where we receive inbound chunks.  */
-	sctp_inqueue_t   inqueue;
+	struct sctp_inq   inqueue;
 
 	/* This substructure includes the defining parameters of the
 	 * endpoint:
@@ -1044,7 +1047,7 @@
  * off one of these.
  */
 
-struct SCTP_endpoint {
+struct sctp_endpoint {
 	/* Common substructure for endpoint and association. */
 	sctp_endpoint_common_t base;
 
@@ -1140,7 +1143,7 @@
 
 
 /* Here we have information about each individual association. */
-struct SCTP_association {
+struct sctp_association {
 
 	/* A base structure common to endpoint and association.
 	 * In this context, it represents the associations's view
@@ -1233,7 +1236,7 @@
 		/* Pointer to last transport I have sent on.  */
 		struct sctp_transport *last_sent_to;
 
-		/* This is the last transport I have recieved DATA on.  */
+		/* This is the last transport I have received DATA on.  */
 		struct sctp_transport *last_data_from;
 
 		/*
@@ -1256,19 +1259,11 @@
 		 * used in the bulk of the text.  This value is hidden
 		 * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn().
 		 */
-		sctp_tsnmap_t tsn_map;
+		struct sctp_tsnmap tsn_map;
 		__u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)];
 
-		/* We record duplicate TSNs here.  We clear this after
-		 * every SACK.
-		 * FIXME: We should move this into the tsnmap? --jgrimm
-		 */
-		sctp_dup_tsn_t dup_tsns[SCTP_MAX_DUP_TSNS];
-		int next_dup_tsn;
-
 		/* Do we need to sack the peer? */
-		uint8_t sack_needed;
-
+		__u8    sack_needed;
 		/* These are capabilities which our peer advertised.  */
 		__u8	ecn_capable;     /* Can peer do ECN? */
 		__u8	ipv4_address;    /* Peer understands IPv4 addresses? */
@@ -1425,7 +1420,10 @@
 
 	struct {
 		__u16 stream;
+		__u16 flags;
 		__u32 ppid;
+		__u32 context;
+		__u32 timetolive;
 	} defaults;
 
 	/* This tracks outbound ssn for a given stream.  */
@@ -1583,6 +1581,7 @@
 void sctp_association_hold(sctp_association_t *);
 
 struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *);
+void sctp_assoc_update_retran_path(sctp_association_t *);
 struct sctp_transport *sctp_assoc_lookup_paddr(const sctp_association_t *,
 					  const union sctp_addr *);
 struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *,
diff -Nru a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h
--- a/include/net/sctp/tsnmap.h	Tue Mar  4 19:30:11 2003
+++ b/include/net/sctp/tsnmap.h	Tue Mar  4 19:30:11 2003
@@ -1,35 +1,40 @@
 /* SCTP kernel reference Implementation Copyright (C) 1999-2001
  * Cisco, Motorola, Intel, and International Business Machines Corp.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * These are the definitions needed for the tsnmap type.  The tsnmap is used
  * to track out of order TSNs received.
- * 
- * The SCTP reference implementation  is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation 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, or (at your option)
  * any later version.
- * 
- * the SCTP reference implementation  is distributed in the hope that it 
+ *
+ * The SCTP reference implementation is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
- * Please send any bug reports or fixes you make to one of the
- * following email addresses:
- * 
- * Jon Grimm <jgrimm@us.ibm.com>
- * La Monte H.P. Yarroll <piggy@acm.org>
- * Karl Knutson <karl@athena.chicago.il.us>
- * 
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ *   Jon Grimm             <jgrimm@us.ibm.com>
+ *   La Monte H.P. Yarroll <piggy@acm.org>
+ *   Karl Knutson          <karl@athena.chicago.il.us>
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -38,8 +43,6 @@
 #ifndef __sctp_tsnmap_h__
 #define __sctp_tsnmap_h__
 
-
-
 /* RFC 2960 12.2 Parameters necessary per association (i.e. the TCB)
  * Mapping  An array of bits or bytes indicating which out of
  * Array    order TSN's have been received (relative to the
@@ -48,9 +51,7 @@
  *          will be set to all zero. This structure may be
  *          in the form of a circular buffer or bit array.
  */
-typedef struct sctp_tsnmap {
-
-
+struct sctp_tsnmap {
 	/* This array counts the number of chunks with each TSN.
 	 * It points at one of the two buffers with which we will
 	 * ping-pong between.
@@ -93,25 +94,30 @@
 	/* This is the highest TSN we've marked.  */
 	__u32 max_tsn_seen;
 
-	/* No. of data chunks pending receipt. used by SCTP_STATUS sockopt */
+	/* Data chunks pending receipt. used by SCTP_STATUS sockopt */
 	__u16 pending_data;
 
+	/* We record duplicate TSNs here.  We clear this after
+	 * every SACK.  Store up to SCTP_MAX_DUP_TSNS worth of
+	 * information.
+	 */
+	__u32 dup_tsns[SCTP_MAX_DUP_TSNS];
+	__u16 num_dup_tsns;
+
 	int malloced;
 
 	__u8 raw_map[0];
-} sctp_tsnmap_t;
+};
 
-typedef struct sctp_tsnmap_iter {
+struct sctp_tsnmap_iter {
 	__u32 start;
-} sctp_tsnmap_iter_t;
-
+};
 
 /* Create a new tsnmap.  */
-sctp_tsnmap_t *sctp_tsnmap_new(__u16 len, __u32 initial_tsn,
-			       int priority);
+struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 init_tsn, int priority);
 
 /* Dispose of a tsnmap.  */
-void sctp_tsnmap_free(sctp_tsnmap_t *map);
+void sctp_tsnmap_free(struct sctp_tsnmap *);
 
 /* This macro assists in creation of external storage for variable length
  * internal buffers.  We double allocate so the overflow map works.
@@ -119,9 +125,8 @@
 #define sctp_tsnmap_storage_size(count) (sizeof(__u8) * (count) * 2)
 
 /* Initialize a block of memory as a tsnmap.  */
-sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn);
-
-
+struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len,
+				     __u32 initial_tsn);
 
 /* Test the tracking state of this TSN.
  * Returns:
@@ -129,31 +134,53 @@
  *  >0 if the TSN has been seen (duplicate)
  *  <0 if the TSN is invalid (too large to track)
  */
-int sctp_tsnmap_check(const sctp_tsnmap_t *map, __u32 tsn);
+int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn);
 
 /* Mark this TSN as seen.  */
-void sctp_tsnmap_mark(sctp_tsnmap_t *map, __u32 tsn);
+void sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn);
 
 /* Retrieve the Cumulative TSN ACK Point.  */
-__u32 sctp_tsnmap_get_ctsn(const sctp_tsnmap_t *map);
+__u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *);
 
 /* Retrieve the highest TSN we've seen.  */
-__u32 sctp_tsnmap_get_max_tsn_seen(const sctp_tsnmap_t *map);
+__u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *);
+
+/* How many Duplicate TSNs are stored? */
+static inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map)
+{
+	return map->num_dup_tsns;
+}
+
+/* Return pointer to duplicate tsn array as needed by SACK. */
+static inline __u32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map)
+{
+	map->num_dup_tsns = 0;
+	return map->dup_tsns;
+}
+
+/* Mark a duplicate TSN.  Note:  limit the storage of duplicate TSN
+ * information.
+ */
+static inline void sctp_tsnmap_mark_dup(struct sctp_tsnmap *map, __u32 tsn)
+{
+	if (map->num_dup_tsns < SCTP_MAX_DUP_TSNS)
+		map->dup_tsns[map->num_dup_tsns++] = htonl(tsn);
+}
+
+/* Renege a TSN that was seen.  */
+void sctp_tsnmap_renege(struct sctp_tsnmap *, __u32 tsn);
 
 /* Is there a gap in the TSN map? */
-int sctp_tsnmap_has_gap(const sctp_tsnmap_t *map);
+int sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
 
 /* Initialize a gap ack block interator from user-provided memory.  */
-void sctp_tsnmap_iter_init(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter);
+void sctp_tsnmap_iter_init(const struct sctp_tsnmap *,
+			   struct sctp_tsnmap_iter *);
 
 /* Get the next gap ack blocks.  We return 0 if there are no more
  * gap ack blocks.
  */
-int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter,
-			     __u16 *start, __u16 *end);
-
+int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *,
+	struct sctp_tsnmap_iter *,__u16 *start, __u16 *end);
 
 #endif /* __sctp_tsnmap_h__ */
-
-
-
diff -Nru a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
--- a/include/net/sctp/ulpevent.h	Tue Mar  4 19:30:04 2003
+++ b/include/net/sctp/ulpevent.h	Tue Mar  4 19:30:04 2003
@@ -6,34 +6,34 @@
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
  *
- * These are the definitions needed for the sctp_ulpevent type.  The 
+ * These are the definitions needed for the sctp_ulpevent type.  The
  * sctp_ulpevent type is used to carry information from the state machine
- * upwards to the ULP. 
- * 
- * The SCTP reference implementation  is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ * upwards to the ULP.
+ *
+ * The SCTP reference implementation  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, or (at your option)
  * any later version.
- * 
- * the SCTP reference implementation  is distributed in the hope that it 
+ *
+ * the SCTP reference implementation  is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to one of the
  * following email addresses:
- * 
+ *
  * Jon Grimm <jgrimm@us.ibm.com>
  * La Monte H.P. Yarroll <piggy@acm.org>
  * Karl Knutson <karl@athena.chicago.il.us>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -46,84 +46,96 @@
 /* Warning: This sits inside an skb.cb[] area.  Be very careful of
  * growing this structure as it is at the maximum limit now.
  */
-typedef struct sctp_ulpevent {
-	int malloced;
-	sctp_association_t *asoc;
-	struct sk_buff *parent;
+struct sctp_ulpevent {
+	struct sctp_association *asoc;
 	struct sctp_sndrcvinfo sndrcvinfo;
-	int chunk_flags; /* Temp. until we get a new chunk_t */
 	int msg_flags;
-} sctp_ulpevent_t;
-
-
-sctp_ulpevent_t *sctp_ulpevent_new(int size, int msg_flags, int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_init(sctp_ulpevent_t *event, struct sk_buff *skb, int msg_flags);
-
-void sctp_ulpevent_free(sctp_ulpevent_t *event);
-
-int sctp_ulpevent_is_notification(const sctp_ulpevent_t *event);
-
-sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(
-				const struct SCTP_association *asoc,
-				__u16 flags,
-				__u16 state,
-				__u16 error,
-				__u16 outbound,
-				__u16 inbound,
-				int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
-				const struct SCTP_association *asoc,
-				const struct sockaddr_storage *aaddr,
-				int flags,
-				int state,
-				int error,
-				int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_make_remote_error(
-				const struct SCTP_association *asoc,
-				struct SCTP_chunk *chunk,
-				__u16 flags,
-				int priority);
-sctp_ulpevent_t *sctp_ulpevent_make_send_failed(
-				const struct SCTP_association *asoc,
-				struct SCTP_chunk *chunk,
-				__u16 flags,
-				__u32 error,
-				int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(
-				const struct SCTP_association *asoc,
-				__u16 flags,
-				int priority);
-
-sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(struct SCTP_association *asoc,
-					   struct SCTP_chunk *chunk,
-					   int priority);
-
-void sctp_ulpevent_read_sndrcvinfo(const sctp_ulpevent_t *event,
-				   struct msghdr *msghdr);
-
-__u16 sctp_ulpevent_get_notification_type(const sctp_ulpevent_t *event);
+};
 
+/* Retrieve the skb this event sits inside of. */
+static inline struct sk_buff *sctp_event2skb(struct sctp_ulpevent *ev)
+{
+	return container_of((void *)ev, struct sk_buff, cb);
+}
 
+/* Retrieve & cast the event sitting inside the skb. */
+static inline struct sctp_ulpevent *sctp_skb2event(struct sk_buff *skb)
+{
+	return (struct sctp_ulpevent *)skb->cb; 
+}
+	
+struct sctp_ulpevent *sctp_ulpevent_new(int size, int flags, int priority);
+struct sctp_ulpevent *sctp_ulpevent_init(struct sctp_ulpevent *, int flags);
+void sctp_ulpevent_free(struct sctp_ulpevent *);
+int sctp_ulpevent_is_notification(const struct sctp_ulpevent *);
+
+struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
+	const struct sctp_association *asoc,
+	__u16 flags,
+	__u16 state,
+	__u16 error,
+	__u16 outbound,
+	__u16 inbound,
+	int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
+	const struct sctp_association *asoc,
+	const struct sockaddr_storage *aaddr,
+	int flags,
+	int state,
+	int error,
+	int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
+	const struct sctp_association *asoc,
+	struct sctp_chunk *chunk,
+	__u16 flags,
+	int priority);
+struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
+	const struct sctp_association *asoc,
+	struct sctp_chunk *chunk,
+	__u16 flags,
+	__u32 error,
+	int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
+	const struct sctp_association *asoc,
+	__u16 flags,
+	int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
+	const struct sctp_association *asoc,
+	__u32 indication, int priority);
+
+struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
+	struct sctp_chunk *chunk,
+	int priority);
+
+void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
+	struct msghdr *);
+__u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
+
+/* Is this event type enabled? */
+static inline int sctp_ulpevent_type_enabled(__u16 sn_type,
+					     struct sctp_event_subscribe *mask)
+{
+	char *amask = (char *) mask;
+	return amask[sn_type - SCTP_SN_TYPE_BASE];
+}
 
 /* Given an event subscription, is this event enabled? */
-static inline int sctp_ulpevent_is_enabled(const sctp_ulpevent_t *event,
-					   const struct sctp_event_subscribe *mask)
+static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
+					   struct sctp_event_subscribe *mask)
 {
-	const char *amask = (const char *) mask;
 	__u16 sn_type;
 	int enabled = 1;
 
 	if (sctp_ulpevent_is_notification(event)) {
 		sn_type = sctp_ulpevent_get_notification_type(event);
-		enabled = amask[sn_type - SCTP_SN_TYPE_BASE];
+		enabled = sctp_ulpevent_type_enabled(sn_type, mask);
 	}
 	return enabled;
 }
-
 
 #endif /* __sctp_ulpevent_h__ */
 
diff -Nru a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
--- a/include/net/sctp/ulpqueue.h	Tue Mar  4 19:30:05 2003
+++ b/include/net/sctp/ulpqueue.h	Tue Mar  4 19:30:05 2003
@@ -48,7 +48,8 @@
 
 /* A structure to carry information to the ULP (e.g. Sockets API) */
 struct sctp_ulpq {
-	int malloced;
+	char malloced;
+	char pd_mode;
 	sctp_association_t *asoc;
 	struct sk_buff_head reasm;
 	struct sk_buff_head lobby;
@@ -60,13 +61,22 @@
 void sctp_ulpq_free(struct sctp_ulpq *);
 
 /* Add a new DATA chunk for processing. */
-int sctp_ulpq_tail_data(struct sctp_ulpq *, sctp_chunk_t *chunk, int priority);
+int sctp_ulpq_tail_data(struct sctp_ulpq *, struct sctp_chunk *, int);
 
 /* Add a new event for propagation to the ULP. */
 int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev);
 
-/* Is the ulpqueue empty. */
-int sctp_ulpqueue_is_empty(struct sctp_ulpq *);
+/* Renege previously received chunks.  */
+void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *, int);
+
+/* Perform partial delivery. */
+void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *, int);
+
+/* Abort the partial delivery. */
+void sctp_ulpq_abort_pd(struct sctp_ulpq *, int);
+
+/* Clear the partial data delivery condition on this socket. */
+int sctp_clear_pd(struct sock *sk);
 
 #endif /* __sctp_ulpqueue_h__ */
 
diff -Nru a/include/net/sctp/user.h b/include/net/sctp/user.h
--- a/include/net/sctp/user.h	Tue Mar  4 19:30:04 2003
+++ b/include/net/sctp/user.h	Tue Mar  4 19:30:04 2003
@@ -166,6 +166,7 @@
 	__u32 sinfo_context;
 	__u32 sinfo_timetolive;
 	__u32 sinfo_tsn;
+	__u32 sinfo_cumtsn;
 	sctp_assoc_t sinfo_assoc_id;
 };
 
@@ -177,7 +178,7 @@
  */
 
 enum sctp_sinfo_flags {
-	MSG_UNORDERED = 1,  /* Send/recieve message unordered. */
+	MSG_UNORDERED = 1,  /* Send/receive message unordered. */
 	MSG_ADDR_OVER = 2,  /* Override the primary destination. */
 	MSG_ABORT=4,        /* Send an ABORT message to the peer. */
 	/* MSG_EOF is already defined per socket.h */
@@ -367,6 +368,7 @@
 	sctp_assoc_t pdapi_assoc_id;
 };
 
+enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, };
 
 /*
  * Described in Section 7.3
@@ -414,8 +416,8 @@
 	SCTP_SN_TYPE_BASE     = (1<<15),
 	SCTP_ASSOC_CHANGE,
 	SCTP_PEER_ADDR_CHANGE,
-	SCTP_REMOTE_ERROR,
 	SCTP_SEND_FAILED,
+	SCTP_REMOTE_ERROR,
 	SCTP_SHUTDOWN_EVENT,
 	SCTP_PARTIAL_DELIVERY_EVENT,
 	SCTP_ADAPTION_INDICATION,
diff -Nru a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h
--- a/include/sound/cs46xx_dsp_spos.h	Tue Mar  4 19:30:10 2003
+++ b/include/sound/cs46xx_dsp_spos.h	Tue Mar  4 19:30:10 2003
@@ -36,12 +36,12 @@
 #define SEGTYPE_SP_COEFFICIENT          0x00000004
 
 #define DSP_SPOS_UU      0x0deadul     /* unused */
-#define DSP_SPOS_DC      0x0badul      /* dont care */
-#define DSP_SPOS_DC_DC   0x0bad0badul  /* dont care */
+#define DSP_SPOS_DC      0x0badul      /* don't care */
+#define DSP_SPOS_DC_DC   0x0bad0badul  /* don't care */
 #define DSP_SPOS_UUUU    0xdeadc0edul  /* unused */
 #define DSP_SPOS_UUHI    0xdeadul
 #define DSP_SPOS_UULO    0xc0edul
-#define DSP_SPOS_DCDC    0x0badf1d0ul  /* dont care */
+#define DSP_SPOS_DCDC    0x0badf1d0ul  /* don't care */
 #define DSP_SPOS_DCDCHI  0x0badul
 #define DSP_SPOS_DCDCLO  0xf1d0ul
 
diff -Nru a/include/sound/uda1341.h b/include/sound/uda1341.h
--- a/include/sound/uda1341.h	Tue Mar  4 19:30:11 2003
+++ b/include/sound/uda1341.h	Tue Mar  4 19:30:11 2003
@@ -160,7 +160,7 @@
  * this was computed as peak_value[i] = pow((63-i)*1.42,1.013)
  *
  * UDA1341 datasheet on page 21: Peak value (dB) = (Peak level - 63.5)*5*log2
- * There is an tabel with these values [level]=value: [3]=-90.31, [7]=-84.29
+ * There is an table with these values [level]=value: [3]=-90.31, [7]=-84.29
  * [61]=-2.78, [62] = -1.48, [63] = 0.0
  * I tried to compute it, but using but even using logarithm with base either 10 or 2
  * i was'n able to get values in the table from the formula. So I constructed another
diff -Nru a/include/sound/wavefront.h b/include/sound/wavefront.h
--- a/include/sound/wavefront.h	Tue Mar  4 19:30:05 2003
+++ b/include/sound/wavefront.h	Tue Mar  4 19:30:05 2003
@@ -687,7 +687,7 @@
 
 /* Allow direct user-space control over FX memory/coefficient data.
    In theory this could be used to download the FX microprogram,
-   but it would be a little slower, and involve some wierd code.
+   but it would be a little slower, and involve some weird code.
  */
 
 #define WFFX_MEMSET              69
diff -Nru a/include/video/sbusfb.h b/include/video/sbusfb.h
--- a/include/video/sbusfb.h	Tue Mar  4 19:30:14 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,147 +0,0 @@
-#include <linux/timer.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
-#include <asm/fbio.h>
-
-#include <video/fbcon.h>
-
-struct bt_regs {
-	volatile unsigned int addr;           /* address register */
-	volatile unsigned int color_map;      /* color map */
-	volatile unsigned int control;        /* control register */
-	volatile unsigned int cursor;         /* cursor map register */
-};
-
-struct fb_info_creator {
-	struct ffb_fbc *fbc;
-	struct ffb_dac *dac;
-	int xy_margin;
-	int fifo_cache;
-	u64 yx_margin;
-	int fg_cache;
-	int bg_cache;
-	int dac_rev;
-};
-struct fb_info_cgsix {
-	struct bt_regs *bt;
-	struct cg6_fbc *fbc;
-	struct cg6_thc *thc;
-	struct cg6_tec *tec;
-	volatile u32 *fhc;
-};
-struct fb_info_bwtwo {
-	struct bw2_regs *regs;
-};
-struct fb_info_cgthree {
-	struct cg3_regs *regs;
-};
-struct fb_info_tcx {
-	struct bt_regs *bt;
-	struct tcx_thc *thc;
-	struct tcx_tec *tec;
-	u32 *cplane;
-};
-struct fb_info_leo {
-	struct leo_lx_krn *lx_krn;
-	struct leo_lc_ss0_usr *lc_ss0_usr;
-	struct leo_ld_ss0 *ld_ss0;
-	struct leo_ld_ss1 *ld_ss1;
-	struct leo_cursor *cursor;
-	unsigned int extent;
-};
-struct fb_info_cgfourteen {
-	struct cg14_regs *regs;
-	struct cg14_cursor *cursor;
-	struct cg14_clut *clut;
-	int ramsize;
-	int mode;
-};
-struct fb_info_p9100 {
-	struct p9100_ctrl *ctrl;
-	volatile u32 *fbmem;
-};
-
-struct cg_cursor {
-	char	enable;         /* cursor is enabled */
-	char	mode;		/* cursor mode */
-	struct	fbcurpos cpos;  /* position */
-	struct	fbcurpos chot;  /* hot-spot */
-	struct	fbcurpos size;  /* size of mask & image fields */
-	struct	fbcurpos hwsize; /* hw max size */
-	int	bits[2][128];   /* space for mask & image bits */
-	char	color [6];      /* cursor colors */
-	struct	timer_list timer; /* cursor timer */
-	int	blink_rate;	/* cursor blink rate */
-};
-
-struct sbus_mmap_map {
-	unsigned long voff;
-	unsigned long poff;
-	unsigned long size;
-};
-
-#define SBUS_MMAP_FBSIZE(n) (-n)
-#define SBUS_MMAP_EMPTY	0x80000000
-
-struct fb_info_sbusfb {
-	struct fb_info info;
-	struct display disp;
-	struct display_switch dispsw;
-	struct fbtype type;
-	struct sbus_dev *sbdp;
-	spinlock_t lock;
-	int prom_node, prom_parent;
-	union {
-		struct fb_info_creator ffb;
-		struct fb_info_cgsix cg6;
-		struct fb_info_bwtwo bw2;
-		struct fb_info_cgthree cg3;
-		struct fb_info_tcx tcx;
-		struct fb_info_leo leo;
-		struct fb_info_cgfourteen cg14;
-		struct fb_info_p9100 p9100;
-	} s;
-	unsigned char *color_map;
-	struct cg_cursor cursor;
-	unsigned char open;
-	unsigned char mmaped;
-	unsigned char blanked;
-	int x_margin;
-	int y_margin;
-	int vtconsole;
-	int consolecnt;
-	int graphmode;
-	int emulations[4];
-	struct sbus_mmap_map *mmap_map;
-	unsigned long physbase;
-	int iospace;
-	/* Methods */
-	void (*setup)(struct display *);
-	void (*setcursor)(struct fb_info_sbusfb *);
-	void (*setcurshape)(struct fb_info_sbusfb *);
-	void (*setcursormap)(struct fb_info_sbusfb *, unsigned char *, unsigned char *, unsigned char *);
-	void (*loadcmap)(struct fb_info_sbusfb *, struct display *, int, int);
-	int (*blank)(struct fb_info_sbusfb *);
-	int (*unblank)(struct fb_info_sbusfb *);
-	void (*margins)(struct fb_info_sbusfb *, struct display *, int, int);
-	void (*reset)(struct fb_info_sbusfb *);
-	void (*fill)(struct fb_info_sbusfb *, struct display *, int, int, unsigned short *);
-	void (*switch_from_graph)(struct fb_info_sbusfb *);
-	void (*restore_palette)(struct fb_info_sbusfb *);
-	int (*ioctl)(struct fb_info_sbusfb *, unsigned int, unsigned long);
-};
-
-extern char *creatorfb_init(struct fb_info_sbusfb *);
-extern char *cgsixfb_init(struct fb_info_sbusfb *);
-extern char *cgthreefb_init(struct fb_info_sbusfb *);
-extern char *tcxfb_init(struct fb_info_sbusfb *);
-extern char *leofb_init(struct fb_info_sbusfb *);
-extern char *bwtwofb_init(struct fb_info_sbusfb *);
-extern char *cgfourteenfb_init(struct fb_info_sbusfb *);
-extern char *p9100fb_init(struct fb_info_sbusfb *);
-
-#define sbusfbinfod(disp) ((struct fb_info_sbusfb *)(disp->fb_info))
-#define sbusfbinfo(info) ((struct fb_info_sbusfb *)(info))
-#define CM(i, j) [3*(i)+(j)]
-
-#define SBUSFBINIT_SIZECHANGE ((char *)-1)
diff -Nru a/init/Makefile b/init/Makefile
--- a/init/Makefile	Tue Mar  4 19:30:07 2003
+++ b/init/Makefile	Tue Mar  4 19:30:07 2003
@@ -2,7 +2,11 @@
 # Makefile for the linux kernel.
 #
 
-obj-y			:= main.o version.o do_mounts.o initramfs.o
+obj-y				:= main.o version.o mounts.o initramfs.o
+mounts-y			:= do_mounts.o
+mounts-$(CONFIG_DEVFS_FS)	+= do_mounts_devfs.o
+mounts-$(CONFIG_BLK_DEV_RAM)	+= do_mounts_rd.o
+mounts-$(CONFIG_BLK_DEV_MD)	+= do_mounts_md.o
 
 # files to be removed upon make clean
 clean-files := ../include/linux/compile.h
@@ -17,5 +21,5 @@
 # actual file if its content has changed.
 
 include/linux/compile.h: FORCE
-	@echo -n '  Generating $@'
+	@echo -n '  GEN     $@'
 	@sh $(srctree)/scripts/mkcompile_h $@ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CC) $(CFLAGS)"
diff -Nru a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c	Tue Mar  4 19:30:07 2003
+++ b/init/do_mounts.c	Tue Mar  4 19:30:07 2003
@@ -1,77 +1,28 @@
-#define __KERNEL_SYSCALLS__
-#include <linux/config.h>
-#include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/unistd.h>
 #include <linux/ctype.h>
-#include <linux/blk.h>
 #include <linux/fd.h>
 #include <linux/tty.h>
-#include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/root_dev.h>
-#include <linux/mount.h>
-#include <linux/dirent.h>
 #include <linux/security.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/romfs_fs.h>
 
-#include <linux/raid/md.h>
-
-#define BUILD_CRAMDISK
+#include "do_mounts.h"
 
 extern int get_filesystem_list(char * buf);
 
-extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
-	 unsigned long flags, void *data);
-extern asmlinkage long sys_mkdir(const char *name, int mode);
-extern asmlinkage long sys_rmdir(const char *name);
-extern asmlinkage long sys_chdir(const char *name);
-extern asmlinkage long sys_fchdir(int fd);
-extern asmlinkage long sys_chroot(const char *name);
-extern asmlinkage long sys_unlink(const char *name);
-extern asmlinkage long sys_symlink(const char *old, const char *new);
-extern asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
-extern asmlinkage long sys_umount(char *name, int flags);
-extern asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
-extern asmlinkage long sys_access(const char * filename, int mode);
-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
-extern asmlinkage long sys_getdents64(unsigned int fd, void * dirent,
-	unsigned int count);
-
-#ifdef CONFIG_BLK_DEV_INITRD
-unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
-static int __initdata mount_initrd = 1;
-
-static int __init no_initrd(char *str)
-{
-	mount_initrd = 0;
-	return 1;
-}
-
-__setup("noinitrd", no_initrd);
-#else
-static int __initdata mount_initrd = 0;
-#endif
-
 int __initdata rd_doload;	/* 1 = load RAM disk, 0 = don't load */
 
 int root_mountflags = MS_RDONLY | MS_VERBOSE;
-static char root_device_name[64];
-static char saved_root_name[64];
+static char * __initdata root_device_name;
+static char __initdata saved_root_name[64];
 
 /* this is initialized in init/main.c */
 dev_t ROOT_DEV;
 
-static int do_devfs = 0;
-
 static int __init load_ramdisk(char *str)
 {
 	rd_doload = simple_strtol(str,NULL,0) & 3;
@@ -98,7 +49,7 @@
 __setup("ro", readonly);
 __setup("rw", readwrite);
 
-static __init dev_t try_name(char *name, int part)
+static dev_t __init try_name(char *name, int part)
 {
 	char path[64];
 	char buf[32];
@@ -167,7 +118,7 @@
  *	is mounted on rootfs /sys.
  */
 
-__init dev_t name_to_dev_t(char *name)
+dev_t name_to_dev_t(char *name)
 {
 	char s[32];
 	char *p;
@@ -225,8 +176,7 @@
 
 static int __init root_dev_setup(char *line)
 {
-	strncpy(saved_root_name, line, 64);
-	saved_root_name[63] = '\0';
+	strncpy(saved_root_name, line, 63);
 	return 1;
 }
 
@@ -275,7 +225,23 @@
 	}
 	*s = '\0';
 }
-static void __init mount_block_root(char *name, int flags)
+
+static int __init do_mount_root(char *name, char *fs, int flags, void *data)
+{
+	int err = sys_mount(name, "/root", fs, flags, data);
+	if (err)
+		return err;
+
+	sys_chdir("/root");
+	ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+	printk("VFS: Mounted root (%s filesystem)%s.\n",
+	       current->fs->pwdmnt->mnt_sb->s_type->name,
+	       current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? 
+	       " readonly" : "");
+	return 0;
+}
+
+void __init mount_block_root(char *name, int flags)
 {
 	char *fs_names = __getname();
 	char *p;
@@ -283,7 +249,7 @@
 	get_fs_names(fs_names);
 retry:
 	for (p = fs_names; *p; p += strlen(p)+1) {
-		int err = sys_mount(name, "/root", p, flags, root_mount_data);
+		int err = do_mount_root(name, p, flags, root_mount_data);
 		switch (err) {
 			case 0:
 				goto out;
@@ -297,20 +263,14 @@
 		 * Allow the user to distinguish between failed open
 		 * and bad superblock on root device.
 		 */
-		printk ("VFS: Cannot open root device \"%s\" or %s\n",
-			root_device_name, kdevname (to_kdev_t(ROOT_DEV)));
-		printk ("Please append a correct \"root=\" boot option\n");
-		panic("VFS: Unable to mount root fs on %s",
-			kdevname(to_kdev_t(ROOT_DEV)));
+		printk("VFS: Cannot open root device \"%s\" or %s\n",
+			root_device_name, __bdevname(ROOT_DEV));
+		printk("Please append a correct \"root=\" boot option\n");
+		panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV));
 	}
-	panic("VFS: Unable to mount root fs on %s", kdevname(to_kdev_t(ROOT_DEV)));
+	panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV));
 out:
 	putname(fs_names);
-	sys_chdir("/root");
-	ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
-	printk("VFS: Mounted root (%s filesystem)%s.\n",
-		current->fs->pwdmnt->mnt_sb->s_type->name,
-		(current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
 }
  
 #ifdef CONFIG_ROOT_NFS
@@ -318,139 +278,16 @@
 {
 	void *data = nfs_root_data();
 
-	if (data && sys_mount("/dev/root","/root","nfs",root_mountflags,data) == 0)
+	create_dev("/dev/root", ROOT_DEV, NULL);
+	if (data &&
+	    do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
 		return 1;
 	return 0;
 }
 #endif
 
-#ifdef CONFIG_DEVFS_FS
-
-/*
- * If the dir will fit in *buf, return its length.  If it won't fit, return
- * zero.  Return -ve on error.
- */
-static int __init do_read_dir(int fd, void *buf, int len)
-{
-	long bytes, n;
-	char *p = buf;
-	lseek(fd, 0, 0);
-
-	for (bytes = 0; bytes < len; bytes += n) {
-		n = sys_getdents64(fd, p + bytes, len - bytes);
-		if (n < 0)
-			return n;
-		if (n == 0)
-			return bytes;
-	}
-	return 0;
-}
-
-/*
- * Try to read all of a directory.  Returns the contents at *p, which
- * is kmalloced memory.  Returns the number of bytes read at *len.  Returns
- * NULL on error.
- */
-static void * __init read_dir(char *path, int *len)
-{
-	int size;
-	int fd = open(path, 0, 0);
-
-	*len = 0;
-	if (fd < 0)
-		return NULL;
-
-	for (size = 1 << 9; size <= (1 << MAX_ORDER); size <<= 1) {
-		void *p = kmalloc(size, GFP_KERNEL);
-		int n;
-		if (!p)
-			break;
-		n = do_read_dir(fd, p, size);
-		if (n > 0) {
-			close(fd);
-			*len = n;
-			return p;
-		}
-		kfree(p);
-		if (n == -EINVAL)
-			continue;	/* Try a larger buffer */
-		if (n < 0)
-			break;
-	}
-	close(fd);
-	return NULL;
-}
-#endif
-
-static int __init find_in_devfs(char *path, dev_t dev)
-{
-#ifdef CONFIG_DEVFS_FS
-	struct stat buf;
-	char *end = path + strlen(path);
-	int rest = path + 64 - end;
-	int size;
-	char *p = read_dir(path, &size);
-	char *s;
-
-	if (!p)
-		return -1;
-	for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
-		struct linux_dirent64 *d = (struct linux_dirent64 *)s;
-		if (strlen(d->d_name) + 2 > rest)
-			continue;
-		switch (d->d_type) {
-			case DT_BLK:
-				sprintf(end, "/%s", d->d_name);
-				if (sys_newstat(path, &buf) < 0)
-					break;
-				if (!S_ISBLK(buf.st_mode))
-					break;
-				if (buf.st_rdev != dev)
-					break;
-				kfree(p);
-				return 0;
-			case DT_DIR:
-				if (strcmp(d->d_name, ".") == 0)
-					break;
-				if (strcmp(d->d_name, "..") == 0)
-					break;
-				sprintf(end, "/%s", d->d_name);
-				if (find_in_devfs(path, dev) < 0)
-					break;
-				kfree(p);
-				return 0;
-		}
-	}
-	kfree(p);
-#endif
-	return -1;
-}
-
-static int __init create_dev(char *name, dev_t dev, char *devfs_name)
-{
-	char path[64];
-
-	sys_unlink(name);
-	if (!do_devfs)
-		return sys_mknod(name, S_IFBLK|0600, dev);
-
-	if (devfs_name && devfs_name[0]) {
-		if (strncmp(devfs_name, "/dev/", 5) == 0)
-			devfs_name += 5;
-		sprintf(path, "/dev/%s", devfs_name);
-		if (sys_access(path, 0) == 0)
-			return sys_symlink(devfs_name, name);
-	}
-	if (!dev)
-		return -1;
-	strcpy(path, "/dev");
-	if (find_in_devfs(path, dev) < 0)
-		return -1;
-	return sys_symlink(path + 5, name);
-}
-
 #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
-static void __init change_floppy(char *fmt, ...)
+void __init change_floppy(char *fmt, ...)
 {
 	struct termios termios;
 	char buf[80];
@@ -479,838 +316,69 @@
 }
 #endif
 
-#ifdef CONFIG_BLK_DEV_RAM
-
-int __initdata rd_prompt = 1;	/* 1 = prompt for RAM disk, 0 = don't prompt */
-
-static int __init prompt_ramdisk(char *str)
-{
-	rd_prompt = simple_strtol(str,NULL,0) & 1;
-	return 1;
-}
-__setup("prompt_ramdisk=", prompt_ramdisk);
-
-int __initdata rd_image_start;		/* starting block # of image */
-
-static int __init ramdisk_start_setup(char *str)
-{
-	rd_image_start = simple_strtol(str,NULL,0);
-	return 1;
-}
-__setup("ramdisk_start=", ramdisk_start_setup);
-
-static int __init crd_load(int in_fd, int out_fd);
-
-/*
- * This routine tries to find a RAM disk image to load, and returns the
- * number of blocks to read for a non-compressed image, 0 if the image
- * is a compressed image, and -1 if an image with the right magic
- * numbers could not be found.
- *
- * We currently check for the following magic numbers:
- * 	minix
- * 	ext2
- *	romfs
- * 	gzip
- */
-static int __init 
-identify_ramdisk_image(int fd, int start_block)
-{
-	const int size = 512;
-	struct minix_super_block *minixsb;
-	struct ext2_super_block *ext2sb;
-	struct romfs_super_block *romfsb;
-	int nblocks = -1;
-	unsigned char *buf;
-
-	buf = kmalloc(size, GFP_KERNEL);
-	if (buf == 0)
-		return -1;
-
-	minixsb = (struct minix_super_block *) buf;
-	ext2sb = (struct ext2_super_block *) buf;
-	romfsb = (struct romfs_super_block *) buf;
-	memset(buf, 0xe5, size);
-
-	/*
-	 * Read block 0 to test for gzipped kernel
-	 */
-	lseek(fd, start_block * BLOCK_SIZE, 0);
-	read(fd, buf, size);
-
-	/*
-	 * If it matches the gzip magic numbers, return -1
-	 */
-	if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
-		printk(KERN_NOTICE
-		       "RAMDISK: Compressed image found at block %d\n",
-		       start_block);
-		nblocks = 0;
-		goto done;
-	}
-
-	/* romfs is at block zero too */
-	if (romfsb->word0 == ROMSB_WORD0 &&
-	    romfsb->word1 == ROMSB_WORD1) {
-		printk(KERN_NOTICE
-		       "RAMDISK: romfs filesystem found at block %d\n",
-		       start_block);
-		nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
-		goto done;
-	}
-
-	/*
-	 * Read block 1 to test for minix and ext2 superblock
-	 */
-	lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
-	read(fd, buf, size);
-
-	/* Try minix */
-	if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
-	    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
-		printk(KERN_NOTICE
-		       "RAMDISK: Minix filesystem found at block %d\n",
-		       start_block);
-		nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
-		goto done;
-	}
-
-	/* Try ext2 */
-	if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
-		printk(KERN_NOTICE
-		       "RAMDISK: ext2 filesystem found at block %d\n",
-		       start_block);
-		nblocks = le32_to_cpu(ext2sb->s_blocks_count);
-		goto done;
-	}
-
-	printk(KERN_NOTICE
-	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
-	       start_block);
-	
-done:
-	lseek(fd, start_block * BLOCK_SIZE, 0);
-	kfree(buf);
-	return nblocks;
-}
-#endif
-
-static int __init rd_load_image(char *from)
-{
-	int res = 0;
-
-#ifdef CONFIG_BLK_DEV_RAM
-	int in_fd, out_fd;
-	unsigned long rd_blocks, devblocks;
-	int nblocks, i, disk;
-	char *buf;
-	unsigned short rotate = 0;
-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
-	char rotator[4] = { '|' , '/' , '-' , '\\' };
-#endif
-
-	out_fd = open("/dev/ram", O_RDWR, 0);
-	if (out_fd < 0)
-		goto out;
-
-	in_fd = open(from, O_RDONLY, 0);
-	if (in_fd < 0)
-		goto noclose_input;
-
-	nblocks = identify_ramdisk_image(in_fd, rd_image_start);
-	if (nblocks < 0)
-		goto done;
-
-	if (nblocks == 0) {
-#ifdef BUILD_CRAMDISK
-		if (crd_load(in_fd, out_fd) == 0)
-			goto successful_load;
-#else
-		printk(KERN_NOTICE
-		       "RAMDISK: Kernel does not support compressed "
-		       "RAM disk images\n");
-#endif
-		goto done;
-	}
-
-	/*
-	 * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
-	 * rd_load_image will work only with filesystem BLOCK_SIZE wide!
-	 * So make sure to use 1k blocksize while generating ext2fs
-	 * ramdisk-images.
-	 */
-	if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
-		rd_blocks = 0;
-	else
-		rd_blocks >>= 1;
-
-	if (nblocks > rd_blocks) {
-		printk("RAMDISK: image too big! (%d/%ld blocks)\n",
-		       nblocks, rd_blocks);
-		goto done;
-	}
-		
-	/*
-	 * OK, time to copy in the data
-	 */
-	if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
-		devblocks = 0;
-	else
-		devblocks >>= 1;
-
-	if (strcmp(from, "/dev/initrd") == 0)
-		devblocks = nblocks;
-
-	if (devblocks == 0) {
-		printk(KERN_ERR "RAMDISK: could not determine device size\n");
-		goto done;
-	}
-
-	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
-	if (buf == 0) {
-		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
-		goto done;
-	}
-
-	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%ld disk%s] into ram disk... ", 
-		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
-	for (i = 0, disk = 1; i < nblocks; i++) {
-		if (i && (i % devblocks == 0)) {
-			printk("done disk #%d.\n", disk++);
-			rotate = 0;
-			if (close(in_fd)) {
-				printk("Error closing the disk.\n");
-				goto noclose_input;
-			}
-			change_floppy("disk #%d", disk);
-			in_fd = open(from, O_RDONLY, 0);
-			if (in_fd < 0)  {
-				printk("Error opening disk.\n");
-				goto noclose_input;
-			}
-			printk("Loading disk #%d... ", disk);
-		}
-		read(in_fd, buf, BLOCK_SIZE);
-		write(out_fd, buf, BLOCK_SIZE);
-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
-		if (!(i % 16)) {
-			printk("%c\b", rotator[rotate & 0x3]);
-			rotate++;
-		}
-#endif
-	}
-	printk("done.\n");
-	kfree(buf);
-
-successful_load:
-	res = 1;
-done:
-	close(in_fd);
-noclose_input:
-	close(out_fd);
-out:
-	sys_unlink("/dev/ram");
-#endif
-	return res;
-}
-
-static int __init rd_load_disk(int n)
-{
-#ifdef CONFIG_BLK_DEV_RAM
-	if (rd_prompt)
-		change_floppy("root floppy disk to be loaded into RAM disk");
-	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
-#endif
-	return rd_load_image("/dev/root");
-}
-
-static void __init mount_root(void)
+void __init mount_root(void)
 {
 #ifdef CONFIG_ROOT_NFS
 	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
-		if (mount_nfs_root()) {
-			sys_chdir("/root");
-			ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
-			printk("VFS: Mounted root (nfs filesystem).\n");
+		if (mount_nfs_root())
 			return;
-		}
+
 		printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
 		ROOT_DEV = Root_FD0;
 	}
 #endif
-	create_dev("/dev/root", ROOT_DEV, root_device_name);
 #ifdef CONFIG_BLK_DEV_FD
 	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
 		/* rd_doload is 2 for a dual initrd/ramload setup */
 		if (rd_doload==2) {
 			if (rd_load_disk(1)) {
 				ROOT_DEV = Root_RAM1;
-				create_dev("/dev/root", ROOT_DEV, NULL);
+				root_device_name = NULL;
 			}
 		} else
 			change_floppy("root floppy");
 	}
 #endif
+	create_dev("/dev/root", ROOT_DEV, root_device_name);
 	mount_block_root("/dev/root", root_mountflags);
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static int old_fd, root_fd;
-static int do_linuxrc(void * shell)
-{
-	static char *argv[] = { "linuxrc", NULL, };
-	extern char * envp_init[];
-
-	close(old_fd);close(root_fd);
-	close(0);close(1);close(2);
-	setsid();
-	(void) open("/dev/console",O_RDWR,0);
-	(void) dup(0);
-	(void) dup(0);
-	return execve(shell, argv, envp_init);
-}
-
-#endif
-
-static void __init handle_initrd(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	int error;
-	int i, pid;
-
-	create_dev("/dev/root.old", Root_RAM0, NULL);
-	/* mount initrd on rootfs' /root */
-	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
-	sys_mkdir("/old", 0700);
-	root_fd = open("/", 0, 0);
-	old_fd = open("/old", 0, 0);
-	/* move initrd over / and chdir/chroot in initrd root */
-	sys_chdir("/root");
-	sys_mount(".", "/", NULL, MS_MOVE, NULL);
-	sys_chroot(".");
-	mount_devfs_fs ();
-
-	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
-	if (pid > 0) {
-		while (pid != waitpid(-1, &i, 0))
-			yield();
-	}
-
-	/* move initrd to rootfs' /old */
-	sys_fchdir(old_fd);
-	sys_mount("/", ".", NULL, MS_MOVE, NULL);
-	/* switch root and cwd back to / of rootfs */
-	sys_fchdir(root_fd);
-	sys_chroot(".");
-	close(old_fd);
-	close(root_fd);
-	sys_umount("/old/dev", 0);
-
-	if (real_root_dev == Root_RAM0) {
-		sys_chdir("/old");
-		return;
-	}
-
-	ROOT_DEV = real_root_dev;
-	mount_root();
-
-	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
-	error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
-	if (!error)
-		printk("okay\n");
-	else {
-		int fd = open("/dev/root.old", O_RDWR, 0);
-		printk("failed\n");
-		printk(KERN_NOTICE "Unmounting old root\n");
-		sys_umount("/old", MNT_DETACH);
-		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
-		if (fd < 0) {
-			error = fd;
-		} else {
-			error = sys_ioctl(fd, BLKFLSBUF, 0);
-			close(fd);
-		}
-		printk(!error ? "okay\n" : "failed\n");
-	}
-#endif
-}
-
-static int __init initrd_load(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
-	create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
-#endif
-	return rd_load_image("/dev/initrd");
-}
-
-static void __init md_run_setup(void);
-
 /*
  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
  */
-void prepare_namespace(void)
+void __init prepare_namespace(void)
 {
 	int is_floppy;
 
-#ifdef CONFIG_DEVFS_FS
-	sys_mount("devfs", "/dev", "devfs", 0, NULL);
-	do_devfs = 1;
-#endif
+	mount_devfs();
 
 	md_run_setup();
 
 	if (saved_root_name[0]) {
-		char *p = saved_root_name;
-		ROOT_DEV = name_to_dev_t(p);
-		if (strncmp(p, "/dev/", 5) == 0)
-			p += 5;
-		strcpy(root_device_name, p);
+		root_device_name = saved_root_name;
+		ROOT_DEV = name_to_dev_t(root_device_name);
+		if (strncmp(root_device_name, "/dev/", 5) == 0)
+			root_device_name += 5;
 	}
 
 	is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (!initrd_start)
-		mount_initrd = 0;
-	real_root_dev = ROOT_DEV;
-#endif
-
-	create_dev("/dev/root", ROOT_DEV, NULL);
-
 	/* This has to be before mounting root, because even readonly mount of reiserfs would replay
 	   log corrupting stuff */
 	software_resume();
 
-	if (mount_initrd) {
-		if (initrd_load() && ROOT_DEV != Root_RAM0) {
-			handle_initrd();
-			goto out;
-		}
-	} else if (is_floppy && rd_doload && rd_load_disk(0))
+	if (initrd_load())
+		goto out;
+
+	if (is_floppy && rd_doload && rd_load_disk(0))
 		ROOT_DEV = Root_RAM0;
+
 	mount_root();
 out:
-	sys_umount("/dev", 0);
+	umount_devfs("/dev");
 	sys_mount(".", "/", NULL, MS_MOVE, NULL);
 	sys_chroot(".");
 	security_sb_post_mountroot();
 	mount_devfs_fs ();
 }
 
-#if defined(BUILD_CRAMDISK) && defined(CONFIG_BLK_DEV_RAM)
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-
-#ifndef memzero
-#define memzero(s, n)     memset ((s), 0, (n))
-#endif
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define INBUFSIZ 4096
-#define WSIZE 0x8000    /* window size--must be a power of two, and */
-			/*  at least 32K for zip's deflate method */
-
-static uch *inbuf;
-static uch *window;
-
-static unsigned insize;  /* valid bytes in inbuf */
-static unsigned inptr;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt;  /* bytes in output buffer */
-static int exit_code;
-static int unzip_error;
-static long bytes_out;
-static int crd_infd, crd_outfd;
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-		
-/* Diagnostic functions (stubbed out) */
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define STATIC static
-
-static int  fill_inbuf(void);
-static void flush_window(void);
-static void *malloc(int size);
-static void free(void *where);
-static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
-
-#include "../lib/inflate.c"
-
-static void __init *malloc(int size)
-{
-	return kmalloc(size, GFP_KERNEL);
-}
-
-static void __init free(void *where)
-{
-	kfree(where);
-}
-
-static void __init gzip_mark(void **ptr)
-{
-}
-
-static void __init gzip_release(void **ptr)
-{
-}
-
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- * Returning -1 does not guarantee that gunzip() will ever return.
- */
-static int __init fill_inbuf(void)
-{
-	if (exit_code) return -1;
-	
-	insize = read(crd_infd, inbuf, INBUFSIZ);
-	if (insize == 0) {
-		error("RAMDISK: ran out of compressed data\n");
-		return -1;
-	}
-
-	inptr = 1;
-
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n, written;
-    uch *in, ch;
-    
-    written = write(crd_outfd, window, outcnt);
-    if (written != outcnt && unzip_error == 0) {
-	printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
-	       written, outcnt, bytes_out);
-	unzip_error = 1;
-    }
-    in = window;
-    for (n = 0; n < outcnt; n++) {
-	    ch = *in++;
-	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    outcnt = 0;
-}
-
-static void __init error(char *x)
-{
-	printk(KERN_ERR "%s", x);
-	exit_code = 1;
-	unzip_error = 1;
-}
-
-static int __init crd_load(int in_fd, int out_fd)
-{
-	int result;
-
-	insize = 0;		/* valid bytes in inbuf */
-	inptr = 0;		/* index of next byte to be processed in inbuf */
-	outcnt = 0;		/* bytes in output buffer */
-	exit_code = 0;
-	bytes_out = 0;
-	crc = (ulg)0xffffffffL; /* shift register contents */
-
-	crd_infd = in_fd;
-	crd_outfd = out_fd;
-	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
-	if (inbuf == 0) {
-		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
-		return -1;
-	}
-	window = kmalloc(WSIZE, GFP_KERNEL);
-	if (window == 0) {
-		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
-		kfree(inbuf);
-		return -1;
-	}
-	makecrc();
-	result = gunzip();
-	if (unzip_error)
-		result = 1;
-	kfree(inbuf);
-	kfree(window);
-	return result;
-}
-
-#endif  /* BUILD_CRAMDISK && CONFIG_BLK_DEV_RAM */
-
-#ifdef CONFIG_BLK_DEV_MD
-
-/*
- * When md (and any require personalities) are compiled into the kernel
- * (not a module), arrays can be assembles are boot time using with AUTODETECT
- * where specially marked partitions are registered with md_autodetect_dev(),
- * and with MD_BOOT where devices to be collected are given on the boot line
- * with md=.....
- * The code for that is here.
- */
-
-struct {
-	int set;
-	int noautodetect;
-} raid_setup_args __initdata;
-
-static struct {
-	char device_set [MAX_MD_DEVS];
-	int pers[MAX_MD_DEVS];
-	int chunk[MAX_MD_DEVS];
-	char *device_names[MAX_MD_DEVS];
-} md_setup_args __initdata;
-
-/*
- * Parse the command-line parameters given our kernel, but do not
- * actually try to invoke the MD device now; that is handled by
- * md_setup_drive after the low-level disk drivers have initialised.
- *
- * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
- *             assigns the task of parsing integer arguments to the
- *             invoked program now).  Added ability to initialise all
- *             the MD devices (by specifying multiple "md=" lines)
- *             instead of just one.  -- KTK
- * 18May2000: Added support for persistent-superblock arrays:
- *             md=n,0,factor,fault,device-list   uses RAID0 for device n
- *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
- *             md=n,device-list      reads a RAID superblock from the devices
- *             elements in device-list are read by name_to_kdev_t so can be
- *             a hex number or something like /dev/hda1 /dev/sdb
- * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
- *		Shifted name_to_kdev_t() and related operations to md_set_drive()
- *		for later execution. Rewrote section to make devfs compatible.
- */
-static int __init md_setup(char *str)
-{
-	int minor, level, factor, fault, pers;
-	char *pername = "";
-	char *str1 = str;
-
-	if (get_option(&str, &minor) != 2) {	/* MD Number */
-		printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
-		return 0;
-	}
-	if (minor >= MAX_MD_DEVS) {
-		printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
-		return 0;
-	} else if (md_setup_args.device_names[minor]) {
-		printk(KERN_WARNING "md: md=%d, Specified more than once. "
-		       "Replacing previous definition.\n", minor);
-	}
-	switch (get_option(&str, &level)) {	/* RAID Personality */
-	case 2: /* could be 0 or -1.. */
-		if (level == 0 || level == LEVEL_LINEAR) {
-			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
-					get_option(&str, &fault) != 2) {
-				printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
-				return 0;
-			}
-			md_setup_args.pers[minor] = level;
-			md_setup_args.chunk[minor] = 1 << (factor+12);
-			switch(level) {
-			case LEVEL_LINEAR:
-				pers = LINEAR;
-				pername = "linear";
-				break;
-			case 0:
-				pers = RAID0;
-				pername = "raid0";
-				break;
-			default:
-				printk(KERN_WARNING
-				       "md: The kernel has not been configured for raid%d support!\n",
-				       level);
-				return 0;
-			}
-			md_setup_args.pers[minor] = pers;
-			break;
-		}
-		/* FALL THROUGH */
-	case 1: /* the first device is numeric */
-		str = str1;
-		/* FALL THROUGH */
-	case 0:
-		md_setup_args.pers[minor] = 0;
-		pername="super-block";
-	}
-
-	printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
-		minor, pername, str);
-	md_setup_args.device_names[minor] = str;
-
-	return 1;
-}
-static void __init md_setup_drive(void)
-{
-	int minor, i;
-	dev_t dev;
-	dev_t devices[MD_SB_DISKS+1];
-
-	for (minor = 0; minor < MAX_MD_DEVS; minor++) {
-		int fd;
-		int err = 0;
-		char *devname;
-		mdu_disk_info_t dinfo;
-		char name[16], devfs_name[16];
-
-		if (!(devname = md_setup_args.device_names[minor]))
-			continue;
-		
-		sprintf(name, "/dev/md%d", minor);
-		sprintf(devfs_name, "/dev/md/%d", minor);
-		create_dev(name, MKDEV(MD_MAJOR, minor), devfs_name);
-		for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
-			char *p;
-			char comp_name[64];
-			struct stat buf;
-
-			p = strchr(devname, ',');
-			if (p)
-				*p++ = 0;
-
-			dev = name_to_dev_t(devname);
-			if (strncmp(devname, "/dev/", 5))
-				devname += 5;
-			snprintf(comp_name, 63, "/dev/%s", devname);
-			if (sys_newstat(comp_name, &buf) == 0 &&
-							S_ISBLK(buf.st_mode))
-				dev = buf.st_rdev;
-			if (!dev) {
-				printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
-				break;
-			}
-
-			devices[i] = dev;
-			md_setup_args.device_set[minor] = 1;
-
-			devname = p;
-		}
-		devices[i] = 0;
-
-		if (!md_setup_args.device_set[minor])
-			continue;
-
-		printk(KERN_INFO "md: Loading md%d: %s\n", minor, md_setup_args.device_names[minor]);
-
-		fd = open(name, 0, 0);
-		if (fd < 0) {
-			printk(KERN_ERR "md: open failed - cannot start array %d\n", minor);
-			continue;
-		}
-		if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
-			printk(KERN_WARNING
-			       "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
-			       minor);
-			close(fd);
-			continue;
-		}
-
-		if (md_setup_args.pers[minor]) {
-			/* non-persistent */
-			mdu_array_info_t ainfo;
-			ainfo.level = pers_to_level(md_setup_args.pers[minor]);
-			ainfo.size = 0;
-			ainfo.nr_disks =0;
-			ainfo.raid_disks =0;
-			while (devices[ainfo.raid_disks])
-				ainfo.raid_disks++;
-			ainfo.md_minor =minor;
-			ainfo.not_persistent = 1;
-
-			ainfo.state = (1 << MD_SB_CLEAN);
-			ainfo.layout = 0;
-			ainfo.chunk_size = md_setup_args.chunk[minor];
-			err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
-			for (i = 0; !err && i <= MD_SB_DISKS; i++) {
-				dev = devices[i];
-				if (!dev)
-					break;
-				dinfo.number = i;
-				dinfo.raid_disk = i;
-				dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
-				dinfo.major = MAJOR(dev);
-				dinfo.minor = MINOR(dev);
-				err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
-			}
-		} else {
-			/* persistent */
-			for (i = 0; i <= MD_SB_DISKS; i++) {
-				dev = devices[i];
-				if (!dev)
-					break;
-				dinfo.major = MAJOR(dev);
-				dinfo.minor = MINOR(dev);
-				sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
-			}
-		}
-		if (!err)
-			err = sys_ioctl(fd, RUN_ARRAY, 0);
-		if (err)
-			printk(KERN_WARNING "md: starting md%d failed\n", minor);
-		close(fd);
-	}
-}
-
-static int __init raid_setup(char *str)
-{
-	int len, pos;
-
-	len = strlen(str) + 1;
-	pos = 0;
-
-	while (pos < len) {
-		char *comma = strchr(str+pos, ',');
-		int wlen;
-		if (comma)
-			wlen = (comma-str)-pos;
-		else	wlen = (len-1)-pos;
-
-		if (!strncmp(str, "noautodetect", wlen))
-			raid_setup_args.noautodetect = 1;
-		pos += wlen+1;
-	}
-	raid_setup_args.set = 1;
-	return 1;
-}
-
-__setup("raid=", raid_setup);
-__setup("md=", md_setup);
-#endif
-
-static void __init md_run_setup(void)
-{
-#ifdef CONFIG_BLK_DEV_MD
-	create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0");
-	if (raid_setup_args.noautodetect)
-		printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
-	else {
-		int fd = open("/dev/md0", 0, 0);
-		if (fd >= 0) {
-			sys_ioctl(fd, RAID_AUTORUN, 0);
-			close(fd);
-		}
-	}
-	md_setup_drive();
-#endif
-}
diff -Nru a/init/do_mounts.h b/init/do_mounts.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/init/do_mounts.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,80 @@
+#define __KERNEL_SYSCALLS__
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/init.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/mount.h>
+#include <linux/blk.h>
+#include <linux/root_dev.h>
+
+asmlinkage long sys_unlink(const char *name);
+asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
+asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
+asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
+asmlinkage long sys_mkdir(const char *name, int mode);
+asmlinkage long sys_rmdir(const char *name);
+asmlinkage long sys_chdir(const char *name);
+asmlinkage long sys_fchdir(int fd);
+asmlinkage long sys_chroot(const char *name);
+asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
+				 unsigned long flags, void *data);
+asmlinkage long sys_umount(char *name, int flags);
+
+dev_t name_to_dev_t(char *name);
+void  change_floppy(char *fmt, ...);
+void  mount_block_root(char *name, int flags);
+void  mount_root(void);
+extern int root_mountflags;
+
+#ifdef CONFIG_DEVFS_FS
+
+void mount_devfs(void);
+void umount_devfs(char *path);
+int  create_dev(char *name, dev_t dev, char *devfs_name);
+
+#else
+
+static inline void mount_devfs(void) {}
+static inline void umount_devfs(const char *path) {}
+
+static inline int create_dev(char *name, dev_t dev, char *devfs_name)
+{
+	sys_unlink(name);
+	return sys_mknod(name, S_IFBLK|0600, dev);
+}
+
+#endif
+
+#ifdef CONFIG_BLK_DEV_RAM
+
+int __init rd_load_disk(int n);
+int __init rd_load_image(char *from);
+
+#else
+
+static inline int rd_load_disk(int n) { return 0; }
+static inline int rd_load_image(char *from) { return 0; }
+
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+int __init initrd_load(void);
+
+#else
+
+static inline int initrd_load(void) { return 0; }
+
+#endif
+
+#ifdef CONFIG_BLK_DEV_MD
+
+void md_run_setup(void);
+
+#else
+
+static inline void md_run_setup(void) {}
+
+#endif
diff -Nru a/init/do_mounts_devfs.c b/init/do_mounts_devfs.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/init/do_mounts_devfs.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,146 @@
+
+#include <linux/kernel.h>
+#include <linux/dirent.h>
+#include <linux/string.h>
+
+#include "do_mounts.h"
+
+extern asmlinkage long sys_symlink(const char *old, const char *new);
+extern asmlinkage long sys_access(const char * filename, int mode);
+extern asmlinkage long sys_getdents64(unsigned int fd, void * dirent,
+				      unsigned int count);
+
+void __init mount_devfs(void)
+{
+	sys_mount("devfs", "/dev", "devfs", 0, NULL);
+}
+
+void __init umount_devfs(char *path)
+{
+	sys_umount(path, 0);
+}
+
+/*
+ * If the dir will fit in *buf, return its length.  If it won't fit, return
+ * zero.  Return -ve on error.
+ */
+static int __init do_read_dir(int fd, void *buf, int len)
+{
+	long bytes, n;
+	char *p = buf;
+	lseek(fd, 0, 0);
+
+	for (bytes = 0; bytes < len; bytes += n) {
+		n = sys_getdents64(fd, p + bytes, len - bytes);
+		if (n < 0)
+			return n;
+		if (n == 0)
+			return bytes;
+	}
+	return 0;
+}
+
+/*
+ * Try to read all of a directory.  Returns the contents at *p, which
+ * is kmalloced memory.  Returns the number of bytes read at *len.  Returns
+ * NULL on error.
+ */
+static void * __init read_dir(char *path, int *len)
+{
+	int size;
+	int fd = open(path, 0, 0);
+
+	*len = 0;
+	if (fd < 0)
+		return NULL;
+
+	for (size = 1 << 9; size <= (1 << MAX_ORDER); size <<= 1) {
+		void *p = kmalloc(size, GFP_KERNEL);
+		int n;
+		if (!p)
+			break;
+		n = do_read_dir(fd, p, size);
+		if (n > 0) {
+			close(fd);
+			*len = n;
+			return p;
+		}
+		kfree(p);
+		if (n == -EINVAL)
+			continue;	/* Try a larger buffer */
+		if (n < 0)
+			break;
+	}
+	close(fd);
+	return NULL;
+}
+
+/*
+ * recursively scan <path>, looking for a device node of type <dev>
+ */
+static int __init find_in_devfs(char *path, dev_t dev)
+{
+	struct stat buf;
+	char *end = path + strlen(path);
+	int rest = path + 64 - end;
+	int size;
+	char *p = read_dir(path, &size);
+	char *s;
+
+	if (!p)
+		return -1;
+	for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
+		struct linux_dirent64 *d = (struct linux_dirent64 *)s;
+		if (strlen(d->d_name) + 2 > rest)
+			continue;
+		switch (d->d_type) {
+			case DT_BLK:
+				sprintf(end, "/%s", d->d_name);
+				if (sys_newstat(path, &buf) < 0)
+					break;
+				if (!S_ISBLK(buf.st_mode))
+					break;
+				if (buf.st_rdev != dev)
+					break;
+				kfree(p);
+				return 0;
+			case DT_DIR:
+				if (strcmp(d->d_name, ".") == 0)
+					break;
+				if (strcmp(d->d_name, "..") == 0)
+					break;
+				sprintf(end, "/%s", d->d_name);
+				if (find_in_devfs(path, dev) < 0)
+					break;
+				kfree(p);
+				return 0;
+		}
+	}
+	kfree(p);
+	return -1;
+}
+
+/*
+ * create a device node called <name> which points to
+ * <devfs_name> if possible, otherwise find a device node
+ * which matches <dev> and make <name> a symlink pointing to it.
+ */
+int __init create_dev(char *name, dev_t dev, char *devfs_name)
+{
+	char path[64];
+
+	sys_unlink(name);
+	if (devfs_name && devfs_name[0]) {
+		if (strncmp(devfs_name, "/dev/", 5) == 0)
+			devfs_name += 5;
+		sprintf(path, "/dev/%s", devfs_name);
+		if (sys_access(path, 0) == 0)
+			return sys_symlink(devfs_name, name);
+	}
+	if (!dev)
+		return -1;
+	strcpy(path, "/dev");
+	if (find_in_devfs(path, dev) < 0)
+		return -1;
+	return sys_symlink(path + 5, name);
+}
diff -Nru a/init/do_mounts_md.c b/init/do_mounts_md.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/init/do_mounts_md.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,253 @@
+
+#include <linux/raid/md.h>
+
+#include "do_mounts.h"
+
+/*
+ * When md (and any require personalities) are compiled into the kernel
+ * (not a module), arrays can be assembles are boot time using with AUTODETECT
+ * where specially marked partitions are registered with md_autodetect_dev(),
+ * and with MD_BOOT where devices to be collected are given on the boot line
+ * with md=.....
+ * The code for that is here.
+ */
+
+static int __initdata raid_noautodetect;
+
+static struct {
+	char device_set [MAX_MD_DEVS];
+	int pers[MAX_MD_DEVS];
+	int chunk[MAX_MD_DEVS];
+	char *device_names[MAX_MD_DEVS];
+} md_setup_args __initdata;
+
+/*
+ * Parse the command-line parameters given our kernel, but do not
+ * actually try to invoke the MD device now; that is handled by
+ * md_setup_drive after the low-level disk drivers have initialised.
+ *
+ * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
+ *             assigns the task of parsing integer arguments to the
+ *             invoked program now).  Added ability to initialise all
+ *             the MD devices (by specifying multiple "md=" lines)
+ *             instead of just one.  -- KTK
+ * 18May2000: Added support for persistent-superblock arrays:
+ *             md=n,0,factor,fault,device-list   uses RAID0 for device n
+ *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
+ *             md=n,device-list      reads a RAID superblock from the devices
+ *             elements in device-list are read by name_to_kdev_t so can be
+ *             a hex number or something like /dev/hda1 /dev/sdb
+ * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
+ *		Shifted name_to_kdev_t() and related operations to md_set_drive()
+ *		for later execution. Rewrote section to make devfs compatible.
+ */
+static int __init md_setup(char *str)
+{
+	int minor, level, factor, fault, pers;
+	char *pername = "";
+	char *str1 = str;
+
+	if (get_option(&str, &minor) != 2) {	/* MD Number */
+		printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
+		return 0;
+	}
+	if (minor >= MAX_MD_DEVS) {
+		printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
+		return 0;
+	} else if (md_setup_args.device_names[minor]) {
+		printk(KERN_WARNING "md: md=%d, Specified more than once. "
+		       "Replacing previous definition.\n", minor);
+	}
+	switch (get_option(&str, &level)) {	/* RAID Personality */
+	case 2: /* could be 0 or -1.. */
+		if (level == 0 || level == LEVEL_LINEAR) {
+			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
+					get_option(&str, &fault) != 2) {
+				printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
+				return 0;
+			}
+			md_setup_args.pers[minor] = level;
+			md_setup_args.chunk[minor] = 1 << (factor+12);
+			switch(level) {
+			case LEVEL_LINEAR:
+				pers = LINEAR;
+				pername = "linear";
+				break;
+			case 0:
+				pers = RAID0;
+				pername = "raid0";
+				break;
+			default:
+				printk(KERN_WARNING
+				       "md: The kernel has not been configured for raid%d support!\n",
+				       level);
+				return 0;
+			}
+			md_setup_args.pers[minor] = pers;
+			break;
+		}
+		/* FALL THROUGH */
+	case 1: /* the first device is numeric */
+		str = str1;
+		/* FALL THROUGH */
+	case 0:
+		md_setup_args.pers[minor] = 0;
+		pername="super-block";
+	}
+
+	printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
+		minor, pername, str);
+	md_setup_args.device_names[minor] = str;
+
+	return 1;
+}
+
+static void __init md_setup_drive(void)
+{
+	int minor, i;
+	dev_t dev;
+	dev_t devices[MD_SB_DISKS+1];
+
+	for (minor = 0; minor < MAX_MD_DEVS; minor++) {
+		int fd;
+		int err = 0;
+		char *devname;
+		mdu_disk_info_t dinfo;
+		char name[16], devfs_name[16];
+
+		if (!(devname = md_setup_args.device_names[minor]))
+			continue;
+		
+		sprintf(name, "/dev/md%d", minor);
+		sprintf(devfs_name, "/dev/md/%d", minor);
+		create_dev(name, MKDEV(MD_MAJOR, minor), devfs_name);
+		for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
+			char *p;
+			char comp_name[64];
+			struct stat buf;
+
+			p = strchr(devname, ',');
+			if (p)
+				*p++ = 0;
+
+			dev = name_to_dev_t(devname);
+			if (strncmp(devname, "/dev/", 5) == 0)
+				devname += 5;
+			snprintf(comp_name, 63, "/dev/%s", devname);
+			if (sys_newstat(comp_name, &buf) == 0 &&
+							S_ISBLK(buf.st_mode))
+				dev = buf.st_rdev;
+			if (!dev) {
+				printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
+				break;
+			}
+
+			devices[i] = dev;
+			md_setup_args.device_set[minor] = 1;
+
+			devname = p;
+		}
+		devices[i] = 0;
+
+		if (!md_setup_args.device_set[minor])
+			continue;
+
+		printk(KERN_INFO "md: Loading md%d: %s\n", minor, md_setup_args.device_names[minor]);
+
+		fd = open(name, 0, 0);
+		if (fd < 0) {
+			printk(KERN_ERR "md: open failed - cannot start array %d\n", minor);
+			continue;
+		}
+		if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
+			printk(KERN_WARNING
+			       "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
+			       minor);
+			close(fd);
+			continue;
+		}
+
+		if (md_setup_args.pers[minor]) {
+			/* non-persistent */
+			mdu_array_info_t ainfo;
+			ainfo.level = pers_to_level(md_setup_args.pers[minor]);
+			ainfo.size = 0;
+			ainfo.nr_disks =0;
+			ainfo.raid_disks =0;
+			while (devices[ainfo.raid_disks])
+				ainfo.raid_disks++;
+			ainfo.md_minor =minor;
+			ainfo.not_persistent = 1;
+
+			ainfo.state = (1 << MD_SB_CLEAN);
+			ainfo.layout = 0;
+			ainfo.chunk_size = md_setup_args.chunk[minor];
+			err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
+			for (i = 0; !err && i <= MD_SB_DISKS; i++) {
+				dev = devices[i];
+				if (!dev)
+					break;
+				dinfo.number = i;
+				dinfo.raid_disk = i;
+				dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
+				dinfo.major = MAJOR(dev);
+				dinfo.minor = MINOR(dev);
+				err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
+			}
+		} else {
+			/* persistent */
+			for (i = 0; i <= MD_SB_DISKS; i++) {
+				dev = devices[i];
+				if (!dev)
+					break;
+				dinfo.major = MAJOR(dev);
+				dinfo.minor = MINOR(dev);
+				sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
+			}
+		}
+		if (!err)
+			err = sys_ioctl(fd, RUN_ARRAY, 0);
+		if (err)
+			printk(KERN_WARNING "md: starting md%d failed\n", minor);
+		close(fd);
+	}
+}
+
+static int __init raid_setup(char *str)
+{
+	int len, pos;
+
+	len = strlen(str) + 1;
+	pos = 0;
+
+	while (pos < len) {
+		char *comma = strchr(str+pos, ',');
+		int wlen;
+		if (comma)
+			wlen = (comma-str)-pos;
+		else	wlen = (len-1)-pos;
+
+		if (!strncmp(str, "noautodetect", wlen))
+			raid_noautodetect = 1;
+		pos += wlen+1;
+	}
+	return 1;
+}
+
+__setup("raid=", raid_setup);
+__setup("md=", md_setup);
+
+void __init md_run_setup(void)
+{
+	create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0");
+	if (raid_noautodetect)
+		printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
+	else {
+		int fd = open("/dev/md0", 0, 0);
+		if (fd >= 0) {
+			sys_ioctl(fd, RAID_AUTORUN, 0);
+			close(fd);
+		}
+	}
+	md_setup_drive();
+}
diff -Nru a/init/do_mounts_rd.c b/init/do_mounts_rd.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/init/do_mounts_rd.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,516 @@
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/minix_fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/romfs_fs.h>
+
+#include "do_mounts.h"
+
+#define BUILD_CRAMDISK
+
+int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
+
+static int __init prompt_ramdisk(char *str)
+{
+	rd_prompt = simple_strtol(str,NULL,0) & 1;
+	return 1;
+}
+__setup("prompt_ramdisk=", prompt_ramdisk);
+
+int __initdata rd_image_start;		/* starting block # of image */
+
+static int __init ramdisk_start_setup(char *str)
+{
+	rd_image_start = simple_strtol(str,NULL,0);
+	return 1;
+}
+__setup("ramdisk_start=", ramdisk_start_setup);
+
+static int __init crd_load(int in_fd, int out_fd);
+
+/*
+ * This routine tries to find a RAM disk image to load, and returns the
+ * number of blocks to read for a non-compressed image, 0 if the image
+ * is a compressed image, and -1 if an image with the right magic
+ * numbers could not be found.
+ *
+ * We currently check for the following magic numbers:
+ * 	minix
+ * 	ext2
+ *	romfs
+ * 	gzip
+ */
+static int __init 
+identify_ramdisk_image(int fd, int start_block)
+{
+	const int size = 512;
+	struct minix_super_block *minixsb;
+	struct ext2_super_block *ext2sb;
+	struct romfs_super_block *romfsb;
+	int nblocks = -1;
+	unsigned char *buf;
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (buf == 0)
+		return -1;
+
+	minixsb = (struct minix_super_block *) buf;
+	ext2sb = (struct ext2_super_block *) buf;
+	romfsb = (struct romfs_super_block *) buf;
+	memset(buf, 0xe5, size);
+
+	/*
+	 * Read block 0 to test for gzipped kernel
+	 */
+	lseek(fd, start_block * BLOCK_SIZE, 0);
+	read(fd, buf, size);
+
+	/*
+	 * If it matches the gzip magic numbers, return -1
+	 */
+	if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
+		printk(KERN_NOTICE
+		       "RAMDISK: Compressed image found at block %d\n",
+		       start_block);
+		nblocks = 0;
+		goto done;
+	}
+
+	/* romfs is at block zero too */
+	if (romfsb->word0 == ROMSB_WORD0 &&
+	    romfsb->word1 == ROMSB_WORD1) {
+		printk(KERN_NOTICE
+		       "RAMDISK: romfs filesystem found at block %d\n",
+		       start_block);
+		nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
+		goto done;
+	}
+
+	/*
+	 * Read block 1 to test for minix and ext2 superblock
+	 */
+	lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
+	read(fd, buf, size);
+
+	/* Try minix */
+	if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
+	    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
+		printk(KERN_NOTICE
+		       "RAMDISK: Minix filesystem found at block %d\n",
+		       start_block);
+		nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
+		goto done;
+	}
+
+	/* Try ext2 */
+	if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
+		printk(KERN_NOTICE
+		       "RAMDISK: ext2 filesystem found at block %d\n",
+		       start_block);
+		nblocks = le32_to_cpu(ext2sb->s_blocks_count);
+		goto done;
+	}
+
+	printk(KERN_NOTICE
+	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
+	       start_block);
+	
+done:
+	lseek(fd, start_block * BLOCK_SIZE, 0);
+	kfree(buf);
+	return nblocks;
+}
+
+int __init rd_load_image(char *from)
+{
+	int res = 0;
+	int in_fd, out_fd;
+	unsigned long rd_blocks, devblocks;
+	int nblocks, i, disk;
+	char *buf;
+	unsigned short rotate = 0;
+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+	char rotator[4] = { '|' , '/' , '-' , '\\' };
+#endif
+
+	out_fd = open("/dev/ram", O_RDWR, 0);
+	if (out_fd < 0)
+		goto out;
+
+	in_fd = open(from, O_RDONLY, 0);
+	if (in_fd < 0)
+		goto noclose_input;
+
+	nblocks = identify_ramdisk_image(in_fd, rd_image_start);
+	if (nblocks < 0)
+		goto done;
+
+	if (nblocks == 0) {
+#ifdef BUILD_CRAMDISK
+		if (crd_load(in_fd, out_fd) == 0)
+			goto successful_load;
+#else
+		printk(KERN_NOTICE
+		       "RAMDISK: Kernel does not support compressed "
+		       "RAM disk images\n");
+#endif
+		goto done;
+	}
+
+	/*
+	 * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
+	 * rd_load_image will work only with filesystem BLOCK_SIZE wide!
+	 * So make sure to use 1k blocksize while generating ext2fs
+	 * ramdisk-images.
+	 */
+	if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
+		rd_blocks = 0;
+	else
+		rd_blocks >>= 1;
+
+	if (nblocks > rd_blocks) {
+		printk("RAMDISK: image too big! (%d/%ld blocks)\n",
+		       nblocks, rd_blocks);
+		goto done;
+	}
+		
+	/*
+	 * OK, time to copy in the data
+	 */
+	if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
+		devblocks = 0;
+	else
+		devblocks >>= 1;
+
+	if (strcmp(from, "/dev/initrd") == 0)
+		devblocks = nblocks;
+
+	if (devblocks == 0) {
+		printk(KERN_ERR "RAMDISK: could not determine device size\n");
+		goto done;
+	}
+
+	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
+	if (buf == 0) {
+		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
+		goto done;
+	}
+
+	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%ld disk%s] into ram disk... ", 
+		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
+	for (i = 0, disk = 1; i < nblocks; i++) {
+		if (i && (i % devblocks == 0)) {
+			printk("done disk #%d.\n", disk++);
+			rotate = 0;
+			if (close(in_fd)) {
+				printk("Error closing the disk.\n");
+				goto noclose_input;
+			}
+			change_floppy("disk #%d", disk);
+			in_fd = open(from, O_RDONLY, 0);
+			if (in_fd < 0)  {
+				printk("Error opening disk.\n");
+				goto noclose_input;
+			}
+			printk("Loading disk #%d... ", disk);
+		}
+		read(in_fd, buf, BLOCK_SIZE);
+		write(out_fd, buf, BLOCK_SIZE);
+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+		if (!(i % 16)) {
+			printk("%c\b", rotator[rotate & 0x3]);
+			rotate++;
+		}
+#endif
+	}
+	printk("done.\n");
+	kfree(buf);
+
+successful_load:
+	res = 1;
+done:
+	close(in_fd);
+noclose_input:
+	close(out_fd);
+out:
+	sys_unlink("/dev/ram");
+	return res;
+}
+
+int __init rd_load_disk(int n)
+{
+	if (rd_prompt)
+		change_floppy("root floppy disk to be loaded into RAM disk");
+	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
+	return rd_load_image("/dev/root");
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
+static int __initdata old_fd, root_fd;
+static int __initdata mount_initrd = 1;
+
+static int __init no_initrd(char *str)
+{
+	mount_initrd = 0;
+	return 1;
+}
+
+__setup("noinitrd", no_initrd);
+
+static int __init do_linuxrc(void * shell)
+{
+	static char *argv[] = { "linuxrc", NULL, };
+	extern char * envp_init[];
+
+	close(old_fd);close(root_fd);
+	close(0);close(1);close(2);
+	setsid();
+	(void) open("/dev/console",O_RDWR,0);
+	(void) dup(0);
+	(void) dup(0);
+	return execve(shell, argv, envp_init);
+}
+
+static void __init handle_initrd(void)
+{
+	int error;
+	int i, pid;
+
+	real_root_dev = ROOT_DEV;
+	create_dev("/dev/root.old", Root_RAM0, NULL);
+	/* mount initrd on rootfs' /root */
+	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
+	sys_mkdir("/old", 0700);
+	root_fd = open("/", 0, 0);
+	old_fd = open("/old", 0, 0);
+	/* move initrd over / and chdir/chroot in initrd root */
+	sys_chdir("/root");
+	sys_mount(".", "/", NULL, MS_MOVE, NULL);
+	sys_chroot(".");
+	mount_devfs_fs ();
+
+	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
+	if (pid > 0) {
+		while (pid != waitpid(-1, &i, 0))
+			yield();
+	}
+
+	/* move initrd to rootfs' /old */
+	sys_fchdir(old_fd);
+	sys_mount("/", ".", NULL, MS_MOVE, NULL);
+	/* switch root and cwd back to / of rootfs */
+	sys_fchdir(root_fd);
+	sys_chroot(".");
+	close(old_fd);
+	close(root_fd);
+	umount_devfs("/old/dev");
+
+	if (real_root_dev == Root_RAM0) {
+		sys_chdir("/old");
+		return;
+	}
+
+	ROOT_DEV = real_root_dev;
+	mount_root();
+
+	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
+	error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
+	if (!error)
+		printk("okay\n");
+	else {
+		int fd = open("/dev/root.old", O_RDWR, 0);
+		printk("failed\n");
+		printk(KERN_NOTICE "Unmounting old root\n");
+		sys_umount("/old", MNT_DETACH);
+		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
+		if (fd < 0) {
+			error = fd;
+		} else {
+			error = sys_ioctl(fd, BLKFLSBUF, 0);
+			close(fd);
+		}
+		printk(!error ? "okay\n" : "failed\n");
+	}
+}
+
+int __init initrd_load(void)
+{
+	if (!mount_initrd)
+		return 0;
+
+	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
+	create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
+	/* Load the initrd data into /dev/ram0. Execute it as initrd unless
+	 * /dev/ram0 is supposed to be our actual root device, in
+	 * that case the ram disk is just set up here, and gets
+	 * mounted in the normal path. */
+	if (rd_load_image("/dev/initrd") && ROOT_DEV != Root_RAM0) {
+		handle_initrd();
+		return 1;
+	}
+	return 0;
+}
+#endif
+
+#ifdef BUILD_CRAMDISK
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+
+#ifndef memzero
+#define memzero(s, n)     memset ((s), 0, (n))
+#endif
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define INBUFSIZ 4096
+#define WSIZE 0x8000    /* window size--must be a power of two, and */
+			/*  at least 32K for zip's deflate method */
+
+static uch *inbuf;
+static uch *window;
+
+static unsigned insize;  /* valid bytes in inbuf */
+static unsigned inptr;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt;  /* bytes in output buffer */
+static int exit_code;
+static int unzip_error;
+static long bytes_out;
+static int crd_infd, crd_outfd;
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+		
+/* Diagnostic functions (stubbed out) */
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+#define STATIC static
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+#include "../lib/inflate.c"
+
+static void __init *malloc(int size)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+
+static void __init free(void *where)
+{
+	kfree(where);
+}
+
+static void __init gzip_mark(void **ptr)
+{
+}
+
+static void __init gzip_release(void **ptr)
+{
+}
+
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ * Returning -1 does not guarantee that gunzip() will ever return.
+ */
+static int __init fill_inbuf(void)
+{
+	if (exit_code) return -1;
+	
+	insize = read(crd_infd, inbuf, INBUFSIZ);
+	if (insize == 0) {
+		error("RAMDISK: ran out of compressed data\n");
+		return -1;
+	}
+
+	inptr = 1;
+
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void __init flush_window(void)
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n, written;
+    uch *in, ch;
+    
+    written = write(crd_outfd, window, outcnt);
+    if (written != outcnt && unzip_error == 0) {
+	printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
+	       written, outcnt, bytes_out);
+	unzip_error = 1;
+    }
+    in = window;
+    for (n = 0; n < outcnt; n++) {
+	    ch = *in++;
+	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void __init error(char *x)
+{
+	printk(KERN_ERR "%s", x);
+	exit_code = 1;
+	unzip_error = 1;
+}
+
+static int __init crd_load(int in_fd, int out_fd)
+{
+	int result;
+
+	insize = 0;		/* valid bytes in inbuf */
+	inptr = 0;		/* index of next byte to be processed in inbuf */
+	outcnt = 0;		/* bytes in output buffer */
+	exit_code = 0;
+	bytes_out = 0;
+	crc = (ulg)0xffffffffL; /* shift register contents */
+
+	crd_infd = in_fd;
+	crd_outfd = out_fd;
+	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
+	if (inbuf == 0) {
+		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
+		return -1;
+	}
+	window = kmalloc(WSIZE, GFP_KERNEL);
+	if (window == 0) {
+		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
+		kfree(inbuf);
+		return -1;
+	}
+	makecrc();
+	result = gunzip();
+	if (unzip_error)
+		result = 1;
+	kfree(inbuf);
+	kfree(window);
+	return result;
+}
+
+#endif  /* BUILD_CRAMDISK */
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c	Tue Mar  4 19:30:05 2003
+++ b/init/main.c	Tue Mar  4 19:30:05 2003
@@ -71,6 +71,7 @@
 extern void radix_tree_init(void);
 extern void free_initmem(void);
 extern void populate_rootfs(void);
+extern void driver_init(void);
 
 #ifdef CONFIG_TC
 extern void tc_init(void);
@@ -476,6 +477,8 @@
  */
 static void __init do_basic_setup(void)
 {
+	driver_init();
+
 #ifdef CONFIG_SYSCTL
 	sysctl_init();
 #endif
diff -Nru a/kernel/cpufreq.c b/kernel/cpufreq.c
--- a/kernel/cpufreq.c	Tue Mar  4 19:30:05 2003
+++ b/kernel/cpufreq.c	Tue Mar  4 19:30:05 2003
@@ -23,11 +23,6 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 
-#ifdef CONFIG_CPU_FREQ_24_API
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#endif
-
 /**
  * The "cpufreq driver" - the arch- or hardware-dependend low
  * level driver of CPUFreq support, and its locking mutex. 
@@ -51,15 +46,6 @@
 static DECLARE_MUTEX            (cpufreq_notifier_sem);
 
 
-#ifdef CONFIG_CPU_FREQ_24_API
-/**
- * A few values needed by the 2.4.-compatible API
- */
-static unsigned int     cpu_max_freq[NR_CPUS];
-static unsigned int     cpu_min_freq[NR_CPUS];
-static unsigned int     cpu_cur_freq[NR_CPUS];
-#endif
-
 LIST_HEAD(cpufreq_governor_list);
 
 static int cpufreq_governor(unsigned int cpu, unsigned int event);
@@ -102,7 +88,7 @@
 
 /* forward declarations */
 static int cpufreq_add_dev (struct device * dev);
-static int cpufreq_remove_dev (struct intf_data * dev);
+static int cpufreq_remove_dev (struct device * dev);
 
 /* drivers/base/cpu.c */
 extern struct device_class cpu_devclass;
@@ -130,70 +116,59 @@
  * "unsigned int".
  */
 
-#define cpufreq_per_cpu_attr_read(file_name, object) 			\
+#define show_one(file_name, object)		 			\
 static ssize_t show_##file_name 					\
-(struct device *dev, char *buf)						\
+(struct cpufreq_policy * policy, char *buf)				\
 {									\
 	unsigned int value = 0;						\
 									\
-	if (!dev)							\
-		return 0;						\
-									\
 	down(&cpufreq_driver_sem);					\
 	if (cpufreq_driver)						\
-		value = cpufreq_driver->policy[to_cpu_nr(dev)].object;	\
+		value = policy->object;					\
 	up(&cpufreq_driver_sem);					\
 									\
 	return sprintf (buf, "%u\n", value);				\
 }
 
+show_one(cpuinfo_min_freq, cpuinfo.min_freq);
+show_one(cpuinfo_max_freq, cpuinfo.max_freq);
+show_one(scaling_min_freq, min);
+show_one(scaling_max_freq, max);
 
 /**
  * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
  */
-#define cpufreq_per_cpu_attr_write(file_name, object)			\
+#define store_one(file_name, object)			\
 static ssize_t store_##file_name					\
-(struct device *dev, const char *buf, size_t count)			\
+(struct cpufreq_policy * policy, const char *buf, size_t count)		\
 {									\
 	unsigned int ret = -EINVAL;					\
-	struct cpufreq_policy policy;					\
 									\
-	if (!dev)							\
-		return 0;						\
-									\
-	ret = cpufreq_get_policy(&policy, to_cpu_nr(dev));		\
-	if (ret)							\
-		return ret;						\
-									\
-	ret = sscanf (buf, "%u", &policy.object);			\
+	ret = sscanf (buf, "%u", &policy->object);			\
 	if (ret != 1)							\
 		return -EINVAL;						\
 									\
-	ret = cpufreq_set_policy(&policy);				\
-	if (ret)							\
-		return ret;						\
+	ret = cpufreq_set_policy(policy);				\
 									\
-	return count;							\
+	return ret ? ret : count;					\
 }
 
+store_one(scaling_min_freq,min);
+store_one(scaling_max_freq,max);
 
 /**
  * show_scaling_governor - show the current policy for the specified CPU
  */
-static ssize_t show_scaling_governor (struct device *dev, char *buf)
+static ssize_t show_scaling_governor (struct cpufreq_policy * policy, char *buf)
 {
 	unsigned int value = 0;
 	char value2[CPUFREQ_NAME_LEN];
 
-
-	if (!dev)
-		return 0;
-
 	down(&cpufreq_driver_sem);
 	if (cpufreq_driver)
-		value = cpufreq_driver->policy[to_cpu_nr(dev)].policy;
+		value = policy->policy;
 	if (value == CPUFREQ_POLICY_GOVERNOR)
-		strncpy(value2, cpufreq_driver->policy[to_cpu_nr(dev)].governor->name, CPUFREQ_NAME_LEN);
+		strncpy(value2, policy->governor->name, CPUFREQ_NAME_LEN);
 	up(&cpufreq_driver_sem);
 
 	switch (value) {
@@ -212,35 +187,89 @@
 /**
  * store_scaling_governor - store policy for the specified CPU
  */
-static ssize_t 
-store_scaling_governor (struct device *dev, const char *buf, size_t count) 
+static ssize_t store_scaling_governor (struct cpufreq_policy * policy, 
+				       const char *buf, size_t count) 
 {
 	unsigned int ret = -EINVAL;
 	char	str_governor[16];
-	struct cpufreq_policy policy;
-
-	if (!dev)
-		return 0;
-
-	ret = cpufreq_get_policy(&policy, to_cpu_nr(dev));
-	if (ret)
-		return ret;
 
 	ret = sscanf (buf, "%15s", str_governor);
 	if (ret != 1)
 		return -EINVAL;
 
-	if (cpufreq_parse_governor(str_governor, &policy.policy, &policy.governor))
+	if (cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor))
 		return -EINVAL;
 
-	ret = cpufreq_set_policy(&policy);
-	if (ret)
-		return ret;
+	ret = cpufreq_set_policy(policy);
 
-	return count;
+	return ret ? ret : count;
 }
 
 
+struct freq_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct cpufreq_policy *, char *);
+	ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
+};
+
+#define define_one_ro(_name) \
+struct freq_attr _name = { \
+	.attr = { .name = __stringify(_name), .mode = 0444 }, \
+	.show = show_##_name, \
+}
+
+#define define_one_rw(_name) \
+struct freq_attr _name = { \
+	.attr = { .name = __stringify(_name), .mode = 0644 }, \
+	.show = show_##_name, \
+	.store = store_##_name, \
+}
+
+define_one_ro(cpuinfo_min_freq);
+define_one_ro(cpuinfo_max_freq);
+define_one_rw(scaling_min_freq);
+define_one_rw(scaling_max_freq);
+define_one_rw(scaling_governor);
+
+static struct attribute * default_attrs[] = {
+	&cpuinfo_min_freq.attr,
+	&cpuinfo_max_freq.attr,
+	&scaling_min_freq.attr,
+	&scaling_max_freq.attr,
+	&scaling_governor.attr,
+	NULL
+};
+
+
+#define to_policy(k) container_of(k,struct cpufreq_policy,kobj)
+#define to_attr(a) container_of(a,struct freq_attr,attr)
+
+static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
+{
+	struct cpufreq_policy * policy = to_policy(kobj);
+	struct freq_attr * fattr = to_attr(attr);
+	return fattr->show ? fattr->show(policy,buf) : 0;
+}
+
+static ssize_t store(struct kobject * kobj, struct attribute * attr, 
+		     const char * buf, size_t count)
+{
+	struct cpufreq_policy * policy = to_policy(kobj);
+	struct freq_attr * fattr = to_attr(attr);
+	return fattr->store ? fattr->store(policy,buf,count) : 0;
+}
+
+static struct sysfs_ops sysfs_ops = {
+	.show	= show,
+	.store	= store,
+};
+
+static struct kobj_type ktype_cpufreq = {
+	.sysfs_ops	= &sysfs_ops,
+	.default_attrs	= default_attrs,
+};
+
+
 /**
  * show_scaling_governor - show the current policy for the specified CPU
  */
@@ -288,34 +317,9 @@
 }
 
 
-/**
- * cpufreq_per_cpu_attr_ro - read-only cpufreq per-CPU file
- */
-#define cpufreq_per_cpu_attr_ro(file_name, object)			\
-cpufreq_per_cpu_attr_read(file_name, object) 				\
-static DEVICE_ATTR(file_name, S_IRUGO, show_##file_name, NULL);
-
-
-/**
- * cpufreq_per_cpu_attr_rw - read-write cpufreq per-CPU file
- */
-#define cpufreq_per_cpu_attr_rw(file_name, object) 			\
-cpufreq_per_cpu_attr_read(file_name, object) 				\
-cpufreq_per_cpu_attr_write(file_name, object) 				\
-static DEVICE_ATTR(file_name, (S_IRUGO | S_IWUSR), show_##file_name, store_##file_name);
-
-
-/* create the file functions */
-cpufreq_per_cpu_attr_ro(cpuinfo_min_freq, cpuinfo.min_freq);
-cpufreq_per_cpu_attr_ro(cpuinfo_max_freq, cpuinfo.max_freq);
-cpufreq_per_cpu_attr_rw(scaling_min_freq, min);
-cpufreq_per_cpu_attr_rw(scaling_max_freq, max);
-
-static DEVICE_ATTR(scaling_governor, (S_IRUGO | S_IWUSR), show_scaling_governor, store_scaling_governor);
 static DEVICE_ATTR(scaling_driver, S_IRUGO, show_scaling_driver, NULL);
 static DEVICE_ATTR(available_scaling_governors, S_IRUGO, show_available_govs, NULL);
 
-
 /**
  * cpufreq_add_dev - add a CPU device
  *
@@ -359,36 +363,14 @@
 		return -EINVAL;
 	down(&cpufreq_driver_sem);
 
-	/* 2.4-API init for this CPU */
-#ifdef CONFIG_CPU_FREQ_24_API
-	cpu_min_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.min_freq;
-	cpu_max_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.max_freq;
-	cpu_cur_freq[cpu] = cpufreq_driver->cpu_cur_freq[cpu];
-#endif
-
 	/* prepare interface data */
-	cpufreq_driver->policy[cpu].intf.dev  = dev;
-	cpufreq_driver->policy[cpu].intf.intf = &cpufreq_interface;
-	strncpy(cpufreq_driver->policy[cpu].intf.kobj.name, cpufreq_interface.name, KOBJ_NAME_LEN);
-	cpufreq_driver->policy[cpu].intf.kobj.parent = &(dev->kobj);
-	cpufreq_driver->policy[cpu].intf.kobj.kset = &(cpufreq_interface.kset);
-
-	/* add interface */
-	/* currently commented out due to deadlock */
-	//ret = interface_add_data(&(cpufreq_driver->policy[cpu].intf));
-	if (ret) {
-		up(&cpufreq_driver_sem);
-		return ret;
-	}
+	policy.kobj.parent = &dev->kobj;
+	policy.kobj.ktype = &ktype_cpufreq;
+	policy.dev = dev;
+	strncpy(policy.kobj.name, 
+		cpufreq_interface.name, KOBJ_NAME_LEN);
 
-	/* create files */
-	device_create_file (dev, &dev_attr_cpuinfo_min_freq);
-	device_create_file (dev, &dev_attr_cpuinfo_max_freq);
-	device_create_file (dev, &dev_attr_scaling_min_freq);
-	device_create_file (dev, &dev_attr_scaling_max_freq);
-	device_create_file (dev, &dev_attr_scaling_governor);
-	device_create_file (dev, &dev_attr_scaling_driver);
-	device_create_file (dev, &dev_attr_available_scaling_governors);
+	ret = kobject_register(&policy.kobj);
 
 	up(&cpufreq_driver_sem);
 	return ret;
@@ -401,9 +383,8 @@
  * Removes the cpufreq interface for a CPU device. Is called with
  * cpufreq_driver_sem locked.
  */
-static int cpufreq_remove_dev (struct intf_data *intf)
+static int cpufreq_remove_dev (struct device * dev)
 {
-	struct device * dev = intf->dev;
 	unsigned int cpu = to_cpu_nr(dev);
 
 	if (cpufreq_driver->target)
@@ -412,411 +393,13 @@
 	if (cpufreq_driver->exit)
 		cpufreq_driver->exit(&cpufreq_driver->policy[cpu]);
 
-	device_remove_file (dev, &dev_attr_cpuinfo_min_freq);
-	device_remove_file (dev, &dev_attr_cpuinfo_max_freq);
-	device_remove_file (dev, &dev_attr_scaling_min_freq);
-	device_remove_file (dev, &dev_attr_scaling_max_freq);
-	device_remove_file (dev, &dev_attr_scaling_governor);
-	device_remove_file (dev, &dev_attr_scaling_driver);
-	device_remove_file (dev, &dev_attr_available_scaling_governors);
+	kobject_unregister(&cpufreq_driver->policy[cpu].kobj);
 
 	return 0;
 }
 
 
 /*********************************************************************
- *                      /proc/sys/cpu/ INTERFACE                     *
- *********************************************************************/
-
-#ifdef CONFIG_CPU_FREQ_24_API
-/** 
- * cpufreq_set - set the CPU frequency
- * @freq: target frequency in kHz
- * @cpu: CPU for which the frequency is to be set
- *
- * Sets the CPU frequency to freq.
- */
-int cpufreq_set(unsigned int freq, unsigned int cpu)
-{
-	struct cpufreq_policy policy;
-	down(&cpufreq_driver_sem);
-	if (!cpufreq_driver || !freq || (cpu > NR_CPUS)) {
-		up(&cpufreq_driver_sem);
-		return -EINVAL;
-	}
-
-	policy.min = freq;
-	policy.max = freq;
-	policy.policy = CPUFREQ_POLICY_POWERSAVE;
-	policy.cpu = cpu;
-	
-	up(&cpufreq_driver_sem);
-
-	if (policy.cpu == CPUFREQ_ALL_CPUS)
-	{
-		unsigned int i;
-		unsigned int ret = 0;
-		for (i=0; i<NR_CPUS; i++) 
-		{
-			policy.cpu = i;
-			if (cpu_online(i))
-				ret |= cpufreq_set_policy(&policy);
-		}
-		return ret;
-	} 
-	else
-		return cpufreq_set_policy(&policy);
-}
-EXPORT_SYMBOL_GPL(cpufreq_set);
-
-
-/** 
- * cpufreq_setmax - set the CPU to the maximum frequency
- * @cpu - affected cpu;
- *
- * Sets the CPU frequency to the maximum frequency supported by
- * this CPU.
- */
-int cpufreq_setmax(unsigned int cpu)
-{
-	if (!cpu_online(cpu) && (cpu != CPUFREQ_ALL_CPUS))
-		return -EINVAL;
-	return cpufreq_set(cpu_max_freq[cpu], cpu);
-}
-EXPORT_SYMBOL_GPL(cpufreq_setmax);
-
-
-/** 
- * cpufreq_get - get the current CPU frequency (in kHz)
- * @cpu: CPU number - currently without effect.
- *
- * Get the CPU current (static) CPU frequency
- */
-unsigned int cpufreq_get(unsigned int cpu)
-{
-	if (!cpu_online(cpu))
-		return -EINVAL;
-	return cpu_cur_freq[cpu];
-}
-EXPORT_SYMBOL(cpufreq_get);
-
-
-#ifdef CONFIG_SYSCTL
-
-
-/*********************** cpufreq_sysctl interface ********************/
-static int
-cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
-		void *buffer, size_t *lenp)
-{
-	char buf[16], *p;
-	int cpu = (int) ctl->extra1;
-	int len, left = *lenp;
-
-	if (!left || (filp->f_pos && !write) || !cpu_online(cpu)) {
-		*lenp = 0;
-		return 0;
-	}
-
-	if (write) {
-		unsigned int freq;
-
-		len = left;
-		if (left > sizeof(buf))
-			left = sizeof(buf);
-		if (copy_from_user(buf, buffer, left))
-			return -EFAULT;
-		buf[sizeof(buf) - 1] = '\0';
-
-		freq = simple_strtoul(buf, &p, 0);
-		cpufreq_set(freq, cpu);
-	} else {
-		len = sprintf(buf, "%d\n", cpufreq_get(cpu));
-		if (len > left)
-			len = left;
-		if (copy_to_user(buffer, buf, len))
-			return -EFAULT;
-	}
-
-	*lenp = len;
-	filp->f_pos += len;
-	return 0;
-}
-
-static int
-cpufreq_sysctl(ctl_table *table, int *name, int nlen,
-	       void *oldval, size_t *oldlenp,
-	       void *newval, size_t newlen, void **context)
-{
-	int cpu = (int) table->extra1;
-
-	if (!cpu_online(cpu))
-		return -EINVAL;
-
-	if (oldval && oldlenp) {
-		size_t oldlen;
-
-		if (get_user(oldlen, oldlenp))
-			return -EFAULT;
-
-		if (oldlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
-		    put_user(sizeof(unsigned int), oldlenp))
-			return -EFAULT;
-	}
-	if (newval && newlen) {
-		unsigned int freq;
-
-		if (newlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (get_user(freq, (unsigned int *)newval))
-			return -EFAULT;
-
-		cpufreq_set(freq, cpu);
-	}
-	return 1;
-}
-
-/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-        CTL_TABLE_CPU_VARS(0);
-#if NR_CPUS > 1
-	CTL_TABLE_CPU_VARS(1);
-#endif
-#if NR_CPUS > 2
-	CTL_TABLE_CPU_VARS(2);
-#endif
-#if NR_CPUS > 3
-	CTL_TABLE_CPU_VARS(3);
-#endif
-#if NR_CPUS > 4
-	CTL_TABLE_CPU_VARS(4);
-#endif
-#if NR_CPUS > 5
-	CTL_TABLE_CPU_VARS(5);
-#endif
-#if NR_CPUS > 6
-	CTL_TABLE_CPU_VARS(6);
-#endif
-#if NR_CPUS > 7
-	CTL_TABLE_CPU_VARS(7);
-#endif
-#if NR_CPUS > 8
-	CTL_TABLE_CPU_VARS(8);
-#endif
-#if NR_CPUS > 9
-	CTL_TABLE_CPU_VARS(9);
-#endif
-#if NR_CPUS > 10
-	CTL_TABLE_CPU_VARS(10);
-#endif
-#if NR_CPUS > 11
-	CTL_TABLE_CPU_VARS(11);
-#endif
-#if NR_CPUS > 12
-	CTL_TABLE_CPU_VARS(12);
-#endif
-#if NR_CPUS > 13
-	CTL_TABLE_CPU_VARS(13);
-#endif
-#if NR_CPUS > 14
-	CTL_TABLE_CPU_VARS(14);
-#endif
-#if NR_CPUS > 15
-	CTL_TABLE_CPU_VARS(15);
-#endif
-#if NR_CPUS > 16
-	CTL_TABLE_CPU_VARS(16);
-#endif
-#if NR_CPUS > 17
-	CTL_TABLE_CPU_VARS(17);
-#endif
-#if NR_CPUS > 18
-	CTL_TABLE_CPU_VARS(18);
-#endif
-#if NR_CPUS > 19
-	CTL_TABLE_CPU_VARS(19);
-#endif
-#if NR_CPUS > 20
-	CTL_TABLE_CPU_VARS(20);
-#endif
-#if NR_CPUS > 21
-	CTL_TABLE_CPU_VARS(21);
-#endif
-#if NR_CPUS > 22
-	CTL_TABLE_CPU_VARS(22);
-#endif
-#if NR_CPUS > 23
-	CTL_TABLE_CPU_VARS(23);
-#endif
-#if NR_CPUS > 24
-	CTL_TABLE_CPU_VARS(24);
-#endif
-#if NR_CPUS > 25
-	CTL_TABLE_CPU_VARS(25);
-#endif
-#if NR_CPUS > 26
-	CTL_TABLE_CPU_VARS(26);
-#endif
-#if NR_CPUS > 27
-	CTL_TABLE_CPU_VARS(27);
-#endif
-#if NR_CPUS > 28
-	CTL_TABLE_CPU_VARS(28);
-#endif
-#if NR_CPUS > 29
-	CTL_TABLE_CPU_VARS(29);
-#endif
-#if NR_CPUS > 30
-	CTL_TABLE_CPU_VARS(30);
-#endif
-#if NR_CPUS > 31
-	CTL_TABLE_CPU_VARS(31);
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
-	CPU_ENUM(0),
-#if NR_CPUS > 1
-	CPU_ENUM(1),
-#endif
-#if NR_CPUS > 2
-	CPU_ENUM(2),
-#endif
-#if NR_CPUS > 3
-	CPU_ENUM(3),
-#endif
-#if NR_CPUS > 4
-	CPU_ENUM(4),
-#endif
-#if NR_CPUS > 5
-	CPU_ENUM(5),
-#endif
-#if NR_CPUS > 6
-	CPU_ENUM(6),
-#endif
-#if NR_CPUS > 7
-	CPU_ENUM(7),
-#endif
-#if NR_CPUS > 8
-	CPU_ENUM(8),
-#endif
-#if NR_CPUS > 9
-	CPU_ENUM(9),
-#endif
-#if NR_CPUS > 10
-	CPU_ENUM(10),
-#endif
-#if NR_CPUS > 11
-	CPU_ENUM(11),
-#endif
-#if NR_CPUS > 12
-	CPU_ENUM(12),
-#endif
-#if NR_CPUS > 13
-	CPU_ENUM(13),
-#endif
-#if NR_CPUS > 14
-	CPU_ENUM(14),
-#endif
-#if NR_CPUS > 15
-	CPU_ENUM(15),
-#endif
-#if NR_CPUS > 16
-	CPU_ENUM(16),
-#endif
-#if NR_CPUS > 17
-	CPU_ENUM(17),
-#endif
-#if NR_CPUS > 18
-	CPU_ENUM(18),
-#endif
-#if NR_CPUS > 19
-	CPU_ENUM(19),
-#endif
-#if NR_CPUS > 20
-	CPU_ENUM(20),
-#endif
-#if NR_CPUS > 21
-	CPU_ENUM(21),
-#endif
-#if NR_CPUS > 22
-	CPU_ENUM(22),
-#endif
-#if NR_CPUS > 23
-	CPU_ENUM(23),
-#endif
-#if NR_CPUS > 24
-	CPU_ENUM(24),
-#endif
-#if NR_CPUS > 25
-	CPU_ENUM(25),
-#endif
-#if NR_CPUS > 26
-	CPU_ENUM(26),
-#endif
-#if NR_CPUS > 27
-	CPU_ENUM(27),
-#endif
-#if NR_CPUS > 28
-	CPU_ENUM(28),
-#endif
-#if NR_CPUS > 29
-	CPU_ENUM(29),
-#endif
-#if NR_CPUS > 30
-	CPU_ENUM(30),
-#endif
-#if NR_CPUS > 31
-	CPU_ENUM(31),
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-	{
-		.ctl_name	= 0,
-	}
-};
-
-static ctl_table ctl_cpu[2] = {
-	{
-		.ctl_name	= CTL_CPU,
-		.procname	= "cpu",
-		.mode		= 0555,
-		.child		= ctl_cpu_table,
-	},
-	{
-		.ctl_name	= 0,
-	}
-};
-
-struct ctl_table_header *cpufreq_sysctl_table;
-
-static inline void cpufreq_sysctl_init(void)
-{
-	cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
-}
-
-static inline void cpufreq_sysctl_exit(void)
-{
-	unregister_sysctl_table(cpufreq_sysctl_table);
-}
-
-#else
-#define cpufreq_sysctl_init() do {} while(0)
-#define cpufreq_sysctl_exit() do {} while(0)
-#endif /* CONFIG_SYSCTL */
-#endif /* CONFIG_CPU_FREQ_24_API */
-
-
-
-/*********************************************************************
  *                     NOTIFIER LISTS INTERFACE                      *
  *********************************************************************/
 
@@ -1078,11 +661,11 @@
 
 	down(&cpufreq_notifier_sem);
 
-	/* adjust if neccessary - all reasons */
+	/* adjust if necessary - all reasons */
 	notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST,
 			    policy);
 
-	/* adjust if neccessary - hardware incompatibility*/
+	/* adjust if necessary - hardware incompatibility*/
 	notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_INCOMPATIBLE,
 			    policy);
 
@@ -1104,10 +687,6 @@
 	cpufreq_driver->policy[policy->cpu].min    = policy->min;
 	cpufreq_driver->policy[policy->cpu].max    = policy->max;
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	cpu_cur_freq[policy->cpu] = policy->max;
-#endif
-
 	if (cpufreq_driver->setpolicy) {
 		cpufreq_driver->policy[policy->cpu].policy = policy->policy;
 		ret = cpufreq_driver->setpolicy(policy);
@@ -1189,9 +768,7 @@
 	case CPUFREQ_POSTCHANGE:
 		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
 		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
-#ifdef CONFIG_CPU_FREQ_24_API
-		cpu_cur_freq[freqs->cpu] = freqs->new;
-#endif
+		cpufreq_driver->policy[freqs->cpu].cur = freqs->new;
 		break;
 	}
 	up(&cpufreq_notifier_sem);
@@ -1245,10 +822,6 @@
 	
 	up(&cpufreq_driver_sem);
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	cpufreq_sysctl_init();
-#endif
-
 	ret = interface_register(&cpufreq_interface);
 
 	return ret;
@@ -1272,19 +845,6 @@
 	    ((driver != cpufreq_driver) && (driver != NULL))) { /* compat */
 		up(&cpufreq_driver_sem);
 		return -EINVAL;
-	}
-
-#ifdef CONFIG_CPU_FREQ_24_API
-	cpufreq_sysctl_exit();
-#endif
-
-	/* remove this workaround as soon as interface_add_data works */
-	{
-		unsigned int i;
-		for (i=0; i<NR_CPUS; i++) {
-			if (cpu_online(i)) 
-				cpufreq_remove_dev(&cpufreq_driver->policy[i].intf);
-		}
 	}
 
 	interface_unregister(&cpufreq_interface);
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Tue Mar  4 19:30:13 2003
+++ b/kernel/exit.c	Tue Mar  4 19:30:13 2003
@@ -482,7 +482,7 @@
 
 static inline void reparent_thread(task_t *p, task_t *father, int traced)
 {
-	/* We dont want people slaying init.  */
+	/* We don't want people slaying init.  */
 	if (p->exit_signal != -1)
 		p->exit_signal = SIGCHLD;
 	p->self_exec_id++;
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Tue Mar  4 19:30:04 2003
+++ b/kernel/fork.c	Tue Mar  4 19:30:04 2003
@@ -72,15 +72,8 @@
 	return total;
 }
 
-void __put_task_struct(struct task_struct *tsk)
+static void free_task_struct(struct task_struct *tsk)
 {
-	WARN_ON(!(tsk->state & (TASK_DEAD | TASK_ZOMBIE)));
-	WARN_ON(atomic_read(&tsk->usage));
-	WARN_ON(tsk == current);
-
-	security_task_free(tsk);
-	free_uid(tsk->user);
-
 	/*
 	 * The task cache is effectively disabled right now.
 	 * Do we want it? The slab cache already has per-cpu
@@ -103,6 +96,17 @@
 	}
 }
 
+void __put_task_struct(struct task_struct *tsk)
+{
+	WARN_ON(!(tsk->state & (TASK_DEAD | TASK_ZOMBIE)));
+	WARN_ON(atomic_read(&tsk->usage));
+	WARN_ON(tsk == current);
+
+	security_task_free(tsk);
+	free_uid(tsk->user);
+	free_task_struct(tsk);
+}
+
 void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
 {
 	unsigned long flags;
@@ -446,7 +450,7 @@
 		tsk->clear_child_tid = NULL;
 
 		/*
-		 * We dont check the error code - if userspace has
+		 * We don't check the error code - if userspace has
 		 * not set up a proper pointer then tough luck.
 		 */
 		put_user(0, tidptr);
@@ -901,7 +905,7 @@
 
 	/*
 	 * Share the timeslice between parent and child, thus the
-	 * total amount of pending timeslices in the system doesnt change,
+	 * total amount of pending timeslices in the system doesn't change,
 	 * resulting in more scheduling fairness.
 	 */
 	local_irq_disable();
@@ -1034,7 +1038,7 @@
 	atomic_dec(&p->user->processes);
 	free_uid(p->user);
 bad_fork_free:
-	put_task_struct(p);
+	free_task_struct(p);
 	goto fork_out;
 }
 
diff -Nru a/kernel/futex.c b/kernel/futex.c
--- a/kernel/futex.c	Tue Mar  4 19:30:05 2003
+++ b/kernel/futex.c	Tue Mar  4 19:30:05 2003
@@ -39,7 +39,7 @@
 
 /*
  * We use this hashed waitqueue instead of a normal wait_queue_t, so
- * we can wake only the relevent ones (hashed queues may be shared):
+ * we can wake only the relevant ones (hashed queues may be shared):
  */
 struct futex_q {
 	struct list_head list;
@@ -297,7 +297,7 @@
 		time = schedule_timeout(time);
 	set_current_state(TASK_RUNNING);
 	/*
-	 * NOTE: we dont remove ourselves from the waitqueue because
+	 * NOTE: we don't remove ourselves from the waitqueue because
 	 * we are the only user of it.
 	 */
 	if (time == 0) {
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Tue Mar  4 19:30:03 2003
+++ b/kernel/ksyms.c	Tue Mar  4 19:30:03 2003
@@ -119,6 +119,7 @@
 EXPORT_SYMBOL(get_unmapped_area);
 EXPORT_SYMBOL(init_mm);
 EXPORT_SYMBOL(blk_queue_bounce);
+EXPORT_SYMBOL(blk_congestion_wait);
 #ifdef CONFIG_HIGHMEM
 EXPORT_SYMBOL(kmap_high);
 EXPORT_SYMBOL(kunmap_high);
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	Tue Mar  4 19:30:11 2003
+++ b/kernel/module.c	Tue Mar  4 19:30:11 2003
@@ -76,6 +76,22 @@
 }
 EXPORT_SYMBOL(init_module);
 
+/* Find a module section: 0 means not found. */
+static unsigned int find_sec(Elf_Ehdr *hdr,
+			     Elf_Shdr *sechdrs,
+			     const char *secstrings,
+			     const char *name)
+{
+	unsigned int i;
+
+	for (i = 1; i < hdr->e_shnum; i++)
+		/* Alloc bit cleared means "ignore it." */
+		if ((sechdrs[i].sh_flags & SHF_ALLOC)
+		    && strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
+			return i;
+	return 0;
+}
+
 /* Find a symbol, return value and the symbol group */
 static unsigned long __find_symbol(const char *name,
 				   struct kernel_symbol_group **group,
@@ -173,16 +189,19 @@
 	struct module_use *use;
 	if (b == NULL || already_uses(a, b)) return 1;
 
+	if (!strong_try_module_get(b))
+		return 0;
+
 	DEBUGP("Allocating new usage for %s.\n", a->name);
 	use = kmalloc(sizeof(*use), GFP_ATOMIC);
 	if (!use) {
 		printk("%s: out of memory loading\n", a->name);
+		module_put(b);
 		return 0;
 	}
 
 	use->module_which_uses = a;
 	list_add(&use->list, &b->modules_which_use_me);
-	try_module_get(b); /* Can't fail */
 	return 1;
 }
 
@@ -875,45 +894,6 @@
 }
 EXPORT_SYMBOL_GPL(__symbol_get);
 
-/* Deal with the given section */
-static int handle_section(const char *name,
-			  Elf_Shdr *sechdrs,
-			  unsigned int strindex,
-			  unsigned int symindex,
-			  unsigned int i,
-			  struct module *mod)
-{
-	int ret;
-	const char *strtab = (char *)sechdrs[strindex].sh_addr;
-
-	switch (sechdrs[i].sh_type) {
-	case SHT_REL:
-		ret = apply_relocate(sechdrs, strtab, symindex, i, mod);
-		break;
-	case SHT_RELA:
-		ret = apply_relocate_add(sechdrs, strtab, symindex, i, mod);
-		break;
-	default:
-		DEBUGP("Ignoring section %u: %s\n", i,
-		       sechdrs[i].sh_type==SHT_NULL ? "NULL":
-		       sechdrs[i].sh_type==SHT_PROGBITS ? "PROGBITS":
-		       sechdrs[i].sh_type==SHT_SYMTAB ? "SYMTAB":
-		       sechdrs[i].sh_type==SHT_STRTAB ? "STRTAB":
-		       sechdrs[i].sh_type==SHT_RELA ? "RELA":
-		       sechdrs[i].sh_type==SHT_HASH ? "HASH":
-		       sechdrs[i].sh_type==SHT_DYNAMIC ? "DYNAMIC":
-		       sechdrs[i].sh_type==SHT_NOTE ? "NOTE":
-		       sechdrs[i].sh_type==SHT_NOBITS ? "NOBITS":
-		       sechdrs[i].sh_type==SHT_REL ? "REL":
-		       sechdrs[i].sh_type==SHT_SHLIB ? "SHLIB":
-		       sechdrs[i].sh_type==SHT_DYNSYM ? "DYNSYM":
-		       sechdrs[i].sh_type==SHT_NUM ? "NUM":
-		       "UNKNOWN");
-		ret = 0;
-	}
-	return ret;
-}
-
 /* Change all symbols so that sh_value encodes the pointer directly. */
 static int simplify_symbols(Elf_Shdr *sechdrs,
 			    unsigned int symindex,
@@ -1103,93 +1083,19 @@
 	sechdrs = (void *)hdr + hdr->e_shoff;
 	secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
 
-	/* May not export symbols, or have setup params, so these may
-           not exist */
-	exportindex = setupindex = obsparmindex = gplindex = licenseindex 
-		= crcindex = gplcrcindex = versindex = 0;
-
 	/* And these should exist, but gcc whinges if we don't init them */
-	symindex = strindex = exindex = modindex = vmagindex = 0;
+	symindex = strindex = 0;
 
-	/* Find where important sections are */
 	for (i = 1; i < hdr->e_shnum; i++) {
 		/* Mark all sections sh_addr with their address in the
 		   temporary image. */
 		sechdrs[i].sh_addr = (size_t)hdr + sechdrs[i].sh_offset;
 
+		/* Internal symbols and strings. */
 		if (sechdrs[i].sh_type == SHT_SYMTAB) {
-			/* Internal symbols */
-			DEBUGP("Symbol table in section %u\n", i);
 			symindex = i;
-			/* Strings */
 			strindex = sechdrs[i].sh_link;
-			DEBUGP("String table found in section %u\n", strindex);
-		} else if (strcmp(secstrings+sechdrs[i].sh_name,
-				  ".gnu.linkonce.this_module") == 0) {
-			/* The module struct */
-			DEBUGP("Module in section %u\n", i);
-			modindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__ksymtab")
-			   == 0) {
-			/* Exported symbols. */
-			DEBUGP("EXPORT table in section %u\n", i);
-			exportindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name,
-				  "__ksymtab_gpl") == 0) {
-			/* Exported symbols. (GPL) */
-			DEBUGP("GPL symbols found in section %u\n", i);
-			gplindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab")
-			   == 0) {
-			/* Exported symbols CRCs. */
-			DEBUGP("CRC table in section %u\n", i);
-			crcindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab_gpl")
-			   == 0) {
-			/* Exported symbols CRCs. (GPL)*/
-			DEBUGP("CRC table in section %u\n", i);
-			gplcrcindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__param")
-			   == 0) {
-			/* Setup parameter info */
-			DEBUGP("Setup table found in section %u\n", i);
-			setupindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__ex_table")
-			   == 0) {
-			/* Exception table */
-			DEBUGP("Exception table found in section %u\n", i);
-			exindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__obsparm")
-			   == 0) {
-			/* Obsolete MODULE_PARM() table */
-			DEBUGP("Obsolete param found in section %u\n", i);
-			obsparmindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name,".init.license")
-			   == 0) {
-			/* MODULE_LICENSE() */
-			DEBUGP("Licence found in section %u\n", i);
-			licenseindex = i;
-			sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name,
-				  "__vermagic") == 0 &&
-			   (sechdrs[i].sh_flags & SHF_ALLOC)) {
-			/* Version magic. */
-			DEBUGP("Version magic found in section %u\n", i);
-			vmagindex = i;
-			sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name,
-				  "__versions") == 0 &&
-			   (sechdrs[i].sh_flags & SHF_ALLOC)) {
-			/* Module version info (both exported and needed) */
-			DEBUGP("Versions found in section %u\n", i);
-			versindex = i;
-			sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
 		}
-#ifdef CONFIG_KALLSYMS
-		/* symbol and string tables for decoding later. */
-		if (sechdrs[i].sh_type == SHT_SYMTAB || i == strindex)
-			sechdrs[i].sh_flags |= SHF_ALLOC;
-#endif
 #ifndef CONFIG_MODULE_UNLOAD
 		/* Don't load .exit sections */
 		if (strstr(secstrings+sechdrs[i].sh_name, ".exit"))
@@ -1197,6 +1103,14 @@
 #endif
 	}
 
+#ifdef CONFIG_KALLSYMS
+	/* Keep symbol and string tables for decoding later. */
+	sechdrs[symindex].sh_flags |= SHF_ALLOC;
+	sechdrs[strindex].sh_flags |= SHF_ALLOC;
+#endif
+
+	modindex = find_sec(hdr, sechdrs, secstrings,
+			    ".gnu.linkonce.this_module");
 	if (!modindex) {
 		printk(KERN_WARNING "No module found in object\n");
 		err = -ENOEXEC;
@@ -1204,6 +1118,18 @@
 	}
 	mod = (void *)sechdrs[modindex].sh_addr;
 
+	/* Optional sections */
+	exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
+	gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
+	crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
+	gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
+	setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
+	exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
+	obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
+	licenseindex = find_sec(hdr, sechdrs, secstrings, ".init.license");
+	vmagindex = find_sec(hdr, sechdrs, secstrings, "__vermagic");
+	versindex = find_sec(hdr, sechdrs, secstrings, "__versions");
+
 	/* Check module struct version now, before we try to use module. */
 	if (!check_modstruct_version(sechdrs, versindex, mod)) {
 		err = -ENOEXEC;
@@ -1336,10 +1262,15 @@
 		mod->extable.entry = (void *)sechdrs[exindex].sh_addr;
 	}
 
-	/* Now handle each section. */
+	/* Now do relocations. */
 	for (i = 1; i < hdr->e_shnum; i++) {
-		err = handle_section(secstrings + sechdrs[i].sh_name,
-				     sechdrs, strindex, symindex, i, mod);
+		const char *strtab = (char *)sechdrs[strindex].sh_addr;
+		if (sechdrs[i].sh_type == SHT_REL)
+			err = apply_relocate(sechdrs, strtab, symindex, i,
+					     mod);
+		else if (sechdrs[i].sh_type == SHT_RELA)
+			err = apply_relocate_add(sechdrs, strtab, symindex, i,
+						 mod);
 		if (err < 0)
 			goto cleanup;
 	}
@@ -1456,10 +1387,12 @@
 	}
 
 	/* Now it's a first class citizen! */
+	down(&module_mutex);
 	mod->state = MODULE_STATE_LIVE;
 	module_free(mod, mod->module_init);
 	mod->module_init = NULL;
 	mod->init_size = 0;
+	up(&module_mutex);
 
 	return 0;
 }
diff -Nru a/kernel/pm.c b/kernel/pm.c
--- a/kernel/pm.c	Tue Mar  4 19:30:05 2003
+++ b/kernel/pm.c	Tue Mar  4 19:30:05 2003
@@ -141,11 +141,11 @@
  *	data field must hold the intended next state. No call is made
  *	if the state matches.
  *
- *	BUGS: what stops two power management requests occuring in parallel
+ *	BUGS: what stops two power management requests occurring in parallel
  *	and conflicting.
  *
  *	WARNING: Calling pm_send directly is not generally recommended, in
- *	paticular there is no locking against the pm_dev going away. The
+ *	particular there is no locking against the pm_dev going away. The
  *	caller must maintain all needed locking or have 'inside knowledge'
  *	on the safety. Also remember that this function is not locked against
  *	pm_unregister. This means that you must handle SMP races on callback
@@ -227,7 +227,7 @@
  *	Zero is returned on success. If a suspend fails then the status
  *	from the device that vetoes the suspend is returned.
  *
- *	BUGS: what stops two power management requests occuring in parallel
+ *	BUGS: what stops two power management requests occurring in parallel
  *	and conflicting.
  */
  
diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c
--- a/kernel/posix-timers.c	Tue Mar  4 19:30:09 2003
+++ b/kernel/posix-timers.c	Tue Mar  4 19:30:09 2003
@@ -1207,7 +1207,7 @@
 {
 	struct timespec t;
 	struct timer_list new_timer;
-	struct abs_struct abs_struct = { list:{next:0} };
+	struct abs_struct abs_struct = { .list = { .next = 0 } };
 	int abs;
 	int rtn = 0;
 	int active;
diff -Nru a/kernel/suspend.c b/kernel/suspend.c
--- a/kernel/suspend.c	Tue Mar  4 19:30:05 2003
+++ b/kernel/suspend.c	Tue Mar  4 19:30:05 2003
@@ -604,12 +604,12 @@
 
 static int prepare_suspend_processes(void)
 {
+	sys_sync();	/* Syncing needs pdflushd, so do it before stopping processes */
 	if (freeze_processes()) {
 		printk( KERN_ERR "Suspend failed: Not all processes stopped!\n" );
 		thaw_processes();
 		return 1;
 	}
-	sys_sync();
 	return 0;
 }
 
@@ -961,7 +961,7 @@
 	printk("Relocating pagedir");
 
 	if(!does_collide_order(old_pagedir, (unsigned long)old_pagedir, pagedir_order)) {
-		printk("not neccessary\n");
+		printk("not necessary\n");
 		return 0;
 	}
 
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c	Tue Mar  4 19:30:04 2003
+++ b/kernel/sys.c	Tue Mar  4 19:30:04 2003
@@ -870,7 +870,7 @@
 		if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
 			return -EFAULT;
 	}
-	return jiffies_to_clock_t(jiffies);
+	return (long) jiffies_64_to_clock_t(get_jiffies_64());
 }
 
 /*
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Tue Mar  4 19:30:13 2003
+++ b/kernel/timer.c	Tue Mar  4 19:30:13 2003
@@ -757,7 +757,7 @@
 }
 
 /* jiffies at the most recent update of wall time */
-unsigned long wall_jiffies;
+unsigned long wall_jiffies = INITIAL_JIFFIES;
 
 /*
  * This read-write spinlock protects us from races in SMP while
@@ -1104,7 +1104,7 @@
 	do {
 		seq = read_seqbegin(&xtime_lock);
 
-		uptime = jiffies_64;
+		uptime = jiffies_64 - INITIAL_JIFFIES;
 		do_div(uptime, HZ);
 		val.uptime = (unsigned long) uptime;
 
@@ -1180,6 +1180,13 @@
 	}
 	for (j = 0; j < TVR_SIZE; j++)
 		INIT_LIST_HEAD(base->tv1.vec + j);
+
+	base->timer_jiffies = INITIAL_JIFFIES;
+	base->tv1.index = INITIAL_JIFFIES & TVR_MASK;
+	base->tv2.index = (INITIAL_JIFFIES >> TVR_BITS) & TVN_MASK;
+	base->tv3.index = (INITIAL_JIFFIES >> (TVR_BITS+TVN_BITS)) & TVN_MASK;
+	base->tv4.index = (INITIAL_JIFFIES >> (TVR_BITS+2*TVN_BITS)) & TVN_MASK;
+	base->tv5.index = (INITIAL_JIFFIES >> (TVR_BITS+3*TVN_BITS)) & TVN_MASK;
 }
 	
 static int __devinit timer_cpu_notify(struct notifier_block *self, 
diff -Nru a/lib/crc32.c b/lib/crc32.c
--- a/lib/crc32.c	Tue Mar  4 19:30:03 2003
+++ b/lib/crc32.c	Tue Mar  4 19:30:03 2003
@@ -90,19 +90,16 @@
 	const u32      *tab = crc32table_le;
 
 # ifdef __LITTLE_ENDIAN
-#  define DO_CRC crc = (crc>>8) ^ tab[ crc & 255 ]
-#  define ENDIAN_SHIFT 0
+#  define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
 # else
-#  define DO_CRC crc = (crc<<8) ^ tab[ crc >> 24 ]
-#  define ENDIAN_SHIFT 24
+#  define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
 # endif
 
 	crc = __cpu_to_le32(crc);
 	/* Align it */
 	if(unlikely(((long)b)&3 && len)){
 		do {
-			crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
-			DO_CRC;
+			DO_CRC(*((u8 *)b)++);
 		} while ((--len) && ((long)b)&3 );
 	}
 	if(likely(len >= 4)){
@@ -112,10 +109,10 @@
 		--b; /* use pre increment below(*++b) for speed */
 		do {
 			crc ^= *++b;
-			DO_CRC;
-			DO_CRC;
-			DO_CRC;
-			DO_CRC;
+			DO_CRC(0);
+			DO_CRC(0);
+			DO_CRC(0);
+			DO_CRC(0);
 		} while (--len);
 		b++; /* point to next byte(s) */
 		len = save_len;
@@ -123,8 +120,7 @@
 	/* And the last few bytes */
 	if(len){
 		do {
-			crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
-			DO_CRC;
+			DO_CRC(*((u8 *)b)++);
 		} while (--len);
 	}
 
@@ -195,19 +191,16 @@
 	const u32      *tab = crc32table_be;
 
 # ifdef __LITTLE_ENDIAN
-#  define DO_CRC crc = (crc>>8) ^ tab[ crc & 255 ]
-#  define ENDIAN_SHIFT 24
+#  define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
 # else
-#  define DO_CRC crc = (crc<<8) ^ tab[ crc >> 24 ]
-#  define ENDIAN_SHIFT 0
+#  define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
 # endif
 
 	crc = __cpu_to_be32(crc);
 	/* Align it */
 	if(unlikely(((long)b)&3 && len)){
 		do {
-			crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
-			DO_CRC;
+			DO_CRC(*((u8 *)b)++);
 		} while ((--len) && ((long)b)&3 );
 	}
 	if(likely(len >= 4)){
@@ -217,10 +210,10 @@
 		--b; /* use pre increment below(*++b) for speed */
 		do {
 			crc ^= *++b;
-			DO_CRC;
-			DO_CRC;
-			DO_CRC;
-			DO_CRC;
+			DO_CRC(0);
+			DO_CRC(0);
+			DO_CRC(0);
+			DO_CRC(0);
 		} while (--len);
 		b++; /* point to next byte(s) */
 		len = save_len;
@@ -228,8 +221,7 @@
 	/* And the last few bytes */
 	if(len){
 		do {
-			crc ^= *((u8 *)b)++ << ENDIAN_SHIFT;
-			DO_CRC;
+			DO_CRC(*((u8 *)b)++);
 		} while (--len);
 	}
 	return __be32_to_cpu(crc);
diff -Nru a/lib/crc32defs.h b/lib/crc32defs.h
--- a/lib/crc32defs.h	Tue Mar  4 19:30:04 2003
+++ b/lib/crc32defs.h	Tue Mar  4 19:30:04 2003
@@ -8,8 +8,12 @@
 
 /* How many bits at a time to use.  Requires a table of 4<<CRC_xx_BITS bytes. */
 /* For less performance-sensitive, use 4 */
-#define CRC_LE_BITS 8
-#define CRC_BE_BITS 8
+#ifndef CRC_LE_BITS 
+# define CRC_LE_BITS 8
+#endif
+#ifndef CRC_BE_BITS
+# define CRC_BE_BITS 8
+#endif
 
 /*
  * Little-endian CRC computation.  Used with serial bit streams sent
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Tue Mar  4 19:30:06 2003
+++ b/mm/filemap.c	Tue Mar  4 19:30:06 2003
@@ -559,21 +559,12 @@
 		page_cache_readahead(mapping, ra, filp, index);
 
 		nr = nr - offset;
-
-		/*
-		 * Try to find the data in the page cache..
-		 */
 find_page:
-		read_lock(&mapping->page_lock);
-		page = radix_tree_lookup(&mapping->page_tree, index);
-		if (!page) {
-			read_unlock(&mapping->page_lock);
-			handle_ra_miss(mapping,ra);
+		page = find_get_page(mapping, index);
+		if (unlikely(page == NULL)) {
+			handle_ra_miss(mapping, ra);
 			goto no_cached_page;
 		}
-		page_cache_get(page);
-		read_unlock(&mapping->page_lock);
-
 		if (!PageUptodate(page))
 			goto page_not_up_to_date;
 page_ok:
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Tue Mar  4 19:30:08 2003
+++ b/mm/memory.c	Tue Mar  4 19:30:08 2003
@@ -158,9 +158,7 @@
 		pmd_populate(mm, pmd, new);
 	}
 out:
-	if (pmd_present(*pmd))
-		return pte_offset_map(pmd, address);
-	return NULL;
+	return pte_offset_map(pmd, address);
 }
 
 pte_t * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Tue Mar  4 19:30:10 2003
+++ b/mm/mmap.c	Tue Mar  4 19:30:10 2003
@@ -797,17 +797,27 @@
 		unsigned long pgoff, unsigned long flags)
 {
 	if (flags & MAP_FIXED) {
+		unsigned long ret;
+
 		if (addr > TASK_SIZE - len)
 			return -ENOMEM;
 		if (addr & ~PAGE_MASK)
 			return -EINVAL;
-		if (file && is_file_hugepages(file)) {
-			unsigned long ret;
-
+		if (file && is_file_hugepages(file))  {
+			/*
+			 * Make sure that addr and length are properly aligned.
+			 */
 			ret = is_aligned_hugepage_range(addr, len);
-			if (ret)
-				return ret;
+		} else {
+			/*
+			 * Ensure that a normal request is not falling in a
+			 * reserved hugepage range.  For some archs like IA-64,
+			 * there is a separate region for hugepages.
+			 */
+			ret = check_valid_hugepage_range(addr, len);
 		}
+		if (ret)
+			return ret;
 		return addr;
 	}
 
diff -Nru a/mm/oom_kill.c b/mm/oom_kill.c
--- a/mm/oom_kill.c	Tue Mar  4 19:30:09 2003
+++ b/mm/oom_kill.c	Tue Mar  4 19:30:09 2003
@@ -61,6 +61,9 @@
 
 	if (!p->mm)
 		return 0;
+
+	if (p->flags & PF_MEMDIE)
+		return 0;
 	/*
 	 * The memory size of the process is the basis for the badness.
 	 */
diff -Nru a/mm/pdflush.c b/mm/pdflush.c
--- a/mm/pdflush.c	Tue Mar  4 19:30:14 2003
+++ b/mm/pdflush.c	Tue Mar  4 19:30:14 2003
@@ -103,9 +103,11 @@
 		my_work->when_i_went_to_sleep = jiffies;
 		spin_unlock_irq(&pdflush_lock);
 
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_IOTHREAD);
 		schedule();
+		if (current->flags & PF_FREEZE) {
+			refrigerator(PF_IOTHREAD);
+			continue;
+		}
 
 		spin_lock_irq(&pdflush_lock);
 		if (!list_empty(&my_work->list)) {
diff -Nru a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c	Tue Mar  4 19:30:12 2003
+++ b/mm/slab.c	Tue Mar  4 19:30:12 2003
@@ -1116,12 +1116,16 @@
 static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
 {
 	check_irq_on();
+	preempt_disable();
+
 	local_irq_disable();
 	func(arg);
 	local_irq_enable();
 
 	if (smp_call_function(func, arg, 1, 1))
 		BUG();
+
+	preempt_enable();
 }
 
 static void free_block (kmem_cache_t* cachep, void** objpp, int len);
@@ -1643,7 +1647,7 @@
 	if (cachep->ctor && cachep->flags & SLAB_POISON) {
 		unsigned long	ctor_flags = SLAB_CTOR_CONSTRUCTOR;
 
-		if (!flags & __GFP_WAIT)
+		if (!(flags & __GFP_WAIT))
 			ctor_flags |= SLAB_CTOR_ATOMIC;
 
 		cachep->ctor(objp, cachep, ctor_flags);
@@ -2064,7 +2068,7 @@
 	else
 		limit = 248;
 
-#ifndef DEBUG
+#if DEBUG
 	/* With debugging enabled, large batchcount lead to excessively
 	 * long periods with disabled local interrupts. Limit the 
 	 * batchcount
diff -Nru a/mm/swap.c b/mm/swap.c
--- a/mm/swap.c	Tue Mar  4 19:30:07 2003
+++ b/mm/swap.c	Tue Mar  4 19:30:07 2003
@@ -27,7 +27,7 @@
 int page_cluster;
 
 /*
- * Writeback is about to end against a page whic has been marked for immediate
+ * Writeback is about to end against a page which has been marked for immediate
  * reclaim.  If it still appears to be reclaimable, move it to the tail of the
  * inactive list.  The page still has PageWriteback set, which will pin it.
  *
@@ -363,5 +363,4 @@
 	 * Right now other parts of the system means that we
 	 * _really_ don't want to cluster much more
 	 */
-	init_MUTEX(&swapper_space.i_shared_sem);
 }
diff -Nru a/mm/swap_state.c b/mm/swap_state.c
--- a/mm/swap_state.c	Tue Mar  4 19:30:08 2003
+++ b/mm/swap_state.c	Tue Mar  4 19:30:08 2003
@@ -33,19 +33,20 @@
 extern struct address_space_operations swap_aops;
 
 struct address_space swapper_space = {
-	.page_tree		= RADIX_TREE_INIT(GFP_ATOMIC),
-	.page_lock		= RW_LOCK_UNLOCKED,
-	.clean_pages		= LIST_HEAD_INIT(swapper_space.clean_pages),
-	.dirty_pages		= LIST_HEAD_INIT(swapper_space.dirty_pages),
-	.io_pages		= LIST_HEAD_INIT(swapper_space.io_pages),
-	.locked_pages		= LIST_HEAD_INIT(swapper_space.locked_pages),
-	.host			= &swapper_inode,
-	.a_ops			= &swap_aops,
-	.backing_dev_info	= &swap_backing_dev_info,
-	.i_mmap			= LIST_HEAD_INIT(swapper_space.i_mmap),
-	.i_mmap_shared		= LIST_HEAD_INIT(swapper_space.i_mmap_shared),
-	.private_lock		= SPIN_LOCK_UNLOCKED,
-	.private_list		= LIST_HEAD_INIT(swapper_space.private_list),
+	.page_tree	= RADIX_TREE_INIT(GFP_ATOMIC),
+	.page_lock	= RW_LOCK_UNLOCKED,
+	.clean_pages	= LIST_HEAD_INIT(swapper_space.clean_pages),
+	.dirty_pages	= LIST_HEAD_INIT(swapper_space.dirty_pages),
+	.io_pages	= LIST_HEAD_INIT(swapper_space.io_pages),
+	.locked_pages	= LIST_HEAD_INIT(swapper_space.locked_pages),
+	.host		= &swapper_inode,
+	.a_ops		= &swap_aops,
+	.backing_dev_info = &swap_backing_dev_info,
+	.i_mmap		= LIST_HEAD_INIT(swapper_space.i_mmap),
+	.i_mmap_shared	= LIST_HEAD_INIT(swapper_space.i_mmap_shared),
+	.i_shared_sem	= __MUTEX_INITIALIZER(swapper_space.i_shared_sem),
+	.private_lock	= SPIN_LOCK_UNLOCKED,
+	.private_list	= LIST_HEAD_INIT(swapper_space.private_list),
 };
 
 #define INC_CACHE_INFO(x)	do { swap_cache_info.x++; } while (0)
diff -Nru a/net/802/fc.c b/net/802/fc.c
--- a/net/802/fc.c	Tue Mar  4 19:30:14 2003
+++ b/net/802/fc.c	Tue Mar  4 19:30:14 2003
@@ -95,4 +95,37 @@
 	return 0;
 #endif
 }
-	
+
+unsigned short
+fc_type_trans(struct sk_buff *skb, struct net_device *dev)
+{
+	struct fch_hdr *fch = (struct fch_hdr *)skb->data;
+	struct fcllc *fcllc;
+
+	skb->mac.raw = skb->data;
+	fcllc = (struct fcllc *)(skb->data + sizeof (struct fch_hdr) + 2);
+	skb_pull(skb, sizeof (struct fch_hdr) + 2);
+
+	if (*fch->daddr & 1) {
+		if (!memcmp(fch->daddr, dev->broadcast, FC_ALEN))
+			skb->pkt_type = PACKET_BROADCAST;
+		else
+			skb->pkt_type = PACKET_MULTICAST;
+	} else if (dev->flags & IFF_PROMISC) {
+		if (memcmp(fch->daddr, dev->dev_addr, FC_ALEN))
+			skb->pkt_type = PACKET_OTHERHOST;
+	}
+
+	/*
+	 * Strip the SNAP header from ARP packets since we don't pass
+	 * them through to the 802.2/SNAP layers.
+	 */
+	if (fcllc->dsap == EXTENDED_SAP &&
+	    (fcllc->ethertype == ntohs(ETH_P_IP) ||
+	     fcllc->ethertype == ntohs(ETH_P_ARP))) {
+		skb_pull(skb, sizeof (struct fcllc));
+		return fcllc->ethertype;
+	}
+
+	return ntohs(ETH_P_802_2);
+}
diff -Nru a/net/8021q/vlan.h b/net/8021q/vlan.h
--- a/net/8021q/vlan.h	Tue Mar  4 19:30:11 2003
+++ b/net/8021q/vlan.h	Tue Mar  4 19:30:11 2003
@@ -38,7 +38,7 @@
 extern struct vlan_group *vlan_group_hash[VLAN_GRP_HASH_SIZE];
 extern spinlock_t vlan_group_lock;
 
-/*  Find a VLAN device by the MAC address of it's Ethernet device, and
+/*  Find a VLAN device by the MAC address of its Ethernet device, and
  *  it's VLAN ID.  The default configuration is to have VLAN's scope
  *  to be box-wide, so the MAC will be ignored.  The mac will only be
  *  looked at if we are configured to have a separate set of VLANs per
diff -Nru a/net/atm/lec.c b/net/atm/lec.c
--- a/net/atm/lec.c	Tue Mar  4 19:30:10 2003
+++ b/net/atm/lec.c	Tue Mar  4 19:30:10 2003
@@ -223,7 +223,8 @@
         struct lecdatahdr_8023 *lec_h;
         struct atm_vcc *send_vcc;
 	struct lec_arp_table *entry;
-        unsigned char *nb, *dst;
+        unsigned char *dst;
+	int min_frame_size;
 #ifdef CONFIG_TR
         unsigned char rdesc[ETH_ALEN]; /* Token Ring route descriptor */
 #endif
@@ -294,26 +295,24 @@
 #endif /* DUMP_PACKETS > 0 */
 
         /* Minimum ethernet-frame size */
-        if (skb->len <62) {
-                if (skb->truesize < 62) {
-                        printk("%s:data packet %d / %d\n",
-                               dev->name,
-                               skb->len,skb->truesize);
-                        nb=(unsigned char*)kmalloc(64, GFP_ATOMIC);
-                        if (nb == NULL) {
+#ifdef CONFIG_TR
+        if (priv->is_trdev)
+                min_frame_size = LEC_MINIMUM_8025_SIZE;
+	else
+#endif
+        min_frame_size = LEC_MINIMUM_8023_SIZE;
+        if (skb->len < min_frame_size) {
+                if (skb->truesize < min_frame_size) {
+                        skb2 = skb_copy_expand(skb, 0,
+                            min_frame_size - skb->truesize, GFP_ATOMIC);
                                 dev_kfree_skb(skb);
+                        if (skb2 == NULL) {
+                                priv->stats.tx_dropped++;
                                 return 0;
                         }
-                        memcpy(nb,skb->data,skb->len);
-                        kfree(skb->head);
-                        skb->head = skb->data = nb;
-                        skb->tail = nb+62;
-                        skb->end = nb+64;
-                        skb->len=62;
-                        skb->truesize = 64;
-                } else {
-                        skb->len = 62;
+                        skb = skb2;
                 }
+		skb_put(skb, min_frame_size - skb->len);
         }
         
         /* Send to right vcc */
@@ -618,6 +617,14 @@
         return 0;
 }
 
+static void lec_set_multicast_list(struct net_device *dev)
+{
+	/* by default, all multicast frames arrive over the bus.
+         * eventually support selective multicast service
+         */
+        return;
+}
+
 static void 
 lec_init(struct net_device *dev)
 {
@@ -627,7 +634,7 @@
         dev->hard_start_xmit = lec_send_packet;
 
         dev->get_stats = lec_get_stats;
-        dev->set_multicast_list = NULL;
+        dev->set_multicast_list = lec_set_multicast_list;
         dev->do_ioctl  = NULL;
         printk("%s: Initialized!\n",dev->name);
         return;
@@ -706,7 +713,7 @@
                         lec_arp_check_empties(priv, vcc, skb);
                 }
                 skb->dev = dev;
-                skb->data += 2; /* skip lec_id */
+                skb_pull(skb, 2); /* skip lec_id */
 #ifdef CONFIG_TR
                 if (priv->is_trdev) skb->protocol = tr_type_trans(skb, dev);
                 else
diff -Nru a/net/atm/lec.h b/net/atm/lec.h
--- a/net/atm/lec.h	Tue Mar  4 19:30:05 2003
+++ b/net/atm/lec.h	Tue Mar  4 19:30:05 2003
@@ -38,6 +38,9 @@
   unsigned char h_source[ETH_ALEN];
 };
 
+#define LEC_MINIMUM_8023_SIZE   62
+#define LEC_MINIMUM_8025_SIZE   16
+
 /*
  * Operations that LANE2 capable device can do. Two first functions
  * are used to make the device do things. See spec 3.1.3 and 3.1.4.
diff -Nru a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
--- a/net/bridge/netfilter/ebtable_broute.c	Tue Mar  4 19:30:03 2003
+++ b/net/bridge/netfilter/ebtable_broute.c	Tue Mar  4 19:30:03 2003
@@ -18,13 +18,20 @@
 
 // EBT_ACCEPT means the frame will be bridged
 // EBT_DROP means the frame will be routed
-static struct ebt_entries initial_chain =
-  {0, "BROUTING", 0, EBT_ACCEPT, 0};
+static struct ebt_entries initial_chain = {
+	.name	= "BROUTING",
+	.policy	= EBT_ACCEPT,
+};
 
 static struct ebt_replace initial_table =
 {
-  "broute", 1 << NF_BR_BROUTING, 0, sizeof(struct ebt_entries),
-  { [NF_BR_BROUTING]&initial_chain}, 0, NULL, (char *)&initial_chain
+	.name		= "broute",
+	.valid_hooks	= 1 << NF_BR_BROUTING,
+	.entries_size	= sizeof(struct ebt_entries),
+	.hook_entry	= {
+		[NF_BR_BROUTING]	= &initial_chain,
+	},
+	.entries	= (char *)&initial_chain
 };
 
 static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
@@ -36,8 +43,11 @@
 
 static struct ebt_table broute_table =
 {
-  {NULL, NULL}, "broute", &initial_table, 1 << NF_BR_BROUTING,
-  RW_LOCK_UNLOCKED, check, NULL
+	.name		= "broute",
+	.table		= &initial_table,
+	.valid_hooks	= 1 << NF_BR_BROUTING,
+	.lock		= RW_LOCK_UNLOCKED,
+	.check		= check,
 };
 
 static int ebt_broute(struct sk_buff **pskb)
diff -Nru a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
--- a/net/bridge/netfilter/ebtable_filter.c	Tue Mar  4 19:30:13 2003
+++ b/net/bridge/netfilter/ebtable_filter.c	Tue Mar  4 19:30:13 2003
@@ -16,16 +16,31 @@
 
 static struct ebt_entries initial_chains[] =
 {
-  {0, "INPUT", 0, EBT_ACCEPT, 0},
-  {0, "FORWARD", 0, EBT_ACCEPT, 0},
-  {0, "OUTPUT", 0, EBT_ACCEPT, 0}
+	{
+		.name	= "INPUT",
+		.policy	= EBT_ACCEPT,
+	},
+	{
+		.name	= "FORWARD",
+		.policy	= EBT_ACCEPT,
+	},
+	{
+		.name	= "OUTPUT",
+		.policy	= EBT_ACCEPT,
+	}
 };
 
 static struct ebt_replace initial_table =
 {
-  "filter", FILTER_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries),
-  { [NF_BR_LOCAL_IN]&initial_chains[0], [NF_BR_FORWARD]&initial_chains[1],
-    [NF_BR_LOCAL_OUT]&initial_chains[2] }, 0, NULL, (char *)initial_chains
+	.name		= "filter",
+	.valid_hooks	= FILTER_VALID_HOOKS,
+	.entries_size	= 3 * sizeof(struct ebt_entries),
+  	.hook_entry	= {
+		[NF_BR_LOCAL_IN]	= &initial_chains[0],
+		[NF_BR_FORWARD]		= &initial_chains[1],
+    		[NF_BR_LOCAL_OUT]	= &initial_chains[2],
+	},
+	.entries	= (char *)initial_chains
 };
 
 static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
@@ -37,8 +52,11 @@
 
 static struct ebt_table frame_filter =
 { 
-  {NULL, NULL}, "filter", &initial_table, FILTER_VALID_HOOKS, 
-  RW_LOCK_UNLOCKED, check, NULL
+	.name		= "filter",
+	.table		= &initial_table,
+	.valid_hooks	= FILTER_VALID_HOOKS, 
+	.lock		= RW_LOCK_UNLOCKED,
+	.check		= check,
 };
 
 static unsigned int
@@ -49,12 +67,24 @@
 }
 
 static struct nf_hook_ops ebt_ops_filter[] = {
-	{ { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_IN,
-	   NF_BR_PRI_FILTER_BRIDGED},
-	{ { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_FORWARD,
-	   NF_BR_PRI_FILTER_BRIDGED},
-	{ { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_OUT,
-	   NF_BR_PRI_FILTER_OTHER}
+	{
+		.hook		= ebt_hook,
+		.pf		= PF_BRIDGE,
+		.hooknum	= NF_BR_LOCAL_IN,
+		.priority	= NF_BR_PRI_FILTER_BRIDGED,
+	},
+	{
+		.hook		= ebt_hook,
+		.pf		= PF_BRIDGE,
+		.hooknum	= NF_BR_FORWARD,
+		.priority	= NF_BR_PRI_FILTER_BRIDGED
+	},
+	{
+		.hook		= ebt_hook,
+		.pf		= PF_BRIDGE,
+		.hooknum	= NF_BR_LOCAL_OUT,
+		.priority	= NF_BR_PRI_FILTER_OTHER
+	}
 };
 
 static int __init init(void)
diff -Nru a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
--- a/net/bridge/netfilter/ebtable_nat.c	Tue Mar  4 19:30:14 2003
+++ b/net/bridge/netfilter/ebtable_nat.c	Tue Mar  4 19:30:14 2003
@@ -15,16 +15,31 @@
 
 static struct ebt_entries initial_chains[] =
 {
-  {0, "PREROUTING", 0, EBT_ACCEPT, 0},
-  {0, "OUTPUT", 0, EBT_ACCEPT, 0},
-  {0, "POSTROUTING", 0, EBT_ACCEPT, 0}
+	{
+		.name	= "PREROUTING",
+		.policy	= EBT_ACCEPT,
+	},
+	{
+		.name	= "OUTPUT",
+		.policy	= EBT_ACCEPT,
+	},
+	{
+		.name	= "POSTROUTING",
+		.policy	= EBT_ACCEPT,
+	}
 };
 
 static struct ebt_replace initial_table =
 {
-  "nat", NAT_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries),
-  { [NF_BR_PRE_ROUTING]&initial_chains[0], [NF_BR_LOCAL_OUT]&initial_chains[1],
-    [NF_BR_POST_ROUTING]&initial_chains[2] }, 0, NULL, (char *)initial_chains
+	.name		= "nat",
+	.valid_hooks	= NAT_VALID_HOOKS,
+	.entries_size	= 3 * sizeof(struct ebt_entries),
+	.hook_entry	= {
+		[NF_BR_PRE_ROUTING]	= &initial_chains[0],
+		[NF_BR_LOCAL_OUT]	= &initial_chains[1],
+		[NF_BR_POST_ROUTING]	= &initial_chains[2],
+	},
+	.entries	= (char *)initial_chains
 };
 
 static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
@@ -36,8 +51,11 @@
 
 static struct ebt_table frame_nat =
 {
-  {NULL, NULL}, "nat", &initial_table, NAT_VALID_HOOKS,
-  RW_LOCK_UNLOCKED, check, NULL
+	.name		= "nat",
+	.table		= &initial_table,
+	.valid_hooks	= NAT_VALID_HOOKS,
+	.lock		= RW_LOCK_UNLOCKED,
+	.check		= check,
 };
 
 static unsigned int
@@ -55,12 +73,24 @@
 }
 
 static struct nf_hook_ops ebt_ops_nat[] = {
-	{ { NULL, NULL }, ebt_nat_dst, PF_BRIDGE, NF_BR_LOCAL_OUT,
-	   NF_BR_PRI_NAT_DST_OTHER},
-	{ { NULL, NULL }, ebt_nat_src, PF_BRIDGE, NF_BR_POST_ROUTING,
-	   NF_BR_PRI_NAT_SRC},
-	{ { NULL, NULL }, ebt_nat_dst, PF_BRIDGE, NF_BR_PRE_ROUTING,
-	   NF_BR_PRI_NAT_DST_BRIDGED},
+	{
+		.hook		= ebt_nat_dst,
+		.pf		= PF_BRIDGE,
+		.hooknum	= NF_BR_LOCAL_OUT,
+		.priority	= NF_BR_PRI_NAT_DST_OTHER
+	},
+	{
+		.hook		= ebt_nat_src,
+		.pf		= PF_BRIDGE,
+		.hooknum	= NF_BR_POST_ROUTING,
+		.priority	= NF_BR_PRI_NAT_SRC
+	},
+	{
+		.hook		= ebt_nat_dst,
+		.pf		= PF_BRIDGE,
+		.hooknum	= NF_BR_PRE_ROUTING,
+		.priority	= NF_BR_PRI_NAT_DST_BRIDGED
+	},
 };
 
 static int __init init(void)
diff -Nru a/net/core/Makefile b/net/core/Makefile
--- a/net/core/Makefile	Tue Mar  4 19:30:13 2003
+++ b/net/core/Makefile	Tue Mar  4 19:30:13 2003
@@ -19,5 +19,3 @@
 obj-$(CONFIG_NET_PROFILE) += profile.o
 obj-$(CONFIG_NET_PKTGEN) += pktgen.o
 obj-$(CONFIG_NET_RADIO) += wireless.o
-# Ugly. I wish all wireless drivers were moved in drivers/net/wireless
-obj-$(CONFIG_NET_PCMCIA_RADIO) += wireless.o
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Tue Mar  4 19:30:09 2003
+++ b/net/core/dev.c	Tue Mar  4 19:30:09 2003
@@ -107,10 +107,10 @@
 #include <linux/kmod.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
-#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
+#ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
-#endif	/* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
+#endif	/* CONFIG_NET_RADIO */
 #ifdef CONFIG_PLIP
 extern int plip_init(void);
 #endif
@@ -1215,7 +1215,7 @@
 #ifdef OFFLINE_SAMPLE
 static void sample_queue(unsigned long dummy)
 {
-/* 10 ms 0r 1ms -- i dont care -- JHS */
+/* 10 ms 0r 1ms -- i don't care -- JHS */
 	int next_tick = 1;
 	int cpu = smp_processor_id();
 
diff -Nru a/net/core/netfilter.c b/net/core/netfilter.c
--- a/net/core/netfilter.c	Tue Mar  4 19:30:08 2003
+++ b/net/core/netfilter.c	Tue Mar  4 19:30:08 2003
@@ -606,7 +606,7 @@
 	struct net_device *dev_src = NULL;
 	int err;
 
-	/* accomodate ip_route_output_slow(), which expects the key src to be
+	/* accommodate ip_route_output_slow(), which expects the key src to be
 	   0 or a local address; however some non-standard hacks like
 	   ipt_REJECT.c:send_reset() can cause packets with foreign
            saddr to be appear on the NF_IP_LOCAL_OUT hook -MB */
diff -Nru a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
--- a/net/decnet/dn_dev.c	Tue Mar  4 19:30:05 2003
+++ b/net/decnet/dn_dev.c	Tue Mar  4 19:30:06 2003
@@ -18,7 +18,7 @@
  *          Steve Whitehouse : Multiple ifaddr support
  *          Steve Whitehouse : SIOCGIFCONF is now a compile time option
  *          Steve Whitehouse : /proc/sys/net/decnet/conf/<sys>/forwarding
- *          Steve Whitehouse : Removed timer1 - its a user space issue now
+ *          Steve Whitehouse : Removed timer1 - it's a user space issue now
  *         Patrick Caulfield : Fixed router hello message format
  */
 
@@ -807,7 +807,7 @@
  * This is one of those areas where the initial VMS concepts don't really
  * map onto the Linux concepts, and since we introduced multiple addresses
  * per interface we have to cope with slightly odd ways of finding out what
- * "our address" really is. Mostly its not a problem; for this we just guess
+ * "our address" really is. Mostly it's not a problem; for this we just guess
  * a sensible default. Eventually the routing code will take care of all the
  * nasties for us I hope.
  */
diff -Nru a/net/ipv4/esp.c b/net/ipv4/esp.c
--- a/net/ipv4/esp.c	Tue Mar  4 19:30:10 2003
+++ b/net/ipv4/esp.c	Tue Mar  4 19:30:10 2003
@@ -360,7 +360,7 @@
 	esp = x->data;
 	alen = esp->auth.icv_trunc_len;
 	tfm = esp->conf.tfm;
-	blksize = crypto_tfm_alg_blocksize(tfm);
+	blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3;
 	clen = (clen + 2 + blksize-1)&~(blksize-1);
 	if (esp->conf.padlen)
 		clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
diff -Nru a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
--- a/net/ipv4/netfilter/arp_tables.c	Tue Mar  4 19:30:12 2003
+++ b/net/ipv4/netfilter/arp_tables.c	Tue Mar  4 19:30:12 2003
@@ -539,8 +539,10 @@
 		duprintf("check_entry: `%s' not found\n", t->u.user.name);
 		goto out;
 	}
-	if (target->me)
-		__MOD_INC_USE_COUNT(target->me);
+	if (!try_module_get((target->me))) {
+		ret = -ENOENT;
+		goto out_unlock;
+	}
 	t->u.kernel.target = target;
 	up(&arpt_mutex);
 
@@ -554,8 +556,7 @@
 						      t->u.target_size
 						      - sizeof(*t),
 						      e->comefrom)) {
-		if (t->u.kernel.target->me)
-			__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
+		module_put(t->u.kernel.target->me);
 		duprintf("arp_tables: check failed for `%s'.\n",
 			 t->u.kernel.target->name);
 		ret = -EINVAL;
@@ -565,6 +566,8 @@
 	(*i)++;
 	return 0;
 
+out_unlock:
+	up(&arpt_mutex);
 out:
 	return ret;
 }
@@ -622,9 +625,7 @@
 	if (t->u.kernel.target->destroy)
 		t->u.kernel.target->destroy(t->data,
 					    t->u.target_size - sizeof(*t));
-	if (t->u.kernel.target->me)
-		__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
-
+	module_put(t->u.kernel.target->me);
 	return 0;
 }
 
@@ -1110,17 +1111,14 @@
 {
 	int ret;
 
-	MOD_INC_USE_COUNT;
 	ret = down_interruptible(&arpt_mutex);
-	if (ret != 0) {
-		MOD_DEC_USE_COUNT;
+	if (ret != 0)
 		return ret;
-	}
+
 	if (!list_named_insert(&arpt_target, target)) {
 		duprintf("arpt_register_target: `%s' already in list!\n",
 			 target->name);
 		ret = -EINVAL;
-		MOD_DEC_USE_COUNT;
 	}
 	up(&arpt_mutex);
 	return ret;
@@ -1131,7 +1129,6 @@
 	down(&arpt_mutex);
 	LIST_DELETE(&arpt_target, target);
 	up(&arpt_mutex);
-	MOD_DEC_USE_COUNT;
 }
 
 int arpt_register_table(struct arpt_table *table)
@@ -1141,12 +1138,10 @@
 	static struct arpt_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
-	MOD_INC_USE_COUNT;
 	newinfo = vmalloc(sizeof(struct arpt_table_info)
 			  + SMP_ALIGN(table->table->size) * NR_CPUS);
 	if (!newinfo) {
 		ret = -ENOMEM;
-		MOD_DEC_USE_COUNT;
 		return ret;
 	}
 	memcpy(newinfo->entries, table->table->entries, table->table->size);
@@ -1159,14 +1154,12 @@
 	duprintf("arpt_register_table: translate table gives %d\n", ret);
 	if (ret != 0) {
 		vfree(newinfo);
-		MOD_DEC_USE_COUNT;
 		return ret;
 	}
 
 	ret = down_interruptible(&arpt_mutex);
 	if (ret != 0) {
 		vfree(newinfo);
-		MOD_DEC_USE_COUNT;
 		return ret;
 	}
 
@@ -1196,7 +1189,6 @@
 
  free_unlock:
 	vfree(newinfo);
-	MOD_DEC_USE_COUNT;
 	goto unlock;
 }
 
@@ -1210,7 +1202,6 @@
 	ARPT_ENTRY_ITERATE(table->private->entries, table->private->size,
 			   cleanup_entry, NULL);
 	vfree(table->private);
-	MOD_DEC_USE_COUNT;
 }
 
 /* The built-in targets: standard (NULL) and error. */
diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
--- a/net/ipv4/netfilter/ip_conntrack_core.c	Tue Mar  4 19:30:03 2003
+++ b/net/ipv4/netfilter/ip_conntrack_core.c	Tue Mar  4 19:30:03 2003
@@ -290,9 +290,6 @@
 {
 	DEBUGP("clean_from_lists(%p)\n", ct);
 	MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
-	/* Remove from both hash lists: must not NULL out next ptrs,
-           otherwise we'll look unconfirmed.  Fortunately, LIST_DELETE
-           doesn't do this. --RR */
 	LIST_DELETE(&ip_conntrack_hash
 		    [hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple)],
 		    &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
@@ -465,6 +462,7 @@
 		ct->timeout.expires += jiffies;
 		add_timer(&ct->timeout);
 		atomic_inc(&ct->ct_general.use);
+		set_bit(IPS_CONFIRMED_BIT, &ct->status);
 		WRITE_UNLOCK(&ip_conntrack_lock);
 		return NF_ACCEPT;
 	}
@@ -583,7 +581,7 @@
    connection.  Too bad: we're in trouble anyway. */
 static inline int unreplied(const struct ip_conntrack_tuple_hash *i)
 {
-	return !(i->ctrack->status & IPS_ASSURED);
+	return !(test_bit(IPS_ASSURED_BIT, &i->ctrack->status));
 }
 
 static int early_drop(struct list_head *chain)
@@ -702,7 +700,7 @@
 	if (!expected)
 		conntrack->helper = ip_ct_find_helper(&repl_tuple);
 
-	/* If the expectation is dying, then this is a looser. */
+	/* If the expectation is dying, then this is a loser. */
 	if (expected
 	    && expected->expectant->helper->timeout
 	    && ! del_timer(&expected->timeout))
@@ -718,7 +716,7 @@
 			conntrack, expected);
 		/* Welcome, Mr. Bond.  We've been expecting you... */
 		IP_NF_ASSERT(master_ct(conntrack));
-		conntrack->status = IPS_EXPECTED;
+		__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
 		conntrack->master = expected;
 		expected->sibling = conntrack;
 		LIST_DELETE(&ip_conntrack_expect_list, expected);
@@ -766,11 +764,11 @@
 		*set_reply = 1;
 	} else {
 		/* Once we've had two way comms, always ESTABLISHED. */
-		if (h->ctrack->status & IPS_SEEN_REPLY) {
+		if (test_bit(IPS_SEEN_REPLY_BIT, &h->ctrack->status)) {
 			DEBUGP("ip_conntrack_in: normal packet for %p\n",
 			       h->ctrack);
 		        *ctinfo = IP_CT_ESTABLISHED;
-		} else if (h->ctrack->status & IPS_EXPECTED) {
+		} else if (test_bit(IPS_EXPECTED_BIT, &h->ctrack->status)) {
 			DEBUGP("ip_conntrack_in: related packet for %p\n",
 			       h->ctrack);
 			*ctinfo = IP_CT_RELATED;
@@ -1128,8 +1126,6 @@
 
 int ip_conntrack_helper_register(struct ip_conntrack_helper *me)
 {
-	MOD_INC_USE_COUNT;
-
 	WRITE_LOCK(&ip_conntrack_lock);
 	list_prepend(&helpers, me);
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -1166,8 +1162,6 @@
 	/* Someone could be still looking at the helper in a bh. */
 	br_write_lock_bh(BR_NETPROTO_LOCK);
 	br_write_unlock_bh(BR_NETPROTO_LOCK);
-
-	MOD_DEC_USE_COUNT;
 }
 
 /* Refresh conntrack for this many jiffies. */
diff -Nru a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c	Tue Mar  4 19:30:12 2003
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c	Tue Mar  4 19:30:12 2003
@@ -32,7 +32,7 @@
 
 static int try_rfc959(const char *, size_t, u_int32_t [], char);
 static int try_eprt(const char *, size_t, u_int32_t [], char);
-static int try_espv_response(const char *, size_t, u_int32_t [], char);
+static int try_epsv_response(const char *, size_t, u_int32_t [], char);
 
 static struct ftp_search {
 	enum ip_conntrack_dir dir;
@@ -65,7 +65,7 @@
 		IP_CT_DIR_REPLY,
 		"229 ", sizeof("229 ") - 1, '(', ')',
 		IP_CT_FTP_EPSV,
-		try_espv_response,
+		try_epsv_response,
 	},
 };
 
@@ -157,7 +157,7 @@
 }
 
 /* Returns 0, or length of numbers: |||6446| */
-static int try_espv_response(const char *data, size_t dlen, u_int32_t array[6],
+static int try_epsv_response(const char *data, size_t dlen, u_int32_t array[6],
 			     char term)
 {
 	char delim;
@@ -321,7 +321,7 @@
 	if (found == -1) {
 		/* We don't usually drop packets.  After all, this is
 		   connection tracking, not packet filtering.
-		   However, it is neccessary for accurate tracking in
+		   However, it is necessary for accurate tracking in
 		   this case. */
 		if (net_ratelimit())
 			printk("conntrack_ftp: partial %s %u+%u\n",
diff -Nru a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
--- a/net/ipv4/netfilter/ip_conntrack_irc.c	Tue Mar  4 19:30:12 2003
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c	Tue Mar  4 19:30:12 2003
@@ -107,7 +107,7 @@
 static int help(const struct iphdr *iph, size_t len,
 		struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
 {
-	/* tcplen not negative guarenteed by ip_conntrack_tcp.c */
+	/* tcplen not negative guaranteed by ip_conntrack_tcp.c */
 	struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
 	const char *data = (const char *) tcph + tcph->doff * 4;
 	const char *_data = data;
@@ -199,7 +199,7 @@
 			LOCK_BH(&ip_irc_lock);
 
 			/* save position of address in dcc string,
-			 * neccessary for NAT */
+			 * necessary for NAT */
 			DEBUGP("tcph->seq = %u\n", tcph->seq);
 			exp->seq = ntohl(tcph->seq) + (addr_beg_p - _data);
 			exp_irc_info->len = (addr_end_p - addr_beg_p);
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Tue Mar  4 19:30:14 2003
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Tue Mar  4 19:30:14 2003
@@ -190,7 +190,7 @@
 	   have an established connection: this is a fairly common
 	   problem case, so we can delete the conntrack
 	   immediately.  --RR */
-	if (!(conntrack->status & IPS_SEEN_REPLY) && tcph->rst) {
+	if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) && tcph->rst) {
 		WRITE_UNLOCK(&tcp_lock);
 		if (del_timer(&conntrack->timeout))
 			conntrack->timeout.function((unsigned long)conntrack);
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c	Tue Mar  4 19:30:03 2003
+++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c	Tue Mar  4 19:30:03 2003
@@ -51,7 +51,7 @@
 {
 	/* If we've seen traffic both ways, this is some kind of UDP
 	   stream.  Extend timeout. */
-	if (conntrack->status & IPS_SEEN_REPLY) {
+	if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
 		ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT);
 		/* Also, more likely to be important, and not a probe */
 		set_bit(IPS_ASSURED_BIT, &conntrack->status);
diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	Tue Mar  4 19:30:08 2003
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	Tue Mar  4 19:30:08 2003
@@ -33,7 +33,6 @@
 #define DEBUGP(format, args...)
 #endif
 
-struct module *ip_conntrack_module = THIS_MODULE;
 MODULE_LICENSE("GPL");
 
 static int kill_proto(const struct ip_conntrack *i, void *data)
@@ -77,7 +76,7 @@
 }
 
 static unsigned int
-print_conntrack(char *buffer, const struct ip_conntrack *conntrack)
+print_conntrack(char *buffer, struct ip_conntrack *conntrack)
 {
 	unsigned int len;
 	struct ip_conntrack_protocol *proto
@@ -95,12 +94,12 @@
 	len += print_tuple(buffer + len,
 			   &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
 			   proto);
-	if (!(conntrack->status & IPS_SEEN_REPLY))
+	if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
 		len += sprintf(buffer + len, "[UNREPLIED] ");
 	len += print_tuple(buffer + len,
 			   &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
 			   proto);
-	if (conntrack->status & IPS_ASSURED)
+	if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
 		len += sprintf(buffer + len, "[ASSURED] ");
 	len += sprintf(buffer + len, "use=%u ",
 		       atomic_read(&conntrack->ct_general.use));
@@ -310,7 +309,6 @@
 	}
 
 	list_prepend(&protocol_list, proto);
-	MOD_INC_USE_COUNT;
 
  out:
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -332,8 +330,6 @@
 
 	/* Remove all contrack entries for this protocol */
 	ip_ct_selective_cleanup(kill_proto, &proto->proto);
-
-	MOD_DEC_USE_COUNT;
 }
 
 static int __init init(void)
@@ -349,13 +345,19 @@
 module_init(init);
 module_exit(fini);
 
+/* Some modules need us, but don't depend directly on any symbol.
+   They should call this. */
+void need_ip_conntrack(void)
+{
+}
+
 EXPORT_SYMBOL(ip_conntrack_protocol_register);
 EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
 EXPORT_SYMBOL(invert_tuplepr);
 EXPORT_SYMBOL(ip_conntrack_alter_reply);
 EXPORT_SYMBOL(ip_conntrack_destroyed);
 EXPORT_SYMBOL(ip_conntrack_get);
-EXPORT_SYMBOL(ip_conntrack_module);
+EXPORT_SYMBOL(need_ip_conntrack);
 EXPORT_SYMBOL(ip_conntrack_helper_register);
 EXPORT_SYMBOL(ip_conntrack_helper_unregister);
 EXPORT_SYMBOL(ip_ct_selective_cleanup);
diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
--- a/net/ipv4/netfilter/ip_nat_core.c	Tue Mar  4 19:30:04 2003
+++ b/net/ipv4/netfilter/ip_nat_core.c	Tue Mar  4 19:30:04 2003
@@ -288,7 +288,7 @@
 		saved_ip = tuple->src.ip;
 		other_ipp = &tuple->src.ip;
 	}
-	/* Don't do do_extra_mangle unless neccessary (overrides
+	/* Don't do do_extra_mangle unless necessary (overrides
            explicit socket bindings, for example) */
 	orig_dstip = tuple->dst.ip;
 
@@ -913,7 +913,7 @@
 		   packet, except it was never src/dst reversed, so
 		   where we would normally apply a dst manip, we apply
 		   a src, and vice versa. */
-		if (info->manips[i].hooknum == opposite_hook[hooknum]) {
+		if (info->manips[i].hooknum == hooknum) {
 			DEBUGP("icmp_reply: inner %s -> %u.%u.%u.%u %u\n",
 			       info->manips[i].maniptype == IP_NAT_MANIP_SRC
 			       ? "DST" : "SRC",
@@ -924,9 +924,9 @@
 				  &info->manips[i].manip,
 				  !info->manips[i].maniptype,
 				  &skb->nfcache);
-		/* Outer packet needs to have IP header NATed like
-                   it's a reply. */
-		} else if (info->manips[i].hooknum == hooknum) {
+			/* Outer packet needs to have IP header NATed like
+	                   it's a reply. */
+
 			/* Use mapping to map outer packet: 0 give no
                            per-proto mapping */
 			DEBUGP("icmp_reply: outer %s -> %u.%u.%u.%u\n",
diff -Nru a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
--- a/net/ipv4/netfilter/ip_nat_helper.c	Tue Mar  4 19:30:05 2003
+++ b/net/ipv4/netfilter/ip_nat_helper.c	Tue Mar  4 19:30:05 2003
@@ -478,9 +478,9 @@
 	if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) {
 		struct ip_conntrack_helper *ct_helper;
 		
-		if ((ct_helper = ip_ct_find_helper(&me->tuple))
-		    && ct_helper->me) {
-			__MOD_INC_USE_COUNT(ct_helper->me);
+		if ((ct_helper = ip_ct_find_helper(&me->tuple))) {
+			if (!try_module_get(ct_helper->me))
+				return -EBUSY;
 		} else {
 			/* We are a NAT helper for protocol X.  If we need
 			 * respective conntrack helper for protoccol X, compute
@@ -498,9 +498,9 @@
 			sprintf(name, "ip_conntrack%s", tmp);
 #ifdef CONFIG_KMOD
 			if (!request_module(name)
-			    && (ct_helper = ip_ct_find_helper(&me->tuple))
-			    && ct_helper->me) {
-				__MOD_INC_USE_COUNT(ct_helper->me);
+			    && (ct_helper = ip_ct_find_helper(&me->tuple))) {
+				if (!try_module_get(ct_helper->me))
+					return -EBUSY;
 			} else {
 				printk("unable to load module %s\n", name);
 				return -EBUSY;
@@ -516,10 +516,8 @@
 	WRITE_LOCK(&ip_nat_lock);
 	if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple))
 		ret = -EBUSY;
-	else {
+	else
 		list_prepend(&helpers, me);
-		MOD_INC_USE_COUNT;
-	}
 	WRITE_UNLOCK(&ip_nat_lock);
 
 	return ret;
@@ -539,13 +537,10 @@
 
 void ip_nat_helper_unregister(struct ip_nat_helper *me)
 {
-	int found = 0;
-	
 	WRITE_LOCK(&ip_nat_lock);
 	/* Autoloading conntrack helper might have failed */
 	if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) {
 		LIST_DELETE(&helpers, me);
-		found = 1;
 	}
 	WRITE_UNLOCK(&ip_nat_lock);
 
@@ -562,18 +557,13 @@
 	   worse. --RR */
 	ip_ct_selective_cleanup(kill_helper, me);
 
-	if (found)
-		MOD_DEC_USE_COUNT;
-
 	/* If we are no standalone NAT helper, we need to decrement usage count
 	 * on our conntrack helper */
 	if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) {
 		struct ip_conntrack_helper *ct_helper;
 		
-		if ((ct_helper = ip_ct_find_helper(&me->tuple))
-		    && ct_helper->me) {
-			__MOD_DEC_USE_COUNT(ct_helper->me);
-		}
+		if ((ct_helper = ip_ct_find_helper(&me->tuple)))
+			module_put(ct_helper->me);
 #ifdef CONFIG_MODULES
 		else 
 			printk("%s: unable to decrement usage count"
diff -Nru a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c
--- a/net/ipv4/netfilter/ip_nat_irc.c	Tue Mar  4 19:30:14 2003
+++ b/net/ipv4/netfilter/ip_nat_irc.c	Tue Mar  4 19:30:14 2003
@@ -188,7 +188,7 @@
 
 	datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
 	LOCK_BH(&ip_irc_lock);
-	/* Check wether the whole IP/address pattern is carried in the payload */
+	/* Check whether the whole IP/address pattern is carried in the payload */
 	if (between(exp->seq + ct_irc_info->len,
 		    ntohl(tcph->seq),
 		    ntohl(tcph->seq) + datalen)) {
diff -Nru a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
--- a/net/ipv4/netfilter/ip_nat_standalone.c	Tue Mar  4 19:30:12 2003
+++ b/net/ipv4/netfilter/ip_nat_standalone.c	Tue Mar  4 19:30:12 2003
@@ -255,8 +255,6 @@
 	}
 
 	list_prepend(&protos, proto);
-	MOD_INC_USE_COUNT;
-
  out:
 	WRITE_UNLOCK(&ip_nat_lock);
 	return ret;
@@ -272,14 +270,14 @@
 	/* Someone could be still looking at the proto in a bh. */
 	br_write_lock_bh(BR_NETPROTO_LOCK);
 	br_write_unlock_bh(BR_NETPROTO_LOCK);
-
-	MOD_DEC_USE_COUNT;
 }
 
 static int init_or_cleanup(int init)
 {
 	int ret = 0;
 
+	need_ip_conntrack();
+
 	if (!init) goto cleanup;
 
 	ret = ip_nat_rule_init();
@@ -314,13 +312,9 @@
 		goto cleanup_localoutops;
 	}
 #endif
-	if (ip_conntrack_module)
-		__MOD_INC_USE_COUNT(ip_conntrack_module);
 	return ret;
 
  cleanup:
-	if (ip_conntrack_module)
-		__MOD_DEC_USE_COUNT(ip_conntrack_module);
 #ifdef CONFIG_IP_NF_NAT_LOCAL
 	nf_unregister_hook(&ip_nat_local_in_ops);
  cleanup_localoutops:
diff -Nru a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
--- a/net/ipv4/netfilter/ip_tables.c	Tue Mar  4 19:30:05 2003
+++ b/net/ipv4/netfilter/ip_tables.c	Tue Mar  4 19:30:05 2003
@@ -598,10 +598,7 @@
 	if (m->u.kernel.match->destroy)
 		m->u.kernel.match->destroy(m->data,
 					   m->u.match_size - sizeof(*m));
-
-	if (m->u.kernel.match->me)
-		__MOD_DEC_USE_COUNT(m->u.kernel.match->me);
-
+	module_put(m->u.kernel.match->me);
 	return 0;
 }
 
@@ -650,8 +647,10 @@
 		duprintf("check_match: `%s' not found\n", m->u.user.name);
 		return ret;
 	}
-	if (match->me)
-		__MOD_INC_USE_COUNT(match->me);
+	if (!try_module_get(match->me)) {
+		up(&ipt_mutex);
+		return -ENOENT;
+	}
 	m->u.kernel.match = match;
 	up(&ipt_mutex);
 
@@ -659,8 +658,7 @@
 	    && !m->u.kernel.match->checkentry(name, ip, m->data,
 					      m->u.match_size - sizeof(*m),
 					      hookmask)) {
-		if (m->u.kernel.match->me)
-			__MOD_DEC_USE_COUNT(m->u.kernel.match->me);
+		module_put(m->u.kernel.match->me);
 		duprintf("ip_tables: check failed for `%s'.\n",
 			 m->u.kernel.match->name);
 		return -EINVAL;
@@ -697,8 +695,11 @@
 		duprintf("check_entry: `%s' not found\n", t->u.user.name);
 		goto cleanup_matches;
 	}
-	if (target->me)
-		__MOD_INC_USE_COUNT(target->me);
+	if (!try_module_get(target->me)) {
+		up(&ipt_mutex);
+		ret = -ENOENT;
+		goto cleanup_matches;
+	}
 	t->u.kernel.target = target;
 	up(&ipt_mutex);
 
@@ -712,8 +713,7 @@
 						      t->u.target_size
 						      - sizeof(*t),
 						      e->comefrom)) {
-		if (t->u.kernel.target->me)
-			__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
+		module_put(t->u.kernel.target->me);
 		duprintf("ip_tables: check failed for `%s'.\n",
 			 t->u.kernel.target->name);
 		ret = -EINVAL;
@@ -785,9 +785,7 @@
 	if (t->u.kernel.target->destroy)
 		t->u.kernel.target->destroy(t->data,
 					    t->u.target_size - sizeof(*t));
-	if (t->u.kernel.target->me)
-		__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
-
+	module_put(t->u.kernel.target->me);
 	return 0;
 }
 
@@ -1319,17 +1317,14 @@
 {
 	int ret;
 
-	MOD_INC_USE_COUNT;
 	ret = down_interruptible(&ipt_mutex);
-	if (ret != 0) {
-		MOD_DEC_USE_COUNT;
+	if (ret != 0)
 		return ret;
-	}
+
 	if (!list_named_insert(&ipt_target, target)) {
 		duprintf("ipt_register_target: `%s' already in list!\n",
 			 target->name);
 		ret = -EINVAL;
-		MOD_DEC_USE_COUNT;
 	}
 	up(&ipt_mutex);
 	return ret;
@@ -1341,7 +1336,6 @@
 	down(&ipt_mutex);
 	LIST_DELETE(&ipt_target, target);
 	up(&ipt_mutex);
-	MOD_DEC_USE_COUNT;
 }
 
 int
@@ -1349,16 +1343,13 @@
 {
 	int ret;
 
-	MOD_INC_USE_COUNT;
 	ret = down_interruptible(&ipt_mutex);
-	if (ret != 0) {
-		MOD_DEC_USE_COUNT;
+	if (ret != 0)
 		return ret;
-	}
+
 	if (!list_named_insert(&ipt_match, match)) {
 		duprintf("ipt_register_match: `%s' already in list!\n",
 			 match->name);
-		MOD_DEC_USE_COUNT;
 		ret = -EINVAL;
 	}
 	up(&ipt_mutex);
@@ -1372,7 +1363,6 @@
 	down(&ipt_mutex);
 	LIST_DELETE(&ipt_match, match);
 	up(&ipt_mutex);
-	MOD_DEC_USE_COUNT;
 }
 
 int ipt_register_table(struct ipt_table *table)
@@ -1382,14 +1372,11 @@
 	static struct ipt_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
-	MOD_INC_USE_COUNT;
 	newinfo = vmalloc(sizeof(struct ipt_table_info)
 			  + SMP_ALIGN(table->table->size) * NR_CPUS);
-	if (!newinfo) {
-		ret = -ENOMEM;
-		MOD_DEC_USE_COUNT;
-		return ret;
-	}
+	if (!newinfo)
+		return -ENOMEM;
+
 	memcpy(newinfo->entries, table->table->entries, table->table->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
@@ -1399,14 +1386,12 @@
 			      table->table->underflow);
 	if (ret != 0) {
 		vfree(newinfo);
-		MOD_DEC_USE_COUNT;
 		return ret;
 	}
 
 	ret = down_interruptible(&ipt_mutex);
 	if (ret != 0) {
 		vfree(newinfo);
-		MOD_DEC_USE_COUNT;
 		return ret;
 	}
 
@@ -1436,7 +1421,6 @@
 
  free_unlock:
 	vfree(newinfo);
-	MOD_DEC_USE_COUNT;
 	goto unlock;
 }
 
@@ -1450,7 +1434,6 @@
 	IPT_ENTRY_ITERATE(table->private->entries, table->private->size,
 			  cleanup_entry, NULL);
 	vfree(table->private);
-	MOD_DEC_USE_COUNT;
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
@@ -1628,7 +1611,7 @@
 		     u_int8_t type, u_int8_t code,
 		     int invert)
 {
-	return (type == test_type && code >= min_code && code <= max_code)
+	return ((test_type == 0xFF) || (type == test_type && code >= min_code && code <= max_code))
 		^ invert;
 }
 
diff -Nru a/net/ipv4/netfilter/ipchains_core.c b/net/ipv4/netfilter/ipchains_core.c
--- a/net/ipv4/netfilter/ipchains_core.c	Tue Mar  4 19:30:13 2003
+++ b/net/ipv4/netfilter/ipchains_core.c	Tue Mar  4 19:30:13 2003
@@ -1566,16 +1566,8 @@
 
 /* File offset is actually in records, not bytes. */
 static int ip_chain_procinfo(char *buffer, char **start,
-			     off_t offset, int length
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)
-			     , int reset
-#endif
-	)
+			     off_t offset, int length)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29)
-	/* FIXME: No more `atomic' read and reset.  Wonderful 8-( --RR */
-	int reset = 0;
-#endif
 	struct ip_chain *i;
 	struct ip_fwkernel *j = ip_fw_chains->chain;
 	unsigned long flags;
@@ -1612,9 +1604,6 @@
 				len = last_len;
 				goto outside;
 			}
-			else if (reset)
-				memset(j->counters, 0,
-				       sizeof(struct ip_counters)*NUM_SLOTS);
 		}
 	}
 outside:
diff -Nru a/net/ipv4/netfilter/ipfwadm_core.c b/net/ipv4/netfilter/ipfwadm_core.c
--- a/net/ipv4/netfilter/ipfwadm_core.c	Tue Mar  4 19:30:07 2003
+++ b/net/ipv4/netfilter/ipfwadm_core.c	Tue Mar  4 19:30:07 2003
@@ -1113,9 +1113,8 @@
 #endif /* CONFIG_IP_FIREWALL */
 
 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
-
 static int ip_chain_procinfo(int stage, char *buffer, char **start,
-			     off_t offset, int length, int reset)
+			     off_t offset, int length)
 {
 	off_t pos=0, begin=0;
 	struct ip_fw *i;
@@ -1184,15 +1183,6 @@
 			len = last_len;
 			break;
 		}
-/* Not possible in 2.3.29+, also allowing read lock instead of write -- JM */
-#if 0
-		else if(reset)
-		{
-			/* This needs to be done at this specific place! */
-			i->fw_pcnt=0L;
-			i->fw_bcnt=0L;
-		}
-#endif
 		last_len = len;
 		i=i->fw_next;
 	}
@@ -1206,69 +1196,30 @@
 #endif
 
 #ifdef CONFIG_IP_ACCT
-
 static int ip_acct_procinfo(char *buffer, char **start, off_t offset,
-			    int length
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)
-			    , int reset
-#endif
-	)
+			    int length)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29)
-	/* FIXME: No more `atomic' read and reset.  Wonderful 8-( --RR */
-	int reset = 0;
-#endif
-	return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length,
-				 reset);
+	return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length);
 }
-
 #endif
 
 #ifdef CONFIG_IP_FIREWALL
-
 static int ip_fw_in_procinfo(char *buffer, char **start, off_t offset,
-			      int length
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)
-			     , int reset
-#endif
-	)
+			      int length)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29)
-	/* FIXME: No more `atomic' read and reset.  Wonderful 8-( --RR */
-	int reset = 0;
-#endif
-	return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length,
-				 reset);
+	return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length);
 }
 
 static int ip_fw_out_procinfo(char *buffer, char **start, off_t offset,
-			      int length
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)
-			    , int reset
-#endif
-	)
+			      int length)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29)
-	/* FIXME: No more `atomic' read and reset.  Wonderful 8-( --RR */
-	int reset = 0;
-#endif
-	return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length,
-				 reset);
+	return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length);
 }
 
 static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset,
-			      int length
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)
-			    , int reset
-#endif
-	)
+			      int length)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29)
-	/* FIXME: No more `atomic' read and reset.  Wonderful 8-( --RR */
-	int reset = 0;
-#endif
-	return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length,
-				 reset);
+	return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length);
 }
 #endif
 
diff -Nru a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c
--- a/net/ipv4/netfilter/ipt_conntrack.c	Tue Mar  4 19:30:13 2003
+++ b/net/ipv4/netfilter/ipt_conntrack.c	Tue Mar  4 19:30:13 2003
@@ -105,17 +105,13 @@
 
 static int __init init(void)
 {
-	/* NULL if ip_conntrack not a module */
-	if (ip_conntrack_module)
-		__MOD_INC_USE_COUNT(ip_conntrack_module);
+	need_ip_conntrack();
 	return ipt_register_match(&conntrack_match);
 }
 
 static void __exit fini(void)
 {
 	ipt_unregister_match(&conntrack_match);
-	if (ip_conntrack_module)
-		__MOD_DEC_USE_COUNT(ip_conntrack_module);
 }
 
 module_init(init);
diff -Nru a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
--- a/net/ipv4/netfilter/ipt_helper.c	Tue Mar  4 19:30:12 2003
+++ b/net/ipv4/netfilter/ipt_helper.c	Tue Mar  4 19:30:12 2003
@@ -94,17 +94,13 @@
 
 static int __init init(void)
 {
-	/* NULL if ip_conntrack not a module */
-	if (ip_conntrack_module)
-		__MOD_INC_USE_COUNT(ip_conntrack_module);
+	need_ip_conntrack();
 	return ipt_register_match(&helper_match);
 }
 
 static void __exit fini(void)
 {
 	ipt_unregister_match(&helper_match);
-	if (ip_conntrack_module)
-		__MOD_DEC_USE_COUNT(ip_conntrack_module);
 }
 
 module_init(init);
diff -Nru a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c
--- a/net/ipv4/netfilter/ipt_state.c	Tue Mar  4 19:30:14 2003
+++ b/net/ipv4/netfilter/ipt_state.c	Tue Mar  4 19:30:14 2003
@@ -46,17 +46,13 @@
 
 static int __init init(void)
 {
-	/* NULL if ip_conntrack not a module */
-	if (ip_conntrack_module)
-		__MOD_INC_USE_COUNT(ip_conntrack_module);
+	need_ip_conntrack();
 	return ipt_register_match(&state_match);
 }
 
 static void __exit fini(void)
 {
 	ipt_unregister_match(&state_match);
-	if (ip_conntrack_module)
-		__MOD_DEC_USE_COUNT(ip_conntrack_module);
 }
 
 module_init(init);
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	Tue Mar  4 19:30:05 2003
+++ b/net/ipv4/tcp.c	Tue Mar  4 19:30:05 2003
@@ -172,7 +172,7 @@
  *					ack if state is TCP_CLOSED.
  *		Alan Cox	:	Look up device on a retransmit - routes may
  *					change. Doesn't yet cope with MSS shrink right
- *					but its a start!
+ *					but it's a start!
  *		Marc Tamsky	:	Closing in closing fixes.
  *		Mike Shaver	:	RFC1122 verifications.
  *		Alan Cox	:	rcv_saddr errors.
diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c	Tue Mar  4 19:30:13 2003
+++ b/net/ipv6/addrconf.c	Tue Mar  4 19:30:13 2003
@@ -2015,6 +2015,9 @@
 		write_lock(&addrconf_hash_lock);
 		for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) {
 			unsigned long age;
+#ifdef CONFIG_IPV6_PRIVACY
+			unsigned long regen_advance;
+#endif
 
 			if (ifp->flags & IFA_F_PERMANENT)
 				continue;
@@ -2022,6 +2025,12 @@
 			spin_lock(&ifp->lock);
 			age = (now - ifp->tstamp) / HZ;
 
+#ifdef CONFIG_IPV6_PRIVACY
+			regen_advance = ifp->idev->cnf.regen_max_retry * 
+					ifp->idev->cnf.dad_transmits * 
+					ifp->idev->nd_parms->retrans_time / HZ;
+#endif
+
 			if (age >= ifp->valid_lft) {
 				spin_unlock(&ifp->lock);
 				in6_ifa_hold(ifp);
@@ -2050,6 +2059,28 @@
 					in6_ifa_put(ifp);
 					goto restart;
 				}
+#ifdef CONFIG_IPV6_PRIVACY
+			} else if ((ifp->flags&IFA_F_TEMPORARY) &&
+				   !(ifp->flags&IFA_F_TENTATIVE)) {
+				if (age >= ifp->prefered_lft - regen_advance) {
+					struct inet6_ifaddr *ifpub = ifp->ifpub;
+					if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
+						next = ifp->tstamp + ifp->prefered_lft * HZ;
+					if (!ifp->regen_count && ifpub) {
+						ifp->regen_count++;
+						in6_ifa_hold(ifp);
+						in6_ifa_hold(ifpub);
+						spin_unlock(&ifp->lock);
+						write_unlock(&addrconf_hash_lock);
+						ipv6_create_tempaddr(ifpub, ifp);
+						in6_ifa_put(ifpub);
+						in6_ifa_put(ifp);
+						goto restart;
+					}
+				} else if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
+					next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
+				spin_unlock(&ifp->lock);
+#endif
 			} else {
 				/* ifp->prefered_lft <= ifp->valid_lft */
 				if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
@@ -2288,75 +2319,163 @@
 	ctl_table addrconf_proto_dir[2];
 	ctl_table addrconf_root_dir[2];
 } addrconf_sysctl = {
-	NULL,
-        {{NET_IPV6_FORWARDING, "forwarding",
-         &ipv6_devconf.forwarding, sizeof(int), 0644, NULL,
-         &addrconf_sysctl_forward},
-
-	{NET_IPV6_HOP_LIMIT, "hop_limit",
-         &ipv6_devconf.hop_limit, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-
-	{NET_IPV6_MTU, "mtu",
-         &ipv6_devconf.mtu6, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-
-	{NET_IPV6_ACCEPT_RA, "accept_ra",
-         &ipv6_devconf.accept_ra, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-
-	{NET_IPV6_ACCEPT_REDIRECTS, "accept_redirects",
-         &ipv6_devconf.accept_redirects, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-
-	{NET_IPV6_AUTOCONF, "autoconf",
-         &ipv6_devconf.autoconf, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-
-	{NET_IPV6_DAD_TRANSMITS, "dad_transmits",
-         &ipv6_devconf.dad_transmits, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-
-	{NET_IPV6_RTR_SOLICITS, "router_solicitations",
-         &ipv6_devconf.rtr_solicits, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-
-	{NET_IPV6_RTR_SOLICIT_INTERVAL, "router_solicitation_interval",
-         &ipv6_devconf.rtr_solicit_interval, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies},
-
-	{NET_IPV6_RTR_SOLICIT_DELAY, "router_solicitation_delay",
-         &ipv6_devconf.rtr_solicit_delay, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies},
-
+	.sysctl_header = NULL,
+	.addrconf_vars = {
+        	{
+			.ctl_name	=	NET_IPV6_FORWARDING,
+			.procname	=	"forwarding",
+         		.data		=	&ipv6_devconf.forwarding,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&addrconf_sysctl_forward,
+		},
+		{
+			.ctl_name	=	NET_IPV6_HOP_LIMIT,
+			.procname	=	"hop_limit",
+         		.data		=	&ipv6_devconf.hop_limit,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+			.proc_handler	=	proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_MTU,
+			.procname	=	"mtu",
+			.data		=	&ipv6_devconf.mtu6,
+         		.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_ACCEPT_RA,
+			.procname	=	"accept_ra",
+         		.data		=	&ipv6_devconf.accept_ra,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_ACCEPT_REDIRECTS,
+			.procname	=	"accept_redirects",
+         		.data		=	&ipv6_devconf.accept_redirects,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_AUTOCONF,
+			.procname	=	"autoconf",
+         		.data		=	&ipv6_devconf.autoconf,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_DAD_TRANSMITS,
+			.procname	=	"dad_transmits",
+         		.data		=	&ipv6_devconf.dad_transmits,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_RTR_SOLICITS,
+			.procname	=	"router_solicitations",
+         		.data		=	&ipv6_devconf.rtr_solicits,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_RTR_SOLICIT_INTERVAL,
+			.procname	=	"router_solicitation_interval",
+         		.data		=	&ipv6_devconf.rtr_solicit_interval,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&proc_dointvec_jiffies,
+		},
+		{
+			.ctl_name	=	NET_IPV6_RTR_SOLICIT_DELAY,
+			.procname	=	"router_solicitation_delay",
+         		.data		=	&ipv6_devconf.rtr_solicit_delay,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+         		.proc_handler	=	&proc_dointvec_jiffies,
+		},
 #ifdef CONFIG_IPV6_PRIVACY
-	{NET_IPV6_USE_TEMPADDR, "use_tempaddr",
-	 &ipv6_devconf.use_tempaddr, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-
-	{NET_IPV6_TEMP_VALID_LFT, "temp_valid_lft",
-	 &ipv6_devconf.temp_valid_lft, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-
-	{NET_IPV6_TEMP_PREFERED_LFT, "temp_prefered_lft",
-	 &ipv6_devconf.temp_prefered_lft, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-
-	{NET_IPV6_REGEN_MAX_RETRY, "regen_max_retry",
-	 &ipv6_devconf.regen_max_retry, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-
-	{NET_IPV6_MAX_DESYNC_FACTOR, "max_desync_factor",
-	 &ipv6_devconf.max_desync_factor, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
+		{
+			.ctl_name	=	NET_IPV6_USE_TEMPADDR,
+			.procname	=	"use_tempaddr",
+	 		.data		=	&ipv6_devconf.use_tempaddr,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+	 		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_TEMP_VALID_LFT,
+			.procname	=	"temp_valid_lft",
+	 		.data		=	&ipv6_devconf.temp_valid_lft,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+	 		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_TEMP_PREFERED_LFT,
+			.procname	=	"temp_prefered_lft",
+	 		.data		=	&ipv6_devconf.temp_prefered_lft,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+	 		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_REGEN_MAX_RETRY,
+			.procname	=	"regen_max_retry",
+	 		.data		=	&ipv6_devconf.regen_max_retry,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+	 		.proc_handler	=	&proc_dointvec,
+		},
+		{
+			.ctl_name	=	NET_IPV6_MAX_DESYNC_FACTOR,
+			.procname	=	"max_desync_factor",
+	 		.data		=	&ipv6_devconf.max_desync_factor,
+			.maxlen		=	sizeof(int),
+			.mode		=	0644,
+	 		.proc_handler	=	&proc_dointvec,
+		},
 #endif
-
-	{0}},
-
-	{{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, addrconf_sysctl.addrconf_vars},{0}},
-	{{NET_IPV6_CONF, "conf", NULL, 0, 0555, addrconf_sysctl.addrconf_dev},{0}},
-	{{NET_IPV6, "ipv6", NULL, 0, 0555, addrconf_sysctl.addrconf_conf_dir},{0}},
-	{{CTL_NET, "net", NULL, 0, 0555, addrconf_sysctl.addrconf_proto_dir},{0}}
+	},
+	.addrconf_dev = {
+		{
+			.ctl_name	=	NET_PROTO_CONF_ALL,
+			.procname	=	"all",
+			.mode		=	0555,
+			.child		=	addrconf_sysctl.addrconf_vars,
+		},
+	},
+	.addrconf_conf_dir = {
+		{
+			.ctl_name	=	NET_IPV6_CONF,
+			.procname	=	"conf",
+			.mode		=	0555,
+			.child		=	addrconf_sysctl.addrconf_dev,
+		},
+	},
+	.addrconf_proto_dir = {
+		{
+			.ctl_name	=	NET_IPV6,
+			.procname	=	"ipv6",
+			.mode		=	0555,
+			.child		=	addrconf_sysctl.addrconf_conf_dir,
+		},
+	},
+	.addrconf_root_dir = {
+		{
+			.ctl_name	=	CTL_NET,
+			.procname	=	"net",
+			.mode		=	0555,
+			.child		=	addrconf_sysctl.addrconf_proto_dir,
+		},
+	},
 };
 
 static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf *p)
diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
--- a/net/ipv6/ipv6_syms.c	Tue Mar  4 19:30:11 2003
+++ b/net/ipv6/ipv6_syms.c	Tue Mar  4 19:30:11 2003
@@ -29,3 +29,5 @@
 EXPORT_SYMBOL(inet6_ioctl);
 EXPORT_SYMBOL(ipv6_get_saddr);
 EXPORT_SYMBOL(ipv6_chk_addr);
+EXPORT_SYMBOL(in6addr_any);
+EXPORT_SYMBOL(in6addr_loopback);
diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
--- a/net/ipv6/ndisc.c	Tue Mar  4 19:30:10 2003
+++ b/net/ipv6/ndisc.c	Tue Mar  4 19:30:10 2003
@@ -208,7 +208,7 @@
 		default:
 			/*
 			 * Unknown options must be silently ignored,
-			 * to accomodate future extension to the protocol.
+			 * to accommodate future extension to the protocol.
 			 */
 			ND_PRINTK2(KERN_WARNING
 				   "ndisc_parse_options(): ignored unsupported option; type=%d, len=%d\n",
diff -Nru a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
--- a/net/ipv6/netfilter/Kconfig	Tue Mar  4 19:30:13 2003
+++ b/net/ipv6/netfilter/Kconfig	Tue Mar  4 19:30:13 2003
@@ -60,6 +60,46 @@
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+config IP6_NF_MATCH_RT
+	tristate "Routing header match support"
+	depends on IP6_NF_IPTABLES && EXPERIMENTAL
+	help
+	  rt matching allows you to match packets based on the routing
+	  header of the packet.
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+config IP6_NF_MATCH_OPTS
+	tristate "Hop-by-hop and Dst opts header match support"
+	depends on IP6_NF_IPTABLES && EXPERIMENTAL
+	help
+	  This allows one to match packets based on the hop-by-hop
+	  and destination options headers of a packet.
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+config IP6_NF_MATCH_FRAG
+	tristate "Fragmentation header match support"
+	depends on IP6_NF_IPTABLES && EXPERIMENTAL
+	help
+	  frag matching allows you to match packets based on the fragmentation
+	  header of the packet.
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+config IP6_NF_MATCH_HL
+	tristate "HL match support"
+	depends on IP6_NF_IPTABLES
+	help
+	  HL matching allows you to match packets based on the hop
+	  limit of the packet.
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 config IP6_NF_MATCH_MULTIPORT
 	tristate "Multiple port match support"
 	depends on IP6_NF_IPTABLES
@@ -89,6 +129,25 @@
 	  Netfilter mark matching allows you to match packets based on the
 	  `nfmark' value in the packet.  This can be set by the MARK target
 	  (see below).
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+config IP6_NF_MATCH_IPV6HEADER
+	tristate "IPv6 Extension Headers Match (EXPERIMENTAL)"
+	depends on IP6_NF_IPTABLES && EXPERIMENTAL
+	help
+	  This module allows one to match packets based upon
+	  the ipv6 extension headers.
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+config IP6_NF_MATCH_AHESP
+	tristate "AH/ESP match support (EXPERIMENTAL)"
+	depends on IP6_NF_IPTABLES && EXPERIMENTAL
+	help
+	  This module allows one to match AH and ESP packets.
 
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
diff -Nru a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
--- a/net/ipv6/netfilter/Makefile	Tue Mar  4 19:30:10 2003
+++ b/net/ipv6/netfilter/Makefile	Tue Mar  4 19:30:10 2003
@@ -8,6 +8,11 @@
 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
+obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
+obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
+obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
+obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
+obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o
 obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
 obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
 obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
@@ -16,3 +21,4 @@
 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
+obj-$(CONFIG_IP_NF_MATCH_HL) += ip6t_hl.o
diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
--- a/net/ipv6/netfilter/ip6_tables.c	Tue Mar  4 19:30:13 2003
+++ b/net/ipv6/netfilter/ip6_tables.c	Tue Mar  4 19:30:13 2003
@@ -671,10 +671,7 @@
 	if (m->u.kernel.match->destroy)
 		m->u.kernel.match->destroy(m->data,
 					   m->u.match_size - sizeof(*m));
-
-	if (m->u.kernel.match->me)
-		__MOD_DEC_USE_COUNT(m->u.kernel.match->me);
-
+	module_put(m->u.kernel.match->me);
 	return 0;
 }
 
@@ -723,8 +720,10 @@
 	  //		duprintf("check_match: `%s' not found\n", m->u.name);
 		return ret;
 	}
-	if (match->me)
-		__MOD_INC_USE_COUNT(match->me);
+	if (!try_module_get(match->me)) {
+		up(&ip6t_mutex);
+		return -ENOENT;
+	}
 	m->u.kernel.match = match;
 	up(&ip6t_mutex);
 
@@ -732,8 +731,7 @@
 	    && !m->u.kernel.match->checkentry(name, ipv6, m->data,
 					      m->u.match_size - sizeof(*m),
 					      hookmask)) {
-		if (m->u.kernel.match->me)
-			__MOD_DEC_USE_COUNT(m->u.kernel.match->me);
+		module_put(m->u.kernel.match->me);
 		duprintf("ip_tables: check failed for `%s'.\n",
 			 m->u.kernel.match->name);
 		return -EINVAL;
@@ -770,11 +768,17 @@
 		duprintf("check_entry: `%s' not found\n", t->u.user.name);
 		goto cleanup_matches;
 	}
-	if (target->me)
-		__MOD_INC_USE_COUNT(target->me);
+	if (!try_module_get(target->me)) {
+		up(&ip6t_mutex);
+		ret = -ENOENT;
+		goto cleanup_matches;
+	}
 	t->u.kernel.target = target;
 	up(&ip6t_mutex);
-
+	if (!t->u.kernel.target) {
+		ret = -EBUSY;
+		goto cleanup_matches;
+	}
 	if (t->u.kernel.target == &ip6t_standard_target) {
 		if (!standard_check(t, size)) {
 			ret = -EINVAL;
@@ -785,8 +789,7 @@
 						      t->u.target_size
 						      - sizeof(*t),
 						      e->comefrom)) {
-		if (t->u.kernel.target->me)
-			__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
+		module_put(t->u.kernel.target->me);
 		duprintf("ip_tables: check failed for `%s'.\n",
 			 t->u.kernel.target->name);
 		ret = -EINVAL;
@@ -858,9 +861,7 @@
 	if (t->u.kernel.target->destroy)
 		t->u.kernel.target->destroy(t->data,
 					    t->u.target_size - sizeof(*t));
-	if (t->u.kernel.target->me)
-		__MOD_DEC_USE_COUNT(t->u.kernel.target->me);
-
+	module_put(t->u.kernel.target->me);
 	return 0;
 }
 
@@ -1388,17 +1389,14 @@
 {
 	int ret;
 
-	MOD_INC_USE_COUNT;
 	ret = down_interruptible(&ip6t_mutex);
-	if (ret != 0) {
-		MOD_DEC_USE_COUNT;
+	if (ret != 0)
 		return ret;
-	}
+
 	if (!list_named_insert(&ip6t_target, target)) {
 		duprintf("ip6t_register_target: `%s' already in list!\n",
 			 target->name);
 		ret = -EINVAL;
-		MOD_DEC_USE_COUNT;
 	}
 	up(&ip6t_mutex);
 	return ret;
@@ -1410,7 +1408,6 @@
 	down(&ip6t_mutex);
 	LIST_DELETE(&ip6t_target, target);
 	up(&ip6t_mutex);
-	MOD_DEC_USE_COUNT;
 }
 
 int
@@ -1418,16 +1415,13 @@
 {
 	int ret;
 
-	MOD_INC_USE_COUNT;
 	ret = down_interruptible(&ip6t_mutex);
-	if (ret != 0) {
-		MOD_DEC_USE_COUNT;
+	if (ret != 0)
 		return ret;
-	}
+
 	if (!list_named_insert(&ip6t_match, match)) {
 		duprintf("ip6t_register_match: `%s' already in list!\n",
 			 match->name);
-		MOD_DEC_USE_COUNT;
 		ret = -EINVAL;
 	}
 	up(&ip6t_mutex);
@@ -1441,7 +1435,6 @@
 	down(&ip6t_mutex);
 	LIST_DELETE(&ip6t_match, match);
 	up(&ip6t_mutex);
-	MOD_DEC_USE_COUNT;
 }
 
 int ip6t_register_table(struct ip6t_table *table)
@@ -1451,14 +1444,11 @@
 	static struct ip6t_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { }, { } };
 
-	MOD_INC_USE_COUNT;
 	newinfo = vmalloc(sizeof(struct ip6t_table_info)
 			  + SMP_ALIGN(table->table->size) * NR_CPUS);
-	if (!newinfo) {
-		ret = -ENOMEM;
-		MOD_DEC_USE_COUNT;
-		return ret;
-	}
+	if (!newinfo)
+		return -ENOMEM;
+
 	memcpy(newinfo->entries, table->table->entries, table->table->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
@@ -1468,14 +1458,12 @@
 			      table->table->underflow);
 	if (ret != 0) {
 		vfree(newinfo);
-		MOD_DEC_USE_COUNT;
 		return ret;
 	}
 
 	ret = down_interruptible(&ip6t_mutex);
 	if (ret != 0) {
 		vfree(newinfo);
-		MOD_DEC_USE_COUNT;
 		return ret;
 	}
 
@@ -1505,7 +1493,6 @@
 
  free_unlock:
 	vfree(newinfo);
-	MOD_DEC_USE_COUNT;
 	goto unlock;
 }
 
@@ -1519,7 +1506,6 @@
 	IP6T_ENTRY_ITERATE(table->private->entries, table->private->size,
 			  cleanup_entry, NULL);
 	vfree(table->private);
-	MOD_DEC_USE_COUNT;
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
diff -Nru a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/netfilter/ip6t_ah.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,218 @@
+/* Kernel module to match AH parameters. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/ipv6.h>
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_ah.h>
+
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv6 AH match");
+MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+struct ahhdr {
+       __u8    nexthdr;
+       __u8    hdrlen;
+       __u16   reserved;
+       __u32   spi;
+};
+
+int ipv6_ext_hdr(u8 nexthdr)
+{
+        return ( (nexthdr == NEXTHDR_HOP)       ||
+                 (nexthdr == NEXTHDR_ROUTING)   ||
+                 (nexthdr == NEXTHDR_FRAGMENT)  ||
+                 (nexthdr == NEXTHDR_AUTH)      ||
+                 (nexthdr == NEXTHDR_ESP)       ||
+                 (nexthdr == NEXTHDR_NONE)      ||
+                 (nexthdr == NEXTHDR_DEST) );
+}
+
+/* Returns 1 if the spi is matched by the range, 0 otherwise */
+static inline int
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
+{
+       int r=0;
+       DEBUGP("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
+              min,spi,max);
+       r=(spi >= min && spi <= max) ^ invert;
+       DEBUGP(" result %s\n",r? "PASS\n" : "FAILED\n");
+       return r;
+}
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *protohdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+       struct ahhdr *ah = NULL;
+       const struct ip6t_ah *ahinfo = matchinfo;
+       unsigned int temp;
+       int len;
+       u8 nexthdr;
+       unsigned int ptr;
+       unsigned int hdrlen = 0;
+
+       /*DEBUGP("IPv6 AH entered\n");*/
+       /* if (opt->auth == 0) return 0;
+       * It does not filled on output */
+
+       /* type of the 1st exthdr */
+       nexthdr = skb->nh.ipv6h->nexthdr;
+       /* pointer to the 1st exthdr */
+       ptr = sizeof(struct ipv6hdr);
+       /* available length */
+       len = skb->len - ptr;
+       temp = 0;
+
+        while (ipv6_ext_hdr(nexthdr)) {
+               struct ipv6_opt_hdr *hdr;
+
+              DEBUGP("ipv6_ah header iteration \n");
+
+              /* Is there enough space for the next ext header? */
+                if (len < (int)sizeof(struct ipv6_opt_hdr))
+                        return 0;
+              /* No more exthdr -> evaluate */
+                if (nexthdr == NEXTHDR_NONE) {
+                     break;
+              }
+              /* ESP -> evaluate */
+                if (nexthdr == NEXTHDR_ESP) {
+                     break;
+              }
+
+              hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+
+              /* Calculate the header length */
+                if (nexthdr == NEXTHDR_FRAGMENT) {
+                        hdrlen = 8;
+                } else if (nexthdr == NEXTHDR_AUTH)
+                        hdrlen = (hdr->hdrlen+2)<<2;
+                else
+                        hdrlen = ipv6_optlen(hdr);
+
+              /* AH -> evaluate */
+                if (nexthdr == NEXTHDR_AUTH) {
+                     temp |= MASK_AH;
+                     break;
+              }
+
+
+              /* set the flag */
+              switch (nexthdr){
+                     case NEXTHDR_HOP:
+                     case NEXTHDR_ROUTING:
+                     case NEXTHDR_FRAGMENT:
+                     case NEXTHDR_AUTH:
+                     case NEXTHDR_DEST:
+                            break;
+                     default:
+                            DEBUGP("ipv6_ah match: unknown nextheader %u\n",nexthdr);
+                            return 0;
+                            break;
+              }
+
+                nexthdr = hdr->nexthdr;
+                len -= hdrlen;
+                ptr += hdrlen;
+		if ( ptr > skb->len ) {
+			DEBUGP("ipv6_ah: new pointer too large! \n");
+			break;
+		}
+        }
+
+       /* AH header not found */
+       if ( temp != MASK_AH ) return 0;
+
+       if (len < (int)sizeof(struct ahhdr)){
+	       *hotdrop = 1;
+       		return 0;
+       }
+
+       ah=skb->data+ptr;
+
+       DEBUGP("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen);
+       DEBUGP("RES %04X ", ah->reserved);
+       DEBUGP("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi));
+
+       DEBUGP("IPv6 AH spi %02X ",
+       		(spi_match(ahinfo->spis[0], ahinfo->spis[1],
+                           ntohl(ah->spi),
+                           !!(ahinfo->invflags & IP6T_AH_INV_SPI))));
+       DEBUGP("len %02X %04X %02X ",
+       		ahinfo->hdrlen, hdrlen,
+       		(!ahinfo->hdrlen ||
+                           (ahinfo->hdrlen == hdrlen) ^
+                           !!(ahinfo->invflags & IP6T_AH_INV_LEN)));
+       DEBUGP("res %02X %04X %02X\n", 
+       		ahinfo->hdrres, ah->reserved,
+       		!(ahinfo->hdrres && ah->reserved));
+
+       return (ah != NULL)
+              &&
+              (spi_match(ahinfo->spis[0], ahinfo->spis[1],
+                           ntohl(ah->spi),
+                           !!(ahinfo->invflags & IP6T_AH_INV_SPI)))
+              &&
+              (!ahinfo->hdrlen ||
+                           (ahinfo->hdrlen == hdrlen) ^
+                           !!(ahinfo->invflags & IP6T_AH_INV_LEN))
+              &&
+              !(ahinfo->hdrres && ah->reserved);
+}
+
+/* Called when user tries to insert an entry of this type. */
+static int
+checkentry(const char *tablename,
+          const struct ip6t_ip6 *ip,
+          void *matchinfo,
+          unsigned int matchinfosize,
+          unsigned int hook_mask)
+{
+       const struct ip6t_ah *ahinfo = matchinfo;
+
+       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_ah))) {
+              DEBUGP("ip6t_ah: matchsize %u != %u\n",
+                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_ah)));
+              return 0;
+       }
+       if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
+              DEBUGP("ip6t_ah: unknown flags %X\n",
+                      ahinfo->invflags);
+              return 0;
+       }
+
+       return 1;
+}
+
+static struct ip6t_match ah_match
+= { { NULL, NULL }, "ah", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+       return ip6t_register_match(&ah_match);
+}
+
+static void __exit cleanup(void)
+{
+       ip6t_unregister_match(&ah_match);
+}
+
+module_init(init);
+module_exit(cleanup);
diff -Nru a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/netfilter/ip6t_dst.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,287 @@
+/* Kernel module to match Hop-by-Hop and Destination parameters. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/ipv6.h>
+
+#include <asm/byteorder.h>
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_opts.h>
+
+#define LOW(n)		(n & 0x00FF)
+
+#define HOPBYHOP	0
+
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
+#if HOPBYHOP
+MODULE_DESCRIPTION("IPv6 HbH match");
+#else
+MODULE_DESCRIPTION("IPv6 DST match");
+#endif
+MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+int ipv6_ext_hdr(u8 nexthdr)
+{
+        return ( (nexthdr == NEXTHDR_HOP)       ||
+                 (nexthdr == NEXTHDR_ROUTING)   ||
+                 (nexthdr == NEXTHDR_FRAGMENT)  ||
+                 (nexthdr == NEXTHDR_AUTH)      ||
+                 (nexthdr == NEXTHDR_ESP)       ||
+                 (nexthdr == NEXTHDR_NONE)      ||
+                 (nexthdr == NEXTHDR_DEST) );
+}
+
+/*
+ * (Type & 0xC0) >> 6
+ * 	0	-> ignorable
+ * 	1	-> must drop the packet
+ * 	2	-> send ICMP PARM PROB regardless and drop packet
+ * 	3	-> Send ICMP if not a multicast address and drop packet
+ *  (Type & 0x20) >> 5
+ *  	0	-> invariant
+ *  	1	-> can change the routing
+ *  (Type & 0x1F) Type
+ *      0	-> PAD0 (only 1 byte!)
+ *      1	-> PAD1 LENGTH info (total length = length + 2)
+ *      C0 | 2	-> JUMBO 4 x x x x ( xxxx > 64k )
+ *      5	-> RTALERT 2 x x
+ */
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *protohdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+       struct ipv6_opt_hdr *optsh = NULL;
+       const struct ip6t_opts *optinfo = matchinfo;
+       unsigned int temp;
+       unsigned int len;
+       u8 nexthdr;
+       unsigned int ptr;
+       unsigned int hdrlen = 0;
+       unsigned int ret = 0;
+       u_int16_t *optdesc = NULL;
+       
+       /* type of the 1st exthdr */
+       nexthdr = skb->nh.ipv6h->nexthdr;
+       /* pointer to the 1st exthdr */
+       ptr = sizeof(struct ipv6hdr);
+       /* available length */
+       len = skb->len - ptr;
+       temp = 0;
+
+        while (ipv6_ext_hdr(nexthdr)) {
+               struct ipv6_opt_hdr *hdr;
+
+              DEBUGP("ipv6_opts header iteration \n");
+
+              /* Is there enough space for the next ext header? */
+                if (len < (int)sizeof(struct ipv6_opt_hdr))
+                        return 0;
+              /* No more exthdr -> evaluate */
+                if (nexthdr == NEXTHDR_NONE) {
+                     break;
+              }
+              /* ESP -> evaluate */
+                if (nexthdr == NEXTHDR_ESP) {
+                     break;
+              }
+
+              hdr=(void *)(skb->data)+ptr;
+
+              /* Calculate the header length */
+                if (nexthdr == NEXTHDR_FRAGMENT) {
+                        hdrlen = 8;
+                } else if (nexthdr == NEXTHDR_AUTH)
+                        hdrlen = (hdr->hdrlen+2)<<2;
+                else
+                        hdrlen = ipv6_optlen(hdr);
+
+              /* OPTS -> evaluate */
+#if HOPBYHOP
+                if (nexthdr == NEXTHDR_HOP) {
+                     temp |= MASK_HOPOPTS;
+#else
+                if (nexthdr == NEXTHDR_DEST) {
+                     temp |= MASK_DSTOPTS;
+#endif
+                     break;
+              }
+
+
+              /* set the flag */
+              switch (nexthdr){
+                     case NEXTHDR_HOP:
+                     case NEXTHDR_ROUTING:
+                     case NEXTHDR_FRAGMENT:
+                     case NEXTHDR_AUTH:
+                     case NEXTHDR_DEST:
+                            break;
+                     default:
+                            DEBUGP("ipv6_opts match: unknown nextheader %u\n",nexthdr);
+                            return 0;
+                            break;
+              }
+
+                nexthdr = hdr->nexthdr;
+                len -= hdrlen;
+                ptr += hdrlen;
+		if ( ptr > skb->len ) {
+			DEBUGP("ipv6_opts: new pointer is too large! \n");
+			break;
+		}
+        }
+
+       /* OPTIONS header not found */
+#if HOPBYHOP
+       if ( temp != MASK_HOPOPTS ) return 0;
+#else
+       if ( temp != MASK_DSTOPTS ) return 0;
+#endif
+
+       if (len < (int)sizeof(struct ipv6_opt_hdr)){
+	       *hotdrop = 1;
+       		return 0;
+       }
+
+       if (len < hdrlen){
+	       /* Packet smaller than it's length field */
+       		return 0;
+       }
+
+       optsh=(void *)(skb->data)+ptr;
+
+       DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, optsh->hdrlen);
+
+       DEBUGP("len %02X %04X %02X ",
+       		optinfo->hdrlen, hdrlen,
+       		(!(optinfo->flags & IP6T_OPTS_LEN) ||
+                           ((optinfo->hdrlen == hdrlen) ^
+                           !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
+
+       ret = (optsh != NULL)
+       		&&
+	      	(!(optinfo->flags & IP6T_OPTS_LEN) ||
+                           ((optinfo->hdrlen == hdrlen) ^
+                           !!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
+
+       temp = len = 0;
+       ptr += 2;
+       hdrlen -= 2;
+       if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
+	       return ret;
+	} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
+		DEBUGP("Not strict - not implemented");
+	} else {
+		DEBUGP("Strict ");
+		DEBUGP("#%d ",optinfo->optsnr);
+		for(temp=0; temp<optinfo->optsnr; temp++){
+			optdesc = (void *)(skb->data)+ptr;
+			/* Type check */
+			if ( (unsigned char)*optdesc != 
+				(optinfo->opts[temp] & 0xFF00)>>8 ){
+				DEBUGP("Tbad %02X %02X\n",
+						(unsigned char)*optdesc,
+						(optinfo->opts[temp] &
+						 0xFF00)>>8);
+				return 0;
+			} else {
+				DEBUGP("Tok ");
+			}
+			/* Length check */
+			if (((optinfo->opts[temp] & 0x00FF) != 0xFF) &&
+				(unsigned char)*optdesc != 0){
+				if ( ntohs((u16)*optdesc) != 
+						optinfo->opts[temp] ){
+					DEBUGP("Lbad %02X %04X %04X\n",
+							(unsigned char)*optdesc,
+							ntohs((u16)*optdesc),
+							optinfo->opts[temp]);
+					return 0;
+				} else {
+					DEBUGP("Lok ");
+				}
+			}
+			/* Step to the next */
+			if ((unsigned char)*optdesc == 0){
+				DEBUGP("PAD0 \n");
+				ptr++;
+				hdrlen--;
+			} else {
+				ptr += LOW(ntohs(*optdesc));
+				hdrlen -= LOW(ntohs(*optdesc));
+				DEBUGP("len%04X \n", 
+					LOW(ntohs(*optdesc)));
+			}
+			if (ptr > skb->len || ( !hdrlen && 
+				(temp != optinfo->optsnr - 1))) {
+				DEBUGP("new pointer is too large! \n");
+				break;
+			}
+		}
+		if (temp == optinfo->optsnr)
+			return ret;
+		else return 0;
+	}
+
+	return 0;
+}
+
+/* Called when user tries to insert an entry of this type. */
+static int
+checkentry(const char *tablename,
+          const struct ip6t_ip6 *ip,
+          void *matchinfo,
+          unsigned int matchinfosize,
+          unsigned int hook_mask)
+{
+       const struct ip6t_opts *optsinfo = matchinfo;
+
+       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
+              DEBUGP("ip6t_opts: matchsize %u != %u\n",
+                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
+              return 0;
+       }
+       if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
+              DEBUGP("ip6t_opts: unknown flags %X\n",
+                      optsinfo->invflags);
+              return 0;
+       }
+
+       return 1;
+}
+
+static struct ip6t_match opts_match
+#if HOPBYHOP
+= { { NULL, NULL }, "hbh", &match, &checkentry, NULL, THIS_MODULE };
+#else
+= { { NULL, NULL }, "dst", &match, &checkentry, NULL, THIS_MODULE };
+#endif
+
+static int __init init(void)
+{
+       return ip6t_register_match(&opts_match);
+}
+
+static void __exit cleanup(void)
+{
+       ip6t_unregister_match(&opts_match);
+}
+
+module_init(init);
+module_exit(cleanup);
diff -Nru a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/netfilter/ip6t_esp.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,186 @@
+/* Kernel module to match ESP parameters. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/ipv6.h>
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_esp.h>
+
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv6 ESP match");
+MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+struct esphdr {
+	__u32   spi;
+};
+
+int ipv6_ext_hdr(u8 nexthdr)
+{
+        return ( (nexthdr == NEXTHDR_HOP)       ||
+                 (nexthdr == NEXTHDR_ROUTING)   ||
+                 (nexthdr == NEXTHDR_FRAGMENT)  ||
+                 (nexthdr == NEXTHDR_AUTH)      ||
+                 (nexthdr == NEXTHDR_ESP)       ||
+                 (nexthdr == NEXTHDR_NONE)      ||
+                 (nexthdr == NEXTHDR_DEST) );
+}
+
+/* Returns 1 if the spi is matched by the range, 0 otherwise */
+static inline int
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
+{
+	int r=0;
+        DEBUGP("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
+        	min,spi,max);
+	r=(spi >= min && spi <= max) ^ invert;
+	DEBUGP(" result %s\n",r? "PASS\n" : "FAILED\n");
+	return r;
+}
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *protohdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+	struct esphdr *esp = NULL;
+	const struct ip6t_esp *espinfo = matchinfo;
+	unsigned int temp;
+	int len;
+	u8 nexthdr;
+	unsigned int ptr;
+
+	/* Make sure this isn't an evil packet */
+	/*DEBUGP("ipv6_esp entered \n");*/
+
+	/* type of the 1st exthdr */
+	nexthdr = skb->nh.ipv6h->nexthdr;
+	/* pointer to the 1st exthdr */
+	ptr = sizeof(struct ipv6hdr);
+	/* available length */
+	len = skb->len - ptr;
+	temp = 0;
+
+        while (ipv6_ext_hdr(nexthdr)) {
+        	struct ipv6_opt_hdr *hdr;
+        	int hdrlen;
+
+		DEBUGP("ipv6_esp header iteration \n");
+
+		/* Is there enough space for the next ext header? */
+                if (len < (int)sizeof(struct ipv6_opt_hdr))
+                        return 0;
+		/* No more exthdr -> evaluate */
+                if (nexthdr == NEXTHDR_NONE) {
+			break;
+		}
+		/* ESP -> evaluate */
+                if (nexthdr == NEXTHDR_ESP) {
+			temp |= MASK_ESP;
+			break;
+		}
+
+		hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+
+		/* Calculate the header length */
+                if (nexthdr == NEXTHDR_FRAGMENT) {
+                        hdrlen = 8;
+                } else if (nexthdr == NEXTHDR_AUTH)
+                        hdrlen = (hdr->hdrlen+2)<<2;
+                else
+                        hdrlen = ipv6_optlen(hdr);
+
+		/* set the flag */
+		switch (nexthdr){
+			case NEXTHDR_HOP:
+			case NEXTHDR_ROUTING:
+			case NEXTHDR_FRAGMENT:
+			case NEXTHDR_AUTH:
+			case NEXTHDR_DEST:
+				break;
+			default:
+				DEBUGP("ipv6_esp match: unknown nextheader %u\n",nexthdr);
+				return 0;
+				break;
+		}
+
+                nexthdr = hdr->nexthdr;
+                len -= hdrlen;
+                ptr += hdrlen;
+		if ( ptr > skb->len ) {
+			DEBUGP("ipv6_esp: new pointer too large! \n");
+			break;
+		}
+        }
+
+	/* ESP header not found */
+	if ( temp != MASK_ESP ) return 0;
+
+       if (len < (int)sizeof(struct esphdr)){
+	       *hotdrop = 1;
+       		return 0;
+       }
+
+	esp=skb->data+ptr;
+
+	DEBUGP("IPv6 ESP SPI %u %08X\n", ntohl(esp->spi), ntohl(esp->spi));
+
+	return (esp != NULL)
+		&& spi_match(espinfo->spis[0], espinfo->spis[1],
+			      ntohl(esp->spi),
+			      !!(espinfo->invflags & IP6T_ESP_INV_SPI));
+}
+
+/* Called when user tries to insert an entry of this type. */
+static int
+checkentry(const char *tablename,
+	   const struct ip6t_ip6 *ip,
+	   void *matchinfo,
+	   unsigned int matchinfosize,
+	   unsigned int hook_mask)
+{
+	const struct ip6t_esp *espinfo = matchinfo;
+
+	if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_esp))) {
+		DEBUGP("ip6t_esp: matchsize %u != %u\n",
+			 matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_esp)));
+		return 0;
+	}
+	if (espinfo->invflags & ~IP6T_ESP_INV_MASK) {
+		DEBUGP("ip6t_esp: unknown flags %X\n",
+			 espinfo->invflags);
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct ip6t_match esp_match
+= { { NULL, NULL }, "esp", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	return ip6t_register_match(&esp_match);
+}
+
+static void __exit cleanup(void)
+{
+	ip6t_unregister_match(&esp_match);
+}
+
+module_init(init);
+module_exit(cleanup);
diff -Nru a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/netfilter/ip6t_frag.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,250 @@
+/* Kernel module to match FRAG parameters. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/ipv6.h>
+
+#include <asm/byteorder.h>
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_frag.h>
+
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv6 FRAG match");
+MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#if 0
+#if     BYTE_ORDER == BIG_ENDIAN
+#define IP6F_OFF_MASK       0xfff8  /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK  0x0006  /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG      0x0001  /* more-fragments flag */
+#else   /* BYTE_ORDER == LITTLE_ENDIAN */
+#define IP6F_OFF_MASK       0xf8ff  /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK  0x0600  /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG      0x0100  /* more-fragments flag */
+#endif
+#endif
+
+#define IP6F_OFF_MASK       0xf8ff  /* mask out offset from _offlg */
+#define IP6F_RESERVED_MASK  0x0600  /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG      0x0100  /* more-fragments flag */
+
+struct fraghdr {
+       __u8    nexthdr;
+       __u8    hdrlen;
+       __u16   info;
+       __u32   id;
+};
+
+int ipv6_ext_hdr(u8 nexthdr)
+{
+        return ( (nexthdr == NEXTHDR_HOP)       ||
+                 (nexthdr == NEXTHDR_ROUTING)   ||
+                 (nexthdr == NEXTHDR_FRAGMENT)  ||
+                 (nexthdr == NEXTHDR_AUTH)      ||
+                 (nexthdr == NEXTHDR_ESP)       ||
+                 (nexthdr == NEXTHDR_NONE)      ||
+                 (nexthdr == NEXTHDR_DEST) );
+}
+
+/* Returns 1 if the id is matched by the range, 0 otherwise */
+static inline int
+id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
+{
+       int r=0;
+       DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
+              min,id,max);
+       r=(id >= min && id <= max) ^ invert;
+       DEBUGP(" result %s\n",r? "PASS" : "FAILED");
+       return r;
+}
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *protohdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+       struct fraghdr *frag = NULL;
+       const struct ip6t_frag *fraginfo = matchinfo;
+       unsigned int temp;
+       int len;
+       u8 nexthdr;
+       unsigned int ptr;
+       unsigned int hdrlen = 0;
+
+       /* type of the 1st exthdr */
+       nexthdr = skb->nh.ipv6h->nexthdr;
+       /* pointer to the 1st exthdr */
+       ptr = sizeof(struct ipv6hdr);
+       /* available length */
+       len = skb->len - ptr;
+       temp = 0;
+
+        while (ipv6_ext_hdr(nexthdr)) {
+               struct ipv6_opt_hdr *hdr;
+
+              DEBUGP("ipv6_frag header iteration \n");
+
+              /* Is there enough space for the next ext header? */
+                if (len < (int)sizeof(struct ipv6_opt_hdr))
+                        return 0;
+              /* No more exthdr -> evaluate */
+                if (nexthdr == NEXTHDR_NONE) {
+                     break;
+              }
+              /* ESP -> evaluate */
+                if (nexthdr == NEXTHDR_ESP) {
+                     break;
+              }
+
+              hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+
+              /* Calculate the header length */
+                if (nexthdr == NEXTHDR_FRAGMENT) {
+                        hdrlen = 8;
+                } else if (nexthdr == NEXTHDR_AUTH)
+                        hdrlen = (hdr->hdrlen+2)<<2;
+                else
+                        hdrlen = ipv6_optlen(hdr);
+
+              /* FRAG -> evaluate */
+                if (nexthdr == NEXTHDR_FRAGMENT) {
+                     temp |= MASK_FRAGMENT;
+                     break;
+              }
+
+
+              /* set the flag */
+              switch (nexthdr){
+                     case NEXTHDR_HOP:
+                     case NEXTHDR_ROUTING:
+                     case NEXTHDR_FRAGMENT:
+                     case NEXTHDR_AUTH:
+                     case NEXTHDR_DEST:
+                            break;
+                     default:
+                            DEBUGP("ipv6_frag match: unknown nextheader %u\n",nexthdr);
+                            return 0;
+                            break;
+              }
+
+                nexthdr = hdr->nexthdr;
+                len -= hdrlen;
+                ptr += hdrlen;
+		if ( ptr > skb->len ) {
+			DEBUGP("ipv6_frag: new pointer too large! \n");
+			break;
+		}
+        }
+
+       /* FRAG header not found */
+       if ( temp != MASK_FRAGMENT ) return 0;
+
+       if (len < (int)sizeof(struct fraghdr)){
+	       *hotdrop = 1;
+       		return 0;
+       }
+
+       frag=skb->data+ptr;
+
+       DEBUGP("IPv6 FRAG LEN %u %u ", hdrlen, frag->hdrlen);
+       DEBUGP("INFO %04X ", frag->info);
+       DEBUGP("OFFSET %04X ", frag->info & IP6F_OFF_MASK);
+       DEBUGP("RES %04X ", frag->info & IP6F_RESERVED_MASK);
+       DEBUGP("MF %04X ", frag->info & IP6F_MORE_FRAG);
+       DEBUGP("ID %u %08X\n", ntohl(frag->id), ntohl(frag->id));
+
+       DEBUGP("IPv6 FRAG id %02X ",
+       		(id_match(fraginfo->ids[0], fraginfo->ids[1],
+                           ntohl(frag->id),
+                           !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))));
+       DEBUGP("len %02X %04X %02X ",
+       		fraginfo->hdrlen, hdrlen,
+       		(!fraginfo->hdrlen ||
+                           (fraginfo->hdrlen == hdrlen) ^
+                           !!(fraginfo->invflags & IP6T_FRAG_INV_LEN)));
+       DEBUGP("res %02X %02X %02X ", 
+       		(fraginfo->flags & IP6T_FRAG_RES), frag->info & IP6F_RESERVED_MASK,
+       		!((fraginfo->flags & IP6T_FRAG_RES) && (frag->info & IP6F_RESERVED_MASK)));
+       DEBUGP("first %02X %02X %02X ", 
+       		(fraginfo->flags & IP6T_FRAG_FST), frag->info & IP6F_OFF_MASK,
+       		!((fraginfo->flags & IP6T_FRAG_FST) && (frag->info & IP6F_OFF_MASK)));
+       DEBUGP("mf %02X %02X %02X ", 
+       		(fraginfo->flags & IP6T_FRAG_MF), frag->info & IP6F_MORE_FRAG,
+       		!((fraginfo->flags & IP6T_FRAG_MF) && !((frag->info & IP6F_MORE_FRAG))));
+       DEBUGP("last %02X %02X %02X\n", 
+       		(fraginfo->flags & IP6T_FRAG_NMF), frag->info & IP6F_MORE_FRAG,
+       		!((fraginfo->flags & IP6T_FRAG_NMF) && (frag->info & IP6F_MORE_FRAG)));
+
+       return (frag != NULL)
+       		&&
+       		(id_match(fraginfo->ids[0], fraginfo->ids[1],
+                           ntohl(frag->id),
+                           !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))
+		&&
+	      	(!fraginfo->hdrlen ||
+                           (fraginfo->hdrlen == hdrlen) ^
+                           !!(fraginfo->invflags & IP6T_FRAG_INV_LEN))
+		&&
+		!((fraginfo->flags & IP6T_FRAG_RES) && (frag->info & IP6F_RESERVED_MASK))
+		&&
+		!((fraginfo->flags & IP6T_FRAG_FST) && (frag->info & IP6F_OFF_MASK))
+		&&
+		!((fraginfo->flags & IP6T_FRAG_MF) && !((frag->info & IP6F_MORE_FRAG)))
+		&&
+		!((fraginfo->flags & IP6T_FRAG_NMF) && (frag->info & IP6F_MORE_FRAG));
+}
+
+/* Called when user tries to insert an entry of this type. */
+static int
+checkentry(const char *tablename,
+          const struct ip6t_ip6 *ip,
+          void *matchinfo,
+          unsigned int matchinfosize,
+          unsigned int hook_mask)
+{
+       const struct ip6t_frag *fraginfo = matchinfo;
+
+       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_frag))) {
+              DEBUGP("ip6t_frag: matchsize %u != %u\n",
+                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_frag)));
+              return 0;
+       }
+       if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
+              DEBUGP("ip6t_frag: unknown flags %X\n",
+                      fraginfo->invflags);
+              return 0;
+       }
+
+       return 1;
+}
+
+static struct ip6t_match frag_match
+= { { NULL, NULL }, "frag", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+       return ip6t_register_match(&frag_match);
+}
+
+static void __exit cleanup(void)
+{
+       ip6t_unregister_match(&frag_match);
+}
+
+module_init(init);
+module_exit(cleanup);
diff -Nru a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/netfilter/ip6t_hbh.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,287 @@
+/* Kernel module to match Hop-by-Hop and Destination parameters. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/ipv6.h>
+
+#include <asm/byteorder.h>
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_opts.h>
+
+#define LOW(n)		(n & 0x00FF)
+
+#define HOPBYHOP	1
+
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
+#if HOPBYHOP
+MODULE_DESCRIPTION("IPv6 HbH match");
+#else
+MODULE_DESCRIPTION("IPv6 DST match");
+#endif
+MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+int ipv6_ext_hdr(u8 nexthdr)
+{
+        return ( (nexthdr == NEXTHDR_HOP)       ||
+                 (nexthdr == NEXTHDR_ROUTING)   ||
+                 (nexthdr == NEXTHDR_FRAGMENT)  ||
+                 (nexthdr == NEXTHDR_AUTH)      ||
+                 (nexthdr == NEXTHDR_ESP)       ||
+                 (nexthdr == NEXTHDR_NONE)      ||
+                 (nexthdr == NEXTHDR_DEST) );
+}
+
+/*
+ * (Type & 0xC0) >> 6
+ * 	0	-> ignorable
+ * 	1	-> must drop the packet
+ * 	2	-> send ICMP PARM PROB regardless and drop packet
+ * 	3	-> Send ICMP if not a multicast address and drop packet
+ *  (Type & 0x20) >> 5
+ *  	0	-> invariant
+ *  	1	-> can change the routing
+ *  (Type & 0x1F) Type
+ *      0	-> PAD0 (only 1 byte!)
+ *      1	-> PAD1 LENGTH info (total length = length + 2)
+ *      C0 | 2	-> JUMBO 4 x x x x ( xxxx > 64k )
+ *      5	-> RTALERT 2 x x
+ */
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *protohdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+       struct ipv6_opt_hdr *optsh = NULL;
+       const struct ip6t_opts *optinfo = matchinfo;
+       unsigned int temp;
+       unsigned int len;
+       u8 nexthdr;
+       unsigned int ptr;
+       unsigned int hdrlen = 0;
+       unsigned int ret = 0;
+       u_int16_t *optdesc = NULL;
+       
+       /* type of the 1st exthdr */
+       nexthdr = skb->nh.ipv6h->nexthdr;
+       /* pointer to the 1st exthdr */
+       ptr = sizeof(struct ipv6hdr);
+       /* available length */
+       len = skb->len - ptr;
+       temp = 0;
+
+        while (ipv6_ext_hdr(nexthdr)) {
+               struct ipv6_opt_hdr *hdr;
+
+              DEBUGP("ipv6_opts header iteration \n");
+
+              /* Is there enough space for the next ext header? */
+                if (len < (int)sizeof(struct ipv6_opt_hdr))
+                        return 0;
+              /* No more exthdr -> evaluate */
+                if (nexthdr == NEXTHDR_NONE) {
+                     break;
+              }
+              /* ESP -> evaluate */
+                if (nexthdr == NEXTHDR_ESP) {
+                     break;
+              }
+
+              hdr=(void *)(skb->data)+ptr;
+
+              /* Calculate the header length */
+                if (nexthdr == NEXTHDR_FRAGMENT) {
+                        hdrlen = 8;
+                } else if (nexthdr == NEXTHDR_AUTH)
+                        hdrlen = (hdr->hdrlen+2)<<2;
+                else
+                        hdrlen = ipv6_optlen(hdr);
+
+              /* OPTS -> evaluate */
+#if HOPBYHOP
+                if (nexthdr == NEXTHDR_HOP) {
+                     temp |= MASK_HOPOPTS;
+#else
+                if (nexthdr == NEXTHDR_DEST) {
+                     temp |= MASK_DSTOPTS;
+#endif
+                     break;
+              }
+
+
+              /* set the flag */
+              switch (nexthdr){
+                     case NEXTHDR_HOP:
+                     case NEXTHDR_ROUTING:
+                     case NEXTHDR_FRAGMENT:
+                     case NEXTHDR_AUTH:
+                     case NEXTHDR_DEST:
+                            break;
+                     default:
+                            DEBUGP("ipv6_opts match: unknown nextheader %u\n",nexthdr);
+                            return 0;
+                            break;
+              }
+
+                nexthdr = hdr->nexthdr;
+                len -= hdrlen;
+                ptr += hdrlen;
+		if ( ptr > skb->len ) {
+			DEBUGP("ipv6_opts: new pointer is too large! \n");
+			break;
+		}
+        }
+
+       /* OPTIONS header not found */
+#if HOPBYHOP
+       if ( temp != MASK_HOPOPTS ) return 0;
+#else
+       if ( temp != MASK_DSTOPTS ) return 0;
+#endif
+
+       if (len < (int)sizeof(struct ipv6_opt_hdr)){
+	       *hotdrop = 1;
+       		return 0;
+       }
+
+       if (len < hdrlen){
+	       /* Packet smaller than it's length field */
+       		return 0;
+       }
+
+       optsh=(void *)(skb->data)+ptr;
+
+       DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, optsh->hdrlen);
+
+       DEBUGP("len %02X %04X %02X ",
+       		optinfo->hdrlen, hdrlen,
+       		(!(optinfo->flags & IP6T_OPTS_LEN) ||
+                           ((optinfo->hdrlen == hdrlen) ^
+                           !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
+
+       ret = (optsh != NULL)
+       		&&
+	      	(!(optinfo->flags & IP6T_OPTS_LEN) ||
+                           ((optinfo->hdrlen == hdrlen) ^
+                           !!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
+
+       temp = len = 0;
+       ptr += 2;
+       hdrlen -= 2;
+       if ( !(optinfo->flags & IP6T_OPTS_OPTS) ){
+	       return ret;
+	} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
+		DEBUGP("Not strict - not implemented");
+	} else {
+		DEBUGP("Strict ");
+		DEBUGP("#%d ",optinfo->optsnr);
+		for(temp=0; temp<optinfo->optsnr; temp++){
+			optdesc = (void *)(skb->data)+ptr;
+			/* Type check */
+			if ( (unsigned char)*optdesc != 
+				(optinfo->opts[temp] & 0xFF00)>>8 ){
+				DEBUGP("Tbad %02X %02X\n",
+						(unsigned char)*optdesc,
+						(optinfo->opts[temp] &
+						 0xFF00)>>8);
+				return 0;
+			} else {
+				DEBUGP("Tok ");
+			}
+			/* Length check */
+			if (((optinfo->opts[temp] & 0x00FF) != 0xFF) &&
+				(unsigned char)*optdesc != 0){
+				if ( ntohs((u16)*optdesc) != 
+						optinfo->opts[temp] ){
+					DEBUGP("Lbad %02X %04X %04X\n",
+							(unsigned char)*optdesc,
+							ntohs((u16)*optdesc),
+							optinfo->opts[temp]);
+					return 0;
+				} else {
+					DEBUGP("Lok ");
+				}
+			}
+			/* Step to the next */
+			if ((unsigned char)*optdesc == 0){
+				DEBUGP("PAD0 \n");
+				ptr++;
+				hdrlen--;
+			} else {
+				ptr += LOW(ntohs(*optdesc));
+				hdrlen -= LOW(ntohs(*optdesc));
+				DEBUGP("len%04X \n", 
+					LOW(ntohs(*optdesc)));
+			}
+			if (ptr > skb->len || ( !hdrlen && 
+				(temp != optinfo->optsnr - 1))) {
+				DEBUGP("new pointer is too large! \n");
+				break;
+			}
+		}
+		if (temp == optinfo->optsnr)
+			return ret;
+		else return 0;
+	}
+
+	return 0;
+}
+
+/* Called when user tries to insert an entry of this type. */
+static int
+checkentry(const char *tablename,
+          const struct ip6t_ip6 *ip,
+          void *matchinfo,
+          unsigned int matchinfosize,
+          unsigned int hook_mask)
+{
+       const struct ip6t_opts *optsinfo = matchinfo;
+
+       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_opts))) {
+              DEBUGP("ip6t_opts: matchsize %u != %u\n",
+                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_opts)));
+              return 0;
+       }
+       if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
+              DEBUGP("ip6t_opts: unknown flags %X\n",
+                      optsinfo->invflags);
+              return 0;
+       }
+
+       return 1;
+}
+
+static struct ip6t_match opts_match
+#if HOPBYHOP
+= { { NULL, NULL }, "hbh", &match, &checkentry, NULL, THIS_MODULE };
+#else
+= { { NULL, NULL }, "dst", &match, &checkentry, NULL, THIS_MODULE };
+#endif
+
+static int __init init(void)
+{
+       return ip6t_register_match(&opts_match);
+}
+
+static void __exit cleanup(void)
+{
+       ip6t_unregister_match(&opts_match);
+}
+
+module_init(init);
+module_exit(cleanup);
diff -Nru a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/netfilter/ip6t_hl.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,74 @@
+/*
+ * Hop Limit matching module
+ * Maciej Soltysiak <solt@dns.toxicfilms.tv>
+ * Based on HW's ttl module
+ *
+ * This software is distributed under the terms  GNU GPL
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+
+#include <linux/netfilter_ipv6/ip6t_hl.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
+MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
+MODULE_DESCRIPTION("IP tables Hop Limit matching module");
+MODULE_LICENSE("GPL");
+
+static int match(const struct sk_buff *skb, const struct net_device *in,
+		 const struct net_device *out, const void *matchinfo,
+		 int offset, const void *hdr, u_int16_t datalen,
+		 int *hotdrop)
+{
+	const struct ip6t_hl_info *info = matchinfo;
+	const struct ipv6hdr *ip6h = skb->nh.ipv6h;
+
+	switch (info->mode) {
+		case IP6T_HL_EQ:
+			return (ip6h->hop_limit == info->hop_limit);
+			break;
+		case IP6T_HL_NE:
+			return (!(ip6h->hop_limit == info->hop_limit));
+			break;
+		case IP6T_HL_LT:
+			return (ip6h->hop_limit < info->hop_limit);
+			break;
+		case IP6T_HL_GT:
+			return (ip6h->hop_limit > info->hop_limit);
+			break;
+		default:
+			printk(KERN_WARNING "ip6t_hl: unknown mode %d\n", 
+				info->mode);
+			return 0;
+	}
+
+	return 0;
+}
+
+static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
+		      void *matchinfo, unsigned int matchsize,
+		      unsigned int hook_mask)
+{
+	if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_hl_info)))
+		return 0;
+
+	return 1;
+}
+
+static struct ip6t_match hl_match = { { NULL, NULL }, "hl", &match,
+		&checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+	return ip6t_register_match(&hl_match);
+}
+
+static void __exit fini(void)
+{
+	ip6t_unregister_match(&hl_match);
+
+}
+
+module_init(init);
+module_exit(fini);
diff -Nru a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,222 @@
+/* ipv6header match - matches IPv6 packets based
+on whether they contain certain headers */
+
+/* Original idea: Brad Chapman 
+ * Rewritten by: Andras Kis-Szabo <kisza@sch.bme.hu> */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/ipv6.h>
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_ipv6header.h>
+
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv6 headers match");
+MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+int ipv6_ext_hdr(u8 nexthdr)
+{
+        return ( (nexthdr == NEXTHDR_HOP)       ||
+                 (nexthdr == NEXTHDR_ROUTING)   ||
+                 (nexthdr == NEXTHDR_FRAGMENT)  ||
+                 (nexthdr == NEXTHDR_AUTH)      ||
+                 (nexthdr == NEXTHDR_ESP)       ||
+                 (nexthdr == NEXTHDR_NONE)      ||
+                 (nexthdr == NEXTHDR_DEST) );
+}
+
+static int
+ipv6header_match(const struct sk_buff *skb,
+		 const struct net_device *in,
+		 const struct net_device *out,
+		 const void *matchinfo,
+		 int offset,
+		 const void *protohdr,
+		 u_int16_t datalen,
+		 int *hotdrop)
+{
+	const struct ip6t_ipv6header_info *info = matchinfo;
+	unsigned int temp;
+	int len;
+	u8 nexthdr;
+	unsigned int ptr;
+        struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+
+	/* Make sure this isn't an evil packet */
+	DEBUGP("ipv6_header entered \n");
+
+	/* type of the 1st exthdr */
+	nexthdr = skb->nh.ipv6h->nexthdr;
+	/* pointer to the 1st exthdr */
+	ptr = sizeof(struct ipv6hdr);
+	/* available length */
+	len = skb->len - ptr;
+	temp = 0;
+
+	DEBUGP("ipv6_header nexthdr %02X \n",nexthdr);
+	DEBUGP("ipv6_header ptr %08X \n",ptr);
+	DEBUGP("ipv6_header skblen %04X \n",skb->len);
+	DEBUGP("ipv6_header skbdatalen %04X \n",skb->data_len);
+	DEBUGP("ipv6_header len %04X \n",len);
+#if 0
+	for (temp=0;temp<skb->len;temp++){
+		if (!(temp % 16 )) DEBUGP("\nipv6_header data ");
+		DEBUGP("%02X ",skb->data[temp]);
+	}
+#endif
+	DEBUGP("\nipv6_header h.raw %02X %02X %02X %02X \n",
+			skb->h.raw[0],
+			skb->h.raw[1],
+			skb->h.raw[2],
+			skb->h.raw[3]);
+	DEBUGP("ipv6_header nh.raw %02X %02X %02X %02X \n",
+			skb->nh.raw[0],
+			skb->nh.raw[1],
+			skb->nh.raw[2],
+			skb->nh.raw[3]);
+	DEBUGP("ipv6_header CB %02X %02X %02X %02X %02X %02X %02X \n",
+			opt->iif,
+			opt->ra,
+			opt->hop,
+			opt->auth,
+			opt->dst0,
+			opt->srcrt,
+			opt->dst1);
+
+	temp = 0;
+
+        while (ipv6_ext_hdr(nexthdr)) {
+        	struct ipv6_opt_hdr *hdr;
+        	int hdrlen;
+
+		DEBUGP("ipv6_header header iteration \n");
+
+		/* Is there enough space for the next ext header? */
+                if (len < (int)sizeof(struct ipv6_opt_hdr))
+                        return 0;
+		/* No more exthdr -> evaluate */
+                if (nexthdr == NEXTHDR_NONE) {
+			temp |= MASK_NONE;
+			break;
+		}
+		/* ESP -> evaluate */
+                if (nexthdr == NEXTHDR_ESP) {
+			temp |= MASK_ESP;
+			break;
+		}
+
+		hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+
+		/* Calculate the header length */
+                if (nexthdr == NEXTHDR_FRAGMENT) {
+                        hdrlen = 8;
+                } else if (nexthdr == NEXTHDR_AUTH)
+                        hdrlen = (hdr->hdrlen+2)<<2;
+                else
+                        hdrlen = ipv6_optlen(hdr);
+
+		DEBUGP("ipv6_header hdrlen %04X \n",hdrlen);
+
+		/* set the flag */
+		switch (nexthdr){
+			case NEXTHDR_HOP:
+				temp |= MASK_HOPOPTS;
+				break;
+			case NEXTHDR_ROUTING:
+				temp |= MASK_ROUTING;
+				break;
+			case NEXTHDR_FRAGMENT:
+				temp |= MASK_FRAGMENT;
+				break;
+			case NEXTHDR_AUTH:
+				temp |= MASK_AH;
+				break;
+			case NEXTHDR_DEST:
+				temp |= MASK_DSTOPTS;
+				break;
+			default:
+				DEBUGP("IPV6HEADER match: unknown nextheader %u\n",nexthdr);
+				return 0;
+				break;
+		}
+
+                nexthdr = hdr->nexthdr;
+                len -= hdrlen;
+                ptr += hdrlen;
+		if ( ptr > skb->len ) {
+			DEBUGP("ipv6_header new ptr %04X \n",ptr);
+			break;
+		}
+        }
+
+	if ( (nexthdr != NEXTHDR_NONE ) && (nexthdr != NEXTHDR_ESP) )
+		temp |= MASK_PROTO;
+
+	DEBUGP ("ipv6header: %02X %02X \n", temp, info->matchflags);
+
+	if (info->modeflag)
+		return (!( (temp & info->matchflags)
+			^ info->matchflags) ^ info->invflags);
+	else
+		return (!( temp ^ info->matchflags) ^ info->invflags);
+}
+
+static int
+ipv6header_checkentry(const char *tablename,
+		      const struct ip6t_ip6 *ip,
+		      void *matchinfo,
+		      unsigned int matchsize,
+		      unsigned int hook_mask)
+{
+	/* Check for obvious errors */
+	/* This match is valid in all hooks! */
+	if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_ipv6header_info))) {
+		DEBUGP("ip6t_ipv6header: matchsize != %u\n",
+			 IP6T_ALIGN(sizeof(struct ip6t_ipv6header_info)));
+		return 0;
+	}
+
+	return 1;
+}
+
+static void
+ipv6header_destroy(void *matchinfo,
+		   unsigned int matchinfosize)
+{
+	return;
+}
+
+static struct ip6t_match
+ip6t_ipv6header_match = {
+	{ NULL, NULL },
+	"ipv6header",
+	&ipv6header_match,
+	&ipv6header_checkentry,
+	&ipv6header_destroy,
+	THIS_MODULE
+};
+
+static int  __init ipv6header_init(void)
+{
+	return ip6t_register_match(&ip6t_ipv6header_match);
+}
+
+static void __exit ipv6header_exit(void)
+{
+	ip6t_unregister_match(&ip6t_ipv6header_match);
+}
+
+module_init(ipv6header_init);
+module_exit(ipv6header_exit);
+
diff -Nru a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/netfilter/ip6t_rt.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,305 @@
+/* Kernel module to match ROUTING parameters. */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/ipv6.h>
+
+#include <asm/byteorder.h>
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_rt.h>
+
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv6 RT match");
+MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+int ipv6_ext_hdr(u8 nexthdr)
+{
+        return ( (nexthdr == NEXTHDR_HOP)       ||
+                 (nexthdr == NEXTHDR_ROUTING)   ||
+                 (nexthdr == NEXTHDR_FRAGMENT)  ||
+                 (nexthdr == NEXTHDR_AUTH)      ||
+                 (nexthdr == NEXTHDR_ESP)       ||
+                 (nexthdr == NEXTHDR_NONE)      ||
+                 (nexthdr == NEXTHDR_DEST) );
+}
+
+/* Returns 1 if the id is matched by the range, 0 otherwise */
+static inline int
+segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
+{
+       int r=0;
+       DEBUGP("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
+              min,id,max);
+       r=(id >= min && id <= max) ^ invert;
+       DEBUGP(" result %s\n",r? "PASS" : "FAILED");
+       return r;
+}
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      const void *protohdr,
+      u_int16_t datalen,
+      int *hotdrop)
+{
+       struct ipv6_rt_hdr *route = NULL;
+       const struct ip6t_rt *rtinfo = matchinfo;
+       unsigned int temp;
+       unsigned int len;
+       u8 nexthdr;
+       unsigned int ptr;
+       unsigned int hdrlen = 0;
+       unsigned int ret = 0;
+
+       /* type of the 1st exthdr */
+       nexthdr = skb->nh.ipv6h->nexthdr;
+       /* pointer to the 1st exthdr */
+       ptr = sizeof(struct ipv6hdr);
+       /* available length */
+       len = skb->len - ptr;
+       temp = 0;
+
+        while (ipv6_ext_hdr(nexthdr)) {
+               struct ipv6_opt_hdr *hdr;
+
+              DEBUGP("ipv6_rt header iteration \n");
+
+              /* Is there enough space for the next ext header? */
+                if (len < (int)sizeof(struct ipv6_opt_hdr))
+                        return 0;
+              /* No more exthdr -> evaluate */
+                if (nexthdr == NEXTHDR_NONE) {
+                     break;
+              }
+              /* ESP -> evaluate */
+                if (nexthdr == NEXTHDR_ESP) {
+                     break;
+              }
+
+              hdr=(struct ipv6_opt_hdr *)skb->data+ptr;
+
+              /* Calculate the header length */
+                if (nexthdr == NEXTHDR_FRAGMENT) {
+                        hdrlen = 8;
+                } else if (nexthdr == NEXTHDR_AUTH)
+                        hdrlen = (hdr->hdrlen+2)<<2;
+                else
+                        hdrlen = ipv6_optlen(hdr);
+
+              /* ROUTING -> evaluate */
+                if (nexthdr == NEXTHDR_ROUTING) {
+                     temp |= MASK_ROUTING;
+                     break;
+              }
+
+
+              /* set the flag */
+              switch (nexthdr){
+                     case NEXTHDR_HOP:
+                     case NEXTHDR_ROUTING:
+                     case NEXTHDR_FRAGMENT:
+                     case NEXTHDR_AUTH:
+                     case NEXTHDR_DEST:
+                            break;
+                     default:
+                            DEBUGP("ipv6_rt match: unknown nextheader %u\n",nexthdr);
+                            return 0;
+                            break;
+              }
+
+                nexthdr = hdr->nexthdr;
+                len -= hdrlen;
+                ptr += hdrlen;
+		if ( ptr > skb->len ) {
+			DEBUGP("ipv6_rt: new pointer is too large! \n");
+			break;
+		}
+        }
+
+       /* ROUTING header not found */
+       if ( temp != MASK_ROUTING ) return 0;
+
+       if (len < (int)sizeof(struct ipv6_rt_hdr)){
+	       *hotdrop = 1;
+       		return 0;
+       }
+
+       if (len < hdrlen){
+	       /* Pcket smaller than its length field */
+       		return 0;
+       }
+
+       route=skb->data+ptr;
+
+       DEBUGP("IPv6 RT LEN %u %u ", hdrlen, route->hdrlen);
+       DEBUGP("TYPE %04X ", route->type);
+       DEBUGP("SGS_LEFT %u %08X\n", ntohl(route->segments_left), ntohl(route->segments_left));
+
+       DEBUGP("IPv6 RT segsleft %02X ",
+       		(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
+                           ntohl(route->segments_left),
+                           !!(rtinfo->invflags & IP6T_RT_INV_SGS))));
+       DEBUGP("type %02X %02X %02X ",
+       		rtinfo->rt_type, route->type, 
+       		(!(rtinfo->flags & IP6T_RT_TYP) ||
+                           ((rtinfo->rt_type == route->type) ^
+                           !!(rtinfo->invflags & IP6T_RT_INV_TYP))));
+       DEBUGP("len %02X %04X %02X ",
+       		rtinfo->hdrlen, hdrlen,
+       		(!(rtinfo->flags & IP6T_RT_LEN) ||
+                           ((rtinfo->hdrlen == hdrlen) ^
+                           !!(rtinfo->invflags & IP6T_RT_INV_LEN))));
+       DEBUGP("res %02X %02X %02X ", 
+       		(rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)route)->bitmap,
+       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->bitmap)));
+
+       ret = (route != NULL)
+       		&&
+       		(segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
+                           ntohl(route->segments_left),
+                           !!(rtinfo->invflags & IP6T_RT_INV_SGS)))
+		&&
+	      	(!(rtinfo->flags & IP6T_RT_LEN) ||
+                           ((rtinfo->hdrlen == hdrlen) ^
+                           !!(rtinfo->invflags & IP6T_RT_INV_LEN)))
+		&&
+       		(!(rtinfo->flags & IP6T_RT_TYP) ||
+                           ((rtinfo->rt_type == route->type) ^
+                           !!(rtinfo->invflags & IP6T_RT_INV_TYP)))
+		&&
+       		!((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->bitmap));
+
+	DEBUGP("#%d ",rtinfo->addrnr);
+       temp = len = ptr = 0;
+       if ( !(rtinfo->flags & IP6T_RT_FST) ){
+	       return ret;
+	} else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) {
+		DEBUGP("Not strict ");
+		if ( rtinfo->addrnr > (unsigned int)((hdrlen-8)/16) ){
+			DEBUGP("There isn't enough space\n");
+			return 0;
+		} else {
+			DEBUGP("#%d ",rtinfo->addrnr);
+			ptr = 0;
+			for(temp=0; temp<(unsigned int)((hdrlen-8)/16); temp++){
+				len = 0;
+				while ((u8)(((struct rt0_hdr *)route)->
+						addr[temp].s6_addr[len]) ==
+					(u8)(rtinfo->addrs[ptr].s6_addr[len])){
+					DEBUGP("%02X?%02X ",
+		(u8)(((struct rt0_hdr *)route)->addr[temp].s6_addr[len]),
+					(u8)(rtinfo->addrs[ptr].s6_addr[len]));
+					len++;
+					if ( len == 16 ) break;
+				}
+				if (len==16) {
+					DEBUGP("ptr=%d temp=%d;\n",ptr,temp);
+					ptr++;
+				} else {
+					DEBUGP("%02X?%02X ",
+		(u8)(((struct rt0_hdr *)route)->addr[temp].s6_addr[len]),
+					(u8)(rtinfo->addrs[ptr].s6_addr[len]));
+					DEBUGP("!ptr=%d temp=%d;\n",ptr,temp);
+				}
+				if (ptr==rtinfo->addrnr) break;
+			}
+			DEBUGP("ptr=%d len=%d #%d\n",ptr,len, rtinfo->addrnr);
+			if ( (len == 16) && (ptr == rtinfo->addrnr))
+				return ret;
+			else return 0;
+		}
+	} else {
+		DEBUGP("Strict ");
+		if ( rtinfo->addrnr > (unsigned int)((hdrlen-8)/16) ){
+			DEBUGP("There isn't enough space\n");
+			return 0;
+		} else {
+			DEBUGP("#%d ",rtinfo->addrnr);
+			for(temp=0; temp<rtinfo->addrnr; temp++){
+				len = 0;
+				while ((u8)(((struct rt0_hdr *)route)->
+						addr[temp].s6_addr[len]) ==
+					(u8)(rtinfo->addrs[temp].s6_addr[len])){
+					DEBUGP("%02X?%02X ",
+		(u8)(((struct rt0_hdr *)route)->addr[temp].s6_addr[len]),
+					(u8)(rtinfo->addrs[temp].s6_addr[len]));
+					len++;
+					if ( len == 16 ) break;
+				}
+				if (len!=16) {
+					DEBUGP("%02X?%02X ",
+		(u8)(((struct rt0_hdr *)route)->addr[temp].s6_addr[len]),
+					(u8)(rtinfo->addrs[temp].s6_addr[len]));
+					DEBUGP("!len=%d temp=%d;\n",len,temp);
+					break;
+				}
+			}
+			DEBUGP("temp=%d len=%d #%d\n",temp,len,rtinfo->addrnr);
+			if ( (len == 16) && (temp == rtinfo->addrnr) && (temp == (unsigned int)((hdrlen-8)/16)))
+				return ret;
+			else return 0;
+		}
+	}
+
+	return 0;
+}
+
+/* Called when user tries to insert an entry of this type. */
+static int
+checkentry(const char *tablename,
+          const struct ip6t_ip6 *ip,
+          void *matchinfo,
+          unsigned int matchinfosize,
+          unsigned int hook_mask)
+{
+       const struct ip6t_rt *rtinfo = matchinfo;
+
+       if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_rt))) {
+              DEBUGP("ip6t_rt: matchsize %u != %u\n",
+                      matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_rt)));
+              return 0;
+       }
+       if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
+              DEBUGP("ip6t_rt: unknown flags %X\n",
+                      rtinfo->invflags);
+              return 0;
+       }
+       if ( (rtinfo->flags & (IP6T_RT_RES|IP6T_RT_FST_MASK)) && 
+		       (!(rtinfo->flags & IP6T_RT_TYP) || 
+		       (rtinfo->rt_type != 0) || 
+		       (rtinfo->invflags & IP6T_RT_INV_TYP)) ) {
+	      DEBUGP("`--rt-type 0' required before `--rt-0-*'");
+              return 0;
+       }
+
+       return 1;
+}
+
+static struct ip6t_match rt_match
+= { { NULL, NULL }, "rt", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+       return ip6t_register_match(&rt_match);
+}
+
+static void __exit cleanup(void)
+{
+       ip6t_unregister_match(&rt_match);
+}
+
+module_init(init);
+module_exit(cleanup);
diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c
--- a/net/ipv6/route.c	Tue Mar  4 19:30:12 2003
+++ b/net/ipv6/route.c	Tue Mar  4 19:30:12 2003
@@ -1777,34 +1777,84 @@
 }
 
 ctl_table ipv6_route_table[] = {
-        {NET_IPV6_ROUTE_FLUSH, "flush",
-         &flush_delay, sizeof(int), 0644, NULL,
-         &ipv6_sysctl_rtcache_flush},
-	{NET_IPV6_ROUTE_GC_THRESH, "gc_thresh",
-         &ip6_dst_ops.gc_thresh, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-	{NET_IPV6_ROUTE_MAX_SIZE, "max_size",
-         &ip6_rt_max_size, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-	{NET_IPV6_ROUTE_GC_MIN_INTERVAL, "gc_min_interval",
-         &ip6_rt_gc_min_interval, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV6_ROUTE_GC_TIMEOUT, "gc_timeout",
-         &ip6_rt_gc_timeout, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV6_ROUTE_GC_INTERVAL, "gc_interval",
-         &ip6_rt_gc_interval, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV6_ROUTE_GC_ELASTICITY, "gc_elasticity",
-         &ip6_rt_gc_elasticity, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV6_ROUTE_MTU_EXPIRES, "mtu_expires",
-         &ip6_rt_mtu_expires, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV6_ROUTE_MIN_ADVMSS, "min_adv_mss",
-         &ip6_rt_min_advmss, sizeof(int), 0644, NULL,
-         &proc_dointvec_jiffies, &sysctl_jiffies},
-	 {0}
+        {
+		.ctl_name	=	NET_IPV6_ROUTE_FLUSH, 
+		.procname	=	"flush",
+         	.data		=	&flush_delay,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&ipv6_sysctl_rtcache_flush
+	},
+	{
+		.ctl_name	=	NET_IPV6_ROUTE_GC_THRESH,
+		.procname	=	"gc_thresh",
+         	.data		=	&ip6_dst_ops.gc_thresh,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&proc_dointvec,
+	},
+	{
+		.ctl_name	=	NET_IPV6_ROUTE_MAX_SIZE,
+		.procname	=	"max_size",
+         	.data		=	&ip6_rt_max_size,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&proc_dointvec,
+	},
+	{
+		.ctl_name	=	NET_IPV6_ROUTE_GC_MIN_INTERVAL,
+		.procname	=	"gc_min_interval",
+         	.data		=	&ip6_rt_gc_min_interval,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&proc_dointvec_jiffies,
+		.strategy	=	&sysctl_jiffies,
+	},
+	{
+		.ctl_name	=	NET_IPV6_ROUTE_GC_TIMEOUT,
+		.procname	=	"gc_timeout",
+         	.data		=	&ip6_rt_gc_timeout,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&proc_dointvec_jiffies,
+		.strategy	=	&sysctl_jiffies,
+	},
+	{
+		.ctl_name	=	NET_IPV6_ROUTE_GC_INTERVAL,
+		.procname	=	"gc_interval",
+         	.data		=	&ip6_rt_gc_interval,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&proc_dointvec_jiffies,
+		.strategy	=	&sysctl_jiffies,
+	},
+	{
+		.ctl_name	=	NET_IPV6_ROUTE_GC_ELASTICITY,
+		.procname	=	"gc_elasticity",
+         	.data		=	&ip6_rt_gc_elasticity,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&proc_dointvec_jiffies,
+		.strategy	=	&sysctl_jiffies,
+	},
+	{
+		.ctl_name	=	NET_IPV6_ROUTE_MTU_EXPIRES,
+		.procname	=	"mtu_expires",
+         	.data		=	&ip6_rt_mtu_expires,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&proc_dointvec_jiffies,
+		.strategy	=	&sysctl_jiffies,
+	},
+	{
+		.ctl_name	=	NET_IPV6_ROUTE_MIN_ADVMSS,
+		.procname	=	"min_adv_mss",
+         	.data		=	&ip6_rt_min_advmss,
+		.maxlen		=	sizeof(int),
+		.mode		=	0644,
+         	.proc_handler	=	&proc_dointvec_jiffies,
+		.strategy	=	&sysctl_jiffies,
+	},
 };
 
 #endif
diff -Nru a/net/ipv6/sit.c b/net/ipv6/sit.c
--- a/net/ipv6/sit.c	Tue Mar  4 19:30:13 2003
+++ b/net/ipv6/sit.c	Tue Mar  4 19:30:13 2003
@@ -68,7 +68,8 @@
 };
 
 static struct ip_tunnel ipip6_fb_tunnel = {
-	NULL, &ipip6_fb_tunnel_dev, {0, }, 0, 0, 0, 0, 0, 0, 0, {"sit0", }
+	.dev = &ipip6_fb_tunnel_dev,
+	.parms = { .name = "sit0" }
 };
 
 static struct ip_tunnel *tunnels_r_l[HASH_SIZE];
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c	Tue Mar  4 19:30:05 2003
+++ b/net/ipx/af_ipx.c	Tue Mar  4 19:30:05 2003
@@ -684,7 +684,7 @@
 	if (ipx->ipx_source.net != intrfc->if_netnum) {
 		/*
 		 * Unshare the buffer before modifying the count in
-		 * case its a flood or tcpdump
+		 * case it's a flood or tcpdump
 		 */
 		skb = skb_unshare(skb, GFP_ATOMIC);
 		if (!skb)
diff -Nru a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c
--- a/net/irda/irlmp_event.c	Tue Mar  4 19:30:05 2003
+++ b/net/irda/irlmp_event.c	Tue Mar  4 19:30:05 2003
@@ -423,7 +423,7 @@
 			/* We don't want to change state just yet, because
 			 * we want to reflect accurately the real state of
 			 * the LAP, not the state we wish it was in,
-			 * so that we don't loose LM_LAP_CONNECT_REQUEST.
+			 * so that we don't lose LM_LAP_CONNECT_REQUEST.
 			 * In some cases, IrLAP won't close the LAP
 			 * immediately. For example, it might still be
 			 * retrying packets or waiting for the pf bit.
diff -Nru a/net/irda/irsyms.c b/net/irda/irsyms.c
--- a/net/irda/irsyms.c	Tue Mar  4 19:30:13 2003
+++ b/net/irda/irsyms.c	Tue Mar  4 19:30:13 2003
@@ -254,7 +254,7 @@
 /*
  * Function irda_init (void)
  *
- *  Protocol stack intialisation entry point.
+ *  Protocol stack initialisation entry point.
  *  Initialise the various components of the IrDA stack
  */
 int __init irda_init(void)
diff -Nru a/net/irda/irttp.c b/net/irda/irttp.c
--- a/net/irda/irttp.c	Tue Mar  4 19:30:10 2003
+++ b/net/irda/irttp.c	Tue Mar  4 19:30:10 2003
@@ -710,7 +710,7 @@
 		 * The current skb has a reference to the socket that sent
 		 * it (skb->sk). When we pass it to IrLMP, the skb will be
 		 * stored in in IrLAP (self->wx_list). When we are within
-		 * IrLAP, we loose the notion of socket, so we should not
+		 * IrLAP, we lose the notion of socket, so we should not
 		 * have a reference to a socket. So, we drop it here.
 		 *
 		 * Why does it matter ?
diff -Nru a/net/llc/af_llc.c b/net/llc/af_llc.c
--- a/net/llc/af_llc.c	Tue Mar  4 19:30:03 2003
+++ b/net/llc/af_llc.c	Tue Mar  4 19:30:03 2003
@@ -301,7 +301,7 @@
 	llc->daddr.lsap = addr->sllc_dsap;
 	memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
 	memcpy(&llc->addr, addr, sizeof(llc->addr));
-	/* assign new connection to it's SAP */
+	/* assign new connection to its SAP */
 	llc_sap_assign_sock(sap, sk);
 	rc = sk->zapped = 0;
 out:
diff -Nru a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c
--- a/net/llc/llc_pdu.c	Tue Mar  4 19:30:05 2003
+++ b/net/llc/llc_pdu.c	Tue Mar  4 19:30:05 2003
@@ -203,7 +203,7 @@
 	xid_info	 = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
 	xid_info->fmt_id = LLC_XID_FMT_ID;	/* 0x81 */
 	xid_info->type	 = svcs_supported;
-	xid_info->rw	 = rx_window << 1;	/* size of recieve window */
+	xid_info->rw	 = rx_window << 1;	/* size of receive window */
 	skb_put(skb, 3);
 }
 
diff -Nru a/net/netsyms.c b/net/netsyms.c
--- a/net/netsyms.c	Tue Mar  4 19:30:07 2003
+++ b/net/netsyms.c	Tue Mar  4 19:30:07 2003
@@ -646,12 +646,12 @@
 
 EXPORT_SYMBOL(softnet_data);
 
-#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
+#ifdef CONFIG_NET_RADIO
 /* Don't include the whole header mess for a single function */
 union iwreq_data;
 extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra);
 EXPORT_SYMBOL(wireless_send_event);
-#endif	/* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
+#endif	/* CONFIG_NET_RADIO */
 
 EXPORT_SYMBOL(linkwatch_fire_event);
 
diff -Nru a/net/sched/sch_gred.c b/net/sched/sch_gred.c
--- a/net/sched/sch_gred.c	Tue Mar  4 19:30:13 2003
+++ b/net/sched/sch_gred.c	Tue Mar  4 19:30:13 2003
@@ -416,7 +416,7 @@
 	memcpy(q->Stab, RTA_DATA(tb[TCA_GRED_STAB-1]), 256);
 
 	if ( table->initd && table->grio) {
-	/* this looks ugly but its not in the fast path */
+	/* this looks ugly but it's not in the fast path */
 		for (i=0;i<table->DPs;i++) {
 			if ((!table->tab[i]) || (i==q->DP) )    
 				continue; 
diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c
--- a/net/sched/sch_htb.c	Tue Mar  4 19:30:10 2003
+++ b/net/sched/sch_htb.c	Tue Mar  4 19:30:10 2003
@@ -623,7 +623,7 @@
 	if (new_mode == cl->cmode)
 		return;	
 	
-	if (cl->prio_activity) { /* not neccessary: speed optimization */
+	if (cl->prio_activity) { /* not necessary: speed optimization */
 		if (cl->cmode != HTB_CANT_SEND) 
 			htb_deactivate_prios(q,cl);
 		cl->cmode = new_mode;
diff -Nru a/net/sctp/Makefile b/net/sctp/Makefile
--- a/net/sctp/Makefile	Tue Mar  4 19:30:14 2003
+++ b/net/sctp/Makefile	Tue Mar  4 19:30:14 2003
@@ -10,7 +10,7 @@
 	  inqueue.o outqueue.o ulpqueue.o command.o \
 	  tsnmap.o bind_addr.o socket.o primitive.o \
 	  output.o input.o hashdriver.o sla1.o \
-	  debug.o ssnmap.o
+	  debug.o ssnmap.o proc.o
 
 ifeq ($(CONFIG_SCTP_ADLER32), y)
 sctp-y += adler32.o
diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c	Tue Mar  4 19:30:04 2003
+++ b/net/sctp/associola.c	Tue Mar  4 19:30:04 2003
@@ -95,7 +95,7 @@
 					  sctp_scope_t scope,
 					  int priority)
 {
-	sctp_opt_t *sp;
+	struct sctp_opt *sp;
 	int i;
 
 	/* Retrieve the SCTP per socket area.  */
@@ -241,8 +241,8 @@
 	asoc->peer.sack_needed = 1;
 
 	/* Create an input queue.  */
-	sctp_inqueue_init(&asoc->base.inqueue);
-	sctp_inqueue_set_th_handler(&asoc->base.inqueue,
+	sctp_inq_init(&asoc->base.inqueue);
+	sctp_inq_set_th_handler(&asoc->base.inqueue,
 				    (void (*)(void *))sctp_assoc_bh_rcv,
 				    asoc);
 
@@ -260,7 +260,6 @@
 
 	/* Set up the tsn tracking. */
 	sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 0);
-	asoc->peer.next_dup_tsn = 0;
 
 	skb_queue_head_init(&asoc->addip_chunks);
 
@@ -311,7 +310,7 @@
 	sctp_ulpq_free(&asoc->ulpq);
 
 	/* Dispose of any pending chunks on the inqueue. */
-	sctp_inqueue_free(&asoc->base.inqueue);
+	sctp_inq_free(&asoc->base.inqueue);
 
 	/* Free ssnmap storage. */
 	sctp_ssnmap_free(asoc->ssnmap);
@@ -368,7 +367,7 @@
 					   int priority)
 {
 	struct sctp_transport *peer;
-	sctp_opt_t *sp;
+	struct sctp_opt *sp;
 	unsigned short port;
 
 	/* AF_INET and AF_INET6 share common port field. */
@@ -505,7 +504,7 @@
 	struct sctp_transport *t = NULL;
 	struct sctp_transport *first;
 	struct sctp_transport *second;
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	struct list_head *pos;
 	int spc_state = 0;
 
@@ -776,7 +775,7 @@
 	sctp_endpoint_t *ep;
 	sctp_chunk_t *chunk;
 	struct sock *sk;
-	sctp_inqueue_t *inqueue;
+	struct sctp_inq *inqueue;
 	int state, subtype;
 	sctp_assoc_t associd = sctp_assoc2id(asoc);
 	int error = 0;
@@ -786,7 +785,7 @@
 	sk = asoc->base.sk;
 
 	inqueue = &asoc->base.inqueue;
-	while (NULL != (chunk = sctp_pop_inqueue(inqueue))) {
+	while (NULL != (chunk = sctp_inq_pop(inqueue))) {
 		state = asoc->state;
 		subtype = chunk->chunk_hdr->type;
 
@@ -795,6 +794,8 @@
 		 */
 		if (sctp_chunk_is_data(chunk))
 			asoc->peer.last_data_from = chunk->transport;
+		else
+			SCTP_INC_STATS(SctpInCtrlChunks);
 
 		if (chunk->transport)
 			chunk->transport->last_time_heard = jiffies;
@@ -819,7 +820,7 @@
 /* This routine moves an association from its old sk to a new sk.  */
 void sctp_assoc_migrate(sctp_association_t *assoc, struct sock *newsk)
 {
-	sctp_opt_t *newsp = sctp_sk(newsk);
+	struct sctp_opt *newsp = sctp_sk(newsk);
 
 	/* Delete the association from the old endpoint's list of
 	 * associations.
@@ -848,7 +849,6 @@
 	/* Copy in new parameters of peer. */
 	asoc->c = new->c;
 	asoc->peer.rwnd = new->peer.rwnd;
-	asoc->peer.next_dup_tsn = new->peer.next_dup_tsn;
 	asoc->peer.sack_needed = new->peer.sack_needed;
 	asoc->peer.i = new->peer.i;
 	sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE,
@@ -887,26 +887,19 @@
 
 }
 
-/* Choose the transport for sending a shutdown packet.
+/* Update the retran path for sending a retransmitted packet.
  * Round-robin through the active transports, else round-robin
  * through the inactive transports as this is the next best thing
  * we can try.
  */
-struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *asoc)
+void sctp_assoc_update_retran_path(sctp_association_t *asoc)
 {
 	struct sctp_transport *t, *next;
 	struct list_head *head = &asoc->peer.transport_addr_list;
 	struct list_head *pos;
 
-	/* If this is the first time SHUTDOWN is sent, use the active
-	 * path.
-	 */
-	if (!asoc->shutdown_last_sent_to)
-		return asoc->peer.active_path;
-
-	/* Otherwise, find the next transport in a round-robin fashion. */
-
-	t = asoc->shutdown_last_sent_to;
+	/* Find the next transport in a round-robin fashion. */
+	t = asoc->peer.retran_path;
 	pos = &t->transports;
 	next = NULL;
 
@@ -935,13 +928,30 @@
 		 * other active transports.  If so, use the next
 		 * transport.
 		 */
-		if (t == asoc->shutdown_last_sent_to) {
+		if (t == asoc->peer.retran_path) {
 			t = next;
 			break;
 		}
 	}
 
-	return t;
+	asoc->peer.retran_path = t;
+}
+
+/* Choose the transport for sending a SHUTDOWN packet.  */
+struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *asoc)
+{
+	/* If this is the first time SHUTDOWN is sent, use the active path,
+	 * else use the retran path. If the last SHUTDOWN was sent over the
+	 * retran path, update the retran path and use it. 
+	 */
+	if (!asoc->shutdown_last_sent_to)
+		return asoc->peer.active_path;
+	else {
+		if (asoc->shutdown_last_sent_to == asoc->peer.retran_path)
+			sctp_assoc_update_retran_path(asoc);
+		return asoc->peer.retran_path;
+	}
+
 }
 
 /* Update the association's pmtu and frag_point by going through all the
@@ -990,13 +1000,13 @@
 		asoc->rwnd += len;
 	}
 
-	SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) - %u\n",
-			  __FUNCTION__, asoc, len, asoc->rwnd, asoc->rwnd_over,
-			  asoc->a_rwnd);
+	SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) "
+			  "- %u\n", __FUNCTION__, asoc, len, asoc->rwnd,
+			  asoc->rwnd_over, asoc->a_rwnd);
 
 	/* Send a window update SACK if the rwnd has increased by at least the
 	 * minimum of the association's PMTU and half of the receive buffer.
-	 * The algorithm used is similar to the one described in 
+	 * The algorithm used is similar to the one described in
 	 * Section 4.2.3.3 of RFC 1122.
 	 */
 	if ((asoc->state == SCTP_STATE_ESTABLISHED) &&
@@ -1004,17 +1014,16 @@
 	    ((asoc->rwnd - asoc->a_rwnd) >=
 		     min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu))) {
 		SCTP_DEBUG_PRINTK("%s: Sending window update SACK- asoc: %p "
-				  "rwnd: %u a_rwnd: %u\n",
-				  __FUNCTION__, asoc, asoc->rwnd, asoc->a_rwnd);
-		sack = sctp_make_sack(asoc); 
+				  "rwnd: %u a_rwnd: %u\n", __FUNCTION__,
+				  asoc, asoc->rwnd, asoc->a_rwnd);
+		sack = sctp_make_sack(asoc);
 		if (!sack)
-			return;	
+			return;
 
 		/* Update the last advertised rwnd value. */
 		asoc->a_rwnd = asoc->rwnd;
 
 		asoc->peer.sack_needed = 0;
-		asoc->peer.next_dup_tsn = 0;
 
 		sctp_outq_tail(&asoc->outqueue, sack);
 
@@ -1022,7 +1031,7 @@
 		timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
 		if (timer_pending(timer) && del_timer(timer))
 			sctp_association_put(asoc);
-	} 
+	}
 }
 
 /* Decrease asoc's rwnd by len. */
diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c	Tue Mar  4 19:30:04 2003
+++ b/net/sctp/endpointola.c	Tue Mar  4 19:30:04 2003
@@ -92,7 +92,7 @@
 sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto,
 				    struct sock *sk, int priority)
 {
-	sctp_opt_t *sp = sctp_sk(sk);
+	struct sctp_opt *sp = sctp_sk(sk);
 	memset(ep, 0, sizeof(sctp_endpoint_t));
 
 	/* Initialize the base structure. */
@@ -105,10 +105,10 @@
 	ep->base.malloced = 1;
 
 	/* Create an input queue.  */
-	sctp_inqueue_init(&ep->base.inqueue);
+	sctp_inq_init(&ep->base.inqueue);
 
 	/* Set its top-half handler */
-	sctp_inqueue_set_th_handler(&ep->base.inqueue,
+	sctp_inq_set_th_handler(&ep->base.inqueue,
 				    (void (*)(void *))sctp_endpoint_bh_rcv,
 				    ep);
 
@@ -198,7 +198,7 @@
 	sctp_unhash_endpoint(ep);
 
 	/* Cleanup the inqueue. */
-	sctp_inqueue_free(&ep->base.inqueue);
+	sctp_inq_free(&ep->base.inqueue);
 
 	sctp_bind_addr_free(&ep->base.bind_addr);
 
@@ -333,7 +333,7 @@
 	struct sock *sk;
 	struct sctp_transport *transport;
 	sctp_chunk_t *chunk;
-	sctp_inqueue_t *inqueue;
+	struct sctp_inq *inqueue;
 	sctp_subtype_t subtype;
 	sctp_state_t state;
 	int error = 0;
@@ -345,7 +345,7 @@
 	inqueue = &ep->base.inqueue;
 	sk = ep->base.sk;
 
-	while (NULL != (chunk = sctp_pop_inqueue(inqueue))) {		
+	while (NULL != (chunk = sctp_inq_pop(inqueue))) {		
 		subtype.chunk = chunk->chunk_hdr->type;
 
 		/* We might have grown an association since last we
@@ -369,6 +369,8 @@
 		 */
 		if (asoc && sctp_chunk_is_data(chunk))
 			asoc->peer.last_data_from = chunk->transport;
+		else
+			SCTP_INC_STATS(SctpInCtrlChunks);
 
 		if (chunk->transport)
 			chunk->transport->last_time_heard = jiffies;
diff -Nru a/net/sctp/input.c b/net/sctp/input.c
--- a/net/sctp/input.c	Tue Mar  4 19:30:04 2003
+++ b/net/sctp/input.c	Tue Mar  4 19:30:04 2003
@@ -90,6 +90,7 @@
 
 	if (val != cmp) {
 		/* CRC failure, dump it. */
+		SCTP_INC_STATS_BH(SctpChecksumErrors);
 		return -1;
 	}
 	return 0;
@@ -115,6 +116,8 @@
 	if (skb->pkt_type!=PACKET_HOST)
 		goto discard_it;
 
+	SCTP_INC_STATS_BH(SctpInSCTPPacks);
+
 	sh = (struct sctphdr *) skb->h.raw;
 
 	/* Pull up the IP and SCTP headers. */
@@ -160,8 +163,10 @@
 	 */
 	if (!asoc) {
 		ep = __sctp_rcv_lookup_endpoint(&dest);
-		if (sctp_rcv_ootb(skb))
+		if (sctp_rcv_ootb(skb)) {
+			SCTP_INC_STATS_BH(SctpOutOfBlues);
 			goto discard_release;
+		}
 	}
 
 	/* Retrieve the common input handling substructure. */
@@ -248,7 +253,7 @@
 int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 {
 	sctp_chunk_t *chunk;
-	sctp_inqueue_t *inqueue;
+	struct sctp_inq *inqueue;
 
 	/* One day chunk will live inside the skb, but for
 	 * now this works.
@@ -256,7 +261,7 @@
 	chunk = (sctp_chunk_t *) skb;
 	inqueue = &chunk->rcvr->inqueue;
 
-	sctp_push_inqueue(inqueue, chunk);
+	sctp_inq_push(inqueue, chunk);
         return 0;
 }
 
diff -Nru a/net/sctp/inqueue.c b/net/sctp/inqueue.c
--- a/net/sctp/inqueue.c	Tue Mar  4 19:30:11 2003
+++ b/net/sctp/inqueue.c	Tue Mar  4 19:30:11 2003
@@ -47,8 +47,8 @@
 #include <net/sctp/sm.h>
 #include <linux/interrupt.h>
 
-/* Initialize an SCTP_inqueue.  */
-void sctp_inqueue_init(sctp_inqueue_t *queue)
+/* Initialize an SCTP inqueue.  */
+void sctp_inq_init(struct sctp_inq *queue)
 {
 	skb_queue_head_init(&queue->in);
 	queue->in_progress = NULL;
@@ -59,21 +59,21 @@
 	queue->malloced = 0;
 }
 
-/* Create an initialized SCTP_inqueue.  */
-sctp_inqueue_t *sctp_inqueue_new(void)
+/* Create an initialized sctp_inq.  */
+struct sctp_inq *sctp_inq_new(void)
 {
-	sctp_inqueue_t *retval;
+	struct sctp_inq *retval;
 
-	retval = t_new(sctp_inqueue_t, GFP_ATOMIC);
+	retval = t_new(struct sctp_inq, GFP_ATOMIC);
 	if (retval) {
-		sctp_inqueue_init(retval);
+		sctp_inq_init(retval);
 		retval->malloced = 1;
 	}
         return retval;
 }
 
 /* Release the memory associated with an SCTP inqueue.  */
-void sctp_inqueue_free(sctp_inqueue_t *queue)
+void sctp_inq_free(struct sctp_inq *queue)
 {
 	sctp_chunk_t *chunk;
 
@@ -96,7 +96,7 @@
 /* Put a new packet in an SCTP inqueue.
  * We assume that packet->sctp_hdr is set and in host byte order.
  */
-void sctp_push_inqueue(sctp_inqueue_t *q, sctp_chunk_t *packet)
+void sctp_inq_push(struct sctp_inq *q, sctp_chunk_t *packet)
 {
 	/* Directly call the packet handling routine. */
 
@@ -114,7 +114,7 @@
  * WARNING:  If you need to put the chunk on another queue, you need to
  * make a shallow copy (clone) of it.
  */
-sctp_chunk_t *sctp_pop_inqueue(sctp_inqueue_t *queue)
+sctp_chunk_t *sctp_inq_pop(struct sctp_inq *queue)
 {
 	sctp_chunk_t *chunk;
 	sctp_chunkhdr_t *ch = NULL;
@@ -172,7 +172,7 @@
 		chunk->end_of_packet = 1;
 	}
 
-	SCTP_DEBUG_PRINTK("+++sctp_pop_inqueue+++ chunk %p[%s],"
+	SCTP_DEBUG_PRINTK("+++sctp_inq_pop+++ chunk %p[%s],"
 			  " length %d, skb->len %d\n",chunk,
 			  sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)),
 			  ntohs(chunk->chunk_hdr->length), chunk->skb->len);
@@ -182,12 +182,12 @@
 /* Set a top-half handler.
  *
  * Originally, we the top-half handler was scheduled as a BH.  We now
- * call the handler directly in sctp_push_inqueue() at a time that
+ * call the handler directly in sctp_inq_push() at a time that
  * we know we are lock safe.
  * The intent is that this routine will pull stuff out of the
  * inqueue and process it.
  */
-void sctp_inqueue_set_th_handler(sctp_inqueue_t *q,
+void sctp_inq_set_th_handler(struct sctp_inq *q,
 				 void (*callback)(void *), void *arg)
 {
 	INIT_WORK(&q->immediate, callback, arg);
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c	Tue Mar  4 19:30:10 2003
+++ b/net/sctp/ipv6.c	Tue Mar  4 19:30:10 2003
@@ -131,6 +131,8 @@
 			  __FUNCTION__, skb, skb->len, NIP6(fl.fl6_src),
 			  NIP6(fl.fl6_dst));
 
+	SCTP_INC_STATS(SctpOutSCTPPacks);
+
 	return ip6_xmit(sk, skb, &fl, np->opt);
 }
 
@@ -443,7 +445,7 @@
 }
 
 /* Initialize a PF_INET msgname from a ulpevent. */
-static void sctp_inet6_event_msgname(sctp_ulpevent_t *event, char *msgname,
+static void sctp_inet6_event_msgname(struct sctp_ulpevent *event, char *msgname,
 				     int *addrlen)
 {
 	struct sockaddr_in6 *sin6, *sin6from;
diff -Nru a/net/sctp/output.c b/net/sctp/output.c
--- a/net/sctp/output.c	Tue Mar  4 19:30:05 2003
+++ b/net/sctp/output.c	Tue Mar  4 19:30:05 2003
@@ -419,6 +419,7 @@
 	dst = transport->dst;
 	/* The 'obsolete' field of dst is set to 2 when a dst is freed. */
 	if (!dst || (dst->obsolete > 1)) {
+		dst_release(dst);
 		sctp_transport_route(transport, NULL, sctp_sk(sk));
 		sctp_assoc_sync_pmtu(asoc);
 	}
diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c
--- a/net/sctp/outqueue.c	Tue Mar  4 19:30:05 2003
+++ b/net/sctp/outqueue.c	Tue Mar  4 19:30:05 2003
@@ -193,11 +193,17 @@
 			  : "Illegal Chunk");
 
 			skb_queue_tail(&q->out, (struct sk_buff *) chunk);
+			if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+				SCTP_INC_STATS(SctpOutUnorderChunks);
+			else
+				SCTP_INC_STATS(SctpOutOrderChunks);
 			q->empty = 0;
 			break;
 		};
-	} else
+	} else {
 		skb_queue_tail(&q->control, (struct sk_buff *) chunk);
+		SCTP_INC_STATS(SctpOutCtrlChunks);
+	}
 
 	if (error < 0)
 		return error;
@@ -315,6 +321,11 @@
 	switch(reason) {
 	case SCTP_RETRANSMIT_T3_RTX:
 		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
+		/* Update the retran path if the T3-rtx timer has expired for
+		 * the current retran path.
+		 */
+		if (transport == transport->asoc->peer.retran_path)
+			sctp_assoc_update_retran_path(transport->asoc);
 		break;
 	case SCTP_RETRANSMIT_FAST_RTX:
 		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
@@ -423,7 +434,7 @@
 				*start_timer = 1;
 
 			/* Stop sending DATA as there is no more room
-			 * at the reciever.
+			 * at the receiver.
 			 */
 			list_add(lchunk, lqueue);
 			lchunk = NULL;
diff -Nru a/net/sctp/primitive.c b/net/sctp/primitive.c
--- a/net/sctp/primitive.c	Tue Mar  4 19:30:14 2003
+++ b/net/sctp/primitive.c	Tue Mar  4 19:30:14 2003
@@ -199,7 +199,7 @@
  * o association id - local handle to the SCTP association
  *
  * o destination transport address - the transport address of the
- *   asociation on which a heartbeat should be issued.
+ *   association on which a heartbeat should be issued.
  */
 
 DECLARE_PRIMITIVE(REQUESTHEARTBEAT);
diff -Nru a/net/sctp/proc.c b/net/sctp/proc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sctp/proc.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,129 @@
+/* SCTP kernel reference Implementation
+ * Copyright (c) 2003 International Business Machines, Corp.
+ *
+ * This file is part of the SCTP kernel reference Implementation
+ *
+ * The SCTP reference implementation 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, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
+#include <linux/types.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <net/sctp/sctp.h>
+
+static char *sctp_snmp_list[] = {
+#define SCTP_SNMP_ENTRY(x) #x 
+	SCTP_SNMP_ENTRY(SctpCurrEstab),
+	SCTP_SNMP_ENTRY(SctpActiveEstabs),
+	SCTP_SNMP_ENTRY(SctpPassiveEstabs),
+	SCTP_SNMP_ENTRY(SctpAborteds),
+	SCTP_SNMP_ENTRY(SctpShutdowns),
+	SCTP_SNMP_ENTRY(SctpOutOfBlues),
+	SCTP_SNMP_ENTRY(SctpChecksumErrors),
+	SCTP_SNMP_ENTRY(SctpOutCtrlChunks),
+	SCTP_SNMP_ENTRY(SctpOutOrderChunks),
+	SCTP_SNMP_ENTRY(SctpOutUnorderChunks),
+	SCTP_SNMP_ENTRY(SctpInCtrlChunks),
+	SCTP_SNMP_ENTRY(SctpInOrderChunks),
+	SCTP_SNMP_ENTRY(SctpInUnorderChunks),
+	SCTP_SNMP_ENTRY(SctpFragUsrMsgs),
+	SCTP_SNMP_ENTRY(SctpReasmUsrMsgs),
+	SCTP_SNMP_ENTRY(SctpOutSCTPPacks),
+	SCTP_SNMP_ENTRY(SctpInSCTPPacks),
+#undef SCTP_SNMP_ENTRY
+};
+
+/* Return the current value of a particular entry in the mib by adding its
+ * per cpu counters.
+ */ 
+static unsigned long
+fold_field(void *mib[], int nr)
+{
+	unsigned long res = 0;
+	int i;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_possible(i))
+			continue;
+		res +=
+		    *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
+					 sizeof (unsigned long) * nr));
+		res +=
+		    *((unsigned long *) (((void *) per_cpu_ptr(mib[1], i)) +
+					 sizeof (unsigned long) * nr));
+	}
+	return res;
+}
+
+/* Display sctp snmp mib statistics(/proc/net/sctp/snmp). */
+static int sctp_snmp_seq_show(struct seq_file *seq, void *v)
+{
+	int i;
+
+	for (i = 0; i < sizeof(sctp_snmp_list) / sizeof(char *); i++)
+		seq_printf(seq, "%-32s\t%ld\n", sctp_snmp_list[i],
+			   fold_field((void **)sctp_statistics, i));
+
+	return 0;
+}
+
+/* Initialize the seq file operations for 'snmp' object. */
+static int sctp_snmp_seq_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, sctp_snmp_seq_show, NULL);
+}
+
+static struct file_operations sctp_snmp_seq_fops = {
+	.open	 = sctp_snmp_seq_open,
+	.read	 = seq_read,
+	.llseek	 = seq_lseek,
+	.release = single_release,
+};
+
+/* Set up the proc fs entry for 'snmp' object. */
+int __init sctp_snmp_proc_init(void)
+{
+	struct proc_dir_entry *p;
+
+	p = create_proc_entry("snmp", S_IRUGO, proc_net_sctp);
+	if (!p)
+		return -ENOMEM;
+
+	p->proc_fops = &sctp_snmp_seq_fops;
+
+	return 0;
+}
+
+/* Cleanup the proc fs entry for 'snmp' object. */
+void sctp_snmp_proc_exit(void)
+{
+	remove_proc_entry("snmp", proc_net_sctp);
+}
diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c	Tue Mar  4 19:30:10 2003
+++ b/net/sctp/protocol.c	Tue Mar  4 19:30:10 2003
@@ -75,6 +75,9 @@
 
 extern struct net_proto_family inet_family_ops;
 
+extern int sctp_snmp_proc_init(void);
+extern int sctp_snmp_proc_exit(void);
+
 /* Return the address of the control sock. */
 struct sock *sctp_get_ctl_sock(void)
 {
@@ -82,21 +85,32 @@
 }
 
 /* Set up the proc fs entry for the SCTP protocol. */
-__init void sctp_proc_init(void)
+__init int sctp_proc_init(void)
 {
+	int rc = 0;
+
 	if (!proc_net_sctp) {
 		struct proc_dir_entry *ent;
 		ent = proc_mkdir("net/sctp", 0);
 		if (ent) {
 			ent->owner = THIS_MODULE;
 			proc_net_sctp = ent;
-		}
+		} else
+			rc = -ENOMEM;
 	}
+
+	if (sctp_snmp_proc_init())
+		rc = -ENOMEM;
+
+	return rc;
 }
 
 /* Clean up the proc fs entry for the SCTP protocol. */
 void sctp_proc_exit(void)
 {
+
+	sctp_snmp_proc_exit();
+
 	if (proc_net_sctp) {
 		proc_net_sctp = NULL;
 		remove_proc_entry("net/sctp", 0);
@@ -124,7 +138,6 @@
 		/* Add the address to the local list.  */
 		addr = t_new(struct sockaddr_storage_list, GFP_ATOMIC);
 		if (addr) {
-			INIT_LIST_HEAD(&addr->list);
 			addr->a.v4.sin_family = AF_INET;
 			addr->a.v4.sin_port = 0;
 			addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
@@ -436,7 +449,6 @@
 
 		if (AF_INET == laddr->a.sa.sa_family) {
 			fl.fl4_src = laddr->a.v4.sin_addr.s_addr;
-			dst = sctp_v4_get_dst(asoc, daddr, &laddr->a);
 			if (!ip_route_output_key(&rt, &fl)) {
 				dst = &rt->u.dst;
 				goto out_unlock;
@@ -557,7 +569,7 @@
 }
 
 /* Copy the primary address of the peer primary address as the msg_name. */
-static void sctp_inet_event_msgname(sctp_ulpevent_t *event, char *msgname,
+static void sctp_inet_event_msgname(struct sctp_ulpevent *event, char *msgname,
 				    int *addr_len)
 {
 	struct sockaddr_in *sin, *sinfrom;
@@ -628,6 +640,7 @@
 			  NIPQUAD(((struct rtable *)skb->dst)->rt_src),
 			  NIPQUAD(((struct rtable *)skb->dst)->rt_dst));
 
+	SCTP_INC_STATS(SctpOutSCTPPacks);
 	return ip_queue_xmit(skb, ipfragok);
 }
 
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c	Tue Mar  4 19:30:04 2003
+++ b/net/sctp/sm_make_chunk.c	Tue Mar  4 19:30:04 2003
@@ -222,9 +222,7 @@
 
 	sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &sat_param);
 	sctp_addto_chunk(retval, sizeof(sat_addr_types), sat_addr_types);
-
 	sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
-
 nodata:
 	if (addrs.v)
 		kfree(addrs.v);
@@ -245,7 +243,8 @@
 
 	retval = NULL;
 
-	addrs = sctp_bind_addrs_to_raw(&asoc->base.bind_addr, &addrs_len, priority);
+	addrs = sctp_bind_addrs_to_raw(&asoc->base.bind_addr, &addrs_len, 
+				       priority);
 	if (!addrs.v)
 		goto nomem_rawaddr;
 
@@ -586,14 +585,12 @@
 	sctp_gap_ack_block_t gab;
 	int length;
 	__u32 ctsn;
-	sctp_tsnmap_iter_t iter;
-	__u16 num_gabs;
-	__u16 num_dup_tsns = asoc->peer.next_dup_tsn;
-	const sctp_tsnmap_t *map = &asoc->peer.tsn_map;
+	struct sctp_tsnmap_iter iter;
+	__u16 num_gabs, num_dup_tsns;
+	struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
 
 	ctsn = sctp_tsnmap_get_ctsn(map);
-	SCTP_DEBUG_PRINTK("make_sack: sackCTSNAck sent is 0x%x.\n",
-			  ctsn);
+	SCTP_DEBUG_PRINTK("sackCTSNAck sent is 0x%x.\n", ctsn);
 
 	/* Count the number of Gap Ack Blocks.  */
 	sctp_tsnmap_iter_init(map, &iter);
@@ -603,15 +600,17 @@
 		/* Do nothing. */
 	}
 
+	num_dup_tsns = sctp_tsnmap_num_dups(map);
+
 	/* Initialize the SACK header.  */
 	sack.cum_tsn_ack	    = htonl(ctsn);
 	sack.a_rwnd 		    = htonl(asoc->rwnd);
 	sack.num_gap_ack_blocks     = htons(num_gabs);
-	sack.num_dup_tsns  = htons(num_dup_tsns);
+	sack.num_dup_tsns           = htons(num_dup_tsns);
 
 	length = sizeof(sack)
 		+ sizeof(sctp_gap_ack_block_t) * num_gabs
-		+ sizeof(sctp_dup_tsn_t) * num_dup_tsns;
+		+ sizeof(__u32) * num_dup_tsns;
 
 	/* Create the chunk.  */
 	retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, length);
@@ -658,21 +657,18 @@
 	while(sctp_tsnmap_next_gap_ack(map, &iter, &gab.start, &gab.end)) {
 		gab.start = htons(gab.start);
 		gab.end = htons(gab.end);
-		sctp_addto_chunk(retval,
-				 sizeof(sctp_gap_ack_block_t),
-				 &gab);
+		sctp_addto_chunk(retval, sizeof(sctp_gap_ack_block_t), &gab);
 	}
 
 	/* Register the duplicates.  */
-	sctp_addto_chunk(retval,
-			 sizeof(sctp_dup_tsn_t) * num_dup_tsns,
-			 &asoc->peer.dup_tsns);
+	sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns,
+			 sctp_tsnmap_get_dups(map));
 
 nodata:
 	return retval;
 }
 
-/* FIXME: Comments. */
+/* Make a SHUTDOWN chunk. */
 sctp_chunk_t *sctp_make_shutdown(const sctp_association_t *asoc)
 {
 	sctp_chunk_t *retval;
@@ -689,7 +685,6 @@
 
 	retval->subh.shutdown_hdr =
 		sctp_addto_chunk(retval, sizeof(shut), &shut);
-
 nodata:
 	return retval;
 }
@@ -1179,6 +1174,9 @@
 	whole += msg_len / max;
 	over = msg_len % max;
 	offset = 0;
+
+	if (whole && over)
+		SCTP_INC_STATS_USER(SctpFragUsrMsgs);
 
 	/* Create chunks for all the full sized DATA chunks. */
 	for (i=0, len=first_len; i < whole; i++) {
diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
--- a/net/sctp/sm_sideeffect.c	Tue Mar  4 19:30:11 2003
+++ b/net/sctp/sm_sideeffect.c	Tue Mar  4 19:30:11 2003
@@ -253,7 +253,7 @@
 {
 	int error = 0;
 	int force;
-	sctp_cmd_t *command;
+	sctp_cmd_t *cmd;
 	sctp_chunk_t *new_obj;
 	sctp_chunk_t *chunk = NULL;
 	sctp_packet_t *packet;
@@ -273,22 +273,22 @@
 	 *         cmd->handle(x, y, z)
 	 * --jgrimm
 	 */
-	while (NULL != (command = sctp_next_cmd(commands))) {
-		switch (command->verb) {
+	while (NULL != (cmd = sctp_next_cmd(commands))) {
+		switch (cmd->verb) {
 		case SCTP_CMD_NOP:
 			/* Do nothing. */
 			break;
 
 		case SCTP_CMD_NEW_ASOC:
 			/* Register a new association.  */
-			asoc = command->obj.ptr;
+			asoc = cmd->obj.ptr;
 			/* Register with the endpoint.  */
 			sctp_endpoint_add_asoc(ep, asoc);
 			sctp_hash_established(asoc);
 			break;
 
 		case SCTP_CMD_UPDATE_ASSOC:
-		       sctp_assoc_update(asoc, command->obj.ptr);
+		       sctp_assoc_update(asoc, cmd->obj.ptr);
 		       break;
 
 		case SCTP_CMD_PURGE_OUTQUEUE:
@@ -304,13 +304,12 @@
 
 		case SCTP_CMD_NEW_STATE:
 			/* Enter a new state.  */
-			sctp_cmd_new_state(commands, asoc, command->obj.state);
+			sctp_cmd_new_state(commands, asoc, cmd->obj.state);
 			break;
 
 		case SCTP_CMD_REPORT_TSN:
 			/* Record the arrival of a TSN.  */
-			sctp_tsnmap_mark(&asoc->peer.tsn_map,
-					 command->obj.u32);
+			sctp_tsnmap_mark(&asoc->peer.tsn_map, cmd->obj.u32);
 			break;
 
 		case SCTP_CMD_GEN_SACK:
@@ -319,14 +318,14 @@
 			 * the packet and MAYBE generate a SACK, or
 			 * force a SACK out.
 			 */
-			force = command->obj.i32;
+			force = cmd->obj.i32;
 			error = sctp_gen_sack(asoc, force, commands);
 			break;
 
 		case SCTP_CMD_PROCESS_SACK:
 			/* Process an inbound SACK.  */
 			error = sctp_cmd_process_sack(commands, asoc,
-						      command->obj.ptr);
+						      cmd->obj.ptr);
 			break;
 
 		case SCTP_CMD_GEN_INIT_ACK:
@@ -347,16 +346,15 @@
 			 * layer which will bail.
 			 */
 			error = sctp_cmd_process_init(commands, asoc, chunk,
-						      command->obj.ptr,
-						      priority);
+						      cmd->obj.ptr, priority);
 			break;
 
 		case SCTP_CMD_GEN_COOKIE_ECHO:
 			/* Generate a COOKIE ECHO chunk.  */
 			new_obj = sctp_make_cookie_echo(asoc, chunk);
 			if (!new_obj) {
-				if (command->obj.ptr)
-					sctp_free_chunk(command->obj.ptr);
+				if (cmd->obj.ptr)
+					sctp_free_chunk(cmd->obj.ptr);
 				goto nomem;
 			}
 			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
@@ -365,9 +363,9 @@
 			/* If there is an ERROR chunk to be sent along with
 			 * the COOKIE_ECHO, send it, too.
 			 */
-			if (command->obj.ptr)
+			if (cmd->obj.ptr)
 				sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
-						SCTP_CHUNK(command->obj.ptr));
+						SCTP_CHUNK(cmd->obj.ptr));
 			break;
 
 		case SCTP_CMD_GEN_SHUTDOWN:
@@ -387,43 +385,36 @@
 		case SCTP_CMD_CHUNK_ULP:
 			/* Send a chunk to the sockets layer.  */
 			SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n",
-					  "chunk_up:",
-					  command->obj.ptr,
-					  "ulpq:",
-					  &asoc->ulpq);
-			sctp_ulpq_tail_data(&asoc->ulpq,
-					    command->obj.ptr,
+					  "chunk_up:", cmd->obj.ptr,
+					  "ulpq:", &asoc->ulpq);
+			sctp_ulpq_tail_data(&asoc->ulpq, cmd->obj.ptr,
 					    GFP_ATOMIC);
 			break;
 
 		case SCTP_CMD_EVENT_ULP:
 			/* Send a notification to the sockets layer.  */
 			SCTP_DEBUG_PRINTK("sm_sideff: %s %p, %s %p.\n",
-					  "event_up:",
-					  command->obj.ptr,
-					  "ulpq:",
-					  &asoc->ulpq);
-			sctp_ulpq_tail_event(&asoc->ulpq,
-					     command->obj.ptr);
+					  "event_up:",cmd->obj.ptr,
+					  "ulpq:",&asoc->ulpq);
+			sctp_ulpq_tail_event(&asoc->ulpq, cmd->obj.ptr);
 			break;
 
 		case SCTP_CMD_REPLY:
 			/* Send a chunk to our peer.  */
 			error = sctp_outq_tail(&asoc->outqueue,
-					       command->obj.ptr);
+					       cmd->obj.ptr);
 			break;
 
 		case SCTP_CMD_SEND_PKT:
 			/* Send a full packet to our peer.  */
-			packet = command->obj.ptr;
+			packet = cmd->obj.ptr;
 			sctp_packet_transmit(packet);
 			sctp_ootb_pkt_free(packet);
 			break;
 
 		case SCTP_CMD_RETRAN:
 			/* Mark a transport for retransmission.  */
-			sctp_retransmit(&asoc->outqueue,
-					command->obj.transport,
+			sctp_retransmit(&asoc->outqueue, cmd->obj.transport,
 					SCTP_RETRANSMIT_T3_RTX);
 			break;
 
@@ -434,32 +425,30 @@
 
 		case SCTP_CMD_ECN_CE:
 			/* Do delayed CE processing.   */
-			sctp_do_ecn_ce_work(asoc, command->obj.u32);
+			sctp_do_ecn_ce_work(asoc, cmd->obj.u32);
 			break;
 
 		case SCTP_CMD_ECN_ECNE:
 			/* Do delayed ECNE processing. */
-			new_obj = sctp_do_ecn_ecne_work(asoc,
-							command->obj.u32,
+			new_obj = sctp_do_ecn_ecne_work(asoc, cmd->obj.u32,
 							chunk);
-			if (new_obj) {
+			if (new_obj)
 				sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
 						SCTP_CHUNK(new_obj));
-			}
 			break;
 
 		case SCTP_CMD_ECN_CWR:
 			/* Do delayed CWR processing.  */
-			sctp_do_ecn_cwr_work(asoc, command->obj.u32);
+			sctp_do_ecn_cwr_work(asoc, cmd->obj.u32);
 			break;
 
 		case SCTP_CMD_SETUP_T2:
-			sctp_cmd_setup_t2(commands, asoc, command->obj.ptr);
+			sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr);
 			break;
 
 		case SCTP_CMD_TIMER_START:
-			timer = &asoc->timers[command->obj.to];
-			timeout = asoc->timeouts[command->obj.to];
+			timer = &asoc->timers[cmd->obj.to];
+			timeout = asoc->timeouts[cmd->obj.to];
 			if (!timeout)
 				BUG();
 
@@ -469,29 +458,28 @@
 			break;
 
 		case SCTP_CMD_TIMER_RESTART:
-			timer = &asoc->timers[command->obj.to];
-			timeout = asoc->timeouts[command->obj.to];
+			timer = &asoc->timers[cmd->obj.to];
+			timeout = asoc->timeouts[cmd->obj.to];
 			if (!mod_timer(timer, jiffies + timeout))
 				sctp_association_hold(asoc);
 			break;
 
 		case SCTP_CMD_TIMER_STOP:
-			timer = &asoc->timers[command->obj.to];
+			timer = &asoc->timers[cmd->obj.to];
 			if (timer_pending(timer) && del_timer(timer))
 				sctp_association_put(asoc);
 			break;
 
 		case SCTP_CMD_INIT_RESTART:
-
 			/* Do the needed accounting and updates
 			 * associated with restarting an initialization
 			 * timer.
 			 */
 			asoc->counters[SCTP_COUNTER_INIT_ERROR]++;
-			asoc->timeouts[command->obj.to] *= 2;
-			if (asoc->timeouts[command->obj.to] >
+			asoc->timeouts[cmd->obj.to] *= 2;
+			if (asoc->timeouts[cmd->obj.to] >
 			    asoc->max_init_timeo) {
-				asoc->timeouts[command->obj.to] =
+				asoc->timeouts[cmd->obj.to] =
 					asoc->max_init_timeo;
 			}
 
@@ -506,7 +494,7 @@
 
 			sctp_add_cmd_sf(commands,
 					SCTP_CMD_TIMER_RESTART,
-					SCTP_TO(command->obj.to));
+					SCTP_TO(cmd->obj.to));
 			break;
 
 		case SCTP_CMD_INIT_FAILED:
@@ -519,25 +507,16 @@
 			break;
 
 		case SCTP_CMD_COUNTER_INC:
-			asoc->counters[command->obj.counter]++;
+			asoc->counters[cmd->obj.counter]++;
 			break;
 
 		case SCTP_CMD_COUNTER_RESET:
-			asoc->counters[command->obj.counter] = 0;
+			asoc->counters[cmd->obj.counter] = 0;
 			break;
 
 		case SCTP_CMD_REPORT_DUP:
-			if (asoc->peer.next_dup_tsn < SCTP_MAX_DUP_TSNS) {
-				asoc->peer.dup_tsns[asoc->peer.next_dup_tsn++] =
-					ntohl(command->obj.u32);
-			}
-			break;
-
-		case SCTP_CMD_REPORT_BIGGAP:
-			SCTP_DEBUG_PRINTK("Big gap: %x to %x\n",
-					  sctp_tsnmap_get_ctsn(
-						  &asoc->peer.tsn_map),
-					  command->obj.u32);
+			sctp_tsnmap_mark_dup(&asoc->peer.tsn_map, 
+					     cmd->obj.u32);
 			break;
 
 		case SCTP_CMD_REPORT_BAD_TAG:
@@ -546,17 +525,16 @@
 
 		case SCTP_CMD_STRIKE:
 			/* Mark one strike against a transport.  */
-			sctp_do_8_2_transport_strike(asoc,
-						     command->obj.transport);
+			sctp_do_8_2_transport_strike(asoc, cmd->obj.transport);
 			break;
 
 		case SCTP_CMD_TRANSPORT_RESET:
-			t = command->obj.transport;
+			t = cmd->obj.transport;
 			sctp_cmd_transport_reset(commands, asoc, t);
 			break;
 
 		case SCTP_CMD_TRANSPORT_ON:
-			t = command->obj.transport;
+			t = cmd->obj.transport;
 			sctp_cmd_transport_on(commands, asoc, t, chunk);
 			break;
 
@@ -565,7 +543,7 @@
 			break;
 
 		case SCTP_CMD_HB_TIMER_UPDATE:
-			t = command->obj.transport;
+			t = cmd->obj.transport;
 			sctp_cmd_hb_timer_update(commands, asoc, t);
 			break;
 
@@ -574,17 +552,16 @@
 			break;
 
 		case SCTP_CMD_REPORT_ERROR:
-			error = command->obj.error;
+			error = cmd->obj.error;
 			break;
 
 		case SCTP_CMD_PROCESS_CTSN:
 			/* Dummy up a SACK for processing. */
-			sackh.cum_tsn_ack = command->obj.u32;
+			sackh.cum_tsn_ack = cmd->obj.u32;
 			sackh.a_rwnd = 0;
 			sackh.num_gap_ack_blocks = 0;
 			sackh.num_dup_tsns = 0;
-			sctp_add_cmd_sf(commands,
-					SCTP_CMD_PROCESS_SACK,
+			sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
 					SCTP_SACKH(&sackh));
 			break;
 
@@ -594,13 +571,23 @@
 			break;
 
 		case SCTP_CMD_RTO_PENDING:
-			t = command->obj.transport;
+			t = cmd->obj.transport;
 			t->rto_pending = 1;
 			break;
 
+		case SCTP_CMD_PART_DELIVER:
+			sctp_ulpq_partial_delivery(&asoc->ulpq, cmd->obj.ptr,
+						   GFP_ATOMIC);
+			break;
+
+		case SCTP_CMD_RENEGE:
+			sctp_ulpq_renege(&asoc->ulpq, cmd->obj.ptr,
+					 GFP_ATOMIC);
+			break;
+
 		default:
 			printk(KERN_WARNING "Impossible command: %u, %p\n",
-			       command->verb, command->obj.ptr);
+			       cmd->verb, cmd->obj.ptr);
 			break;
 		};
 		if (error)
@@ -737,7 +724,6 @@
 		asoc->a_rwnd = asoc->rwnd;
 
 		asoc->peer.sack_needed = 0;
-		asoc->peer.next_dup_tsn = 0;
 
 		error = sctp_outq_tail(&asoc->outqueue, sack);
 
@@ -1014,7 +1000,7 @@
 static void sctp_cmd_init_failed(sctp_cmd_seq_t *commands,
 				 sctp_association_t *asoc)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 
 	event = sctp_ulpevent_make_assoc_change(asoc,
 						0,
@@ -1041,7 +1027,7 @@
 				  sctp_subtype_t subtype,
 				  sctp_chunk_t *chunk)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	__u16 error = 0;
 
 	switch(event_type) {
@@ -1061,12 +1047,11 @@
 		break;
 	}
 
-	event = sctp_ulpevent_make_assoc_change(asoc,
-						0,
-						SCTP_COMM_LOST,
-						error, 0, 0,
-						GFP_ATOMIC);
+	/* Cancel any partial delivery in progress. */
+	sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
 
+	event = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_LOST,
+						error, 0, 0, GFP_ATOMIC);
 	if (event)
 		sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
 				SCTP_ULPEVENT(event));
@@ -1141,7 +1126,7 @@
 		if (del_timer(&t->hb_timer))
 			sctp_transport_put(t);
 	}
-} 
+}
 
 /* Helper function to update the heartbeat timer. */
 static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
--- a/net/sctp/sm_statefuns.c	Tue Mar  4 19:30:04 2003
+++ b/net/sctp/sm_statefuns.c	Tue Mar  4 19:30:04 2003
@@ -102,7 +102,7 @@
 				  sctp_cmd_seq_t *commands)
 {
 	sctp_chunk_t *chunk = arg;
-	sctp_ulpevent_t *ev;
+	struct sctp_ulpevent *ev;
 
 	/* RFC 2960 6.10 Bundling
 	 *
@@ -146,6 +146,9 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_CLOSED));
 
+	SCTP_INC_STATS(SctpShutdowns);
+	SCTP_DEC_STATS(SctpCurrEstab);
+
 	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
 
 	return SCTP_DISPOSITION_DELETE_TCB;
@@ -223,6 +226,7 @@
 			if (packet) {
 				sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
 						SCTP_PACKET(packet));
+				SCTP_INC_STATS(SctpOutCtrlChunks);
 				return SCTP_DISPOSITION_CONSUME;
 			} else {
 				return SCTP_DISPOSITION_NOMEM;
@@ -264,7 +268,7 @@
 
 	if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
 		goto nomem_ack;
-	
+
 	repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
 	if (!repl)
 		goto nomem_ack;
@@ -379,6 +383,7 @@
 		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
 		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 				SCTP_STATE(SCTP_STATE_CLOSED));
+		SCTP_INC_STATS(SctpAborteds);
 		sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
 		return SCTP_DISPOSITION_DELETE_TCB;
 	}
@@ -388,6 +393,9 @@
 	if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
 			      (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
 			      &err_chunk)) {
+
+		SCTP_INC_STATS(SctpAborteds);
+
 		/* This chunk contains fatal error. It is to be discarded.
 		 * Send an ABORT, with causes if there is any.
 		 */
@@ -403,6 +411,7 @@
 			if (packet) {
 				sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
 						SCTP_PACKET(packet));
+				SCTP_INC_STATS(SctpOutCtrlChunks);
 				sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 						SCTP_STATE(SCTP_STATE_CLOSED));
 				sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
@@ -504,7 +513,7 @@
 	sctp_association_t *new_asoc;
 	sctp_init_chunk_t *peer_init;
 	sctp_chunk_t *repl;
-	sctp_ulpevent_t *ev;
+	struct sctp_ulpevent *ev;
 	int error = 0;
 	sctp_chunk_t *err_chk_p;
 
@@ -557,6 +566,8 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_ESTABLISHED));
+	SCTP_INC_STATS(SctpCurrEstab);
+	SCTP_INC_STATS(SctpPassiveEstabs);
 	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
 
 	if (new_asoc->autoclose)
@@ -636,7 +647,7 @@
 				      const sctp_subtype_t type, void *arg,
 				      sctp_cmd_seq_t *commands)
 {
-	sctp_ulpevent_t *ev;
+	struct sctp_ulpevent *ev;
 
 	/* RFC 2960 5.1 Normal Establishment of an Association
 	 *
@@ -648,6 +659,8 @@
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_ESTABLISHED));
+	SCTP_INC_STATS(SctpCurrEstab);
+	SCTP_INC_STATS(SctpActiveEstabs);
 	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
 	if (asoc->autoclose)
 		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
@@ -669,7 +682,6 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
 
 	return SCTP_DISPOSITION_CONSUME;
-
 nomem:
 	return SCTP_DISPOSITION_NOMEM;
 }
@@ -719,6 +731,8 @@
 	if (asoc->overall_error_count >= asoc->overall_error_threshold) {
 		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
+		SCTP_INC_STATS(SctpAborteds);
+		SCTP_DEC_STATS(SctpCurrEstab);
 		return SCTP_DISPOSITION_DELETE_TCB;
 	}
 
@@ -929,6 +943,8 @@
 		goto out;
 	sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, SCTP_PACKET(pkt));
 
+	SCTP_INC_STATS(SctpOutCtrlChunks);
+
 	/* Discard the rest of the inbound packet. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
 
@@ -939,7 +955,7 @@
 	return 0;
 }
 
-/* A restart is occuring, check to make sure no new addresses
+/* A restart is occurring, check to make sure no new addresses
  * are being added as we may be under a takeover attack.
  */
 static int sctp_sf_check_restart_addrs(const sctp_association_t *new_asoc,
@@ -1125,6 +1141,7 @@
 			if (packet) {
 				sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
 						SCTP_PACKET(packet));
+				SCTP_INC_STATS(SctpOutCtrlChunks);
 				retval = SCTP_DISPOSITION_CONSUME;
 			} else {
 				retval = SCTP_DISPOSITION_NOMEM;
@@ -1355,7 +1372,7 @@
 					       sctp_association_t *new_asoc)
 {
 	sctp_init_chunk_t *peer_init;
-	sctp_ulpevent_t *ev;
+	struct sctp_ulpevent *ev;
 	sctp_chunk_t *repl;
 
 	/* new_asoc is a brand-new association, so these are not yet
@@ -1413,7 +1430,7 @@
  *      at about the same time but the peer endpoint started its INIT
  *      after responding to the local endpoint's INIT
  */
-/* This case represents an intialization collision.  */
+/* This case represents an initialization collision.  */
 static sctp_disposition_t sctp_sf_do_dupcook_b(const sctp_endpoint_t *ep,
 					       const sctp_association_t *asoc,
 					       sctp_chunk_t *chunk,
@@ -1421,7 +1438,7 @@
 					       sctp_association_t *new_asoc)
 {
 	sctp_init_chunk_t *peer_init;
-	sctp_ulpevent_t *ev;
+	struct sctp_ulpevent *ev;
 	sctp_chunk_t *repl;
 
 	/* new_asoc is a brand-new association, so these are not yet
@@ -1436,6 +1453,7 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_ESTABLISHED));
+	SCTP_INC_STATS(SctpCurrEstab);
 	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
 
 	repl = sctp_make_cookie_ack(new_asoc, chunk);
@@ -1503,7 +1521,7 @@
 					       sctp_cmd_seq_t *commands,
 					       sctp_association_t *new_asoc)
 {
-	sctp_ulpevent_t *ev = NULL;
+	struct sctp_ulpevent *ev = NULL;
 	sctp_chunk_t *repl;
 
 	/* Clarification from Implementor's Guide:
@@ -1519,6 +1537,7 @@
 				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
 		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 				SCTP_STATE(SCTP_STATE_ESTABLISHED));
+		SCTP_INC_STATS(SctpCurrEstab);
 		sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START,
 				SCTP_NULL());
 
@@ -1540,11 +1559,11 @@
 				SCTP_ULPEVENT(ev));
 	}
 	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
-	
+
 	repl = sctp_make_cookie_ack(new_asoc, chunk);
 	if (!repl)
 		goto nomem;
-	
+
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
 	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
 
@@ -1925,6 +1944,8 @@
 
  	/* ASSOC_FAILED will DELETE_TCB. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
+	SCTP_INC_STATS(SctpAborteds);
+	SCTP_DEC_STATS(SctpCurrEstab);
 
 	/* BUG?  This does not look complete... */
 	return SCTP_DISPOSITION_ABORT;
@@ -1948,6 +1969,7 @@
 
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_CLOSED));
+	SCTP_INC_STATS(SctpAborteds);
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
 
@@ -2241,6 +2263,7 @@
 	sctp_datahdr_t *data_hdr;
 	sctp_chunk_t *err;
 	size_t datalen;
+	sctp_verb_t deliver;
 	int tmp;
 	__u32 tsn;
 
@@ -2250,7 +2273,6 @@
 	 * that the value in the Verification Tag field of the
 	 * received SCTP packet matches its own Tag.
 	 */
-
 	if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
 				SCTP_NULL());
@@ -2307,10 +2329,40 @@
 	datalen = ntohs(chunk->chunk_hdr->length);
 	datalen -= sizeof(sctp_data_chunk_t);
 
+	deliver = SCTP_CMD_CHUNK_ULP;
+
+	/* Think about partial delivery. */
+	if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
+
+		/* Even if we don't accept this chunk there is
+		 * memory pressure.
+		 */
+		sctp_add_cmd_sf(commands, SCTP_CMD_PART_DELIVER, SCTP_NULL());
+	}
+
+        /* Spill over rwnd a little bit.  Note: While allowed, this spill over
+	 * seems a bit troublesome in that frag_point varies based on
+	 * PMTU.  In cases, such as loopback, this might be a rather
+	 * large spill over.
+	 */
 	if (asoc->rwnd_over || (datalen > asoc->rwnd + asoc->frag_point)) {
-		SCTP_DEBUG_PRINTK("Discarding tsn: %u datalen: %Zd, "
-				  "rwnd: %d\n", tsn, datalen, asoc->rwnd);
-		goto discard_force;
+
+		/* If this is the next TSN, consider reneging to make
+		 * room.   Note: Playing nice with a confused sender.  A
+		 * malicious sender can still eat up all our buffer
+		 * space and in the future we may want to detect and
+		 * do more drastic reneging. 
+		 */
+		if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
+		    (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
+			SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn);
+			deliver = SCTP_CMD_RENEGE;
+		} else {
+			SCTP_DEBUG_PRINTK("Discard tsn: %u len: %Zd, "
+					  "rwnd: %d\n", tsn, datalen,
+					  asoc->rwnd);
+			goto discard_force;
+		}
 	}
 
 	/*
@@ -2332,13 +2384,24 @@
 		 */
 		sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
+		SCTP_INC_STATS(SctpAborteds);
+		SCTP_DEC_STATS(SctpCurrEstab);
 		return SCTP_DISPOSITION_CONSUME;
 	}
 
-	/* We are accepting this DATA chunk.  */
+	/* If definately accepting the DATA chunk, record its TSN, otherwise
+	 * wait for renege processing.
+	 */
+	if (SCTP_CMD_CHUNK_ULP == deliver)
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
 
-	/* Record the fact that we have received this TSN.  */
-	sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
+	/* Note: Some chunks may get overcounted (if we drop) or overcounted
+	 * if we renege and the chunk arrives again.
+	 */
+	if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+		SCTP_INC_STATS(SctpInUnorderChunks);
+	else
+		SCTP_INC_STATS(SctpInOrderChunks);
 
 	/* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
 	 *
@@ -2352,10 +2415,9 @@
 		err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
 					 &data_hdr->stream,
 					 sizeof(data_hdr->stream));
-		if (err) {
+		if (err)
 			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
 					SCTP_CHUNK(err));
-		}
 		goto discard_noforce;
 	}
 
@@ -2363,7 +2425,8 @@
 	 * SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
 	 * chunk needs the updated rwnd.
 	 */
-	sctp_add_cmd_sf(commands, SCTP_CMD_CHUNK_ULP, SCTP_CHUNK(chunk));
+	sctp_add_cmd_sf(commands, deliver, SCTP_CHUNK(chunk));
+
 	if (asoc->autoclose) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
 				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
@@ -2536,6 +2599,8 @@
 		 */
 		sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
+		SCTP_INC_STATS(SctpAborteds);
+		SCTP_DEC_STATS(SctpCurrEstab);
 		return SCTP_DISPOSITION_CONSUME;
 	}
 
@@ -2544,6 +2609,11 @@
 	/* Record the fact that we have received this TSN.  */
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
 
+	if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+		SCTP_INC_STATS(SctpInUnorderChunks);
+	else
+		SCTP_INC_STATS(SctpInOrderChunks);
+
 	/* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
 	 *
 	 * If an endpoint receive a DATA chunk with an invalid stream
@@ -2705,6 +2775,8 @@
 		sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
 				SCTP_PACKET(packet));
 
+		SCTP_INC_STATS(SctpOutCtrlChunks);
+
 		return SCTP_DISPOSITION_CONSUME;
 	}
 
@@ -2726,7 +2798,7 @@
 					sctp_cmd_seq_t *commands)
 {
 	sctp_chunk_t *chunk = arg;
-	sctp_ulpevent_t *ev;
+	struct sctp_ulpevent *ev;
 
 	while (chunk->chunk_end > chunk->skb->data) {
 		ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0,
@@ -2764,7 +2836,7 @@
 {
 	sctp_chunk_t *chunk = arg;
 	sctp_chunk_t *reply;
-	sctp_ulpevent_t *ev;
+	struct sctp_ulpevent *ev;
 
 	/* 10.2 H) SHUTDOWN COMPLETE notification
 	 *
@@ -2794,6 +2866,8 @@
 
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_CLOSED));
+	SCTP_INC_STATS(SctpShutdowns);
+	SCTP_DEC_STATS(SctpCurrEstab);
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
 
 	/* ...and remove all record of the association. */
@@ -2834,6 +2908,8 @@
 	__u8 *ch_end;
 	int ootb_shut_ack = 0;
 
+	SCTP_INC_STATS(SctpOutOfBlues);
+
 	ch = (sctp_chunkhdr_t *) chunk->chunk_hdr;
 	do {
 		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
@@ -2901,6 +2977,8 @@
 		sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
 				SCTP_PACKET(packet));
 
+		SCTP_INC_STATS(SctpOutCtrlChunks);
+
 		return SCTP_DISPOSITION_CONSUME;
 	}
 
@@ -3472,6 +3550,10 @@
 
 	/* Delete the established association. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
+
+	SCTP_INC_STATS(SctpAborteds);
+	SCTP_DEC_STATS(SctpCurrEstab);
+
 	return retval;
 }
 
@@ -3527,6 +3609,8 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_CLOSED));
 
+	SCTP_INC_STATS(SctpShutdowns);
+
 	sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
 
 	return SCTP_DISPOSITION_DELETE_TCB;
@@ -3597,6 +3681,8 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_CLOSED));
 
+	SCTP_INC_STATS(SctpAborteds);
+
 	/* Even if we can't send the ABORT due to low memory delete the
 	 * TCB.  This is a departure from our typical NOMEM handling.
 	 */
@@ -3734,7 +3820,7 @@
  * o association id - local handle to the SCTP association
  *
  * o destination transport address - the transport address of the
- *   asociation on which a heartbeat should be issued.
+ *   association on which a heartbeat should be issued.
  */
 sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
 					const sctp_endpoint_t *ep,
@@ -3929,6 +4015,8 @@
 	if (asoc->overall_error_count >= asoc->overall_error_threshold) {
 		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
+		SCTP_INC_STATS(SctpAborteds);
+		SCTP_DEC_STATS(SctpCurrEstab);
 		return SCTP_DISPOSITION_DELETE_TCB;
 	}
 
@@ -4096,6 +4184,8 @@
 	if (asoc->overall_error_count >= asoc->overall_error_threshold) {
 		/* Note:  CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
 		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
+		SCTP_INC_STATS(SctpAborteds);
+		SCTP_DEC_STATS(SctpCurrEstab);
 		return SCTP_DISPOSITION_DELETE_TCB;
 	}
 
@@ -4271,6 +4361,9 @@
 	__u16 num_blocks;
 	__u16 num_dup_tsns;
 
+	/* FIXME:  Protect ourselves from reading too far into
+	 * the skb from a bogus sender.
+	 */
 	sack = (sctp_sackhdr_t *) chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_sackhdr_t));
 
@@ -4401,6 +4494,7 @@
 			sctp_packet_append_chunk(packet, err_chunk);
 			sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
 					SCTP_PACKET(packet));
+			SCTP_INC_STATS(SctpOutCtrlChunks);
 		} else
 			sctp_free_chunk (err_chunk);
 	}
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c	Tue Mar  4 19:30:14 2003
+++ b/net/sctp/socket.c	Tue Mar  4 19:30:14 2003
@@ -81,13 +81,13 @@
 
 /* Forward declarations for internal helper functions. */
 static int sctp_writeable(struct sock *sk);
-static inline int sctp_wspace(sctp_association_t *asoc);
+static inline int sctp_wspace(struct sctp_association *asoc);
 static inline void sctp_set_owner_w(sctp_chunk_t *chunk);
 static void sctp_wfree(struct sk_buff *skb);
-static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p,
+static int sctp_wait_for_sndbuf(struct sctp_association *, long *timeo_p,
 				int msg_len);
 static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p);
-static int sctp_wait_for_connect(sctp_association_t *asoc, long *timeo_p);
+static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p);
 static inline int sctp_verify_addr(struct sock *, union sctp_addr *, int);
 static int sctp_bindx_add(struct sock *, struct sockaddr_storage *, int);
 static int sctp_bindx_rem(struct sock *, struct sockaddr_storage *, int);
@@ -158,7 +158,7 @@
 /* Bind a local address either to an endpoint or to an association.  */
 SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
 {
-	sctp_opt_t *sp = sctp_sk(sk);
+	struct sctp_opt *sp = sctp_sk(sk);
 	sctp_endpoint_t *ep = sp->ep;
 	sctp_bind_addr_t *bp = &ep->base.bind_addr;
 	struct sctp_af *af;
@@ -454,7 +454,7 @@
  */
 int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
 {
-	sctp_opt_t *sp = sctp_sk(sk);
+	struct sctp_opt *sp = sctp_sk(sk);
 	sctp_endpoint_t *ep = sp->ep;
 	int cnt;
 	sctp_bind_addr_t *bp = &ep->base.bind_addr;
@@ -662,6 +662,7 @@
 
 	/* Clean up any skbs sitting on the receive queue.  */
 	skb_queue_purge(&sk->receive_queue);
+	skb_queue_purge(&sctp_sk(sk)->pd_lobby);
 
 	/* This will run the backlog queue.  */
 	sctp_release_sock(sk);
@@ -714,7 +715,7 @@
 SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 			     struct msghdr *msg, int msg_len)
 {
-	sctp_opt_t *sp;
+	struct sctp_opt *sp;
 	sctp_endpoint_t *ep;
 	sctp_association_t *new_asoc=NULL, *asoc=NULL;
 	struct sctp_transport *transport;
@@ -939,6 +940,19 @@
 	/* ASSERT: we have a valid association at this point.  */
 	SCTP_DEBUG_PRINTK("We have a valid association.\n");
 
+	if (!sinfo) {
+		/* If the user didn't specify SNDRCVINFO, make up one with
+		 * some defaults.
+		 */
+		default_sinfo.sinfo_stream = asoc->defaults.stream;
+		default_sinfo.sinfo_flags = asoc->defaults.flags;
+		default_sinfo.sinfo_ppid = asoc->defaults.ppid;
+		default_sinfo.sinfo_context = asoc->defaults.context;
+		default_sinfo.sinfo_timetolive = asoc->defaults.timetolive;
+		default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc);
+		sinfo = &default_sinfo;
+	}
+
 	/* API 7.1.7, the sndbuf size per association bounds the
 	 * maximum size of data that can be sent in a single send call.
 	 */
@@ -963,13 +977,6 @@
 			err = -EINVAL;
 			goto out_free;
 		}
-	} else {
-		/* If the user didn't specify SNDRCVINFO, make up one with
-		 * some defaults.
-		 */
-		default_sinfo.sinfo_stream = asoc->defaults.stream;
-		default_sinfo.sinfo_ppid = asoc->defaults.ppid;
-		sinfo = &default_sinfo;
 	}
 
 	timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
@@ -979,21 +986,6 @@
 			goto out_free;
 	}
 
-#if 0
-	/* FIXME: This looks wrong so I'll comment out.
-	 * We should be able to use this same technique for
-	 * primary address override!  --jgrimm
-	 */
-	/* If the user gave us an address, copy it in.  */
-	if (msg->msg_name) {
-		chunk->transport = sctp_assoc_lookup_paddr(asoc, &to);
-		if (!chunk->transport) {
-			err = -EINVAL;
-			goto out_free;
-		}
-	}
-#endif /* 0 */
-
 	/* Break the message into multiple chunks of maximum size. */
 	skb_queue_head_init(&chunks);
 	err = sctp_datachunks_from_user(asoc, sinfo, msg, msg_len, &chunks);
@@ -1013,6 +1005,23 @@
 
 		/* Do accounting for the write space.  */
 		sctp_set_owner_w(chunk);
+
+		/* This flag, in the UDP model, requests the SCTP stack to
+		 * override the primary destination address with the 
+		 * address found with the sendto/sendmsg call.
+		 */
+		if (sinfo_flags & MSG_ADDR_OVER) {
+			if (!msg->msg_name) {
+				err = -EINVAL;
+				goto out_free;
+			}
+			chunk->transport = sctp_assoc_lookup_paddr(asoc, &to);
+			if (!chunk->transport) {
+				err = -EINVAL;
+				goto out_free;
+			}
+		}
+
 		/* Send it to the lower layers.  */
 		sctp_primitive_SEND(asoc, chunk);
 		SCTP_DEBUG_PRINTK("We sent primitively.\n");
@@ -1110,8 +1119,8 @@
 SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 			     int len, int noblock, int flags, int *addr_len)
 {
-	sctp_ulpevent_t *event = NULL;
-	sctp_opt_t *sp = sctp_sk(sk);
+	struct sctp_ulpevent *event = NULL;
+	struct sctp_opt *sp = sctp_sk(sk);
 	struct sk_buff *skb;
 	int copied;
 	int err = 0;
@@ -1143,7 +1152,7 @@
 
 	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
-	event = (sctp_ulpevent_t *) skb->cb;
+	event = sctp_skb2event(skb);
 
 	if (err)
 		goto out_free;
@@ -1170,7 +1179,6 @@
 	/* If skb's length exceeds the user's buffer, update the skb and
 	 * push it back to the receive_queue so that the next call to
 	 * recvmsg() will return the remaining data. Don't set MSG_EOR.
-	 * Otherwise, set MSG_EOR indicating the end of a message.
 	 */
 	if (skb_len > copied) {
 		msg->msg_flags &= ~MSG_EOR;
@@ -1178,6 +1186,7 @@
 			goto out_free;
 		sctp_skb_pull(skb, copied);
 		skb_queue_head(&sk->receive_queue, skb);
+
 		/* When only partial message is copied to the user, increase
 		 * rwnd by that amount. If all the data in the skb is read,
 		 * rwnd is updated when the skb's destructor is called via
@@ -1185,9 +1194,11 @@
 		 */
 		sctp_assoc_rwnd_increase(event->asoc, copied);
 		goto out;
-	} else {
-		 msg->msg_flags |= MSG_EOR;
-	}
+	} else if ((event->msg_flags & MSG_NOTIFICATION) ||
+		   (event->msg_flags & MSG_EOR))
+		msg->msg_flags |= MSG_EOR;
+	else
+		msg->msg_flags &= ~MSG_EOR;
 
 out_free:
 	sctp_ulpevent_free(event); /* Free the skb. */
@@ -1225,7 +1236,7 @@
 static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
 					    int optlen)
 {
-	sctp_opt_t *sp = sctp_sk(sk);
+	struct sctp_opt *sp = sctp_sk(sk);
 
 	/* Applicable to UDP-style socket only */
 	if (SCTP_SOCKET_TCP == sp->type)
@@ -1310,6 +1321,44 @@
 	return 0;
 }
 
+/*
+ *
+ * 7.1.15 Set default send parameters (SET_DEFAULT_SEND_PARAM)
+ *
+ *   Applications that wish to use the sendto() system call may wish to
+ *   specify a default set of parameters that would normally be supplied
+ *   through the inclusion of ancillary data.  This socket option allows
+ *   such an application to set the default sctp_sndrcvinfo structure.
+ *   The application that wishes to use this socket option simply passes
+ *   in to this call the sctp_sndrcvinfo structure defined in Section
+ *   5.2.2) The input parameters accepted by this call include
+ *   sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context,
+ *   sinfo_timetolive.  The user must provide the sinfo_assoc_id field in
+ *   to this call if the caller is using the UDP model.
+ */
+static inline int sctp_setsockopt_set_default_send_param(struct sock *sk,
+						char *optval, int optlen)
+{
+	struct sctp_sndrcvinfo info;
+	sctp_association_t *asoc;
+
+	if (optlen != sizeof(struct sctp_sndrcvinfo))
+		return -EINVAL;
+	if (copy_from_user(&info, optval, optlen))
+		return -EFAULT;
+
+	asoc = sctp_id2assoc(sk, info.sinfo_assoc_id);
+	if (!asoc)
+		return -EINVAL;
+
+	asoc->defaults.stream = info.sinfo_stream;
+	asoc->defaults.flags = info.sinfo_flags;
+	asoc->defaults.ppid = info.sinfo_ppid;
+	asoc->defaults.context = info.sinfo_context;
+	asoc->defaults.timetolive = info.sinfo_timetolive;
+	return 0;
+}
+
 /* API 6.2 setsockopt(), getsockopt()
  *
  * Applications use setsockopt() and getsockopt() to set or retrieve
@@ -1401,6 +1450,11 @@
 		retval = sctp_setsockopt_initmsg(sk, optval, optlen);
 		break;
 
+	case SCTP_SET_DEFAULT_SEND_PARAM:
+		retval = sctp_setsockopt_set_default_send_param(sk,
+							optval, optlen);
+		break;
+
 	default:
 		retval = -ENOPROTOOPT;
 		break;
@@ -1432,7 +1486,7 @@
 SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *uaddr,
 			     int addr_len)
 {
-	sctp_opt_t *sp;
+	struct sctp_opt *sp;
 	sctp_endpoint_t *ep;
 	sctp_association_t *asoc;
 	struct sctp_transport *transport;
@@ -1554,7 +1608,7 @@
 {
 	sctp_endpoint_t *ep;
 	sctp_protocol_t *proto;
-	sctp_opt_t *sp;
+	struct sctp_opt *sp;
 
 	SCTP_DEBUG_PRINTK("sctp_init_sock(sk: %p)\n", sk);
 
@@ -1583,7 +1637,7 @@
 
 	/* Initialize default RTO related parameters.  These parameters can
 	 * be modified for with the SCTP_RTOINFO socket option.
-	 * FIXME: This are not used yet.
+	 * FIXME: These are not used yet.
 	 */
 	sp->rtoinfo.srto_initial = proto->rto_initial;
 	sp->rtoinfo.srto_max     = proto->rto_max;
@@ -1620,6 +1674,11 @@
 	 */
 	sp->autoclose         = 0;
 	sp->pf = sctp_get_pf_specific(sk->family);
+
+	/* Control variables for partial data delivery. */
+	sp->pd_mode           = 0;
+	skb_queue_head_init(&sp->pd_lobby);
+
 	/* Create a per socket endpoint structure.  Even if we
 	 * change the data structure relationships, this may still
 	 * be useful for storing pre-connect address information.
@@ -1774,10 +1833,10 @@
 	struct sock *newsk;
 	struct socket *tmpsock;
 	sctp_endpoint_t *newep;
-	sctp_opt_t *oldsp = sctp_sk(oldsk);
-	sctp_opt_t *newsp;
+	struct sctp_opt *oldsp = sctp_sk(oldsk);
+	struct sctp_opt *newsp;
 	struct sk_buff *skb, *tmp;
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	int err = 0;
 
 	/* An association cannot be branched off from an already peeled-off
@@ -1811,13 +1870,50 @@
 	 * peeled off association to the new socket's receive queue.
 	 */
 	sctp_skb_for_each(skb, &oldsk->receive_queue, tmp) {
-		event = (sctp_ulpevent_t *)skb->cb;
+		event = sctp_skb2event(skb);
 		if (event->asoc == assoc) {
 			__skb_unlink(skb, skb->list);
 			__skb_queue_tail(&newsk->receive_queue, skb);
 		}
 	}
 
+	/* Clean up an messages pending delivery due to partial
+	 * delivery.   Three cases:
+	 * 1) No partial deliver;  no work.
+	 * 2) Peeling off partial delivery; keep pd_lobby in new pd_lobby.
+	 * 3) Peeling off non-partial delivery; move pd_lobby to recieve_queue.
+	 */
+	skb_queue_head_init(&newsp->pd_lobby);
+	sctp_sk(newsk)->pd_mode = assoc->ulpq.pd_mode;;
+
+	if (sctp_sk(oldsk)->pd_mode) {
+		struct sk_buff_head *queue;
+
+		/* Decide which queue to move pd_lobby skbs to. */
+		if (assoc->ulpq.pd_mode) {
+			queue = &newsp->pd_lobby;
+		} else
+			queue = &newsk->receive_queue;
+
+		/* Walk through the pd_lobby, looking for skbs that
+		 * need moved to the new socket.
+		 */
+		sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
+			event = sctp_skb2event(skb);
+			if (event->asoc == assoc) {
+				__skb_unlink(skb, skb->list);
+				__skb_queue_tail(queue, skb);
+			}
+		}
+
+		/* Clear up any skbs waiting for the partial
+		 * delivery to finish.
+		 */
+		if (assoc->ulpq.pd_mode)
+			sctp_clear_pd(oldsk);
+
+	}
+
 	/* Set the type of socket to indicate that it is peeled off from the
 	 * original socket.
 	 */
@@ -2087,6 +2183,50 @@
 	return 0;
 }
 
+/*
+ *
+ * 7.1.15 Set default send parameters (SET_DEFAULT_SEND_PARAM)
+ *
+ *   Applications that wish to use the sendto() system call may wish to
+ *   specify a default set of parameters that would normally be supplied
+ *   through the inclusion of ancillary data.  This socket option allows
+ *   such an application to set the default sctp_sndrcvinfo structure.
+ *   The application that wishes to use this socket option simply passes
+ *   in to this call the sctp_sndrcvinfo structure defined in Section
+ *   5.2.2) The input parameters accepted by this call include
+ *   sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context,
+ *   sinfo_timetolive.  The user must provide the sinfo_assoc_id field in
+ *   to this call if the caller is using the UDP model.
+ *
+ *   For getsockopt, it get the default sctp_sndrcvinfo structure.
+ */
+static inline int sctp_getsockopt_set_default_send_param(struct sock *sk,
+					int len, char *optval, int *optlen)
+{
+	struct sctp_sndrcvinfo info;
+	sctp_association_t *asoc;
+
+	if (len != sizeof(struct sctp_sndrcvinfo))
+		return -EINVAL;
+	if (copy_from_user(&info, optval, sizeof(struct sctp_sndrcvinfo)))
+		return -EFAULT;
+
+	asoc = sctp_id2assoc(sk, info.sinfo_assoc_id);
+	if (!asoc)
+		return -EINVAL;
+
+	info.sinfo_stream = asoc->defaults.stream;
+	info.sinfo_flags = asoc->defaults.flags;
+	info.sinfo_ppid = asoc->defaults.ppid;
+	info.sinfo_context = asoc->defaults.context;
+	info.sinfo_timetolive = asoc->defaults.timetolive;
+
+	if (copy_to_user(optval, &info, sizeof(struct sctp_sndrcvinfo)))
+		return -EFAULT;
+
+	return 0;
+}
+
 SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
 				char *optval, int *optlen)
 {
@@ -2164,6 +2304,11 @@
 							      optlen);
 		break;
 
+	case SCTP_SET_DEFAULT_SEND_PARAM:
+		retval = sctp_getsockopt_set_default_send_param(sk, len,
+							optval, optlen);
+		break;
+
 	default:
 		retval = -ENOPROTOOPT;
 		break;
@@ -2389,7 +2534,7 @@
  */
 SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
 {
-	sctp_opt_t *sp = sctp_sk(sk);
+	struct sctp_opt *sp = sctp_sk(sk);
 	sctp_endpoint_t *ep = sp->ep;
 
 	/* Only UDP style sockets that are not peeled off are allowed to
diff -Nru a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
--- a/net/sctp/tsnmap.c	Tue Mar  4 19:30:14 2003
+++ b/net/sctp/tsnmap.c	Tue Mar  4 19:30:14 2003
@@ -3,40 +3,40 @@
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * These functions manipulate sctp tsn mapping array.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation 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, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Jon Grimm             <jgrimm@us.ibm.com>
  *    Karl Knutson          <karl@athena.chicago.il.us>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -45,21 +45,21 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-static void _sctp_tsnmap_update(sctp_tsnmap_t *map);
-static void _sctp_tsnmap_update_pending_data(sctp_tsnmap_t *map);
-static void _sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
-				      __u16 len, __u16 base,
-				      int *started, __u16 *start,
-				      int *ended, __u16 *end);
+static void sctp_tsnmap_update(struct sctp_tsnmap *map);
+static void sctp_tsnmap_update_pending_data(struct sctp_tsnmap *map);
+static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
+				     __u16 len, __u16 base,
+				     int *started, __u16 *start,
+				     int *ended, __u16 *end);
 
 /* Create a new sctp_tsnmap.
  * Allocate room to store at least 'len' contiguous TSNs.
  */
-sctp_tsnmap_t *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int priority)
+struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int priority)
 {
-	sctp_tsnmap_t *retval;
+	struct sctp_tsnmap *retval;
 
-	retval = kmalloc(sizeof(sctp_tsnmap_t) +
+	retval = kmalloc(sizeof(struct sctp_tsnmap) +
 			 sctp_tsnmap_storage_size(len),
 			 priority);
 	if (!retval)
@@ -72,13 +72,13 @@
 
 fail_map:
 	kfree(retval);
-
 fail:
 	return NULL;
 }
 
 /* Initialize a block of memory as a tsnmap.  */
-sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn)
+struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
+				     __u32 initial_tsn)
 {
 	map->tsn_map = map->raw_map;
 	map->overflow_map = map->tsn_map + len;
@@ -94,6 +94,7 @@
 	map->max_tsn_seen = map->cumulative_tsn_ack_point;
 	map->malloced = 0;
 	map->pending_data = 0;
+	map->num_dup_tsns = 0;
 
 	return map;
 }
@@ -104,7 +105,7 @@
  *  >0 if the TSN has been seen (duplicate)
  *  <0 if the TSN is invalid (too large to track)
  */
-int sctp_tsnmap_check(const sctp_tsnmap_t *map, __u32 tsn)
+int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn)
 {
 	__s32 gap;
 	int dup;
@@ -136,7 +137,7 @@
 }
 
 /* Is there a gap in the TSN map?  */
-int sctp_tsnmap_has_gap(const sctp_tsnmap_t *map)
+int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
 {
 	int has_gap;
 
@@ -145,7 +146,7 @@
 }
 
 /* Mark this TSN as seen.  */
-void sctp_tsnmap_mark(sctp_tsnmap_t *map, __u32 tsn)
+void sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn)
 {
 	__s32 gap;
 
@@ -173,40 +174,45 @@
 	/* Go fixup any internal TSN mapping variables including
 	 * cumulative_tsn_ack_point.
 	 */
-	_sctp_tsnmap_update(map);
+	sctp_tsnmap_update(map);
+}
+
+void sctp_tsnmap_report_dup(struct sctp_tsnmap *map, __u32 tsn)
+{
 }
 
 /* Retrieve the Cumulative TSN Ack Point. */
-__u32 sctp_tsnmap_get_ctsn(const sctp_tsnmap_t *map)
+__u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map)
 {
 	return map->cumulative_tsn_ack_point;
 }
 
 /* Retrieve the highest TSN we've seen.  */
-__u32 sctp_tsnmap_get_max_tsn_seen(const sctp_tsnmap_t *map)
+__u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map)
 {
 	return map->max_tsn_seen;
 }
 
 /* Dispose of a tsnmap.  */
-void sctp_tsnmap_free(sctp_tsnmap_t *map)
+void sctp_tsnmap_free(struct sctp_tsnmap *map)
 {
 	if (map->malloced)
 		kfree(map);
 }
 
 /* Initialize a Gap Ack Block iterator from memory being provided.  */
-void sctp_tsnmap_iter_init(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter)
+void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
+			   struct sctp_tsnmap_iter *iter)
 {
 	/* Only start looking one past the Cumulative TSN Ack Point.  */
 	iter->start = map->cumulative_tsn_ack_point + 1;
 }
 
-/* Get the next Gap Ack Blocks. Returns 0 if there was not
- * another block to get.
+/* Get the next Gap Ack Blocks. Returns 0 if there was not another block
+ * to get.
  */
-int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter,
-			     __u16 *start, __u16 *end)
+int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
+	struct sctp_tsnmap_iter *iter, __u16 *start, __u16 *end)
 {
 	int started, ended;
 	__u16 _start, _end, offset;
@@ -216,12 +222,10 @@
 
 	/* Search the first mapping array.  */
 	if (iter->start - map->base_tsn < map->len) {
+
 		offset = iter->start - map->base_tsn;
-		_sctp_tsnmap_find_gap_ack(map->tsn_map,
-					  offset,
-					  map->len, 0,
-					  &started, &_start,
-					  &ended, &_end);
+		sctp_tsnmap_find_gap_ack(map->tsn_map, offset, map->len, 0,
+					 &started, &_start, &ended, &_end);
 	}
 
 	/* Do we need to check the overflow map? */
@@ -235,12 +239,12 @@
 			offset = iter->start - map->base_tsn - map->len;
 
 		/* Search the overflow map.  */
-		_sctp_tsnmap_find_gap_ack(map->overflow_map,
-					  offset,
-					  map->len,
-					  map->len,
-					  &started, &_start,
-					  &ended, &_end);
+		sctp_tsnmap_find_gap_ack(map->overflow_map,
+					 offset,
+					 map->len,
+					 map->len,
+					 &started, &_start,
+					 &ended, &_end);
 	}
 
 	/* The Gap Ack Block happens to end at the end of the
@@ -278,7 +282,7 @@
 /* This private helper function updates the tsnmap buffers and
  * the Cumulative TSN Ack Point.
  */
-static void _sctp_tsnmap_update(sctp_tsnmap_t *map)
+static void sctp_tsnmap_update(struct sctp_tsnmap *map)
 {
 	__u32 ctsn;
 
@@ -301,10 +305,10 @@
 	} while (map->tsn_map[ctsn - map->base_tsn]);
 
 	map->cumulative_tsn_ack_point = ctsn - 1; /* Back up one. */
-	_sctp_tsnmap_update_pending_data(map);
+	sctp_tsnmap_update_pending_data(map);
 }
 
-static void _sctp_tsnmap_update_pending_data(sctp_tsnmap_t *map)
+static void sctp_tsnmap_update_pending_data(struct sctp_tsnmap *map)
 {
 	__u32 cum_tsn = map->cumulative_tsn_ack_point;
 	__u32 max_tsn = map->max_tsn_seen;
@@ -324,7 +328,7 @@
 	for (i = start; i < end; i++) {
 		if (map->tsn_map[i])
 			pending_data--;
-	} 
+	}
 
 	if (gap >= map->len) {
 		start = 0;
@@ -345,14 +349,14 @@
  * The flags "started" and "ended" tell is if we found the beginning
  * or (respectively) the end of a Gap Ack Block.
  */
-static void _sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
-				      __u16 len, __u16 base,
-				      int *started, __u16 *start,
-				      int *ended, __u16 *end)
+static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
+				     __u16 len, __u16 base,
+				     int *started, __u16 *start,
+				     int *ended, __u16 *end)
 {
 	int i = off;
 
-	/* Let's look through the entire array, but break out
+	/* Look through the entire array, but break out
 	 * early if we have found the end of the Gap Ack Block.
 	 */
 
@@ -380,4 +384,24 @@
 			}
 		}
 	}
+}
+
+/* Renege that we have seen a TSN.  */
+void sctp_tsnmap_renege(struct sctp_tsnmap *map, __u32 tsn)
+{
+	__s32 gap;
+
+	if (TSN_lt(tsn, map->base_tsn))
+		return;
+	if (!TSN_lt(tsn, map->base_tsn + map->len + map->len))
+		return;
+	
+	/* Assert: TSN is in range.  */
+	gap = tsn - map->base_tsn;
+
+	/* Pretend we never saw the TSN.  */
+	if (gap < map->len)
+		map->tsn_map[gap] = 0;
+	else
+		map->overflow_map[gap - map->len] = 0;
 }
diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
--- a/net/sctp/ulpevent.c	Tue Mar  4 19:30:05 2003
+++ b/net/sctp/ulpevent.c	Tue Mar  4 19:30:05 2003
@@ -5,37 +5,37 @@
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
- * 
- * These functions manipulate an sctp event.   The sctp_ulpevent_t is used
- * to carry notifications and data to the ULP (sockets).  
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * These functions manipulate an sctp event.   The struct ulpevent is used
+ * to carry notifications and data to the ULP (sockets).
+ * The SCTP reference implementation 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, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email address(es):
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    Jon Grimm             <jgrimm@us.ibm.com>
  *    La Monte H.P. Yarroll <piggy@acm.org>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -47,58 +47,51 @@
 #include <net/sctp/sm.h>
 
 static void sctp_ulpevent_set_owner_r(struct sk_buff *skb,
-				      sctp_association_t *asoc);
-static void
-sctp_ulpevent_set_owner(struct sk_buff *skb, const sctp_association_t *asoc);
+				      struct sctp_association *asoc);
+static void sctp_ulpevent_set_owner(struct sk_buff *skb,
+				    const struct sctp_association *asoc);
 
 /* Create a new sctp_ulpevent.  */
-sctp_ulpevent_t *sctp_ulpevent_new(int size, int msg_flags, int priority)
+struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, int priority)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	struct sk_buff *skb;
 
 	skb = alloc_skb(size, priority);
 	if (!skb)
 		goto fail;
 
-	event = (sctp_ulpevent_t *) skb->cb;
-	event = sctp_ulpevent_init(event, skb, msg_flags);
+	event = sctp_skb2event(skb);
+	event = sctp_ulpevent_init(event, msg_flags);
 	if (!event)
 		goto fail_init;
-
-	event->malloced = 1;
 	return event;
 
 fail_init:
-	kfree_skb(event->parent);
-
+	kfree_skb(skb);
 fail:
 	return NULL;
 }
 
 /* Initialize an ULP event from an given skb.  */
-sctp_ulpevent_t *sctp_ulpevent_init(sctp_ulpevent_t *event,
-				    struct sk_buff *parent,
-				    int msg_flags)
+struct sctp_ulpevent *sctp_ulpevent_init(struct sctp_ulpevent *event,
+					 int msg_flags)
 {
-	memset(event, sizeof(sctp_ulpevent_t), 0x00);
+	memset(event, sizeof(struct sctp_ulpevent), 0x00);
 	event->msg_flags = msg_flags;
-	event->parent = parent;
-	event->malloced = 0;
 	return event;
 }
 
 /* Dispose of an event.  */
-void sctp_ulpevent_free(sctp_ulpevent_t *event)
+void sctp_ulpevent_free(struct sctp_ulpevent *event)
 {
-	if (event->malloced)
-		kfree_skb(event->parent);
+	kfree_skb(sctp_event2skb(event));
 }
 
 /* Is this a MSG_NOTIFICATION?  */
-int sctp_ulpevent_is_notification(const sctp_ulpevent_t *event)
+int sctp_ulpevent_is_notification(const struct sctp_ulpevent *event)
 {
-	return event->msg_flags & MSG_NOTIFICATION;
+	return MSG_NOTIFICATION == (event->msg_flags & MSG_NOTIFICATION);
 }
 
 /* Create and initialize an SCTP_ASSOC_CHANGE event.
@@ -112,24 +105,22 @@
  * Note: There is no field checking here.  If a field is unused it will be
  * zero'd out.
  */
-sctp_ulpevent_t *sctp_ulpevent_make_assoc_change(const sctp_association_t *asoc,
-						 __u16 flags,
-						 __u16 state,
-						 __u16 error,
-						 __u16 outbound,
-						 __u16 inbound,
-						 int priority)
+struct sctp_ulpevent  *sctp_ulpevent_make_assoc_change(
+	const sctp_association_t *asoc,
+	__u16 flags, __u16 state, __u16 error, __u16 outbound,
+	__u16 inbound, int priority)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	struct sctp_assoc_change *sac;
+	struct sk_buff *skb;
 
 	event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
 				  MSG_NOTIFICATION, priority);
 	if (!event)
 		goto fail;
-
+	skb = sctp_event2skb(event);
 	sac = (struct sctp_assoc_change *)
-		skb_put(event->parent, sizeof(struct sctp_assoc_change));
+		skb_put(skb, sizeof(struct sctp_assoc_change));
 
 	/* Socket Extensions for SCTP
 	 * 5.3.1.1 SCTP_ASSOC_CHANGE
@@ -198,13 +189,13 @@
 	 * All notifications for a given association have the same association
 	 * identifier.  For TCP style socket, this field is ignored.
 	 */
-	sctp_ulpevent_set_owner(event->parent, asoc);
+	sctp_ulpevent_set_owner(skb, asoc);
 	sac->sac_assoc_id = sctp_assoc2id(asoc);
 
 	return event;
 
 fail:
-	return NULL;	
+	return NULL;
 }
 
 /* Create and initialize an SCTP_PEER_ADDR_CHANGE event.
@@ -215,24 +206,22 @@
  * When a destination address on a multi-homed peer encounters a change
  * an interface details event is sent.
  */
-sctp_ulpevent_t *sctp_ulpevent_make_peer_addr_change(
-				const sctp_association_t *asoc,
-				const struct sockaddr_storage *aaddr,
-				int flags,
-				int state,
-				int error,
-				int priority)
+struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
+	const sctp_association_t *asoc, const struct sockaddr_storage *aaddr,
+	int flags, int state, int error, int priority)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	struct sctp_paddr_change  *spc;
+	struct sk_buff *skb;
 
 	event = sctp_ulpevent_new(sizeof(struct sctp_paddr_change),
 				  MSG_NOTIFICATION, priority);
 	if (!event)
 		goto fail;
 
+	skb = sctp_event2skb(event);
 	spc = (struct sctp_paddr_change *)
-		skb_put(event->parent, sizeof(struct sctp_paddr_change));
+		skb_put(skb, sizeof(struct sctp_paddr_change));
 
 	/* Sockets API Extensions for SCTP
 	 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
@@ -265,7 +254,7 @@
 	 * Section 5.3.1.2 SCTP_PEER_ADDR_CHANGE
 	 *
 	 * spc_state:  32 bits (signed integer)
-	 * 
+	 *
 	 * This field holds one of a number of values that communicate the
 	 * event that happened to the address.
 	 */
@@ -291,7 +280,7 @@
 	 * All notifications for a given association have the same association
 	 * identifier.  For TCP style socket, this field is ignored.
 	 */
-	sctp_ulpevent_set_owner(event->parent, asoc);
+	sctp_ulpevent_set_owner(skb, asoc);
 	spc->spc_assoc_id = sctp_assoc2id(asoc);
 
 	/* Sockets API Extensions for SCTP
@@ -325,12 +314,11 @@
  * specification [SCTP] and any extensions for a list of possible
  * error formats.
  */
-sctp_ulpevent_t *sctp_ulpevent_make_remote_error(const sctp_association_t *asoc,
-						 sctp_chunk_t *chunk,
-						 __u16 flags,
-						 int priority)
+struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
+	const sctp_association_t *asoc, sctp_chunk_t *chunk,
+	__u16 flags, int priority)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	struct sctp_remote_error *sre;
 	struct sk_buff *skb;
 	sctp_errhdr_t *ch;
@@ -358,13 +346,12 @@
 		goto fail;
 
 	/* Embed the event fields inside the cloned skb.  */
-	event = (sctp_ulpevent_t *) skb->cb;
-	event = sctp_ulpevent_init(event, skb, MSG_NOTIFICATION);
+	event = sctp_skb2event(skb);
+	event = sctp_ulpevent_init(event, MSG_NOTIFICATION);
 
 	if (!event)
 		goto fail;
 
-	event->malloced = 1;
 	sre = (struct sctp_remote_error *)
 		skb_push(skb, sizeof(struct sctp_remote_error));
 
@@ -416,7 +403,8 @@
 	 * All notifications for a given association have the same association
 	 * identifier.  For TCP style socket, this field is ignored.
 	 */
-	sctp_ulpevent_set_owner(event->parent, asoc);
+	skb = sctp_event2skb(event);
+	sctp_ulpevent_set_owner(skb, asoc);
 	sre->sre_assoc_id = sctp_assoc2id(asoc);
 
 	return event;
@@ -430,13 +418,11 @@
  * Socket Extensions for SCTP - draft-01
  * 5.3.1.4 SCTP_SEND_FAILED
  */
-sctp_ulpevent_t *sctp_ulpevent_make_send_failed(const sctp_association_t *asoc,
-						sctp_chunk_t *chunk,
-						__u16 flags,
-						__u32 error,
-						int priority)
+struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
+	const sctp_association_t *asoc, sctp_chunk_t *chunk,
+	__u16 flags, __u32 error, int priority)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	struct sctp_send_failed *ssf;
 	struct sk_buff *skb;
 
@@ -452,16 +438,11 @@
 	skb_pull(skb, sizeof(sctp_data_chunk_t));
 
 	/* Embed the event fields inside the cloned skb.  */
-	event = (sctp_ulpevent_t *) skb->cb;
-	event = sctp_ulpevent_init(event, skb, MSG_NOTIFICATION);
+	event = sctp_skb2event(skb);
+	event = sctp_ulpevent_init(event, MSG_NOTIFICATION);
 	if (!event)
 		goto fail;
 
-	/* Mark as malloced, even though the constructor was not
-	 * called.
-	 */
-	event->malloced = 1;
-
 	ssf = (struct sctp_send_failed *)
 		skb_push(skb, sizeof(struct sctp_send_failed));
 
@@ -525,7 +506,8 @@
 	 * same association identifier.  For TCP style socket, this field is
 	 * ignored.
 	 */
-	sctp_ulpevent_set_owner(event->parent, asoc);
+	skb = sctp_event2skb(event);
+	sctp_ulpevent_set_owner(skb, asoc);
 	ssf->ssf_assoc_id = sctp_assoc2id(asoc);
 	return event;
 
@@ -538,21 +520,22 @@
  * Socket Extensions for SCTP - draft-01
  * 5.3.1.5 SCTP_SHUTDOWN_EVENT
  */
-sctp_ulpevent_t *sctp_ulpevent_make_shutdown_event(
+struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
 	const sctp_association_t *asoc,
-	__u16 flags,
-	int priority)
+	__u16 flags, int priority)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 	struct sctp_shutdown_event *sse;
+	struct sk_buff *skb;
 
 	event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
 				  MSG_NOTIFICATION, priority);
 	if (!event)
 		goto fail;
 
+	skb = sctp_event2skb(event);
 	sse = (struct sctp_shutdown_event *)
-		skb_put(event->parent, sizeof(struct sctp_shutdown_event));
+		skb_put(skb, sizeof(struct sctp_shutdown_event));
 
 	/* Socket Extensions for SCTP
 	 * 5.3.1.5 SCTP_SHUTDOWN_EVENT
@@ -587,7 +570,7 @@
 	 * All notifications for a given association have the same association
 	 * identifier.  For TCP style socket, this field is ignored.
 	 */
-	sctp_ulpevent_set_owner(event->parent, asoc);
+	sctp_ulpevent_set_owner(skb, asoc);
 	sse->sse_assoc_id = sctp_assoc2id(asoc);
 
 	return event;
@@ -600,13 +583,13 @@
  * to pass it to the upper layers.  Go ahead and calculate the sndrcvinfo
  * even if filtered out later.
  *
- * Socket Extensions for SCTP - draft-01
+ * Socket Extensions for SCTP
  * 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
  */
-sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
-					   sctp_chunk_t *chunk, int priority)
+struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
+		   sctp_chunk_t *chunk, int priority)
 {
-	sctp_ulpevent_t *event, *levent;
+	struct sctp_ulpevent *event;
 	struct sctp_sndrcvinfo *info;
 	struct sk_buff *skb, *list;
 	size_t padding, len;
@@ -638,24 +621,19 @@
 	sctp_ulpevent_set_owner_r(skb, asoc);
 
 	/* Embed the event fields inside the cloned skb.  */
-	event = (sctp_ulpevent_t *) skb->cb;
+	event = sctp_skb2event(skb);
 
 	/* Initialize event with flags 0.  */
-	event = sctp_ulpevent_init(event, skb, 0);
+	event = sctp_ulpevent_init(event, 0);
 	if (!event)
 		goto fail_init;
 
-	event->malloced = 1;
-
-	for (list = skb_shinfo(skb)->frag_list; list; list = list->next) {
+	/* Note:  Not clearing the entire event struct as
+	 * this is just a fragment of the real event.  However,
+	 * we still need to do rwnd accounting. 
+	 */
+	for (list = skb_shinfo(skb)->frag_list; list; list = list->next)
 		sctp_ulpevent_set_owner_r(list, asoc);
-		/* Initialize event with flags 0.  */
-		levent = sctp_ulpevent_init(event, skb, 0);
-		if (!levent)
-			goto fail_init;
-
-		levent->malloced = 1;
-	}
 
 	info = (struct sctp_sndrcvinfo *) &event->sndrcvinfo;
 
@@ -707,18 +685,26 @@
 	 * MSG_UNORDERED - This flag is present when the message was sent
 	 *                 non-ordered.
 	 */
-	if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+	if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
 		info->sinfo_flags |= MSG_UNORDERED;
 
-	/* FIXME:  For reassembly, we need to have the fragmentation bits.
-	 * This really does not belong in the event structure, but
-	 * its difficult to fix everything at the same time.   Eventually,
-	 * we should create and skb based chunk structure.   This structure
-	 * storage can be converted to an event.  --jgrimm
+		/* sinfo_cumtsn: 32 bit (unsigned integer)
+		 *  
+		 * This field will hold the current cumulative TSN as 
+		 * known by the underlying SCTP layer.  Note this field is 
+		 * ignored when sending and only valid for a receive 
+		 * operation when sinfo_flags are set to MSG_UNORDERED.
+		 */
+		info->sinfo_cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
+	}
+
+	/* Note:  For reassembly, we need to have the fragmentation bits. 
+	 * For now, merge these into the msg_flags, since those bit
+	 * possitions are not used.
 	 */
-	event->chunk_flags = chunk->chunk_hdr->flags;
+	event->msg_flags |= chunk->chunk_hdr->flags;
 
-	/* With -04 draft, tsn moves into sndrcvinfo. */
+	/* With 04 draft, tsn moves into sndrcvinfo. */
 	info->sinfo_tsn = ntohl(chunk->subh.data_hdr->tsn);
 
 	/* Context is not used on receive. */
@@ -745,19 +731,79 @@
 	return NULL;
 }
 
+/* Create a partial delivery related event. 
+ *
+ * 5.3.1.7 SCTP_PARTIAL_DELIVERY_EVENT
+ *
+ *   When a reciever is engaged in a partial delivery of a
+ *   message this notification will be used to inidicate
+ *   various events.
+ */
+struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
+	const sctp_association_t *asoc, __u32 indication, int priority)
+{
+	struct sctp_ulpevent *event;
+	struct sctp_rcv_pdapi_event *pd;
+	struct sk_buff *skb;
+
+	event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
+				  MSG_NOTIFICATION, priority);
+	if (!event)
+		goto fail;
+
+	skb = sctp_event2skb(event);
+	pd = (struct sctp_rcv_pdapi_event *)
+		skb_put(skb, sizeof(struct sctp_rcv_pdapi_event));
+
+	/* pdapi_type
+	 *   It should be SCTP_PARTIAL_DELIVERY_EVENT
+	 *
+	 * pdapi_flags: 16 bits (unsigned integer)
+	 *   Currently unused.
+	 */
+	pd->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
+	pd->pdapi_flags = 0;
+
+	/* pdapi_length: 32 bits (unsigned integer)
+	 *
+	 * This field is the total length of the notification data, including
+	 * the notification header.  It will generally be sizeof (struct
+	 * sctp_rcv_pdapi_event).
+	 */
+	pd->pdapi_length = sizeof(struct sctp_rcv_pdapi_event);
+
+        /*  pdapi_indication: 32 bits (unsigned integer)
+	 *
+	 * This field holds the indication being sent to the application.
+	 */
+	pd->pdapi_indication = indication;
+
+	/*  pdapi_assoc_id: sizeof (sctp_assoc_t)
+	 * 
+	 * The association id field, holds the identifier for the association.
+	 */
+	pd->pdapi_assoc_id = sctp_assoc2id(asoc);
+
+	return event;
+fail:
+	return NULL;
+}
+
 /* Return the notification type, assuming this is a notification
  * event.
  */
-__u16 sctp_ulpevent_get_notification_type(const sctp_ulpevent_t *event)
+__u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event)
 {
 	union sctp_notification *notification;
+	struct sk_buff *skb;
 
-	notification = (union sctp_notification *) event->parent->data;
+	skb = sctp_event2skb((struct sctp_ulpevent *)event);
+	notification = (union sctp_notification *) skb->data;
 	return notification->h.sn_type;
 }
 
 /* Copy out the sndrcvinfo into a msghdr.  */
-void sctp_ulpevent_read_sndrcvinfo(const sctp_ulpevent_t *event,
+void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
 				   struct msghdr *msghdr)
 {
 	if (!sctp_ulpevent_is_notification(event)) {
@@ -771,7 +817,7 @@
 static void sctp_rcvmsg_rfree(struct sk_buff *skb)
 {
 	sctp_association_t *asoc;
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 
 	/* Current stack structures assume that the rcv buffer is
 	 * per socket.   For UDP style sockets this is not true as
@@ -779,16 +825,17 @@
 	 * Use the local private area of the skb to track the owning
 	 * association.
 	 */
-	event = (sctp_ulpevent_t *) skb->cb;
+	event = sctp_skb2event(skb);
 	asoc = event->asoc;
 	sctp_assoc_rwnd_increase(asoc, skb_headlen(skb));
 	sctp_association_put(asoc);
 }
 
-/* Charge receive window for bytes recieved.  */
-static void sctp_ulpevent_set_owner_r(struct sk_buff *skb, sctp_association_t *asoc)
+/* Charge receive window for bytes received.  */
+static void sctp_ulpevent_set_owner_r(struct sk_buff *skb,
+				      sctp_association_t *asoc)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 
 	/* The current stack structures assume that the rcv buffer is
 	 * per socket.  For UDP-style sockets this is not true as
@@ -798,7 +845,7 @@
 	 */
 	sctp_association_hold(asoc);
 	skb->sk = asoc->base.sk;
-	event = (sctp_ulpevent_t *) skb->cb;
+	event = sctp_skb2event(skb);
 	event->asoc = asoc;
 
 	skb->destructor = sctp_rcvmsg_rfree;
@@ -809,26 +856,26 @@
 /* A simple destructor to give up the reference to the association. */
 static void sctp_ulpevent_rfree(struct sk_buff *skb)
 {
-	sctp_ulpevent_t *event;	
-	
-	event = (sctp_ulpevent_t *)skb->cb;
+	struct sctp_ulpevent *event;
+
+	event = sctp_skb2event(skb);
 	sctp_association_put(event->asoc);
 }
 
-/* Hold the association in case the msg_name needs read out of 
- * the association. 
+/* Hold the association in case the msg_name needs read out of
+ * the association.
  */
 static void sctp_ulpevent_set_owner(struct sk_buff *skb,
-				    const sctp_association_t *asoc)
+				    const struct sctp_association *asoc)
 {
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 
 	/* Cast away the const, as we are just wanting to
 	 * bump the reference count.
 	 */
-	sctp_association_hold((sctp_association_t *)asoc);
+	sctp_association_hold((struct sctp_association *)asoc);
 	skb->sk = asoc->base.sk;
-	event = (sctp_ulpevent_t *)skb->cb;
-	event->asoc = (sctp_association_t *)asoc;
+	event = sctp_skb2event(skb);
+	event->asoc = (struct sctp_association *)asoc;
 	skb->destructor = sctp_ulpevent_rfree;
 }
diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c	Tue Mar  4 19:30:13 2003
+++ b/net/sctp/ulpqueue.c	Tue Mar  4 19:30:13 2003
@@ -84,6 +84,7 @@
 	ulpq->asoc = asoc;
 	skb_queue_head_init(&ulpq->reasm);
 	skb_queue_head_init(&ulpq->lobby);
+	ulpq->pd_mode  = 0;
 	ulpq->malloced = 0;
 
 	return ulpq;
@@ -96,15 +97,16 @@
 	struct sk_buff *skb;
 	struct sctp_ulpevent *event;
 
-	while ((skb = skb_dequeue(&ulpq->lobby))) {
-		event = (struct sctp_ulpevent *) skb->cb;
+	while ((skb = __skb_dequeue(&ulpq->lobby))) {
+		event = sctp_skb2event(skb);
 		sctp_ulpevent_free(event);
 	}
 
-	while ((skb = skb_dequeue(&ulpq->reasm))) {
-		event = (struct sctp_ulpevent *) skb->cb;
+	while ((skb = __skb_dequeue(&ulpq->reasm))) {
+		event = sctp_skb2event(skb);
 		sctp_ulpevent_free(event);
 	}
+
 }
 
 /* Dispose of a ulpqueue.  */
@@ -117,7 +119,7 @@
 
 /* Process an incoming DATA chunk.  */
 int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, sctp_chunk_t *chunk,
-			    int priority)
+			int priority)
 {
 	struct sk_buff_head temp;
 	sctp_data_chunk_t *hdr;
@@ -125,12 +127,7 @@
 
 	hdr = (sctp_data_chunk_t *) chunk->chunk_hdr;
 
-	/* FIXME: Instead of event being the skb clone, we really should
-	 * have a new skb based chunk structure that we can convert to
-	 * an event.  Temporarily, I'm carrying a few chunk fields in
-	 * the event to allow reassembly.  Its too painful to change
-	 * everything at once.  --jgrimm
-	 */
+	/* Create an event from the incoming chunk. */
 	event = sctp_ulpevent_make_rcvmsg(chunk->asoc, chunk, priority);
 	if (!event)
 		return -ENOMEM;
@@ -139,10 +136,10 @@
 	event = sctp_ulpq_reasm(ulpq, event);
 
 	/* Do ordering if needed.  */
-	if (event) {
+	if ((event) && (event->msg_flags & MSG_EOR)){
 		/* Create a temporary list to collect chunks on.  */
 		skb_queue_head_init(&temp);
-		skb_queue_tail(&temp, event->parent);
+		__skb_queue_tail(&temp, sctp_event2skb(event));
 
 		event = sctp_ulpq_order(ulpq, event);
 	}
@@ -155,9 +152,39 @@
 }
 
 /* Add a new event for propagation to the ULP.  */
+/* Clear the partial delivery mode for this socket.   Note: This
+ * assumes that no association is currently in partial delivery mode.
+ */
+int sctp_clear_pd(struct sock *sk)
+{
+	struct sctp_opt *sp;
+	sp = sctp_sk(sk);
+
+	sp->pd_mode = 0;
+	if (!skb_queue_empty(&sp->pd_lobby)) {
+		struct list_head *list;
+		sctp_skb_list_tail(&sp->pd_lobby, &sk->receive_queue);
+		list = (struct list_head *)&sctp_sk(sk)->pd_lobby;
+		INIT_LIST_HEAD(list);
+		return 1;
+	}
+	return 0;
+}
+
+/* Clear the pd_mode and restart any pending messages waiting for delivery. */
+static int sctp_ulpq_clear_pd(struct sctp_ulpq *ulpq)
+{
+	ulpq->pd_mode = 0;
+	return sctp_clear_pd(ulpq->asoc->base.sk);
+}
+
+
+
 int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
 {
 	struct sock *sk = ulpq->asoc->base.sk;
+	struct sk_buff_head *queue;
+	int clear_pd = 0;
 
 	/* If the socket is just going to throw this away, do not
 	 * even try to deliver it.
@@ -169,29 +196,55 @@
 	if (!sctp_ulpevent_is_enabled(event, &sctp_sk(sk)->subscribe))
 		goto out_free;
 
+	/* If we are in partial delivery mode, post to the lobby until
+	 * partial delivery is cleared, unless, of course _this_ is
+	 * the association the cause of the partial delivery.
+	 */
+
+	if (!sctp_sk(sk)->pd_mode) {
+		queue = &sk->receive_queue;
+	} else if (ulpq->pd_mode) {
+		if (event->msg_flags & MSG_NOTIFICATION)
+		       	queue = &sctp_sk(sk)->pd_lobby;
+		else {
+			clear_pd = event->msg_flags & MSG_EOR;
+			queue = &sk->receive_queue;
+		}
+	} else
+		queue = &sctp_sk(sk)->pd_lobby;
+
+
 	/* If we are harvesting multiple skbs they will be
 	 * collected on a list.
 	 */
-	if (event->parent->list)
-		sctp_skb_list_tail(event->parent->list, &sk->receive_queue);
+	if (sctp_event2skb(event)->list)
+		sctp_skb_list_tail(sctp_event2skb(event)->list, queue);
 	else
-		skb_queue_tail(&sk->receive_queue, event->parent);
+		skb_queue_tail(queue, sctp_event2skb(event));
+
+	/* Did we just complete partial delivery and need to get
+	 * rolling again?  Move pending data to the receive
+	 * queue.
+	 */
+	if (clear_pd)
+		sctp_ulpq_clear_pd(ulpq);
 
-	wake_up_interruptible(sk->sleep);
+	if (queue == &sk->receive_queue)
+		wake_up_interruptible(sk->sleep);
 	return 1;
 
 out_free:
-	if (event->parent->list)
-		skb_queue_purge(event->parent->list);
+	if (sctp_event2skb(event)->list)
+		skb_queue_purge(sctp_event2skb(event)->list);
 	else
-		kfree_skb(event->parent);
+		kfree_skb(sctp_event2skb(event));
 	return 0;
 }
 
 /* 2nd Level Abstractions */
 
 /* Helper function to store chunks that need to be reassembled.  */
-static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, 
+static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq,
 					 struct sctp_ulpevent *event)
 {
 	struct sk_buff *pos, *tmp;
@@ -202,7 +255,7 @@
 
 	/* Find the right place in this list. We store them by TSN.  */
 	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
-		cevent = (struct sctp_ulpevent *)pos->cb;
+		cevent = sctp_skb2event(pos);
 		ctsn = cevent->sndrcvinfo.sinfo_tsn;
 
 		if (TSN_lt(tsn, ctsn))
@@ -211,9 +264,10 @@
 
 	/* If the queue is empty, we have a different function to call.  */
 	if (skb_peek(&ulpq->reasm))
-		__skb_insert(event->parent, pos->prev, pos, &ulpq->reasm);
+		__skb_insert(sctp_event2skb(event), pos->prev, pos,
+			     &ulpq->reasm);
 	else
-		__skb_queue_tail(&ulpq->reasm, event->parent);
+		__skb_queue_tail(&ulpq->reasm, sctp_event2skb(event));
 }
 
 /* Helper function to return an event corresponding to the reassembled
@@ -231,7 +285,10 @@
 	struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
 
 	/* Store the pointer to the 2nd skb */
-	pos = f_frag->next;
+	if (f_frag == l_frag)
+		pos = NULL;
+	else
+		pos = f_frag->next;
 
 	/* Get the last skb in the f_frag's frag_list if present. */
 	for (last = list; list; last = list, list = list->next);
@@ -246,7 +303,8 @@
 
 	/* Remove the first fragment from the reassembly queue.  */
 	__skb_unlink(f_frag, f_frag->list);
-	do {
+	while (pos) {
+
 		pnext = pos->next;
 
 		/* Update the len and data_len fields of the first fragment. */
@@ -262,25 +320,27 @@
 
 		pos->next = pnext;
 		pos = pnext;
-	} while (1);
+	};
 
-	event = (sctp_ulpevent_t *) f_frag->cb;
+	event = sctp_skb2event(f_frag);
+	SCTP_INC_STATS(SctpReasmUsrMsgs);
 
 	return event;
 }
 
+
 /* Helper function to check if an incoming chunk has filled up the last
  * missing fragment in a SCTP datagram and return the corresponding event.
  */
-static inline sctp_ulpevent_t *sctp_ulpq_retrieve_reassembled(struct sctp_ulpq *ulpq)
+static inline struct sctp_ulpevent *sctp_ulpq_retrieve_reassembled(struct sctp_ulpq *ulpq)
 {
 	struct sk_buff *pos, *tmp;
-	sctp_ulpevent_t *cevent;
+	struct sctp_ulpevent *cevent;
 	struct sk_buff *first_frag = NULL;
 	__u32 ctsn, next_tsn;
-	sctp_ulpevent_t *retval = NULL;
+	struct sctp_ulpevent *retval = NULL;
 
-	/* Initialized to 0 just to avoid compiler warning message. Will
+	/* Initialized to 0 just to avoid compiler warning message.  Will
 	 * never be used with this value. It is referenced only after it
 	 * is set when we find the first fragment of a message.
 	 */
@@ -296,10 +356,10 @@
 	 * start the next pass when we find another first fragment.
 	 */
 	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
-		cevent = (sctp_ulpevent_t *) pos->cb;
+		cevent = sctp_skb2event(pos);
 		ctsn = cevent->sndrcvinfo.sinfo_tsn;
 
-		switch (cevent->chunk_flags & SCTP_DATA_FRAG_MASK) {
+		switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
 		case SCTP_DATA_FIRST_FRAG:
 			first_frag = pos;
 			next_tsn = ctsn + 1;
@@ -313,7 +373,7 @@
 			break;
 
 		case SCTP_DATA_LAST_FRAG:
-			if ((first_frag) && (ctsn == next_tsn))
+			if (first_frag && (ctsn == next_tsn))
 				retval = sctp_make_reassembled_event(
 						first_frag, pos);
 			else
@@ -324,42 +384,170 @@
 		/* We have the reassembled event. There is no need to look
 		 * further.
 		 */
-		if (retval)
+		if (retval) {
+			retval->msg_flags |= MSG_EOR;
 			break;
+		}
 	}
 
 	return retval;
 }
 
-/* Helper function to reassemble chunks. Hold chunks on the reasm queue that
- * need reassembling.
- */
-static inline sctp_ulpevent_t *sctp_ulpq_reasm(struct sctp_ulpq *ulpq,
-						   sctp_ulpevent_t *event)
+/* Retrieve the next set of fragments of a partial message. */
+static inline struct sctp_ulpevent *sctp_ulpq_retrieve_partial(struct sctp_ulpq *ulpq)
 {
-	sctp_ulpevent_t *retval = NULL;
+	struct sk_buff *pos, *tmp, *last_frag, *first_frag;
+	struct sctp_ulpevent *cevent;
+	__u32 ctsn, next_tsn;
+	int is_last;
+	struct sctp_ulpevent *retval;
+
+	/* The chunks are held in the reasm queue sorted by TSN.
+	 * Walk through the queue sequentially and look for the first
+	 * sequence of fragmented chunks.
+	 */
+
+	if (skb_queue_empty(&ulpq->reasm))
+		return NULL;
 
-	/* FIXME: We should be using some new chunk structure here
-	 * instead of carrying chunk fields in the event structure.
-	 * This is temporary as it is too painful to change everything
-	 * at once.
+	last_frag = first_frag = NULL;
+	retval = NULL;
+	next_tsn = 0;
+	is_last = 0;
+
+	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
+		cevent = sctp_skb2event(pos);
+		ctsn = cevent->sndrcvinfo.sinfo_tsn;
+
+		switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
+		case SCTP_DATA_MIDDLE_FRAG:
+			if (!first_frag) {
+				first_frag = pos;
+				next_tsn = ctsn + 1;
+				last_frag = pos;
+			} else if (next_tsn == ctsn)
+				next_tsn++;
+			else
+				goto done;
+			break;
+		case SCTP_DATA_LAST_FRAG:
+			if (!first_frag)
+				first_frag = pos;
+			else if (ctsn != next_tsn)
+				goto done;
+			last_frag = pos;
+			is_last = 1;
+			goto done;
+		default:
+			return NULL;
+		};
+	}
+
+	/* We have the reassembled event. There is no need to look
+	 * further.
 	 */
+done:
+	retval = sctp_make_reassembled_event(first_frag, last_frag);
+	if (is_last)
+		retval->msg_flags |= MSG_EOR;
+
+	return retval;
+}
+
+
+/* Helper function to reassemble chunks.  Hold chunks on the reasm queue that
+ * need reassembling.
+ */
+static inline struct sctp_ulpevent *sctp_ulpq_reasm(struct sctp_ulpq *ulpq,
+						   struct sctp_ulpevent *event)
+{
+	struct sctp_ulpevent *retval = NULL;
 
 	/* Check if this is part of a fragmented message.  */
-	if (SCTP_DATA_NOT_FRAG == (event->chunk_flags & SCTP_DATA_FRAG_MASK))
+	if (SCTP_DATA_NOT_FRAG == (event->msg_flags & SCTP_DATA_FRAG_MASK)) {
+		event->msg_flags |= MSG_EOR;
 		return event;
+	}
 
 	sctp_ulpq_store_reasm(ulpq, event);
-	retval = sctp_ulpq_retrieve_reassembled(ulpq);
+	if (!ulpq->pd_mode)
+		retval = sctp_ulpq_retrieve_reassembled(ulpq);
+	else {
+		__u32 ctsn, ctsnap;
+
+		/* Do not even bother unless this is the next tsn to
+		 * be delivered.
+		 */
+		ctsn = event->sndrcvinfo.sinfo_tsn;
+		ctsnap = sctp_tsnmap_get_ctsn(&ulpq->asoc->peer.tsn_map);
+		if (TSN_lte(ctsn, ctsnap))
+			retval = sctp_ulpq_retrieve_partial(ulpq);
+	}
 
 	return retval;
 }
 
+/* Retrieve the first part (sequential fragments) for partial delivery.  */
+static inline struct sctp_ulpevent *sctp_ulpq_retrieve_first(struct sctp_ulpq *ulpq)
+{
+	struct sk_buff *pos, *tmp, *last_frag, *first_frag;
+	struct sctp_ulpevent *cevent;
+	__u32 ctsn, next_tsn;
+	struct sctp_ulpevent *retval;
+
+	/* The chunks are held in the reasm queue sorted by TSN.
+	 * Walk through the queue sequentially and look for a sequence of
+	 * fragmented chunks that start a datagram.
+	 */
+
+	if (skb_queue_empty(&ulpq->reasm))
+		return NULL;
+
+	last_frag = first_frag = NULL;
+	retval = NULL;
+	next_tsn = 0;
+
+	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
+		cevent = sctp_skb2event(pos);
+		ctsn = cevent->sndrcvinfo.sinfo_tsn;
+
+		switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
+		case SCTP_DATA_FIRST_FRAG:
+			if (!first_frag) {
+				first_frag = pos;
+				next_tsn = ctsn + 1;
+				last_frag = pos;
+			} else
+				goto done;
+			break;
+
+		case SCTP_DATA_MIDDLE_FRAG:
+			if (!first_frag)
+				return NULL;
+			if (ctsn == next_tsn) {
+				next_tsn++;
+				last_frag = pos;
+			} else
+				goto done;
+			break;
+		default:
+			return NULL;
+		};
+	}
+
+	/* We have the reassembled event. There is no need to look
+	 * further.
+	 */
+done:
+	retval = sctp_make_reassembled_event(first_frag, last_frag);
+	return retval;
+}
+
 /* Helper function to gather skbs that have possibly become
  * ordered by an an incoming chunk.
  */
 static inline void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
-					      sctp_ulpevent_t *event)
+					      struct sctp_ulpevent *event)
 {
 	struct sk_buff *pos, *tmp;
 	struct sctp_ulpevent *cevent;
@@ -373,7 +561,7 @@
 
 	/* We are holding the chunks by stream, by SSN.  */
 	sctp_skb_for_each(pos, &ulpq->lobby, tmp) {
-		cevent = (sctp_ulpevent_t *) pos->cb;
+		cevent = (struct sctp_ulpevent *) pos->cb;
 		csid = cevent->sndrcvinfo.sinfo_stream;
 		cssn = cevent->sndrcvinfo.sinfo_ssn;
 
@@ -390,32 +578,31 @@
 
 		/* Found it, so mark in the ssnmap. */
 		sctp_ssn_next(in, sid);
-	       
+
 		__skb_unlink(pos, pos->list);
 
 		/* Attach all gathered skbs to the event.  */
-		__skb_queue_tail(event->parent->list, pos);
+		__skb_queue_tail(sctp_event2skb(event)->list, pos);
 	}
 }
 
 /* Helper function to store chunks needing ordering.  */
 static inline void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq,
-					   sctp_ulpevent_t *event)
+					   struct sctp_ulpevent *event)
 {
 	struct sk_buff *pos, *tmp;
-	sctp_ulpevent_t *cevent;
+	struct sctp_ulpevent *cevent;
 	__u16 sid, csid;
 	__u16 ssn, cssn;
 
 	sid = event->sndrcvinfo.sinfo_stream;
 	ssn = event->sndrcvinfo.sinfo_ssn;
 
-
 	/* Find the right place in this list.  We store them by
 	 * stream ID and then by SSN.
 	 */
 	sctp_skb_for_each(pos, &ulpq->lobby, tmp) {
-		cevent = (sctp_ulpevent_t *) pos->cb;
+		cevent = (struct sctp_ulpevent *) pos->cb;
 		csid = cevent->sndrcvinfo.sinfo_stream;
 		cssn = cevent->sndrcvinfo.sinfo_ssn;
 
@@ -427,25 +614,20 @@
 
 	/* If the queue is empty, we have a different function to call.  */
 	if (skb_peek(&ulpq->lobby))
-		__skb_insert(event->parent, pos->prev, pos, &ulpq->lobby);
+		__skb_insert(sctp_event2skb(event), pos->prev, pos,
+			     &ulpq->lobby);
 	else
-		__skb_queue_tail(&ulpq->lobby, event->parent);
+		__skb_queue_tail(&ulpq->lobby, sctp_event2skb(event));
 }
 
-static inline sctp_ulpevent_t *sctp_ulpq_order(struct sctp_ulpq *ulpq,
-					       sctp_ulpevent_t *event)
+static inline struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
+					struct sctp_ulpevent *event)
 {
 	__u16 sid, ssn;
 	struct sctp_stream *in;
 
-	/* FIXME: We should be using some new chunk structure here
-	 * instead of carrying chunk fields in the event structure.
-	 * This is temporary as it is too painful to change everything
-	 * at once.
-	 */
-
 	/* Check if this message needs ordering.  */
-	if (SCTP_DATA_UNORDERED & event->chunk_flags)
+	if (SCTP_DATA_UNORDERED & event->msg_flags)
 		return event;
 
 	/* Note: The stream ID must be verified before this routine.  */
@@ -471,4 +653,142 @@
 	sctp_ulpq_retrieve_ordered(ulpq, event);
 
 	return event;
+}
+
+/* Renege 'needed' bytes from the ordering queue. */
+static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed)
+{
+	__u16 freed = 0;
+	__u32 tsn;
+	struct sk_buff *skb;
+	struct sctp_ulpevent *event;
+	struct sctp_tsnmap *tsnmap;
+
+	tsnmap = &ulpq->asoc->peer.tsn_map;
+
+	while ((skb = __skb_dequeue_tail(&ulpq->lobby))) {
+		freed += skb_headlen(skb);
+		event = sctp_skb2event(skb);
+		tsn = event->sndrcvinfo.sinfo_tsn;
+
+		sctp_ulpevent_free(event);
+		sctp_tsnmap_renege(tsnmap, tsn);
+		if (freed >= needed)
+			return freed;
+	}
+
+	return freed;
+}
+
+/* Renege 'needed' bytes from the reassembly queue. */
+static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed)
+{
+	__u16 freed = 0;
+	__u32 tsn;
+	struct sk_buff *skb;
+	struct sctp_ulpevent *event;
+	struct sctp_tsnmap *tsnmap;
+
+	tsnmap = &ulpq->asoc->peer.tsn_map;
+
+	/* Walk backwards through the list, reneges the newest tsns. */
+	while ((skb = __skb_dequeue_tail(&ulpq->reasm))) {
+		freed += skb_headlen(skb);
+		event = sctp_skb2event(skb);
+		tsn = event->sndrcvinfo.sinfo_tsn;
+
+		sctp_ulpevent_free(event);
+		sctp_tsnmap_renege(tsnmap, tsn);
+		if (freed >= needed)
+			return freed;
+	}
+
+	return freed;
+}
+
+/* Partial deliver the first message as there is pressure on rwnd. */
+void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
+				struct sctp_chunk *chunk, int priority)
+{
+	struct sctp_ulpevent *event;
+	struct sctp_association *asoc;
+
+	asoc = ulpq->asoc;
+
+	/* Are we already in partial delivery mode?  */
+	if (!sctp_sk(asoc->base.sk)->pd_mode) {
+
+		/* Is partial delivery possible?  */
+		event = sctp_ulpq_retrieve_first(ulpq);
+		/* Send event to the ULP.   */
+		if (event) {
+			sctp_ulpq_tail_event(ulpq, event);
+			sctp_sk(asoc->base.sk)->pd_mode = 1;
+			ulpq->pd_mode = 1;
+			return;
+		}
+	}
+}
+
+/* Renege some packets to make room for an incoming chunk.  */
+void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
+		      int priority)
+{
+	struct sctp_association *asoc;
+	__u16 needed, freed;
+
+	asoc = ulpq->asoc;
+
+	if (chunk) {
+		needed = ntohs(chunk->chunk_hdr->length);
+		needed -= sizeof(sctp_data_chunk_t);
+	} else 
+		needed = SCTP_DEFAULT_MAXWINDOW;
+
+	freed = 0;
+
+	if (skb_queue_empty(&asoc->base.sk->receive_queue)) {
+		freed = sctp_ulpq_renege_order(ulpq, needed);
+		if (freed < needed) {
+			freed += sctp_ulpq_renege_frags(ulpq, needed - freed);
+		}
+	}
+	/* If able to free enough room, accept this chunk. */
+	if (chunk && (freed >= needed)) {
+		__u32 tsn;
+		tsn = ntohl(chunk->subh.data_hdr->tsn);
+		sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn);
+		sctp_ulpq_tail_data(ulpq, chunk, priority);
+		
+		sctp_ulpq_partial_delivery(ulpq, chunk, priority);
+	}
+
+	return;
+}
+
+
+
+/* Notify the application if an association is aborted and in
+ * partial delivery mode.  Send up any pending received messages.
+ */
+void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, int priority)
+{
+	struct sctp_ulpevent *ev = NULL;
+	struct sock *sk;
+
+	if (!ulpq->pd_mode)
+		return;
+
+	sk = ulpq->asoc->base.sk;
+	if (sctp_ulpevent_type_enabled(SCTP_PARTIAL_DELIVERY_EVENT,
+				       &sctp_sk(sk)->subscribe))
+		ev = sctp_ulpevent_make_pdapi(ulpq->asoc,
+					      SCTP_PARTIAL_DELIVERY_ABORTED,
+					      priority);
+	if (ev)
+		skb_queue_tail(&sk->receive_queue, sctp_event2skb(ev));
+
+	/* If there is data waiting, send it up the socket now. */
+	if (sctp_ulpq_clear_pd(ulpq) || ev)
+		wake_up_interruptible(sk->sleep);
 }
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Tue Mar  4 19:30:07 2003
+++ b/net/socket.c	Tue Mar  4 19:30:07 2003
@@ -83,9 +83,9 @@
 #include <linux/kmod.h>
 #endif
 
-#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
+#ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
-#endif	/* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
+#endif	/* CONFIG_NET_RADIO */
 
 #include <asm/uaccess.h>
 
diff -Nru a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
--- a/net/sunrpc/auth_unix.c	Tue Mar  4 19:30:10 2003
+++ b/net/sunrpc/auth_unix.c	Tue Mar  4 19:30:10 2003
@@ -163,7 +163,7 @@
 	memcpy(p, clnt->cl_nodename, n);
 	p += (n + 3) >> 2;
 
-	/* Note: we don't use real uid if it involves raising priviledge */
+	/* Note: we don't use real uid if it involves raising privilege */
 	if (ruid && cred->uc_puid != 0 && cred->uc_pgid != 0) {
 		*p++ = htonl((u32) cred->uc_puid);
 		*p++ = htonl((u32) cred->uc_pgid);
diff -Nru a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
--- a/net/sunrpc/rpc_pipe.c	Tue Mar  4 19:30:05 2003
+++ b/net/sunrpc/rpc_pipe.c	Tue Mar  4 19:30:05 2003
@@ -479,7 +479,7 @@
 rpc_depopulate(struct dentry *parent)
 {
 	struct inode *dir = parent->d_inode;
-	LIST_HEAD(head);
+	HLIST_HEAD(head);
 	struct list_head *pos, *next;
 	struct dentry *dentry;
 
@@ -490,12 +490,12 @@
 		if (!d_unhashed(dentry)) {
 			dget_locked(dentry);
 			__d_drop(dentry);
-			list_add(&dentry->d_hash, &head);
+			hlist_add_head(&dentry->d_hash, &head);
 		}
 	}
 	spin_unlock(&dcache_lock);
-	while (!list_empty(&head)) {
-		dentry = list_entry(head.next, struct dentry, d_hash);
+	while (!hlist_empty(&head)) {
+		dentry = list_entry(head.first, struct dentry, d_hash);
 		/* Private list, so no dcache_lock needed and use __d_drop */
 		__d_drop(dentry);
 		if (dentry->d_inode) {
diff -Nru a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
--- a/net/wanrouter/af_wanpipe.c	Tue Mar  4 19:30:14 2003
+++ b/net/wanrouter/af_wanpipe.c	Tue Mar  4 19:30:14 2003
@@ -388,7 +388,7 @@
 
 	/* Register the lcn on which incoming call came
          * from. Thus, if we have to clear it, we know
-         * whic lcn to clear 
+         * which lcn to clear
 	 */ 
 
 	newwp->lcn = mbox_ptr->cmd.lcn;
@@ -674,7 +674,7 @@
 /*============================================================
  * wanpipe_delayed_tarnsmit
  *
- *	Transmit bottom half handeler. It dequeues packets
+ *	Transmit bottom half handler. It dequeues packets
  *      from sk->write_queue and passes them to the 
  *      driver.  If the driver is busy, the packet is 
  *      re-enqueued.  
diff -Nru a/scripts/Makefile b/scripts/Makefile
--- a/scripts/Makefile	Tue Mar  4 19:30:09 2003
+++ b/scripts/Makefile	Tue Mar  4 19:30:09 2003
@@ -5,7 +5,7 @@
 # fix-dep: 	 Used to generate dependency information during build process
 # split-include: Divide all config symbols up in a number of files in
 #                include/config/...
-# docproc: 	 Preprocess .tmpl file in order to generate .sgml documentation
+# docproc: 	 Preprocess .tmpl file in order to generate .sgml docs
 # conmakehash:	 Create arrays for initializing the kernel console tables
 
 host-progs    := fixdep split-include conmakehash docproc kallsyms modpost \
@@ -14,20 +14,20 @@
 
 modpost-objs  := modpost.o file2alias.o
 
-clean-files := elfconfig.h
+subdir-$(CONFIG_MODVERSIONS)	+= genksyms
 
 # Let clean descend into subdirs
-subdir-	:= lxdialog kconfig
+subdir-	+= lxdialog kconfig
 
 # fixdep is needed to compile other host programs
-$(addprefix $(obj)/,$(filter-out fixdep,$(build-targets))): $(obj)/fixdep
+$(addprefix $(obj)/,$(filter-out fixdep,$(build-targets)) $(subdir-y)): $(obj)/fixdep
 
 # dependencies on generated files need to be listed explicitly
 
 $(obj)/modpost.o $(obj)/file2alias.o: $(obj)/elfconfig.h
 
 quiet_cmd_elfconfig = MKELF   $@
-      cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@
+      cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
 
 $(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
 	$(call if_changed,elfconfig)
diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build
--- a/scripts/Makefile.build	Tue Mar  4 19:30:12 2003
+++ b/scripts/Makefile.build	Tue Mar  4 19:30:12 2003
@@ -90,8 +90,7 @@
 		mv $(@D)/.tmp_$(@F) $@;					      \
 	else								      \
 		$(CPP) -D__GENKSYMS__ $(c_flags) $<			      \
-		| $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)	      \
-		| sed -n 's/\#define __ver_\([^ 	]*\)[ 	]*\([^ 	]*\)/__crc_\1 = 0x\2 ;/gp' \
+		| $(GENKSYMS)						      \
 		> $(@D)/.tmp_$(@F:.o=.ver);				      \
 									      \
 		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		      \
diff -Nru a/scripts/Makefile.clean b/scripts/Makefile.clean
--- a/scripts/Makefile.clean	Tue Mar  4 19:30:03 2003
+++ b/scripts/Makefile.clean	Tue Mar  4 19:30:03 2003
@@ -35,7 +35,7 @@
 
 # ==========================================================================
 
-__clean-files := $(wildcard $(EXTRA_TARGETS) $(host-progs) $(clean-files))
+__clean-files := $(wildcard $(EXTRA_TARGETS) $(host-progs) $(clean-files) $(targets))
 
 quiet_cmd_clean = CLEAN   $(obj)
       cmd_clean = rm -f $(__clean-files); $(clean-rule)
diff -Nru a/scripts/Makefile.modpost b/scripts/Makefile.modpost
--- a/scripts/Makefile.modpost	Tue Mar  4 19:30:09 2003
+++ b/scripts/Makefile.modpost	Tue Mar  4 19:30:09 2003
@@ -37,10 +37,7 @@
 quiet_cmd_cc_o_c = CC      $@
       cmd_cc_o_c = $(CC) $(CFLAGS) $(CFLAGS_MODULE) -c -o $@ $<
 
-#	We have a fake dependency on compile.h to make sure that we
-#	notice if the compiler version changes under us.
-
-$(modules:.ko=.mod.o): %.mod.o: %.mod.c include/linux/compile.h FORCE
+$(modules:.ko=.mod.o): %.mod.o: %.mod.c
 	$(call if_changed,cc_o_c)
 
 targets += $(modules:.ko=.mod.o)
diff -Nru a/scripts/README.Menuconfig b/scripts/README.Menuconfig
--- a/scripts/README.Menuconfig	Tue Mar  4 19:30:08 2003
+++ b/scripts/README.Menuconfig	Tue Mar  4 19:30:08 2003
@@ -127,7 +127,7 @@
 source tree is fresh, or changes are patched into it via a kernel
 patch or you do 'make mrproper'.  If changes to lxdialog are patched
 in, most likely the rebuild time will be short.  You may force a
-complete rebuild of lxdialog by changing to it's directory and doing
+complete rebuild of lxdialog by changing to its directory and doing
 'make clean all'
 
 If you use Menuconfig in an XTERM window make sure you have your 
diff -Nru a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/Makefile	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,47 @@
+
+host-progs	:= genksyms
+build-targets	:= $(host-progs)
+
+genksyms-objs	:= genksyms.o parse.o lex.o
+
+HOSTCFLAGS_parse.o := -Wno-uninitialized
+
+# dependencies on generated files need to be listed explicitly
+
+$(obj)/lex.o: $(obj)/parse.h $(obj)/keywords.c
+
+
+ifdef GENERATE_PARSER
+
+# gperf
+
+quiet_cmd_keywords.c = GPERF   $@
+      cmd_keywords.c = gperf -L ANSI-C -a -C -E -g -H is_reserved_hash	\
+		       -k 1,3,$$ -N is_reserved_word -p -t $< > $@
+
+$(obj)/keywords.c: $(obj)/keywords.gperf FORCE
+	$(call if_changed,keywords.c)
+
+# flex
+
+quiet_cmd_lex.c = FLEX    $@
+      cmd_lex.c = flex -o$@ -d $(filter-out FORCE,$^)
+
+$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h FORCE
+	$(call if_changed,lex.c)
+
+# bison
+
+quiet_cmd_parse.c = BISON   $@
+      cmd_parse.c = bison -o$@ -dtv $(filter-out FORCE,$^)
+
+$(obj)/parse.c: $(obj)/parse.y FORCE
+	$(call if_changed,parse.c)
+
+$(obj)/parse.h: $(obj)/parse.c ;
+
+clean-files	+= parse.output
+
+endif
+
+targets += $(obj)/keywords.c $(obj)/lex.c $(obj)/parse.c $(obj)/parse.h
diff -Nru a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/genksyms.c	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,576 @@
+/* Generate kernel symbol version hashes.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   This file was part of the Linux modutils 2.4.22: moved back into the
+   kernel sources by Rusty Russell/Kai Germaschewski.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2 of the License, or (at your
+   option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <getopt.h>
+
+#include "genksyms.h"
+
+/*----------------------------------------------------------------------*/
+
+#define HASH_BUCKETS  4096
+
+static struct symbol *symtab[HASH_BUCKETS];
+FILE *debugfile;
+
+int cur_line = 1;
+char *cur_filename, *output_directory;
+
+int flag_debug, flag_dump_defs, flag_warnings;
+
+static int errors;
+static int nsyms;
+
+static struct symbol *expansion_trail;
+
+static const char * const symbol_type_name[] = {
+  "normal", "typedef", "enum", "struct", "union"
+};
+
+/*----------------------------------------------------------------------*/
+
+static const unsigned int crctab32[] =
+{
+  0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
+  0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
+  0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
+  0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
+  0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
+  0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
+  0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
+  0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
+  0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
+  0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
+  0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
+  0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
+  0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
+  0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
+  0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
+  0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
+  0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
+  0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
+  0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
+  0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
+  0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
+  0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
+  0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
+  0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
+  0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
+  0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
+  0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
+  0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
+  0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
+  0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
+  0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
+  0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
+  0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
+  0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
+  0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
+  0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
+  0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
+  0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
+  0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
+  0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
+  0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
+  0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
+  0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
+  0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
+  0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
+  0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
+  0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
+  0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
+  0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
+  0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
+  0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
+  0x2d02ef8dU
+};
+
+static inline unsigned long
+partial_crc32_one(unsigned char c, unsigned long crc)
+{
+  return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
+}
+
+static inline unsigned long
+partial_crc32(const char *s, unsigned long crc)
+{
+  while (*s)
+    crc = partial_crc32_one(*s++, crc);
+  return crc;
+}
+
+static inline unsigned long
+crc32(const char *s)
+{
+  return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
+}
+
+
+/*----------------------------------------------------------------------*/
+
+static inline enum symbol_type
+map_to_ns(enum symbol_type t)
+{
+  if (t == SYM_TYPEDEF)
+    t = SYM_NORMAL;
+  else if (t == SYM_UNION)
+    t = SYM_STRUCT;
+  return t;
+}
+
+struct symbol *
+find_symbol(const char *name, enum symbol_type ns)
+{
+  unsigned long h = crc32(name) % HASH_BUCKETS;
+  struct symbol *sym;
+
+  for (sym = symtab[h]; sym ; sym = sym->hash_next)
+    if (map_to_ns(sym->type) == map_to_ns(ns) && strcmp(name, sym->name) == 0)
+      break;
+
+  return sym;
+}
+
+struct symbol *
+add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern)
+{
+  unsigned long h = crc32(name) % HASH_BUCKETS;
+  struct symbol *sym;
+
+  for (sym = symtab[h]; sym ; sym = sym->hash_next)
+    if (map_to_ns(sym->type) == map_to_ns(type)
+	&& strcmp(name, sym->name) == 0)
+      {
+	if (!equal_list(sym->defn, defn))
+	  error_with_pos("redefinition of %s", name);
+	return sym;
+      }
+
+  sym = xmalloc(sizeof(*sym));
+  sym->name = name;
+  sym->type = type;
+  sym->defn = defn;
+  sym->expansion_trail = NULL;
+  sym->is_extern = is_extern;
+
+  sym->hash_next = symtab[h];
+  symtab[h] = sym;
+
+  if (flag_debug)
+    {
+      fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type],  name);
+      if (is_extern)
+        fputs("extern ", debugfile);
+      print_list(debugfile, defn);
+      fputs(">\n", debugfile);
+    }
+
+  ++nsyms;
+  return sym;
+}
+
+
+/*----------------------------------------------------------------------*/
+
+inline void
+free_node(struct string_list *node)
+{
+  free(node->string);
+  free(node);
+}
+
+void
+free_list(struct string_list *s, struct string_list *e)
+{
+  while (s != e)
+    {
+      struct string_list *next = s->next;
+      free_node(s);
+      s = next;
+    }
+}
+
+inline struct string_list *
+copy_node(struct string_list *node)
+{
+  struct string_list *newnode;
+
+  newnode = xmalloc(sizeof(*newnode));
+  newnode->string = xstrdup(node->string);
+  newnode->tag = node->tag;
+
+  return newnode;
+}
+
+struct string_list *
+copy_list(struct string_list *s, struct string_list *e)
+{
+  struct string_list *h, *p;
+
+  if (s == e)
+    return NULL;
+
+  p = h = copy_node(s);
+  while ((s = s->next) != e)
+    p = p->next = copy_node(s);
+  p->next = NULL;
+
+  return h;
+}
+
+int
+equal_list(struct string_list *a, struct string_list *b)
+{
+  while (a && b)
+    {
+      if (a->tag != b->tag || strcmp(a->string, b->string))
+	return 0;
+      a = a->next;
+      b = b->next;
+    }
+
+  return !a && !b;
+}
+
+static inline void
+print_node(FILE *f, struct string_list *list)
+{
+  switch (list->tag)
+    {
+    case SYM_STRUCT:
+      putc('s', f);
+      goto printit;
+    case SYM_UNION:
+      putc('u', f);
+      goto printit;
+    case SYM_ENUM:
+      putc('e', f);
+      goto printit;
+    case SYM_TYPEDEF:
+      putc('t', f);
+      goto printit;
+
+    printit:
+      putc('#', f);
+    case SYM_NORMAL:
+      fputs(list->string, f);
+      break;
+    }
+}
+
+void
+print_list(FILE *f, struct string_list *list)
+{
+  struct string_list **e, **b;
+  struct string_list *tmp, **tmp2;
+  int elem = 1;
+
+  if (list == NULL)
+    {
+      fputs("(nil)", f);
+      return;
+    }
+
+  tmp = list;
+  while((tmp = tmp->next) != NULL)
+	  elem++;
+
+  b = alloca(elem * sizeof(*e));
+  e = b + elem;
+  tmp2 = e - 1;
+
+  (*tmp2--) = list;
+  while((list = list->next) != NULL)
+	  *(tmp2--) = list;
+
+  while (b != e)
+    {
+      print_node(f, *b++);
+      putc(' ', f);
+    }
+}
+
+static unsigned long
+expand_and_crc_list(struct string_list *list, unsigned long crc)
+{
+  struct string_list **e, **b;
+  struct string_list *tmp, **tmp2;
+  int elem = 1;
+
+  if (!list)
+    return crc;
+
+  tmp = list;
+  while((tmp = tmp->next) != NULL)
+	  elem++;
+
+  b = alloca(elem * sizeof(*e));
+  e = b + elem;
+  tmp2 = e - 1;
+
+  *(tmp2--) = list;
+  while ((list = list->next) != NULL)
+    *(tmp2--) = list;
+
+  while (b != e)
+    {
+      struct string_list *cur;
+      struct symbol *subsym;
+
+      cur = *(b++);
+      switch (cur->tag)
+	{
+	case SYM_NORMAL:
+	  if (flag_dump_defs)
+	    fprintf(debugfile, "%s ", cur->string);
+	  crc = partial_crc32(cur->string, crc);
+	  crc = partial_crc32_one(' ', crc);
+	  break;
+
+	case SYM_TYPEDEF:
+	  subsym = find_symbol(cur->string, cur->tag);
+	  if (subsym->expansion_trail)
+	    {
+	      if (flag_dump_defs)
+		fprintf(debugfile, "%s ", cur->string);
+	      crc = partial_crc32(cur->string, crc);
+	      crc = partial_crc32_one(' ', crc);
+	    }
+	  else
+	    {
+	      subsym->expansion_trail = expansion_trail;
+	      expansion_trail = subsym;
+	      crc = expand_and_crc_list(subsym->defn, crc);
+	    }
+	  break;
+
+	case SYM_STRUCT:
+	case SYM_UNION:
+	case SYM_ENUM:
+	  subsym = find_symbol(cur->string, cur->tag);
+	  if (!subsym)
+	    {
+	      struct string_list *n, *t = NULL;
+
+	      error_with_pos("expand undefined %s %s",
+			     symbol_type_name[cur->tag], cur->string);
+
+	      n = xmalloc(sizeof(*n));
+	      n->string = xstrdup(symbol_type_name[cur->tag]);
+	      n->tag = SYM_NORMAL;
+	      n->next = t;
+	      t = n;
+
+	      n = xmalloc(sizeof(*n));
+	      n->string = xstrdup(cur->string);
+	      n->tag = SYM_NORMAL;
+	      n->next = t;
+	      t = n;
+
+	      n = xmalloc(sizeof(*n));
+	      n->string = xstrdup("{ UNKNOWN }");
+	      n->tag = SYM_NORMAL;
+	      n->next = t;
+
+	      subsym = add_symbol(cur->string, cur->tag, n, 0);
+	    }
+	  if (subsym->expansion_trail)
+	    {
+	      if (flag_dump_defs)
+		{
+		  fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag],
+			  cur->string);
+		}
+
+	      crc = partial_crc32(symbol_type_name[cur->tag], crc);
+	      crc = partial_crc32_one(' ', crc);
+	      crc = partial_crc32(cur->string, crc);
+	      crc = partial_crc32_one(' ', crc);
+	    }
+	  else
+	    {
+	      subsym->expansion_trail = expansion_trail;
+	      expansion_trail = subsym;
+	      crc = expand_and_crc_list(subsym->defn, crc);
+	    }
+	  break;
+	}
+    }
+
+  return crc;
+}
+
+void
+export_symbol(const char *name)
+{
+  struct symbol *sym;
+
+  sym = find_symbol(name, SYM_NORMAL);
+  if (!sym)
+    error_with_pos("export undefined symbol %s", name);
+  else
+    {
+      unsigned long crc;
+
+      if (flag_dump_defs)
+	fprintf(debugfile, "Export %s == <", name);
+
+      expansion_trail = (struct symbol *)-1L;
+
+      crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff;
+
+      sym = expansion_trail;
+      while (sym != (struct symbol *)-1L)
+	{
+	  struct symbol *n = sym->expansion_trail;
+	  sym->expansion_trail = 0;
+	  sym = n;
+	}
+
+      if (flag_dump_defs)
+	fputs(">\n", debugfile);
+
+      /* Used as a linker script. */
+      printf("__crc_%s = 0x%08lx ;\n", name, crc);
+    }
+}
+
+/*----------------------------------------------------------------------*/
+
+void
+error(const char *fmt, ...)
+{
+  va_list args;
+
+  if (flag_warnings)
+    {
+      va_start(args, fmt);
+      vfprintf(stderr, fmt, args);
+      va_end(args);
+      putc('\n', stderr);
+
+      errors++;
+    }
+}
+
+void
+error_with_pos(const char *fmt, ...)
+{
+  va_list args;
+
+  if (flag_warnings)
+    {
+      fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
+
+      va_start(args, fmt);
+      vfprintf(stderr, fmt, args);
+      va_end(args);
+      putc('\n', stderr);
+
+      errors++;
+    }
+}
+
+
+void genksyms_usage(void)
+{
+	fputs("Usage:\n"
+	      "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n"
+	      "\n"
+	      "  -d, --debug           Increment the debug level (repeatable)\n"
+	      "  -D, --dump            Dump expanded symbol defs (for debugging only)\n"
+	      "  -w, --warnings        Enable warnings\n"
+	      "  -q, --quiet           Disable warnings (default)\n"
+	      "  -h, --help            Print this message\n"
+	      "  -V, --version         Print the release version\n"
+	      , stderr);
+}
+
+int
+main(int argc, char **argv)
+{
+  int o;
+
+  struct option long_opts[] = {
+    {"debug", 0, 0, 'd'},
+    {"warnings", 0, 0, 'w'},
+    {"quiet", 0, 0, 'q'},
+    {"dump", 0, 0, 'D'},
+    {"version", 0, 0, 'V'},
+    {"help", 0, 0, 'h'},
+    {0, 0, 0, 0}
+  };
+
+  while ((o = getopt_long(argc, argv, "dwqVDk:p:",
+			  &long_opts[0], NULL)) != EOF)
+    switch (o)
+      {
+      case 'd':
+	flag_debug++;
+	break;
+      case 'w':
+	flag_warnings = 1;
+	break;
+      case 'q':
+	flag_warnings = 0;
+	break;
+      case 'V':
+	fputs("genksyms version 2.5.60\n", stderr);
+	break;
+      case 'D':
+	flag_dump_defs = 1;
+	break;
+      case 'h':
+	genksyms_usage();
+	return 0;
+      default:
+	genksyms_usage();
+	return 1;
+      }
+
+    {
+      extern int yydebug;
+      extern int yy_flex_debug;
+
+      yydebug = (flag_debug > 1);
+      yy_flex_debug = (flag_debug > 2);
+
+      debugfile = stderr;
+      /* setlinebuf(debugfile); */
+    }
+
+  yyparse();
+
+  if (flag_debug)
+    {
+      fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
+	      nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS);
+    }
+
+  return errors != 0;
+}
diff -Nru a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/genksyms.h	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,96 @@
+/* Generate kernel symbol version hashes.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   This file is part of the Linux modutils.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2 of the License, or (at your
+   option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+#ifndef MODUTILS_GENKSYMS_H
+#define MODUTILS_GENKSYMS_H 1
+
+#include <stdio.h>
+#include <assert.h>
+
+
+enum symbol_type
+{
+  SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
+};
+
+struct string_list
+{
+  struct string_list *next;
+  enum symbol_type tag;
+  char *string;
+};
+
+struct symbol
+{
+  struct symbol *hash_next;
+  const char *name;
+  enum symbol_type type;
+  struct string_list *defn;
+  struct symbol *expansion_trail;
+  int is_extern;
+};
+
+typedef struct string_list **yystype;
+#define YYSTYPE yystype
+
+extern FILE *outfile, *debugfile;
+
+extern int cur_line;
+extern char *cur_filename, *output_directory;
+
+extern int flag_debug, flag_dump_defs, flag_warnings;
+extern int checksum_version, kernel_version;
+
+extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents;
+extern struct string_list *current_list, *next_list;
+
+
+struct symbol *find_symbol(const char *name, enum symbol_type ns);
+struct symbol *add_symbol(const char *name, enum symbol_type type,
+			   struct string_list *defn, int is_extern);
+void export_symbol(const char *);
+
+struct string_list *reset_list(void);
+void free_list(struct string_list *s, struct string_list *e);
+void free_node(struct string_list *list);
+struct string_list *copy_node(struct string_list *);
+struct string_list *copy_list(struct string_list *s, struct string_list *e);
+int equal_list(struct string_list *a, struct string_list *b);
+void print_list(FILE *, struct string_list *list);
+
+int yylex(void);
+int yyparse(void);
+
+void error_with_pos(const char *, ...);
+
+#define version(a,b,c)  ((a << 16) | (b << 8) | (c))
+
+/*----------------------------------------------------------------------*/
+
+#define MODUTILS_VERSION "<in-kernel>"
+
+#define xmalloc(size) ({ void *__ptr = malloc(size); assert(__ptr || size == 0); __ptr; })
+#define xstrdup(str)  ({ char *__str = strdup(str); assert(__str); __str; })
+
+
+#endif /* genksyms.h */
diff -Nru a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/keywords.c_shipped	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,145 @@
+/* ANSI-C code produced by gperf version 2.7.2 */
+/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf  */
+struct resword { const char *name; int token; };
+/* maximum key range = 109, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+is_reserved_hash (register const char *str, register unsigned int len)
+{
+  static const unsigned char asso_values[] =
+    {
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113,   5,
+      113, 113, 113, 113, 113, 113,   0, 113, 113, 113,
+        0, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113,   0, 113,   0, 113,  20,
+       25,   0,  35,  30, 113,  20, 113, 113,  40,  30,
+       30,   0,   0, 113,   0,  51,   0,  15,   5, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113
+    };
+  return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
+}
+
+#ifdef __GNUC__
+__inline
+#endif
+const struct resword *
+is_reserved_word (register const char *str, register unsigned int len)
+{
+  enum
+    {
+      TOTAL_KEYWORDS = 41,
+      MIN_WORD_LENGTH = 3,
+      MAX_WORD_LENGTH = 17,
+      MIN_HASH_VALUE = 4,
+      MAX_HASH_VALUE = 112
+    };
+
+  static const struct resword wordlist[] =
+    {
+      {""}, {""}, {""}, {""},
+      {"auto", AUTO_KEYW},
+      {""}, {""},
+      {"__asm__", ASM_KEYW},
+      {""},
+      {"_restrict", RESTRICT_KEYW},
+      {"__typeof__", TYPEOF_KEYW},
+      {"__attribute", ATTRIBUTE_KEYW},
+      {"__restrict__", RESTRICT_KEYW},
+      {"__attribute__", ATTRIBUTE_KEYW},
+      {""},
+      {"__volatile", VOLATILE_KEYW},
+      {""},
+      {"__volatile__", VOLATILE_KEYW},
+      {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
+      {""}, {""}, {""},
+      {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
+      {"int", INT_KEYW},
+      {"char", CHAR_KEYW},
+      {""}, {""},
+      {"__const", CONST_KEYW},
+      {"__inline", INLINE_KEYW},
+      {"__const__", CONST_KEYW},
+      {"__inline__", INLINE_KEYW},
+      {""}, {""}, {""}, {""},
+      {"__asm", ASM_KEYW},
+      {"extern", EXTERN_KEYW},
+      {""},
+      {"register", REGISTER_KEYW},
+      {""},
+      {"float", FLOAT_KEYW},
+      {"typeof", TYPEOF_KEYW},
+      {"typedef", TYPEDEF_KEYW},
+      {""}, {""},
+      {"_Bool", BOOL_KEYW},
+      {"double", DOUBLE_KEYW},
+      {""}, {""},
+      {"enum", ENUM_KEYW},
+      {""}, {""}, {""},
+      {"volatile", VOLATILE_KEYW},
+      {"void", VOID_KEYW},
+      {"const", CONST_KEYW},
+      {"short", SHORT_KEYW},
+      {"struct", STRUCT_KEYW},
+      {""},
+      {"restrict", RESTRICT_KEYW},
+      {""},
+      {"__signed__", SIGNED_KEYW},
+      {""},
+      {"asm", ASM_KEYW},
+      {""}, {""},
+      {"inline", INLINE_KEYW},
+      {""}, {""}, {""},
+      {"union", UNION_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""},
+      {"static", STATIC_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""},
+      {"__signed", SIGNED_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""},
+      {"unsigned", UNSIGNED_KEYW},
+      {""}, {""}, {""}, {""},
+      {"long", LONG_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {"signed", SIGNED_KEYW}
+    };
+
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+      register int key = is_reserved_hash (str, len);
+
+      if (key <= MAX_HASH_VALUE && key >= 0)
+        {
+          register const char *s = wordlist[key].name;
+
+          if (*str == *s && !strcmp (str + 1, s + 1))
+            return &wordlist[key];
+        }
+    }
+  return 0;
+}
diff -Nru a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/keywords.gperf	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,50 @@
+%{
+%}
+struct resword { const char *name; int token; }
+%%
+EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
+EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
+__asm, ASM_KEYW
+__asm__, ASM_KEYW
+__attribute, ATTRIBUTE_KEYW
+__attribute__, ATTRIBUTE_KEYW
+__const, CONST_KEYW
+__const__, CONST_KEYW
+__inline, INLINE_KEYW
+__inline__, INLINE_KEYW
+__signed, SIGNED_KEYW
+__signed__, SIGNED_KEYW
+__volatile, VOLATILE_KEYW
+__volatile__, VOLATILE_KEYW
+# According to rth, c99 defines _Bool, __restrict, __restrict__, restrict.  KAO
+_Bool, BOOL_KEYW
+_restrict, RESTRICT_KEYW
+__restrict__, RESTRICT_KEYW
+restrict, RESTRICT_KEYW
+asm, ASM_KEYW
+# attribute commented out in modutils 2.4.2.  People are using 'attribute' as a
+# field name which breaks the genksyms parser.  It is not a gcc keyword anyway.
+# KAO.
+#   attribute, ATTRIBUTE_KEYW
+auto, AUTO_KEYW
+char, CHAR_KEYW
+const, CONST_KEYW
+double, DOUBLE_KEYW
+enum, ENUM_KEYW
+extern, EXTERN_KEYW
+float, FLOAT_KEYW
+inline, INLINE_KEYW
+int, INT_KEYW
+long, LONG_KEYW
+register, REGISTER_KEYW
+short, SHORT_KEYW
+signed, SIGNED_KEYW
+static, STATIC_KEYW
+struct, STRUCT_KEYW
+typedef, TYPEDEF_KEYW
+union, UNION_KEYW
+unsigned, UNSIGNED_KEYW
+void, VOID_KEYW
+volatile, VOLATILE_KEYW
+typeof, TYPEOF_KEYW
+__typeof__, TYPEOF_KEYW
diff -Nru a/scripts/genksyms/lex.c_shipped b/scripts/genksyms/lex.c_shipped
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/lex.c_shipped	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,2082 @@
+#line 2 "scripts/genksyms/lex.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+
+#define FLEX_DEBUG
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+
+#define FLEX_DEBUG
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yyleng = (int) (yy_cp - yy_bp); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 13
+#define YY_END_OF_BUFFER 14
+static yyconst short int yy_accept[76] =
+    {   0,
+        0,    0,    0,    0,   14,   12,    4,    3,   12,   12,
+       12,    7,    7,   12,   12,   12,   12,   12,    9,    9,
+       12,   12,   12,    4,    0,    5,    0,    0,    6,    0,
+        0,    7,    0,    0,    0,    0,    2,    8,   10,   10,
+        9,    0,    0,    9,    9,    0,    9,    0,    0,   11,
+        0,    0,    0,   10,    0,   10,    9,    9,    0,    0,
+        0,    0,    0,    0,    0,   10,   10,    0,    0,    0,
+        0,    0,    0,    1,    0
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        4,    4,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    5,    6,    1,    7,    8,    9,    1,
+        1,    7,   10,    1,   11,   12,    7,   13,   14,   14,
+       14,   14,   14,   14,   14,   15,   15,    1,    1,   16,
+       17,   18,    1,    1,   19,   19,   19,   19,   20,   21,
+       22,   22,   22,   22,   22,   23,   22,   22,   22,   22,
+       22,   22,   22,   22,   24,   22,   22,   25,   22,   22,
+        1,   26,    1,    7,   22,    1,   19,   19,   19,   19,
+
+       20,   21,   22,   22,   22,   22,   22,   27,   22,   22,
+       22,   22,   22,   22,   22,   22,   24,   22,   22,   25,
+       22,   22,    1,   28,    1,    7,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst int yy_meta[29] =
+    {   0,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    3,
+        3,    4,    5,    5,    5,    1,    1,    1,    6,    7,
+        6,    8,    8,    8,    8,    1,    8,    1
+    } ;
+
+static yyconst short int yy_base[88] =
+    {   0,
+        0,  166,   22,  152,  151,  282,   39,  282,   26,   33,
+      138,    0,   39,   43,  124,   39,   36,   48,   52,   55,
+       41,   56,   54,   47,   73,  282,    0,   72,  282,    0,
+      116,    0,   78,   75,  122,  103,  282,  282,  106,    0,
+       97,   73,   76,   91,   65,    0,    0,   84,   81,  282,
+      132,   98,   84,  282,  117,  147,  282,   73,  134,   89,
+      100,  140,  172,  139,  134,  181,  282,  135,  106,  142,
+      168,   88,   52,  282,  282,  208,  216,  220,  228,  236,
+      244,  249,  254,  255,  260,  265,  273
+    } ;
+
+static yyconst short int yy_def[88] =
+    {   0,
+       75,    1,    1,    3,   75,   75,   75,   75,   76,   77,
+       75,   78,   78,   79,   75,   75,   75,   75,   75,   19,
+       75,   75,   75,   75,   76,   75,   80,   77,   75,   81,
+       75,   78,   76,   77,   79,   79,   75,   75,   75,   39,
+       19,   82,   83,   75,   75,   84,   20,   76,   77,   75,
+       79,   51,   85,   75,   75,   75,   75,   84,   79,   51,
+       79,   79,   79,   51,   75,   75,   75,   86,   79,   63,
+       86,   87,   87,   75,    0,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75
+    } ;
+
+static yyconst short int yy_nxt[311] =
+    {   0,
+        6,    7,    8,    7,    9,    6,    6,    6,   10,    6,
+        6,   11,    6,    6,    6,    6,    6,    6,   12,   12,
+       12,   12,   13,   12,   12,    6,   12,    6,   15,   16,
+       26,   15,   17,   18,   19,   20,   20,   21,   15,   22,
+       24,   29,   24,   33,   36,   37,   38,   34,   24,   23,
+       24,   27,   38,   38,   74,   38,   38,   38,   30,   31,
+       39,   39,   39,   40,   41,   41,   42,   47,   47,   47,
+       38,   43,   38,   38,   44,   45,   46,   26,   44,   75,
+       29,   38,   26,   29,   40,   55,   55,   57,   26,   29,
+       74,   57,   43,   65,   65,   44,   45,   30,   27,   44,
+
+       30,   59,   37,   27,   36,   37,   30,   59,   37,   27,
+       64,   64,   64,   35,   57,   51,   52,   52,   39,   39,
+       39,   75,   35,   69,   37,   53,   54,   50,   54,   56,
+       56,   56,   54,   59,   37,   59,   37,   37,   68,   35,
+       38,   59,   37,   59,   60,   60,   66,   66,   66,   31,
+       75,   64,   64,   64,   61,   62,   63,   14,   61,   56,
+       56,   56,   69,   35,   61,   62,   69,   67,   61,   67,
+       37,   14,   72,   67,   37,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   70,   70,   70,   75,   75,   75,
+       70,   70,   70,   66,   66,   66,   75,   75,   75,   75,
+
+       75,   54,   75,   54,   75,   75,   75,   54,   25,   25,
+       25,   25,   25,   25,   25,   25,   28,   28,   28,   28,
+       28,   28,   28,   28,   32,   32,   32,   32,   35,   35,
+       35,   35,   35,   35,   35,   35,   48,   75,   48,   48,
+       48,   48,   48,   48,   49,   75,   49,   49,   49,   49,
+       49,   49,   42,   42,   75,   42,   56,   75,   56,   58,
+       58,   58,   66,   75,   66,   71,   71,   71,   71,   71,
+       71,   71,   71,   73,   73,   73,   73,   73,   73,   73,
+       73,    5,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75
+    } ;
+
+static yyconst short int yy_chk[311] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    3,    3,
+        9,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        7,   10,    7,   13,   14,   14,   16,   13,   24,    3,
+       24,    9,   17,   17,   73,   16,   21,   21,   10,   18,
+       18,   18,   18,   19,   19,   19,   19,   20,   20,   20,
+       23,   19,   22,   22,   19,   19,   19,   25,   19,   20,
+       28,   23,   33,   34,   42,   43,   43,   45,   48,   49,
+       72,   45,   42,   53,   53,   58,   58,   28,   25,   58,
+
+       34,   61,   61,   33,   36,   36,   49,   69,   69,   48,
+       52,   52,   52,   60,   44,   36,   36,   36,   39,   39,
+       39,   41,   52,   61,   35,   39,   39,   31,   39,   55,
+       55,   55,   39,   51,   51,   59,   59,   68,   59,   68,
+       15,   62,   62,   70,   51,   51,   65,   65,   65,   11,
+        5,   64,   64,   64,   51,   51,   51,    4,   51,   56,
+       56,   56,   62,   64,   70,   70,   62,   56,   70,   56,
+       71,    2,   71,   56,   63,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,   63,   63,   63,    0,    0,    0,
+       63,   63,   63,   66,   66,   66,    0,    0,    0,    0,
+
+        0,   66,    0,   66,    0,    0,    0,   66,   76,   76,
+       76,   76,   76,   76,   76,   76,   77,   77,   77,   77,
+       77,   77,   77,   77,   78,   78,   78,   78,   79,   79,
+       79,   79,   79,   79,   79,   79,   80,    0,   80,   80,
+       80,   80,   80,   80,   81,    0,   81,   81,   81,   81,
+       81,   81,   82,   82,    0,   82,   83,    0,   83,   84,
+       84,   84,   85,    0,   85,   86,   86,   86,   86,   86,
+       86,   86,   86,   87,   87,   87,   87,   87,   87,   87,
+       87,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 1;
+
+static yyconst short int yy_rule_linenum[13] =
+    {   0,
+       69,   70,   71,   74,   77,   78,   79,   85,   86,   87,
+       89,   92
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "scripts/genksyms/lex.l"
+#define INITIAL 0
+/* Lexical analysis for genksyms.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   Taken from Linux modutils 2.4.22.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2 of the License, or (at your
+   option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+#line 25 "scripts/genksyms/lex.l"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "genksyms.h"
+#include "parse.h"
+
+/* We've got a two-level lexer here.  We let flex do basic tokenization
+   and then we categorize those basic tokens in the second stage.  */
+#define YY_DECL		static int yylex1(void)
+
+/* Version 2 checksumming does proper tokenization; version 1 wasn't
+   quite so pedantic.  */
+#define V2_TOKENS 1
+
+/* We don't do multiple input files.  */
+#line 511 "scripts/genksyms/lex.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	if ( yyleng > 0 ) \
+		yy_current_buffer->yy_at_bol = \
+				(yytext[yyleng - 1] == '\n'); \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp = NULL, *yy_bp = NULL;
+	register int yy_act;
+
+#line 65 "scripts/genksyms/lex.l"
+
+
+
+ /* Keep track of our location in the original source files.  */
+#line 670 "scripts/genksyms/lex.c"
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+		yy_current_state += YY_AT_BOL();
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yy_last_accepting_state = yy_current_state;
+				yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 76 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 282 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		if ( yy_flex_debug )
+			{
+			if ( yy_act == 0 )
+				fprintf( stderr, "--scanner backing up\n" );
+			else if ( yy_act < 13 )
+				fprintf( stderr, "--accepting rule at line %d (\"%s\")\n",
+				         yy_rule_linenum[yy_act], yytext );
+			else if ( yy_act == 13 )
+				fprintf( stderr, "--accepting default rule (\"%s\")\n",
+				         yytext );
+			else if ( yy_act == 14 )
+				fprintf( stderr, "--(end of buffer or a NUL)\n" );
+			else
+				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
+			}
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yy_hold_char;
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 69 "scripts/genksyms/lex.l"
+return FILENAME;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 70 "scripts/genksyms/lex.l"
+cur_line++;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 71 "scripts/genksyms/lex.l"
+cur_line++;
+	YY_BREAK
+/* Ignore all other whitespace.  */
+case 4:
+YY_RULE_SETUP
+#line 74 "scripts/genksyms/lex.l"
+;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 77 "scripts/genksyms/lex.l"
+return STRING;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 78 "scripts/genksyms/lex.l"
+return CHAR;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 79 "scripts/genksyms/lex.l"
+return IDENT;
+	YY_BREAK
+/* The Pedant requires that the other C multi-character tokens be
+    recognized as tokens.  We don't actually use them since we don't
+    parse expressions, but we do want whitespace to be arranged
+    around them properly.  */
+case 8:
+YY_RULE_SETUP
+#line 85 "scripts/genksyms/lex.l"
+return OTHER;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 86 "scripts/genksyms/lex.l"
+return INT;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 87 "scripts/genksyms/lex.l"
+return REAL;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 89 "scripts/genksyms/lex.l"
+return DOTS;
+	YY_BREAK
+/* All other tokens are single characters.  */
+case 12:
+YY_RULE_SETUP
+#line 92 "scripts/genksyms/lex.l"
+return yytext[0];
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 95 "scripts/genksyms/lex.l"
+ECHO;
+	YY_BREAK
+#line 840 "scripts/genksyms/lex.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(V2_TOKENS):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+	yy_current_state += YY_AT_BOL();
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yy_last_accepting_state = yy_current_state;
+			yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 76 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+	register char *yy_cp = yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yy_last_accepting_state = yy_current_state;
+		yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 76 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 75);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+	yy_current_buffer->yy_at_bol = (c == '\n');
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 95 "scripts/genksyms/lex.l"
+
+
+/* Bring in the keyword recognizer.  */
+
+#include "keywords.c"
+
+
+/* Macros to append to our phrase collection list.  */
+
+#define _APP(T,L)	do {						   \
+			  cur_node = next_node;				   \
+			  next_node = xmalloc(sizeof(*next_node));	   \
+			  next_node->next = cur_node;			   \
+			  cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
+			  cur_node->tag = SYM_NORMAL;			   \
+			} while (0)
+
+#define APP		_APP(yytext, yyleng)
+
+
+/* The second stage lexer.  Here we incorporate knowledge of the state
+   of the parser to tailor the tokens that are returned.  */
+
+int
+yylex(void)
+{
+  static enum {
+    ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE,
+    ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
+    ST_TABLE_5, ST_TABLE_6
+  } lexstate = ST_NOTSTARTED;
+
+  static int suppress_type_lookup, dont_want_brace_phrase;
+  static struct string_list *next_node;
+
+  int token, count = 0;
+  struct string_list *cur_node;
+
+  if (lexstate == ST_NOTSTARTED)
+    {
+      BEGIN(V2_TOKENS);
+      next_node = xmalloc(sizeof(*next_node));
+      next_node->next = NULL;
+      lexstate = ST_NORMAL;
+    }
+
+repeat:
+  token = yylex1();
+
+  if (token == 0)
+    return 0;
+  else if (token == FILENAME)
+    {
+      char *file, *e;
+
+      /* Save the filename and line number for later error messages.  */
+
+      if (cur_filename)
+	free(cur_filename);
+
+      file = strchr(yytext, '\"')+1;
+      e = strchr(file, '\"');
+      *e = '\0';
+      cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
+      cur_line = atoi(yytext+2);
+
+      goto repeat;
+    }
+
+  switch (lexstate)
+    {
+    case ST_NORMAL:
+      switch (token)
+	{
+	case IDENT:
+	  APP;
+	  {
+	    const struct resword *r = is_reserved_word(yytext, yyleng);
+	    if (r)
+	      {
+		switch (token = r->token)
+		  {
+		  case ATTRIBUTE_KEYW:
+		    lexstate = ST_ATTRIBUTE;
+		    count = 0;
+		    goto repeat;
+		  case ASM_KEYW:
+		    lexstate = ST_ASM;
+		    count = 0;
+		    goto repeat;
+
+		  case STRUCT_KEYW:
+		  case UNION_KEYW:
+		    dont_want_brace_phrase = 3;
+		  case ENUM_KEYW:
+		    suppress_type_lookup = 2;
+		    goto fini;
+
+		  case EXPORT_SYMBOL_KEYW:
+		      goto fini;
+		  }
+	      }
+	    if (!suppress_type_lookup)
+	      {
+		struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
+		if (sym && sym->type == SYM_TYPEDEF)
+		  token = TYPE;
+	      }
+	  }
+	  break;
+
+	case '[':
+	  APP;
+	  lexstate = ST_BRACKET;
+	  count = 1;
+	  goto repeat;
+
+	case '{':
+	  APP;
+	  if (dont_want_brace_phrase)
+	    break;
+	  lexstate = ST_BRACE;
+	  count = 1;
+	  goto repeat;
+
+	case '=': case ':':
+	  APP;
+	  lexstate = ST_EXPRESSION;
+	  break;
+
+	case DOTS:
+	default:
+	  APP;
+	  break;
+	}
+      break;
+
+    case ST_ATTRIBUTE:
+      APP;
+      switch (token)
+	{
+	case '(':
+	  ++count;
+	  goto repeat;
+	case ')':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = ATTRIBUTE_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_ASM:
+      APP;
+      switch (token)
+	{
+	case '(':
+	  ++count;
+	  goto repeat;
+	case ')':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = ASM_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_BRACKET:
+      APP;
+      switch (token)
+	{
+	case '[':
+	  ++count;
+	  goto repeat;
+	case ']':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = BRACKET_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_BRACE:
+      APP;
+      switch (token)
+	{
+	case '{':
+	  ++count;
+	  goto repeat;
+	case '}':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = BRACE_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_EXPRESSION:
+      switch (token)
+	{
+	case '(': case '[': case '{':
+	  ++count;
+	  APP;
+	  goto repeat;
+	case ')': case ']': case '}':
+	  --count;
+	  APP;
+	  goto repeat;
+	case ',': case ';':
+	  if (count == 0)
+	    {
+	      /* Put back the token we just read so's we can find it again
+		 after registering the expression.  */
+	      unput(token);
+
+	      lexstate = ST_NORMAL;
+	      token = EXPRESSION_PHRASE;
+	      break;
+	    }
+	  APP;
+	  goto repeat;
+	default:
+	  APP;
+	  goto repeat;
+	}
+      break;
+
+    case ST_TABLE_1:
+      goto repeat;
+
+    case ST_TABLE_2:
+      if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
+	{
+	  token = EXPORT_SYMBOL_KEYW;
+	  lexstate = ST_TABLE_5;
+	  APP;
+	  break;
+	}
+      lexstate = ST_TABLE_6;
+      /* FALLTHRU */
+
+    case ST_TABLE_6:
+      switch (token)
+	{
+	case '{': case '[': case '(':
+	  ++count;
+	  break;
+	case '}': case ']': case ')':
+	  --count;
+	  break;
+	case ',':
+	  if (count == 0)
+	    lexstate = ST_TABLE_2;
+	  break;
+	};
+      goto repeat;
+
+    case ST_TABLE_3:
+      goto repeat;
+
+    case ST_TABLE_4:
+      if (token == ';')
+	lexstate = ST_NORMAL;
+      goto repeat;
+
+    case ST_TABLE_5:
+      switch (token)
+	{
+	case ',':
+	  token = ';';
+	  lexstate = ST_TABLE_2;
+	  APP;
+	  break;
+	default:
+	  APP;
+	  break;
+	}
+      break;
+
+    default:
+      abort();
+    }
+fini:
+
+  if (suppress_type_lookup > 0)
+    --suppress_type_lookup;
+  if (dont_want_brace_phrase > 0)
+    --dont_want_brace_phrase;
+
+  yylval = &next_node->next;
+
+  return token;
+}
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#define	ASM_KEYW	257
+#define	ATTRIBUTE_KEYW	258
+#define	AUTO_KEYW	259
+#define	BOOL_KEYW	260
+#define	CHAR_KEYW	261
+#define	CONST_KEYW	262
+#define	DOUBLE_KEYW	263
+#define	ENUM_KEYW	264
+#define	EXTERN_KEYW	265
+#define	FLOAT_KEYW	266
+#define	INLINE_KEYW	267
+#define	INT_KEYW	268
+#define	LONG_KEYW	269
+#define	REGISTER_KEYW	270
+#define	RESTRICT_KEYW	271
+#define	SHORT_KEYW	272
+#define	SIGNED_KEYW	273
+#define	STATIC_KEYW	274
+#define	STRUCT_KEYW	275
+#define	TYPEDEF_KEYW	276
+#define	UNION_KEYW	277
+#define	UNSIGNED_KEYW	278
+#define	VOID_KEYW	279
+#define	VOLATILE_KEYW	280
+#define	TYPEOF_KEYW	281
+#define	EXPORT_SYMBOL_KEYW	282
+#define	ASM_PHRASE	283
+#define	ATTRIBUTE_PHRASE	284
+#define	BRACE_PHRASE	285
+#define	BRACKET_PHRASE	286
+#define	EXPRESSION_PHRASE	287
+#define	CHAR	288
+#define	DOTS	289
+#define	IDENT	290
+#define	INT	291
+#define	REAL	292
+#define	STRING	293
+#define	TYPE	294
+#define	OTHER	295
+#define	FILENAME	296
+
+
+extern YYSTYPE yylval;
diff -Nru a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/lex.l	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,407 @@
+/* Lexical analysis for genksyms.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   Taken from Linux modutils 2.4.22.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2 of the License, or (at your
+   option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+%{
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "genksyms.h"
+#include "parse.h"
+
+/* We've got a two-level lexer here.  We let flex do basic tokenization
+   and then we categorize those basic tokens in the second stage.  */
+#define YY_DECL		static int yylex1(void)
+
+%}
+
+IDENT			[A-Za-z_][A-Za-z0-9_]*
+
+O_INT			0[0-7]*
+D_INT			[1-9][0-9]*
+X_INT			0[Xx][0-9A-Fa-f]+
+I_SUF			[Uu]|[Ll]|[Uu][Ll]|[Ll][Uu]
+INT			({O_INT}|{D_INT}|{X_INT}){I_SUF}?
+
+FRAC			([0-9]*\.[0-9]+)|([0-9]+\.)
+EXP			[Ee][+-]?[0-9]+
+F_SUF			[FfLl]
+REAL			({FRAC}{EXP}?{F_SUF}?)|([0-9]+{EXP}{F_SUF}?)
+
+STRING			L?\"([^\\\"]*\\.)*[^\\\"]*\"
+CHAR			L?\'([^\\\']*\\.)*[^\\\']*\'
+
+MC_TOKEN		([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
+
+/* Version 2 checksumming does proper tokenization; version 1 wasn't
+   quite so pedantic.  */
+%s V2_TOKENS
+
+/* We don't do multiple input files.  */
+%option noyywrap
+
+%%
+
+
+ /* Keep track of our location in the original source files.  */
+^#[ \t]+{INT}[ \t]+\"[^\"\n]+\".*\n	return FILENAME;
+^#.*\n					cur_line++;
+\n					cur_line++;
+
+ /* Ignore all other whitespace.  */
+[ \t\f\v\r]+				;
+
+
+{STRING}				return STRING;
+{CHAR}					return CHAR;
+{IDENT}					return IDENT;
+
+ /* The Pedant requires that the other C multi-character tokens be
+    recognized as tokens.  We don't actually use them since we don't
+    parse expressions, but we do want whitespace to be arranged
+    around them properly.  */
+<V2_TOKENS>{MC_TOKEN}			return OTHER;
+<V2_TOKENS>{INT}			return INT;
+<V2_TOKENS>{REAL}			return REAL;
+
+"..."					return DOTS;
+
+ /* All other tokens are single characters.  */
+.					return yytext[0];
+
+
+%%
+
+/* Bring in the keyword recognizer.  */
+
+#include "keywords.c"
+
+
+/* Macros to append to our phrase collection list.  */
+
+#define _APP(T,L)	do {						   \
+			  cur_node = next_node;				   \
+			  next_node = xmalloc(sizeof(*next_node));	   \
+			  next_node->next = cur_node;			   \
+			  cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
+			  cur_node->tag = SYM_NORMAL;			   \
+			} while (0)
+
+#define APP		_APP(yytext, yyleng)
+
+
+/* The second stage lexer.  Here we incorporate knowledge of the state
+   of the parser to tailor the tokens that are returned.  */
+
+int
+yylex(void)
+{
+  static enum {
+    ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE,
+    ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
+    ST_TABLE_5, ST_TABLE_6
+  } lexstate = ST_NOTSTARTED;
+
+  static int suppress_type_lookup, dont_want_brace_phrase;
+  static struct string_list *next_node;
+
+  int token, count = 0;
+  struct string_list *cur_node;
+
+  if (lexstate == ST_NOTSTARTED)
+    {
+      BEGIN(V2_TOKENS);
+      next_node = xmalloc(sizeof(*next_node));
+      next_node->next = NULL;
+      lexstate = ST_NORMAL;
+    }
+
+repeat:
+  token = yylex1();
+
+  if (token == 0)
+    return 0;
+  else if (token == FILENAME)
+    {
+      char *file, *e;
+
+      /* Save the filename and line number for later error messages.  */
+
+      if (cur_filename)
+	free(cur_filename);
+
+      file = strchr(yytext, '\"')+1;
+      e = strchr(file, '\"');
+      *e = '\0';
+      cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
+      cur_line = atoi(yytext+2);
+
+      goto repeat;
+    }
+
+  switch (lexstate)
+    {
+    case ST_NORMAL:
+      switch (token)
+	{
+	case IDENT:
+	  APP;
+	  {
+	    const struct resword *r = is_reserved_word(yytext, yyleng);
+	    if (r)
+	      {
+		switch (token = r->token)
+		  {
+		  case ATTRIBUTE_KEYW:
+		    lexstate = ST_ATTRIBUTE;
+		    count = 0;
+		    goto repeat;
+		  case ASM_KEYW:
+		    lexstate = ST_ASM;
+		    count = 0;
+		    goto repeat;
+
+		  case STRUCT_KEYW:
+		  case UNION_KEYW:
+		    dont_want_brace_phrase = 3;
+		  case ENUM_KEYW:
+		    suppress_type_lookup = 2;
+		    goto fini;
+
+		  case EXPORT_SYMBOL_KEYW:
+		      goto fini;
+		  }
+	      }
+	    if (!suppress_type_lookup)
+	      {
+		struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
+		if (sym && sym->type == SYM_TYPEDEF)
+		  token = TYPE;
+	      }
+	  }
+	  break;
+
+	case '[':
+	  APP;
+	  lexstate = ST_BRACKET;
+	  count = 1;
+	  goto repeat;
+
+	case '{':
+	  APP;
+	  if (dont_want_brace_phrase)
+	    break;
+	  lexstate = ST_BRACE;
+	  count = 1;
+	  goto repeat;
+
+	case '=': case ':':
+	  APP;
+	  lexstate = ST_EXPRESSION;
+	  break;
+
+	case DOTS:
+	default:
+	  APP;
+	  break;
+	}
+      break;
+
+    case ST_ATTRIBUTE:
+      APP;
+      switch (token)
+	{
+	case '(':
+	  ++count;
+	  goto repeat;
+	case ')':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = ATTRIBUTE_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_ASM:
+      APP;
+      switch (token)
+	{
+	case '(':
+	  ++count;
+	  goto repeat;
+	case ')':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = ASM_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_BRACKET:
+      APP;
+      switch (token)
+	{
+	case '[':
+	  ++count;
+	  goto repeat;
+	case ']':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = BRACKET_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_BRACE:
+      APP;
+      switch (token)
+	{
+	case '{':
+	  ++count;
+	  goto repeat;
+	case '}':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = BRACE_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_EXPRESSION:
+      switch (token)
+	{
+	case '(': case '[': case '{':
+	  ++count;
+	  APP;
+	  goto repeat;
+	case ')': case ']': case '}':
+	  --count;
+	  APP;
+	  goto repeat;
+	case ',': case ';':
+	  if (count == 0)
+	    {
+	      /* Put back the token we just read so's we can find it again
+		 after registering the expression.  */
+	      unput(token);
+
+	      lexstate = ST_NORMAL;
+	      token = EXPRESSION_PHRASE;
+	      break;
+	    }
+	  APP;
+	  goto repeat;
+	default:
+	  APP;
+	  goto repeat;
+	}
+      break;
+
+    case ST_TABLE_1:
+      goto repeat;
+
+    case ST_TABLE_2:
+      if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
+	{
+	  token = EXPORT_SYMBOL_KEYW;
+	  lexstate = ST_TABLE_5;
+	  APP;
+	  break;
+	}
+      lexstate = ST_TABLE_6;
+      /* FALLTHRU */
+
+    case ST_TABLE_6:
+      switch (token)
+	{
+	case '{': case '[': case '(':
+	  ++count;
+	  break;
+	case '}': case ']': case ')':
+	  --count;
+	  break;
+	case ',':
+	  if (count == 0)
+	    lexstate = ST_TABLE_2;
+	  break;
+	};
+      goto repeat;
+
+    case ST_TABLE_3:
+      goto repeat;
+
+    case ST_TABLE_4:
+      if (token == ';')
+	lexstate = ST_NORMAL;
+      goto repeat;
+
+    case ST_TABLE_5:
+      switch (token)
+	{
+	case ',':
+	  token = ';';
+	  lexstate = ST_TABLE_2;
+	  APP;
+	  break;
+	default:
+	  APP;
+	  break;
+	}
+      break;
+
+    default:
+      abort();
+    }
+fini:
+
+  if (suppress_type_lookup > 0)
+    --suppress_type_lookup;
+  if (dont_want_brace_phrase > 0)
+    --dont_want_brace_phrase;
+
+  yylval = &next_node->next;
+
+  return token;
+}
diff -Nru a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/parse.c_shipped	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,1569 @@
+
+/*  A Bison parser, made from scripts/genksyms/parse.y
+    by GNU Bison version 1.28  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+#define	ASM_KEYW	257
+#define	ATTRIBUTE_KEYW	258
+#define	AUTO_KEYW	259
+#define	BOOL_KEYW	260
+#define	CHAR_KEYW	261
+#define	CONST_KEYW	262
+#define	DOUBLE_KEYW	263
+#define	ENUM_KEYW	264
+#define	EXTERN_KEYW	265
+#define	FLOAT_KEYW	266
+#define	INLINE_KEYW	267
+#define	INT_KEYW	268
+#define	LONG_KEYW	269
+#define	REGISTER_KEYW	270
+#define	RESTRICT_KEYW	271
+#define	SHORT_KEYW	272
+#define	SIGNED_KEYW	273
+#define	STATIC_KEYW	274
+#define	STRUCT_KEYW	275
+#define	TYPEDEF_KEYW	276
+#define	UNION_KEYW	277
+#define	UNSIGNED_KEYW	278
+#define	VOID_KEYW	279
+#define	VOLATILE_KEYW	280
+#define	TYPEOF_KEYW	281
+#define	EXPORT_SYMBOL_KEYW	282
+#define	ASM_PHRASE	283
+#define	ATTRIBUTE_PHRASE	284
+#define	BRACE_PHRASE	285
+#define	BRACKET_PHRASE	286
+#define	EXPRESSION_PHRASE	287
+#define	CHAR	288
+#define	DOTS	289
+#define	IDENT	290
+#define	INT	291
+#define	REAL	292
+#define	STRING	293
+#define	TYPE	294
+#define	OTHER	295
+#define	FILENAME	296
+
+#line 24 "scripts/genksyms/parse.y"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include "genksyms.h"
+
+static int is_typedef;
+static int is_extern;
+static char *current_name;
+static struct string_list *decl_spec;
+
+static void yyerror(const char *);
+
+static inline void
+remove_node(struct string_list **p)
+{
+  struct string_list *node = *p;
+  *p = node->next;
+  free_node(node);
+}
+
+static inline void
+remove_list(struct string_list **pb, struct string_list **pe)
+{
+  struct string_list *b = *pb, *e = *pe;
+  *pb = e;
+  free_list(b, e);
+}
+
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#ifndef YYDEBUG
+#define YYDEBUG 1
+#endif
+
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define	YYFINAL		172
+#define	YYFLAG		-32768
+#define	YYNTBASE	52
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 96)
+
+static const char yytranslate[] = {     0,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,    46,
+    47,    48,     2,    45,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,    51,    43,     2,
+    49,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    50,     2,    44,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
+     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+    27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+    37,    38,    39,    40,    41,    42
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = {     0,
+     0,     2,     5,     6,     9,    10,    14,    16,    18,    20,
+    22,    25,    28,    32,    33,    35,    37,    41,    46,    47,
+    49,    51,    54,    56,    58,    60,    62,    64,    66,    68,
+    70,    72,    77,    80,    83,    86,    90,    94,    98,   101,
+   104,   107,   109,   111,   113,   115,   117,   119,   121,   123,
+   125,   127,   129,   132,   133,   135,   137,   140,   142,   144,
+   146,   148,   151,   153,   155,   160,   165,   168,   172,   176,
+   179,   181,   183,   185,   190,   195,   198,   202,   206,   209,
+   211,   215,   216,   218,   220,   224,   227,   230,   232,   233,
+   235,   237,   242,   247,   250,   254,   258,   262,   263,   265,
+   268,   272,   276,   277,   279,   281,   284,   288,   291,   292,
+   294,   296,   300,   303,   306,   308,   311,   312,   314,   317,
+   318,   320
+};
+
+static const short yyrhs[] = {    53,
+     0,    52,    53,     0,     0,    54,    55,     0,     0,    22,
+    56,    57,     0,    57,     0,    81,     0,    93,     0,    95,
+     0,     1,    43,     0,     1,    44,     0,    61,    58,    43,
+     0,     0,    59,     0,    60,     0,    59,    45,    60,     0,
+    71,    94,    92,    82,     0,     0,    62,     0,    63,     0,
+    62,    63,     0,    64,     0,    65,     0,     5,     0,    16,
+     0,    20,     0,    11,     0,    13,     0,    66,     0,    70,
+     0,    27,    46,    65,    47,     0,    21,    36,     0,    23,
+    36,     0,    10,    36,     0,    21,    36,    84,     0,    23,
+    36,    84,     0,    10,    36,    31,     0,    10,    31,     0,
+    21,    84,     0,    23,    84,     0,     7,     0,    18,     0,
+    14,     0,    15,     0,    19,     0,    24,     0,    12,     0,
+     9,     0,    25,     0,     6,     0,    40,     0,    48,    68,
+     0,     0,    69,     0,    70,     0,    69,    70,     0,     8,
+     0,    26,     0,    30,     0,    17,     0,    67,    71,     0,
+    72,     0,    36,     0,    72,    46,    75,    47,     0,    72,
+    46,     1,    47,     0,    72,    32,     0,    46,    71,    47,
+     0,    46,     1,    47,     0,    67,    73,     0,    74,     0,
+    36,     0,    40,     0,    74,    46,    75,    47,     0,    74,
+    46,     1,    47,     0,    74,    32,     0,    46,    73,    47,
+     0,    46,     1,    47,     0,    76,    35,     0,    76,     0,
+    77,    45,    35,     0,     0,    77,     0,    78,     0,    77,
+    45,    78,     0,    62,    79,     0,    67,    79,     0,    80,
+     0,     0,    36,     0,    40,     0,    80,    46,    75,    47,
+     0,    80,    46,     1,    47,     0,    80,    32,     0,    46,
+    79,    47,     0,    46,     1,    47,     0,    61,    71,    31,
+     0,     0,    83,     0,    49,    33,     0,    50,    85,    44,
+     0,    50,     1,    44,     0,     0,    86,     0,    87,     0,
+    86,    87,     0,    61,    88,    43,     0,     1,    43,     0,
+     0,    89,     0,    90,     0,    89,    45,    90,     0,    73,
+    92,     0,    36,    91,     0,    91,     0,    51,    33,     0,
+     0,    30,     0,    29,    43,     0,     0,    29,     0,    28,
+    46,    36,    47,    43,     0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+   101,   103,   106,   109,   112,   114,   115,   116,   117,   118,
+   119,   120,   123,   137,   139,   142,   151,   163,   169,   171,
+   174,   176,   179,   186,   189,   191,   192,   193,   194,   197,
+   199,   200,   204,   206,   208,   212,   219,   226,   235,   236,
+   237,   240,   242,   243,   244,   245,   246,   247,   248,   249,
+   250,   251,   254,   259,   261,   264,   266,   269,   270,   270,
+   271,   278,   280,   283,   293,   295,   297,   299,   301,   307,
+   309,   312,   314,   315,   317,   319,   321,   323,   327,   329,
+   330,   333,   335,   338,   340,   344,   349,   352,   355,   357,
+   365,   369,   371,   373,   375,   377,   381,   390,   392,   396,
+   401,   403,   406,   408,   411,   413,   416,   419,   423,   425,
+   428,   430,   433,   435,   436,   439,   443,   445,   448,   452,
+   454,   457
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = {   "$","error","$undefined.","ASM_KEYW",
+"ATTRIBUTE_KEYW","AUTO_KEYW","BOOL_KEYW","CHAR_KEYW","CONST_KEYW","DOUBLE_KEYW",
+"ENUM_KEYW","EXTERN_KEYW","FLOAT_KEYW","INLINE_KEYW","INT_KEYW","LONG_KEYW",
+"REGISTER_KEYW","RESTRICT_KEYW","SHORT_KEYW","SIGNED_KEYW","STATIC_KEYW","STRUCT_KEYW",
+"TYPEDEF_KEYW","UNION_KEYW","UNSIGNED_KEYW","VOID_KEYW","VOLATILE_KEYW","TYPEOF_KEYW",
+"EXPORT_SYMBOL_KEYW","ASM_PHRASE","ATTRIBUTE_PHRASE","BRACE_PHRASE","BRACKET_PHRASE",
+"EXPRESSION_PHRASE","CHAR","DOTS","IDENT","INT","REAL","STRING","TYPE","OTHER",
+"FILENAME","';'","'}'","','","'('","')'","'*'","'='","'{'","':'","declaration_seq",
+"declaration","@1","declaration1","@2","simple_declaration","init_declarator_list_opt",
+"init_declarator_list","init_declarator","decl_specifier_seq_opt","decl_specifier_seq",
+"decl_specifier","storage_class_specifier","type_specifier","simple_type_specifier",
+"ptr_operator","cvar_qualifier_seq_opt","cvar_qualifier_seq","cvar_qualifier",
+"declarator","direct_declarator","nested_declarator","direct_nested_declarator",
+"parameter_declaration_clause","parameter_declaration_list_opt","parameter_declaration_list",
+"parameter_declaration","m_abstract_declarator","direct_m_abstract_declarator",
+"function_definition","initializer_opt","initializer","class_body","member_specification_opt",
+"member_specification","member_declaration","member_declarator_list_opt","member_declarator_list",
+"member_declarator","member_bitfield_declarator","attribute_opt","asm_definition",
+"asm_phrase_opt","export_definition", NULL
+};
+#endif
+
+static const short yyr1[] = {     0,
+    52,    52,    54,    53,    56,    55,    55,    55,    55,    55,
+    55,    55,    57,    58,    58,    59,    59,    60,    61,    61,
+    62,    62,    63,    63,    64,    64,    64,    64,    64,    65,
+    65,    65,    65,    65,    65,    65,    65,    65,    65,    65,
+    65,    66,    66,    66,    66,    66,    66,    66,    66,    66,
+    66,    66,    67,    68,    68,    69,    69,    70,    70,    70,
+    70,    71,    71,    72,    72,    72,    72,    72,    72,    73,
+    73,    74,    74,    74,    74,    74,    74,    74,    75,    75,
+    75,    76,    76,    77,    77,    78,    79,    79,    80,    80,
+    80,    80,    80,    80,    80,    80,    81,    82,    82,    83,
+    84,    84,    85,    85,    86,    86,    87,    87,    88,    88,
+    89,    89,    90,    90,    90,    91,    92,    92,    93,    94,
+    94,    95
+};
+
+static const short yyr2[] = {     0,
+     1,     2,     0,     2,     0,     3,     1,     1,     1,     1,
+     2,     2,     3,     0,     1,     1,     3,     4,     0,     1,
+     1,     2,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     4,     2,     2,     2,     3,     3,     3,     2,     2,
+     2,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     2,     0,     1,     1,     2,     1,     1,     1,
+     1,     2,     1,     1,     4,     4,     2,     3,     3,     2,
+     1,     1,     1,     4,     4,     2,     3,     3,     2,     1,
+     3,     0,     1,     1,     3,     2,     2,     1,     0,     1,
+     1,     4,     4,     2,     3,     3,     3,     0,     1,     2,
+     3,     3,     0,     1,     1,     2,     3,     2,     0,     1,
+     1,     3,     2,     2,     1,     2,     0,     1,     2,     0,
+     1,     5
+};
+
+static const short yydefact[] = {     3,
+     3,     1,     0,     2,     0,    25,    51,    42,    58,    49,
+     0,    28,    48,    29,    44,    45,    26,    61,    43,    46,
+    27,     0,     5,     0,    47,    50,    59,     0,     0,     0,
+    60,    52,     4,     7,    14,    20,    21,    23,    24,    30,
+    31,     8,     9,    10,    11,    12,    39,    35,    33,     0,
+    40,    19,    34,    41,     0,     0,   119,    64,     0,    54,
+     0,    15,    16,     0,   120,    63,    22,    38,    36,     0,
+   109,     0,     0,   105,     6,    14,    37,     0,     0,     0,
+     0,    53,    55,    56,    13,     0,    62,   121,    97,   117,
+    67,     0,   108,   102,    72,    73,     0,     0,     0,   117,
+    71,     0,   110,   111,   115,   101,     0,   106,   120,    32,
+     0,    69,    68,    57,    17,   118,    98,     0,    89,     0,
+    80,    83,    84,   114,     0,    72,     0,   116,    70,   113,
+    76,     0,   107,     0,   122,     0,    18,    99,    66,    90,
+    52,     0,    89,    86,    88,    65,    79,     0,    78,    77,
+     0,     0,   112,   100,     0,    91,     0,    87,    94,     0,
+    81,    85,    75,    74,    96,    95,     0,     0,    93,    92,
+     0,     0
+};
+
+static const short yydefgoto[] = {     1,
+     2,     3,    33,    52,    34,    61,    62,    63,    71,    36,
+    37,    38,    39,    40,    64,    82,    83,    41,   109,    66,
+   100,   101,   120,   121,   122,   123,   144,   145,    42,   137,
+   138,    51,    72,    73,    74,   102,   103,   104,   105,   117,
+    43,    90,    44
+};
+
+static const short yypact[] = {-32768,
+    19,-32768,   175,-32768,    32,-32768,-32768,-32768,-32768,-32768,
+   -18,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,   -30,-32768,   -26,-32768,-32768,-32768,   -32,   -10,    -2,
+-32768,-32768,-32768,-32768,     2,   428,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,    34,    12,    79,
+-32768,   428,    12,-32768,   455,    33,-32768,-32768,    15,    14,
+    35,    29,-32768,     2,   -14,   -21,-32768,-32768,-32768,    67,
+    31,    37,   127,-32768,-32768,     2,-32768,    54,    60,    66,
+    69,-32768,    14,-32768,-32768,     2,-32768,-32768,-32768,    84,
+-32768,   219,-32768,-32768,    70,-32768,    20,    91,    72,    84,
+   -20,    74,    81,-32768,-32768,-32768,    86,-32768,   102,-32768,
+   106,-32768,-32768,-32768,-32768,-32768,   109,   108,   348,   112,
+   126,   117,-32768,-32768,   118,-32768,   122,-32768,-32768,-32768,
+-32768,   262,-32768,    31,-32768,   131,-32768,-32768,-32768,-32768,
+-32768,     7,   120,-32768,    -9,-32768,-32768,   392,-32768,-32768,
+   125,   130,-32768,-32768,   132,-32768,   159,-32768,-32768,   305,
+-32768,-32768,-32768,-32768,-32768,-32768,   160,   161,-32768,-32768,
+   174,-32768
+};
+
+static const short yypgoto[] = {-32768,
+   208,-32768,-32768,-32768,   158,-32768,-32768,   128,     0,   -90,
+   -36,-32768,   157,-32768,   -70,-32768,-32768,   -51,   -31,-32768,
+   -40,-32768,  -125,-32768,-32768,    65,   -97,-32768,-32768,-32768,
+-32768,   -19,-32768,-32768,   143,-32768,-32768,    83,   124,   141,
+-32768,-32768,-32768
+};
+
+
+#define	YYLAST		495
+
+
+static const short yytable[] = {    67,
+    99,   119,    35,    65,    54,    49,   152,   155,    84,    53,
+    91,   131,    47,    55,    88,    80,    89,    48,   171,    50,
+   125,     9,   159,    50,    92,   132,    99,    81,    99,    69,
+    18,   114,    87,    77,   168,    56,   160,    58,   -89,    27,
+    57,   119,   140,    31,   157,   158,   156,    59,   143,    60,
+    58,    76,   142,   -89,    60,   126,   127,   119,   129,    96,
+    59,    50,    60,    99,    68,    97,    95,    60,    79,   119,
+    96,   143,   143,    86,    45,    46,    97,    85,    60,    70,
+   106,    98,    67,     6,     7,     8,     9,    10,    11,    12,
+    13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+   110,    24,    25,    26,    27,    28,   111,   126,    31,    93,
+    94,    96,   112,   116,   -19,   113,   133,    97,    32,    60,
+    98,   -19,  -103,   128,   -19,   134,   -19,   107,    93,   -19,
+    88,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+    15,    16,    17,    18,    19,    20,    21,    22,   135,    24,
+    25,    26,    27,    28,   139,   140,    31,   136,   146,   156,
+   147,   148,   -19,   154,   149,   142,    32,    60,   150,   -19,
+  -104,   163,   -19,   172,   -19,     5,   164,   -19,   165,     6,
+     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+    27,    28,    29,    30,    31,   166,   169,   170,     4,    75,
+   -19,    78,   162,   115,    32,   108,   153,   -19,   124,   118,
+   -19,     0,   -19,     6,     7,     8,     9,    10,    11,    12,
+    13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+   130,    24,    25,    26,    27,    28,     0,     0,    31,     0,
+     0,     0,     0,   -82,     0,     0,     0,     0,    32,     0,
+     0,     0,   151,     0,     0,   -82,     6,     7,     8,     9,
+    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+    20,    21,    22,     0,    24,    25,    26,    27,    28,     0,
+     0,    31,     0,     0,     0,     0,   -82,     0,     0,     0,
+     0,    32,     0,     0,     0,   167,     0,     0,   -82,     6,
+     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,     0,    24,    25,    26,
+    27,    28,     0,     0,    31,     0,     0,     0,     0,   -82,
+     0,     0,     0,     0,    32,     0,     0,     0,     0,     0,
+     0,   -82,     6,     7,     8,     9,    10,    11,    12,    13,
+    14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+    24,    25,    26,    27,    28,     0,     0,    31,     0,     0,
+     0,     0,     0,   140,     0,     0,     0,   141,     0,     0,
+     0,     0,     0,   142,     0,    60,     6,     7,     8,     9,
+    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+    20,    21,    22,     0,    24,    25,    26,    27,    28,     0,
+     0,    31,     0,     0,     0,     0,   161,     0,     0,     0,
+     0,    32,     6,     7,     8,     9,    10,    11,    12,    13,
+    14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+    24,    25,    26,    27,    28,     0,     0,    31,     0,     0,
+     7,     8,     9,    10,    11,     0,    13,    32,    15,    16,
+     0,    18,    19,    20,     0,    22,     0,    24,    25,    26,
+    27,    28,     0,     0,    31,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    32
+};
+
+static const short yycheck[] = {    36,
+    71,    92,     3,    35,    24,    36,   132,     1,    60,    36,
+    32,    32,    31,    46,    29,     1,    31,    36,     0,    50,
+     1,     8,    32,    50,    46,    46,    97,    59,    99,    49,
+    17,    83,    64,    53,   160,    46,    46,    36,    32,    26,
+    43,   132,    36,    30,   142,   143,    40,    46,   119,    48,
+    36,    52,    46,    47,    48,    36,    97,   148,    99,    40,
+    46,    50,    48,   134,    31,    46,    36,    48,    36,   160,
+    40,   142,   143,    45,    43,    44,    46,    43,    48,     1,
+    44,    51,   119,     5,     6,     7,     8,     9,    10,    11,
+    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+    47,    23,    24,    25,    26,    27,    47,    36,    30,    43,
+    44,    40,    47,    30,    36,    47,    43,    46,    40,    48,
+    51,    43,    44,    33,    46,    45,    48,     1,    43,    51,
+    29,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+    14,    15,    16,    17,    18,    19,    20,    21,    43,    23,
+    24,    25,    26,    27,    47,    36,    30,    49,    47,    40,
+    35,    45,    36,    33,    47,    46,    40,    48,    47,    43,
+    44,    47,    46,     0,    48,     1,    47,    51,    47,     5,
+     6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+    16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
+    26,    27,    28,    29,    30,    47,    47,    47,     1,    52,
+    36,    55,   148,    86,    40,    73,   134,    43,    95,     1,
+    46,    -1,    48,     5,     6,     7,     8,     9,    10,    11,
+    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+   100,    23,    24,    25,    26,    27,    -1,    -1,    30,    -1,
+    -1,    -1,    -1,    35,    -1,    -1,    -1,    -1,    40,    -1,
+    -1,    -1,     1,    -1,    -1,    47,     5,     6,     7,     8,
+     9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+    19,    20,    21,    -1,    23,    24,    25,    26,    27,    -1,
+    -1,    30,    -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,
+    -1,    40,    -1,    -1,    -1,     1,    -1,    -1,    47,     5,
+     6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+    16,    17,    18,    19,    20,    21,    -1,    23,    24,    25,
+    26,    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,    35,
+    -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,
+    -1,    47,     5,     6,     7,     8,     9,    10,    11,    12,
+    13,    14,    15,    16,    17,    18,    19,    20,    21,    -1,
+    23,    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,
+    -1,    -1,    -1,    36,    -1,    -1,    -1,    40,    -1,    -1,
+    -1,    -1,    -1,    46,    -1,    48,     5,     6,     7,     8,
+     9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+    19,    20,    21,    -1,    23,    24,    25,    26,    27,    -1,
+    -1,    30,    -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,
+    -1,    40,     5,     6,     7,     8,     9,    10,    11,    12,
+    13,    14,    15,    16,    17,    18,    19,    20,    21,    -1,
+    23,    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,
+     6,     7,     8,     9,    10,    -1,    12,    40,    14,    15,
+    -1,    17,    18,    19,    -1,    21,    -1,    23,    24,    25,
+    26,    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    40
+};
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/lib/bison.simple"
+/* This file comes from bison-1.28.  */
+
+/* Skeleton output parser for bison,
+   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* This is the parser code that is written into each bison parser
+  when the %semantic_parser declaration is not specified in the grammar.
+  It was written by Richard Stallman by simplifying the hairy parser
+  used when %semantic_parser is specified.  */
+
+#ifndef YYSTACK_USE_ALLOCA
+#ifdef alloca
+#define YYSTACK_USE_ALLOCA
+#else /* alloca not defined */
+#ifdef __GNUC__
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#else /* not GNU C.  */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
+#define YYSTACK_USE_ALLOCA
+#include <alloca.h>
+#else /* not sparc */
+/* We think this test detects Watcom and Microsoft C.  */
+/* This used to test MSDOS, but that is a bad idea
+   since that symbol is in the user namespace.  */
+#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
+#if 0 /* No need for malloc.h, which pollutes the namespace;
+	 instead, just don't use alloca.  */
+#include <malloc.h>
+#endif
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+/* I don't know what this was needed for, but it pollutes the namespace.
+   So I turned it off.   rms, 2 May 1997.  */
+/* #include <malloc.h>  */
+ #pragma alloca
+#define YYSTACK_USE_ALLOCA
+#else /* not MSDOS, or __TURBOC__, or _AIX */
+#if 0
+#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
+		 and on HPUX 10.  Eventually we can turn this on.  */
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#endif /* __hpux */
+#endif
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc */
+#endif /* not GNU C */
+#endif /* alloca not defined */
+#endif /* YYSTACK_USE_ALLOCA not defined */
+
+#ifdef YYSTACK_USE_ALLOCA
+#define YYSTACK_ALLOC alloca
+#else
+#define YYSTACK_ALLOC malloc
+#endif
+
+/* Note: there must be only one dollar sign in this file.
+   It is replaced by the list of actions, each action
+   as one case of the switch.  */
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT 	goto yyabortlab
+#define YYERROR		goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+   This remains here temporarily to ease the
+   transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+#define YYFAIL		goto yyerrlab
+#define YYRECOVERING()  (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    { yychar = (token), yylval = (value);			\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { yyerror ("syntax error: cannot back up"); YYERROR; }	\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+#ifndef YYPURE
+#define YYLEX		yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int	yychar;			/*  the lookahead symbol		*/
+YYSTYPE	yylval;			/*  the semantic value of the		*/
+				/*  lookahead symbol			*/
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc;			/*  location data for the lookahead	*/
+				/*  symbol				*/
+#endif
+
+int yynerrs;			/*  number of parse errors so far       */
+#endif  /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug;			/*  nonzero means print parse trace	*/
+/* Since this is uninitialized, it does not stop multiple parsers
+   from coexisting.  */
+#endif
+
+/*  YYINITDEPTH indicates the initial size of the parser's stacks	*/
+
+#ifndef	YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/*  YYMAXDEPTH is the maximum size the stacks can grow to
+    (effective only if the built-in stack extension method is used).  */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Define __yy_memcpy.  Note that the size argument
+   should be passed with type unsigned int, because that is what the non-GCC
+   definitions require.  With GCC, __builtin_memcpy takes an arg
+   of type size_t, but it can handle unsigned int.  */
+
+#if __GNUC__ > 1		/* GNU C and GNU C++ define this.  */
+#define __yy_memcpy(TO,FROM,COUNT)	__builtin_memcpy(TO,FROM,COUNT)
+#else				/* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (to, from, count)
+     char *to;
+     char *from;
+     unsigned int count;
+{
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (char *to, char *from, unsigned int count)
+{
+  register char *t = to;
+  register char *f = from;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 217 "/usr/lib/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+#ifdef YYPARSE_PARAM
+int yyparse (void *);
+#else
+int yyparse (void);
+#endif
+#endif
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  register int yystate;
+  register int yyn;
+  register short *yyssp;
+  register YYSTYPE *yyvsp;
+  int yyerrstatus;	/*  number of tokens to shift before error messages enabled */
+  int yychar1 = 0;		/*  lookahead token as an internal (translated) token number */
+
+  short	yyssa[YYINITDEPTH];	/*  the state stack			*/
+  YYSTYPE yyvsa[YYINITDEPTH];	/*  the semantic value stack		*/
+
+  short *yyss = yyssa;		/*  refer to the stacks thru separate pointers */
+  YYSTYPE *yyvs = yyvsa;	/*  to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylsa[YYINITDEPTH];	/*  the location stack			*/
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  int yystacksize = YYINITDEPTH;
+  int yyfree_stacks = 0;
+
+#ifdef YYPURE
+  int yychar;
+  YYSTYPE yylval;
+  int yynerrs;
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylloc;
+#endif
+#endif
+
+  YYSTYPE yyval;		/*  the variable used to return		*/
+				/*  semantic values from the action	*/
+				/*  routines				*/
+
+  int yylen;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Starting parse\n");
+#endif
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss - 1;
+  yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in  yystate  .  */
+/* In all cases, when you get here, the value and location stacks
+   have just been pushed. so pushing a state here evens the stacks.  */
+yynewstate:
+
+  *++yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Give user a chance to reallocate the stack */
+      /* Use copies of these so that the &'s don't force the real ones into memory. */
+      YYSTYPE *yyvs1 = yyvs;
+      short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+      YYLTYPE *yyls1 = yyls;
+#endif
+
+      /* Get the current used size of the three stacks, in elements.  */
+      int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      /* Each stack pointer address is followed by the size of
+	 the data in use in that stack, in bytes.  */
+#ifdef YYLSP_NEEDED
+      /* This used to be a conditional around just the two extra args,
+	 but that might be undefined if yyoverflow is a macro.  */
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yyls1, size * sizeof (*yylsp),
+		 &yystacksize);
+#else
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yystacksize);
+#endif
+
+      yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+      yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+	{
+	  yyerror("parser stack overflow");
+	  if (yyfree_stacks)
+	    {
+	      free (yyss);
+	      free (yyvs);
+#ifdef YYLSP_NEEDED
+	      free (yyls);
+#endif
+	    }
+	  return 2;
+	}
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+	yystacksize = YYMAXDEPTH;
+#ifndef YYSTACK_USE_ALLOCA
+      yyfree_stacks = 1;
+#endif
+      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
+      __yy_memcpy ((char *)yyss, (char *)yyss1,
+		   size * (unsigned int) sizeof (*yyssp));
+      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
+      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
+		   size * (unsigned int) sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
+      __yy_memcpy ((char *)yyls, (char *)yyls1,
+		   size * (unsigned int) sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + size - 1;
+      yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+      yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+      if (yyssp >= yyss + yystacksize - 1)
+	YYABORT;
+    }
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+  goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Reading a token: ");
+#endif
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)		/* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;		/* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Now at end of input.\n");
+#endif
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+      if (yydebug)
+	{
+	  fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+	  /* Give the individual parser a way to print the precise meaning
+	     of a token, for further debugging info.  */
+#ifdef YYPRINT
+	  YYPRINT (stderr, yychar, yylval);
+#endif
+	  fprintf (stderr, ")\n");
+	}
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrlab;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  /* count tokens shifted since error; after three, turn off error status.  */
+  if (yyerrstatus) yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+/* Do the default action for the current state.  */
+yydefault:
+
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+yyreduce:
+  yylen = yyr2[yyn];
+  if (yylen > 0)
+    yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      int i;
+
+      fprintf (stderr, "Reducing via rule %d (line %d), ",
+	       yyn, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+	fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+
+
+  switch (yyn) {
+
+case 3:
+#line 107 "scripts/genksyms/parse.y"
+{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;
+    break;}
+case 4:
+#line 109 "scripts/genksyms/parse.y"
+{ free_list(*yyvsp[0], NULL); *yyvsp[0] = NULL; ;
+    break;}
+case 5:
+#line 113 "scripts/genksyms/parse.y"
+{ is_typedef = 1; ;
+    break;}
+case 6:
+#line 114 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 11:
+#line 119 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 12:
+#line 120 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 13:
+#line 125 "scripts/genksyms/parse.y"
+{ if (current_name) {
+		    struct string_list *decl = (*yyvsp[0])->next;
+		    (*yyvsp[0])->next = NULL;
+		    add_symbol(current_name,
+			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
+			       decl, is_extern);
+		    current_name = NULL;
+		  }
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 14:
+#line 138 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 16:
+#line 144 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[0];
+		  *yyvsp[0] = NULL;
+		  add_symbol(current_name,
+			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+		  current_name = NULL;
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 17:
+#line 152 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[0];
+		  *yyvsp[0] = NULL;
+		  free_list(*yyvsp[-1], NULL);
+		  *yyvsp[-1] = decl_spec;
+		  add_symbol(current_name,
+			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+		  current_name = NULL;
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 18:
+#line 165 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1] ? yyvsp[-1] : yyvsp[-2] ? yyvsp[-2] : yyvsp[-3]; ;
+    break;}
+case 19:
+#line 170 "scripts/genksyms/parse.y"
+{ decl_spec = NULL; ;
+    break;}
+case 21:
+#line 175 "scripts/genksyms/parse.y"
+{ decl_spec = *yyvsp[0]; ;
+    break;}
+case 22:
+#line 176 "scripts/genksyms/parse.y"
+{ decl_spec = *yyvsp[0]; ;
+    break;}
+case 23:
+#line 181 "scripts/genksyms/parse.y"
+{ /* Version 2 checksumming ignores storage class, as that
+		     is really irrelevant to the linkage.  */
+		  remove_node(yyvsp[0]);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 28:
+#line 193 "scripts/genksyms/parse.y"
+{ is_extern = 1; yyval = yyvsp[0]; ;
+    break;}
+case 29:
+#line 194 "scripts/genksyms/parse.y"
+{ is_extern = 0; yyval = yyvsp[0]; ;
+    break;}
+case 33:
+#line 205 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_STRUCT; yyval = yyvsp[0]; ;
+    break;}
+case 34:
+#line 207 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_UNION; yyval = yyvsp[0]; ;
+    break;}
+case 35:
+#line 209 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_ENUM; yyval = yyvsp[0]; ;
+    break;}
+case 36:
+#line 213 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+		  r = copy_node(i); r->tag = SYM_STRUCT;
+		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  add_symbol(i->string, SYM_STRUCT, s, is_extern);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 37:
+#line 220 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+		  r = copy_node(i); r->tag = SYM_UNION;
+		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  add_symbol(i->string, SYM_UNION, s, is_extern);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 38:
+#line 227 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+		  r = copy_node(i); r->tag = SYM_ENUM;
+		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  add_symbol(i->string, SYM_ENUM, s, is_extern);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 39:
+#line 235 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 40:
+#line 236 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 41:
+#line 237 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 52:
+#line 251 "scripts/genksyms/parse.y"
+{ (*yyvsp[0])->tag = SYM_TYPEDEF; yyval = yyvsp[0]; ;
+    break;}
+case 53:
+#line 256 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+    break;}
+case 54:
+#line 260 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 57:
+#line 266 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 61:
+#line 272 "scripts/genksyms/parse.y"
+{ /* restrict has no effect in prototypes so ignore it */
+		  remove_node(yyvsp[0]);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 62:
+#line 279 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 64:
+#line 285 "scripts/genksyms/parse.y"
+{ if (current_name != NULL) {
+		    error_with_pos("unexpected second declaration name");
+		    YYERROR;
+		  } else {
+		    current_name = (*yyvsp[0])->string;
+		    yyval = yyvsp[0];
+		  }
+		;
+    break;}
+case 65:
+#line 294 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 66:
+#line 296 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 67:
+#line 298 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 68:
+#line 300 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 69:
+#line 302 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 70:
+#line 308 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 74:
+#line 316 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 75:
+#line 318 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 76:
+#line 320 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 77:
+#line 322 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 78:
+#line 324 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 79:
+#line 328 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 81:
+#line 330 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 82:
+#line 334 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 85:
+#line 341 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 86:
+#line 346 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+    break;}
+case 87:
+#line 351 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+    break;}
+case 89:
+#line 356 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 90:
+#line 358 "scripts/genksyms/parse.y"
+{ /* For version 2 checksums, we don't want to remember
+		     private parameter names.  */
+		  remove_node(yyvsp[0]);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 91:
+#line 366 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[0]);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 92:
+#line 370 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 93:
+#line 372 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 94:
+#line 374 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 95:
+#line 376 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 96:
+#line 378 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 97:
+#line 383 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[-1];
+		  *yyvsp[-1] = NULL;
+		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 98:
+#line 391 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 100:
+#line 398 "scripts/genksyms/parse.y"
+{ remove_list(yyvsp[0], &(*yyvsp[-1])->next); yyval = yyvsp[0]; ;
+    break;}
+case 101:
+#line 402 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 102:
+#line 403 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 103:
+#line 407 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 106:
+#line 413 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 107:
+#line 418 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 108:
+#line 420 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 109:
+#line 424 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 112:
+#line 430 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 113:
+#line 434 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+    break;}
+case 114:
+#line 435 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 116:
+#line 440 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 117:
+#line 444 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 119:
+#line 449 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 120:
+#line 453 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 122:
+#line 459 "scripts/genksyms/parse.y"
+{ export_symbol((*yyvsp[-2])->string); yyval = yyvsp[0]; ;
+    break;}
+}
+   /* the action file gets copied in in place of this dollarsign */
+#line 543 "/usr/lib/bison.simple"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+  yylsp++;
+  if (yylen == 0)
+    {
+      yylsp->first_line = yylloc.first_line;
+      yylsp->first_column = yylloc.first_column;
+      yylsp->last_line = (yylsp-1)->last_line;
+      yylsp->last_column = (yylsp-1)->last_column;
+      yylsp->text = 0;
+    }
+  else
+    {
+      yylsp->last_line = (yylsp+yylen-1)->last_line;
+      yylsp->last_column = (yylsp+yylen-1)->last_column;
+    }
+#endif
+
+  /* Now "shift" the result of the reduction.
+     Determine what state that goes to,
+     based on the state we popped back to
+     and the rule number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTBASE];
+
+  goto yynewstate;
+
+yyerrlab:   /* here on detecting error */
+
+  if (! yyerrstatus)
+    /* If not already recovering from an error, report this error.  */
+    {
+      ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (yyn > YYFLAG && yyn < YYLAST)
+	{
+	  int size = 0;
+	  char *msg;
+	  int x, count;
+
+	  count = 0;
+	  /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
+	  for (x = (yyn < 0 ? -yyn : 0);
+	       x < (sizeof(yytname) / sizeof(char *)); x++)
+	    if (yycheck[x + yyn] == x)
+	      size += strlen(yytname[x]) + 15, count++;
+	  msg = (char *) malloc(size + 15);
+	  if (msg != 0)
+	    {
+	      strcpy(msg, "parse error");
+
+	      if (count < 5)
+		{
+		  count = 0;
+		  for (x = (yyn < 0 ? -yyn : 0);
+		       x < (sizeof(yytname) / sizeof(char *)); x++)
+		    if (yycheck[x + yyn] == x)
+		      {
+			strcat(msg, count == 0 ? ", expecting `" : " or `");
+			strcat(msg, yytname[x]);
+			strcat(msg, "'");
+			count++;
+		      }
+		}
+	      yyerror(msg);
+	      free(msg);
+	    }
+	  else
+	    yyerror ("parse error; also virtual memory exceeded");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror("parse error");
+    }
+
+  goto yyerrlab1;
+yyerrlab1:   /* here on error raised explicitly by an action */
+
+  if (yyerrstatus == 3)
+    {
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+	YYABORT;
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token
+     after shifting the error token.  */
+
+  yyerrstatus = 3;		/* Each real token shifted decrements this */
+
+  goto yyerrhandle;
+
+yyerrdefault:  /* current state does not do anything special for the error token. */
+
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
+  if (yyn) goto yydefault;
+#endif
+
+yyerrpop:   /* pop the current state because it cannot handle the error token */
+
+  if (yyssp == yyss) YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+  yylsp--;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "Error: state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+yyerrhandle:
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
+
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
+
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrpop;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting error token, ");
+#endif
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  yystate = yyn;
+  goto yynewstate;
+
+ yyacceptlab:
+  /* YYACCEPT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
+#endif
+    }
+  return 0;
+
+ yyabortlab:
+  /* YYABORT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
+#endif
+    }
+  return 1;
+}
+#line 463 "scripts/genksyms/parse.y"
+
+
+static void
+yyerror(const char *e)
+{
+  error_with_pos("%s", e);
+}
diff -Nru a/scripts/genksyms/parse.h_shipped b/scripts/genksyms/parse.h_shipped
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/parse.h_shipped	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,46 @@
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#define	ASM_KEYW	257
+#define	ATTRIBUTE_KEYW	258
+#define	AUTO_KEYW	259
+#define	BOOL_KEYW	260
+#define	CHAR_KEYW	261
+#define	CONST_KEYW	262
+#define	DOUBLE_KEYW	263
+#define	ENUM_KEYW	264
+#define	EXTERN_KEYW	265
+#define	FLOAT_KEYW	266
+#define	INLINE_KEYW	267
+#define	INT_KEYW	268
+#define	LONG_KEYW	269
+#define	REGISTER_KEYW	270
+#define	RESTRICT_KEYW	271
+#define	SHORT_KEYW	272
+#define	SIGNED_KEYW	273
+#define	STATIC_KEYW	274
+#define	STRUCT_KEYW	275
+#define	TYPEDEF_KEYW	276
+#define	UNION_KEYW	277
+#define	UNSIGNED_KEYW	278
+#define	VOID_KEYW	279
+#define	VOLATILE_KEYW	280
+#define	TYPEOF_KEYW	281
+#define	EXPORT_SYMBOL_KEYW	282
+#define	ASM_PHRASE	283
+#define	ATTRIBUTE_PHRASE	284
+#define	BRACE_PHRASE	285
+#define	BRACKET_PHRASE	286
+#define	EXPRESSION_PHRASE	287
+#define	CHAR	288
+#define	DOTS	289
+#define	IDENT	290
+#define	INT	291
+#define	REAL	292
+#define	STRING	293
+#define	TYPE	294
+#define	OTHER	295
+#define	FILENAME	296
+
+
+extern YYSTYPE yylval;
diff -Nru a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/genksyms/parse.y	Tue Mar  4 19:30:14 2003
@@ -0,0 +1,469 @@
+/* C global declaration parser for genksyms.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   This file is part of the Linux modutils.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2 of the License, or (at your
+   option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+%{
+
+#include <assert.h>
+#include <malloc.h>
+#include "genksyms.h"
+
+static int is_typedef;
+static int is_extern;
+static char *current_name;
+static struct string_list *decl_spec;
+
+static void yyerror(const char *);
+
+static inline void
+remove_node(struct string_list **p)
+{
+  struct string_list *node = *p;
+  *p = node->next;
+  free_node(node);
+}
+
+static inline void
+remove_list(struct string_list **pb, struct string_list **pe)
+{
+  struct string_list *b = *pb, *e = *pe;
+  *pb = e;
+  free_list(b, e);
+}
+
+%}
+
+%token ASM_KEYW
+%token ATTRIBUTE_KEYW
+%token AUTO_KEYW
+%token BOOL_KEYW
+%token CHAR_KEYW
+%token CONST_KEYW
+%token DOUBLE_KEYW
+%token ENUM_KEYW
+%token EXTERN_KEYW
+%token FLOAT_KEYW
+%token INLINE_KEYW
+%token INT_KEYW
+%token LONG_KEYW
+%token REGISTER_KEYW
+%token RESTRICT_KEYW
+%token SHORT_KEYW
+%token SIGNED_KEYW
+%token STATIC_KEYW
+%token STRUCT_KEYW
+%token TYPEDEF_KEYW
+%token UNION_KEYW
+%token UNSIGNED_KEYW
+%token VOID_KEYW
+%token VOLATILE_KEYW
+%token TYPEOF_KEYW
+
+%token EXPORT_SYMBOL_KEYW
+
+%token ASM_PHRASE
+%token ATTRIBUTE_PHRASE
+%token BRACE_PHRASE
+%token BRACKET_PHRASE
+%token EXPRESSION_PHRASE
+
+%token CHAR
+%token DOTS
+%token IDENT
+%token INT
+%token REAL
+%token STRING
+%token TYPE
+%token OTHER
+%token FILENAME
+
+%%
+
+declaration_seq:
+	declaration
+	| declaration_seq declaration
+	;
+
+declaration:
+	{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
+	declaration1
+	{ free_list(*$2, NULL); *$2 = NULL; }
+	;
+
+declaration1:
+	TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
+		{ $$ = $3; }
+	| simple_declaration
+	| function_definition
+	| asm_definition
+	| export_definition
+	| error ';'				{ $$ = $2; }
+	| error '}'				{ $$ = $2; }
+	;
+
+simple_declaration:
+	decl_specifier_seq_opt init_declarator_list_opt ';'
+		{ if (current_name) {
+		    struct string_list *decl = (*$3)->next;
+		    (*$3)->next = NULL;
+		    add_symbol(current_name,
+			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
+			       decl, is_extern);
+		    current_name = NULL;
+		  }
+		  $$ = $3;
+		}
+	;
+
+init_declarator_list_opt:
+	/* empty */				{ $$ = NULL; }
+	| init_declarator_list
+	;
+
+init_declarator_list:
+	init_declarator
+		{ struct string_list *decl = *$1;
+		  *$1 = NULL;
+		  add_symbol(current_name,
+			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+		  current_name = NULL;
+		  $$ = $1;
+		}
+	| init_declarator_list ',' init_declarator
+		{ struct string_list *decl = *$3;
+		  *$3 = NULL;
+		  free_list(*$2, NULL);
+		  *$2 = decl_spec;
+		  add_symbol(current_name,
+			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+		  current_name = NULL;
+		  $$ = $3;
+		}
+	;
+
+init_declarator:
+	declarator asm_phrase_opt attribute_opt initializer_opt
+		{ $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
+	;
+
+/* Hang on to the specifiers so that we can reuse them.  */
+decl_specifier_seq_opt:
+	/* empty */				{ decl_spec = NULL; }
+	| decl_specifier_seq
+	;
+
+decl_specifier_seq:
+	decl_specifier				{ decl_spec = *$1; }
+	| decl_specifier_seq decl_specifier	{ decl_spec = *$2; }
+	;
+
+decl_specifier:
+	storage_class_specifier
+		{ /* Version 2 checksumming ignores storage class, as that
+		     is really irrelevant to the linkage.  */
+		  remove_node($1);
+		  $$ = $1;
+		}
+	| type_specifier
+	;
+
+storage_class_specifier:
+	AUTO_KEYW
+	| REGISTER_KEYW
+	| STATIC_KEYW
+	| EXTERN_KEYW	{ is_extern = 1; $$ = $1; }
+	| INLINE_KEYW	{ is_extern = 0; $$ = $1; }
+	;
+
+type_specifier:
+	simple_type_specifier
+	| cvar_qualifier
+	| TYPEOF_KEYW '(' type_specifier ')'
+
+	/* References to s/u/e's defined elsewhere.  Rearrange things
+	   so that it is easier to expand the definition fully later.  */
+	| STRUCT_KEYW IDENT
+		{ remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
+	| UNION_KEYW IDENT
+		{ remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
+	| ENUM_KEYW IDENT
+		{ remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
+
+	/* Full definitions of an s/u/e.  Record it.  */
+	| STRUCT_KEYW IDENT class_body
+		{ struct string_list *s = *$3, *i = *$2, *r;
+		  r = copy_node(i); r->tag = SYM_STRUCT;
+		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+		  add_symbol(i->string, SYM_STRUCT, s, is_extern);
+		  $$ = $3;
+		}
+	| UNION_KEYW IDENT class_body
+		{ struct string_list *s = *$3, *i = *$2, *r;
+		  r = copy_node(i); r->tag = SYM_UNION;
+		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+		  add_symbol(i->string, SYM_UNION, s, is_extern);
+		  $$ = $3;
+		}
+	| ENUM_KEYW IDENT BRACE_PHRASE
+		{ struct string_list *s = *$3, *i = *$2, *r;
+		  r = copy_node(i); r->tag = SYM_ENUM;
+		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+		  add_symbol(i->string, SYM_ENUM, s, is_extern);
+		  $$ = $3;
+		}
+
+	/* Anonymous s/u/e definitions.  Nothing needs doing.  */
+	| ENUM_KEYW BRACE_PHRASE			{ $$ = $2; }
+	| STRUCT_KEYW class_body			{ $$ = $2; }
+	| UNION_KEYW class_body				{ $$ = $2; }
+	;
+
+simple_type_specifier:
+	CHAR_KEYW
+	| SHORT_KEYW
+	| INT_KEYW
+	| LONG_KEYW
+	| SIGNED_KEYW
+	| UNSIGNED_KEYW
+	| FLOAT_KEYW
+	| DOUBLE_KEYW
+	| VOID_KEYW
+	| BOOL_KEYW
+	| TYPE			{ (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
+	;
+
+ptr_operator:
+	'*' cvar_qualifier_seq_opt
+		{ $$ = $2 ? $2 : $1; }
+	;
+
+cvar_qualifier_seq_opt:
+	/* empty */					{ $$ = NULL; }
+	| cvar_qualifier_seq
+	;
+
+cvar_qualifier_seq:
+	cvar_qualifier
+	| cvar_qualifier_seq cvar_qualifier		{ $$ = $2; }
+	;
+
+cvar_qualifier:
+	CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
+	| RESTRICT_KEYW
+		{ /* restrict has no effect in prototypes so ignore it */
+		  remove_node($1);
+		  $$ = $1;
+		}
+	;
+
+declarator:
+	ptr_operator declarator			{ $$ = $2; }
+	| direct_declarator
+	;
+
+direct_declarator:
+	IDENT
+		{ if (current_name != NULL) {
+		    error_with_pos("unexpected second declaration name");
+		    YYERROR;
+		  } else {
+		    current_name = (*$1)->string;
+		    $$ = $1;
+		  }
+		}
+	| direct_declarator '(' parameter_declaration_clause ')'
+		{ $$ = $4; }
+	| direct_declarator '(' error ')'
+		{ $$ = $4; }
+	| direct_declarator BRACKET_PHRASE
+		{ $$ = $2; }
+	| '(' declarator ')'
+		{ $$ = $3; }
+	| '(' error ')'
+		{ $$ = $3; }
+	;
+
+/* Nested declarators differ from regular declarators in that they do
+   not record the symbols they find in the global symbol table.  */
+nested_declarator:
+	ptr_operator nested_declarator		{ $$ = $2; }
+	| direct_nested_declarator
+	;
+
+direct_nested_declarator:
+	IDENT
+	| TYPE
+	| direct_nested_declarator '(' parameter_declaration_clause ')'
+		{ $$ = $4; }
+	| direct_nested_declarator '(' error ')'
+		{ $$ = $4; }
+	| direct_nested_declarator BRACKET_PHRASE
+		{ $$ = $2; }
+	| '(' nested_declarator ')'
+		{ $$ = $3; }
+	| '(' error ')'
+		{ $$ = $3; }
+	;
+
+parameter_declaration_clause:
+	parameter_declaration_list_opt DOTS		{ $$ = $2; }
+	| parameter_declaration_list_opt
+	| parameter_declaration_list ',' DOTS		{ $$ = $3; }
+	;
+
+parameter_declaration_list_opt:
+	/* empty */					{ $$ = NULL; }
+	| parameter_declaration_list
+	;
+
+parameter_declaration_list:
+	parameter_declaration
+	| parameter_declaration_list ',' parameter_declaration
+		{ $$ = $3; }
+	;
+
+parameter_declaration:
+	decl_specifier_seq m_abstract_declarator
+		{ $$ = $2 ? $2 : $1; }
+	;
+
+m_abstract_declarator:
+	ptr_operator m_abstract_declarator
+		{ $$ = $2 ? $2 : $1; }
+	| direct_m_abstract_declarator
+	;
+
+direct_m_abstract_declarator:
+	/* empty */					{ $$ = NULL; }
+	| IDENT
+		{ /* For version 2 checksums, we don't want to remember
+		     private parameter names.  */
+		  remove_node($1);
+		  $$ = $1;
+		}
+	/* This wasn't really a typedef name but an identifier that
+	   shadows one.  */
+	| TYPE
+		{ remove_node($1);
+		  $$ = $1;
+		}
+	| direct_m_abstract_declarator '(' parameter_declaration_clause ')'
+		{ $$ = $4; }
+	| direct_m_abstract_declarator '(' error ')'
+		{ $$ = $4; }
+	| direct_m_abstract_declarator BRACKET_PHRASE
+		{ $$ = $2; }
+	| '(' m_abstract_declarator ')'
+		{ $$ = $3; }
+	| '(' error ')'
+		{ $$ = $3; }
+	;
+
+function_definition:
+	decl_specifier_seq_opt declarator BRACE_PHRASE
+		{ struct string_list *decl = *$2;
+		  *$2 = NULL;
+		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
+		  $$ = $3;
+		}
+	;
+
+initializer_opt:
+	/* empty */					{ $$ = NULL; }
+	| initializer
+	;
+
+/* We never care about the contents of an initializer.  */
+initializer:
+	'=' EXPRESSION_PHRASE
+		{ remove_list($2, &(*$1)->next); $$ = $2; }
+	;
+
+class_body:
+	'{' member_specification_opt '}'		{ $$ = $3; }
+	| '{' error '}'					{ $$ = $3; }
+	;
+
+member_specification_opt:
+	/* empty */					{ $$ = NULL; }
+	| member_specification
+	;
+
+member_specification:
+	member_declaration
+	| member_specification member_declaration	{ $$ = $2; }
+	;
+
+member_declaration:
+	decl_specifier_seq_opt member_declarator_list_opt ';'
+		{ $$ = $3; }
+	| error ';'
+		{ $$ = $2; }
+	;
+
+member_declarator_list_opt:
+	/* empty */					{ $$ = NULL; }
+	| member_declarator_list
+	;
+
+member_declarator_list:
+	member_declarator
+	| member_declarator_list ',' member_declarator	{ $$ = $3; }
+	;
+
+member_declarator:
+	nested_declarator attribute_opt			{ $$ = $2 ? $2 : $1; }
+	| IDENT member_bitfield_declarator		{ $$ = $2; }
+	| member_bitfield_declarator
+	;
+
+member_bitfield_declarator:
+	':' EXPRESSION_PHRASE				{ $$ = $2; }
+	;
+
+attribute_opt:
+	/* empty */					{ $$ = NULL; }
+	| ATTRIBUTE_PHRASE
+	;
+
+asm_definition:
+	ASM_PHRASE ';'					{ $$ = $2; }
+	;
+
+asm_phrase_opt:
+	/* empty */					{ $$ = NULL; }
+	| ASM_PHRASE
+	;
+
+export_definition:
+	EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
+		{ export_symbol((*$3)->string); $$ = $5; }
+	;
+
+
+%%
+
+static void
+yyerror(const char *e)
+{
+  error_with_pos("%s", e);
+}
diff -Nru a/scripts/mk_elfconfig.c b/scripts/mk_elfconfig.c
--- a/scripts/mk_elfconfig.c	Tue Mar  4 19:30:14 2003
+++ b/scripts/mk_elfconfig.c	Tue Mar  4 19:30:14 2003
@@ -9,6 +9,9 @@
 	unsigned char ei[EI_NIDENT];	
 	union { short s; char c[2]; } endian_test;
 
+	if (argc != 2) {
+		fprintf(stderr, "Error: no arch\n");
+	}
 	if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
 		fprintf(stderr, "Error: input truncated\n");
 		return 1;
@@ -51,6 +54,11 @@
 		printf("#define HOST_ELFDATA ELFDATA2LSB\n");
 	else
 		abort();
+
+	if (strcmp(argv[1], "v850") == 0)
+		printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
+	else 
+		printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
 
 	return 0;
 }
diff -Nru a/scripts/mkspec b/scripts/mkspec
--- a/scripts/mkspec	Tue Mar  4 19:30:03 2003
+++ b/scripts/mkspec	Tue Mar  4 19:30:03 2003
@@ -45,24 +45,18 @@
 echo "%setup -q"
 echo ""
 echo "%build"
-# This is the first 'disagreement' between x86 and other archs.
-if [ $PC = 1 ]; then 
-	echo "make oldconfig dep clean bzImage modules"
-else
-	echo "make oldconfig dep clean vmlinux modules"
-fi
-# Back on track
+echo "make clean oldconfig all"
 echo ""
 echo "%install"
 echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules'
 echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make modules_install'
-# And that's the second
+# This is the first disagreement between i386 and most others
 if [ $PC = 1 ]; then
 	echo 'cp arch/i386/boot/bzImage $RPM_BUILD_ROOT'"/boot/vmlinuz-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
 else
 	echo 'cp vmlinux $RPM_BUILD_ROOT'"/boot/vmlinux-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
 fi
-# Back on track, again
+# Back on track
 echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
 echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
 echo ""
diff -Nru a/scripts/modpost.c b/scripts/modpost.c
--- a/scripts/modpost.c	Tue Mar  4 19:30:05 2003
+++ b/scripts/modpost.c	Tue Mar  4 19:30:05 2003
@@ -265,6 +265,9 @@
 	munmap(info->hdr, info->size);
 }
 
+#define CRC_PFX     MODULE_SYMBOL_PREFIX "__crc_"
+#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
+
 void
 handle_modversions(struct module *mod, struct elf_info *info,
 		   Elf_Sym *sym, const char *symname)
@@ -279,9 +282,10 @@
 		break;
 	case SHN_ABS:
 		/* CRC'd symbol */
-		if (memcmp(symname, "__crc_", 6) == 0) {
+		if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
 			crc = (unsigned int) sym->st_value;
-			add_exported_symbol(symname+6, mod, &crc);
+			add_exported_symbol(symname + strlen(CRC_PFX),
+					    mod, &crc);
 			modversions = 1;
 		}
 		break;
@@ -290,15 +294,20 @@
 		if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
 			break;
 		
-		s = alloc_symbol(symname);
-		/* add to list */
-		s->next = mod->unres;
-		mod->unres = s;
+		if (memcmp(symname, MODULE_SYMBOL_PREFIX,
+			   strlen(MODULE_SYMBOL_PREFIX)) == 0) {
+			s = alloc_symbol(symname + 
+					 strlen(MODULE_SYMBOL_PREFIX));
+			/* add to list */
+			s->next = mod->unres;
+			mod->unres = s;
+		}
 		break;
 	default:
 		/* All exported symbols */
-		if (memcmp(symname, "__ksymtab_", 10) == 0) {
-			add_exported_symbol(symname+10, mod, NULL);
+		if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
+			add_exported_symbol(symname + strlen(KSYMTAB_PFX),
+					    mod, NULL);
 		}
 		break;
 	}
diff -Nru a/sound/core/device.c b/sound/core/device.c
--- a/sound/core/device.c	Tue Mar  4 19:30:10 2003
+++ b/sound/core/device.c	Tue Mar  4 19:30:10 2003
@@ -144,7 +144,7 @@
  * Registers the device which was already created via
  * snd_device_new().  Usually this is called from snd_card_register(),
  * but it can be called later if any new devices are created after
- * invokation of snd_card_register().
+ * invocation of snd_card_register().
  *
  * Returns zero if successful, or a negative error code on failure or if the
  * device not found.
diff -Nru a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
--- a/sound/core/seq/seq_midi_emul.c	Tue Mar  4 19:30:13 2003
+++ b/sound/core/seq/seq_midi_emul.c	Tue Mar  4 19:30:13 2003
@@ -375,7 +375,7 @@
 
 
 /*
- * intialize the MIDI status
+ * initialize the MIDI status
  */
 void
 snd_midi_channel_set_clear(snd_midi_channel_set_t *chset)
diff -Nru a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
--- a/sound/core/seq/seq_timer.c	Tue Mar  4 19:30:12 2003
+++ b/sound/core/seq/seq_timer.c	Tue Mar  4 19:30:12 2003
@@ -401,7 +401,7 @@
 	return cur_time;	
 }
 
-/* TODO: use interpolation on tick queue (will only be usefull for very
+/* TODO: use interpolation on tick queue (will only be useful for very
  high PPQ values) */
 snd_seq_tick_time_t snd_seq_timer_get_cur_tick(seq_timer_t *tmr)
 {
diff -Nru a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
--- a/sound/drivers/mtpav.c	Tue Mar  4 19:30:12 2003
+++ b/sound/drivers/mtpav.c	Tue Mar  4 19:30:12 2003
@@ -102,7 +102,7 @@
 /*
  *      defines
  */
-//#define USE_FAKE_MTP //       dont actually read/write to MTP device (for debugging without an actual unit) (does not work yet)
+//#define USE_FAKE_MTP //       don't actually read/write to MTP device (for debugging without an actual unit) (does not work yet)
 
 // parallel port usage masks
 #define SIGS_BYTE 0x08
@@ -763,7 +763,7 @@
 	if (err < 0)
 		goto __error;
 
-	err = snd_card_register(mtp_card->card);	// dont snd_card_register until AFTER all cards reources done!
+	err = snd_card_register(mtp_card->card);	// don't snd_card_register until AFTER all cards reources done!
 
 	//printk("snd_card_register returned %d\n", err);
 	if (err < 0)
diff -Nru a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
--- a/sound/i2c/l3/uda1341.c	Tue Mar  4 19:30:08 2003
+++ b/sound/i2c/l3/uda1341.c	Tue Mar  4 19:30:08 2003
@@ -494,7 +494,7 @@
 	
 	DEBUG_NAME(KERN_DEBUG "info_enum where: %d\n", where);
 
-	// this register we dont handle this way
+	// this register we don't handle this way
 	if (!uda1341_enum_items[where])
 		return -EINVAL;
 
diff -Nru a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
--- a/sound/isa/opl3sa2.c	Tue Mar  4 19:30:14 2003
+++ b/sound/isa/opl3sa2.c	Tue Mar  4 19:30:14 2003
@@ -268,7 +268,7 @@
 		snd_printd("OPL3-SA [0x%lx] detect (1) = 0x%x (0x%x)\n", port, tmp, tmp1);
 		return -ENODEV;
 	}
-	/* try if the MIC register is accesible */
+	/* try if the MIC register is accessible */
 	tmp = snd_opl3sa2_read(chip, OPL3SA2_MIC);
 	snd_opl3sa2_write(chip, OPL3SA2_MIC, 0x8a);
 	if (((tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MIC)) & 0x9f) != 0x8a) {
diff -Nru a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
--- a/sound/isa/wavefront/wavefront_fx.c	Tue Mar  4 19:30:10 2003
+++ b/sound/isa/wavefront/wavefront_fx.c	Tue Mar  4 19:30:11 2003
@@ -227,7 +227,7 @@
    This code was developed using DOSEMU. The Turtle Beach SETUPSND
    utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
    of the port I/O done, using the Yamaha faxback document as a guide
-   to add more logic to the code. Its really pretty wierd.
+   to add more logic to the code. Its really pretty weird.
 
    There was an alternative approach of just dumping the whole I/O
    sequence as a series of port/value pairs and a simple loop
@@ -692,7 +692,7 @@
 	return (0);
 }
 
-/* wierd stuff, derived from port I/O tracing with dosemu */
+/* weird stuff, derived from port I/O tracing with dosemu */
 
 static unsigned char page_zero[] __initdata = {
 0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00,
diff -Nru a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
--- a/sound/isa/wavefront/wavefront_synth.c	Tue Mar  4 19:30:07 2003
+++ b/sound/isa/wavefront/wavefront_synth.c	Tue Mar  4 19:30:07 2003
@@ -518,7 +518,7 @@
 /***********************************************************************
 WaveFront data munging   
 
-Things here are wierd. All data written to the board cannot 
+Things here are weird. All data written to the board cannot 
 have its most significant bit set. Any data item with values 
 potentially > 0x7F (127) must be split across multiple bytes.
 
@@ -527,7 +527,7 @@
 that is represented on the x86 side as an array of bytes. The most
 efficient approach to handling both cases seems to be to use 2
 different functions for munging and 2 for de-munging. This avoids
-wierd casting and worrying about bit-level offsets.
+weird casting and worrying about bit-level offsets.
 
 **********************************************************************/
 
@@ -906,7 +906,7 @@
 
 	if (header->size) {
 
-		/* XXX its a debatable point whether or not RDONLY semantics
+		/* XXX it's a debatable point whether or not RDONLY semantics
 		   on the ROM samples should cover just the sample data or
 		   the sample header. For now, it only covers the sample data,
 		   so anyone is free at all times to rewrite sample headers.
@@ -1034,7 +1034,7 @@
 	shptr = munge_int32 (*((u32 *) &header->hdr.s.sampleEndOffset),
 			     shptr, 4);
 	
-	/* This one is truly wierd. What kind of wierdo decided that in
+	/* This one is truly weird. What kind of weirdo decided that in
 	   a system dominated by 16 and 32 bit integers, they would use
 	   a just 12 bits ?
 	*/
diff -Nru a/sound/oss/ad1816.c b/sound/oss/ad1816.c
--- a/sound/oss/ad1816.c	Tue Mar  4 19:30:13 2003
+++ b/sound/oss/ad1816.c	Tue Mar  4 19:30:13 2003
@@ -1227,7 +1227,7 @@
 			sound_free_dma(devc->dma_capture);
 		}
 
-		/* card wont get added if resources could not be allocated
+		/* card won't get added if resources could not be allocated
 		   thus we need not ckeck if allocation was successful */
 		sound_free_dma (devc->dma_playback);
 		free_irq(devc->irq, devc->osp);
diff -Nru a/sound/oss/ad1848.c b/sound/oss/ad1848.c
--- a/sound/oss/ad1848.c	Tue Mar  4 19:30:10 2003
+++ b/sound/oss/ad1848.c	Tue Mar  4 19:30:10 2003
@@ -2987,7 +2987,7 @@
 	if (err < 0)
 		return(NULL);
 
-	if((err = pnp_activate_dev(dev,NULL)) < 0) {
+	if((err = pnp_activate_dev(dev)) < 0) {
 		printk(KERN_ERR "ad1848: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
 
 		pnp_device_detach(dev);
@@ -3024,7 +3024,7 @@
 
 static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pnp_card *bus, int slot)
 {
-	char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name;
+	char *busname = bus->dev.name[0] ? bus->dev.name : ad1848_isapnp_list[slot].name;
 
 	/* Initialize this baby. */
 
diff -Nru a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
--- a/sound/oss/awe_wave.c	Tue Mar  4 19:30:07 2003
+++ b/sound/oss/awe_wave.c	Tue Mar  4 19:30:07 2003
@@ -562,7 +562,7 @@
 	/* clear all samples */
 	awe_reset_samples();
 
-	/* intialize AWE32 hardware */
+	/* initialize AWE32 hardware */
 	awe_initialize();
 
 	sprintf(awe_info.name, "AWE32-%s (RAM%dk)",
diff -Nru a/sound/oss/cs4232.c b/sound/oss/cs4232.c
--- a/sound/oss/cs4232.c	Tue Mar  4 19:30:10 2003
+++ b/sound/oss/cs4232.c	Tue Mar  4 19:30:10 2003
@@ -127,7 +127,7 @@
 	 * method conflicts with possible PnP support in the OS. For this reason 
 	 * driver is just a temporary kludge.
 	 *
-	 * Also the Cirrus/Crystal method doesnt always work. Try ISA PnP first ;)
+	 * Also the Cirrus/Crystal method doesn't always work. Try ISA PnP first ;)
 	 */
 
 	/*
diff -Nru a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
--- a/sound/oss/cs46xx.c	Tue Mar  4 19:30:03 2003
+++ b/sound/oss/cs46xx.c	Tue Mar  4 19:30:03 2003
@@ -1016,7 +1016,7 @@
 	}
 		
 	/*
-	 * ganularity is byte boundry, good part.
+	 * ganularity is byte boundary, good part.
 	 */
 	if(dmabuf->enable & DAC_RUNNING)
 	{
diff -Nru a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
--- a/sound/oss/dmasound/dmasound_awacs.c	Tue Mar  4 19:30:07 2003
+++ b/sound/oss/dmasound/dmasound_awacs.c	Tue Mar  4 19:30:07 2003
@@ -1354,7 +1354,7 @@
 			case AWACS_DACA:
 				wait_ms(10); /* Check this !!! */
 				daca_leave_sleep();
-				break ;		/* dont know how yet */
+				break ;		/* don't know how yet */
 			case AWACS_BURGUNDY:
 				break ;
 			case AWACS_SCREAMER:
@@ -2960,7 +2960,7 @@
 			request_module("i2c-keywest");
 #endif /* CONFIG_KMOD */
 			daca_init();
-			break ;		/* dont know how yet */
+			break ;		/* don't know how yet */
 		case AWACS_BURGUNDY:
 			awacs_burgundy_init();
 			break ;
diff -Nru a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
--- a/sound/oss/dmasound/dmasound_core.c	Tue Mar  4 19:30:04 2003
+++ b/sound/oss/dmasound/dmasound_core.c	Tue Mar  4 19:30:04 2003
@@ -1212,7 +1212,7 @@
 		return result ;
 		break ;
 	case SNDCTL_DSP_SPEED:
-		/* changing this on the fly will have wierd effects on the sound.
+		/* changing this on the fly will have weird effects on the sound.
 		   Where there are rate conversions implemented in soft form - it
 		   will cause the _ctx_xxx() functions to be substituted.
 		   However, there doesn't appear to be any reason to dis-allow it from
diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c
--- a/sound/oss/es1371.c	Tue Mar  4 19:30:12 2003
+++ b/sound/oss/es1371.c	Tue Mar  4 19:30:12 2003
@@ -73,7 +73,7 @@
  *                       detect the ES1373 and later parts.
  *                       added AC97 #defines for readability
  *                       added a /proc file system for dumping hardware state
- *                       updated SRC and CODEC w/r functions to accomodate bugs
+ *                       updated SRC and CODEC w/r functions to accommodate bugs
  *                       in some versions of the ES137x chips.
  *    31.08.1999   0.17  add spin_lock_init
  *                       replaced current->state = x with set_current_state(x)
@@ -2863,7 +2863,7 @@
 	if ((res=(s->dev_midi = register_sound_midi(&es1371_midi_fops, -1))<0 ))
 		goto err_dev4;
 #ifdef ES1371_DEBUG
-	/* intialize the debug proc device */
+	/* initialize the debug proc device */
 	s->ps = create_proc_read_entry("es1371",0,NULL,proc_es1371_dump,NULL);
 #endif /* ES1371_DEBUG */
 	
diff -Nru a/sound/oss/ite8172.c b/sound/oss/ite8172.c
--- a/sound/oss/ite8172.c	Tue Mar  4 19:30:05 2003
+++ b/sound/oss/ite8172.c	Tue Mar  4 19:30:05 2003
@@ -1780,7 +1780,7 @@
 	goto err_dev2;
 
 #ifdef IT8172_DEBUG
-    /* intialize the debug proc device */
+    /* initialize the debug proc device */
     s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
 				   proc_it8172_dump, NULL);
 #endif /* IT8172_DEBUG */
diff -Nru a/sound/oss/maestro.c b/sound/oss/maestro.c
--- a/sound/oss/maestro.c	Tue Mar  4 19:30:13 2003
+++ b/sound/oss/maestro.c	Tue Mar  4 19:30:13 2003
@@ -252,7 +252,7 @@
 
 /* we try to setup 2^(dsps_order) /dev/dsp devices */
 static int dsps_order=0;
-/* wether or not we mess around with power management */
+/* whether or not we mess around with power management */
 static int use_pm=2; /* set to 1 for force */
 /* clocking for broken hardware - a few laptops seem to use a 50Khz clock
 	ie insmod with clocking=50000 or so */
@@ -292,7 +292,7 @@
 
 
 /* changed so that I could actually find all the
-	references and fix them up.  its a little more readable now. */
+	references and fix them up.  it's a little more readable now. */
 #define ESS_FMT_STEREO	0x01
 #define ESS_FMT_16BIT	0x02
 #define ESS_FMT_MASK	0x03
@@ -804,7 +804,7 @@
 
 	if (read) return val;
 
-	/* oss can have many inputs, maestro cant.  try
+	/* oss can have many inputs, maestro can't.  try
 		to pick the 'new' one */
 
 	if (mask != val) mask &= ~val;
@@ -1518,7 +1518,7 @@
 				pa = virt_to_bus(buffer);
 			} else {
 				/* right channel records its split half.
-				*2 accomodates for rampant shifting earlier */
+				*2 accommodates for rampant shifting earlier */
 				pa = virt_to_bus(buffer + size*2);
 			}
 
@@ -3271,7 +3271,7 @@
 	outb(0x88, iobase+0x1f);
 
 	/* it appears some maestros (dell 7500) only work if these are set,
-		regardless of wether we use the assp or not. */
+		regardless of whether we use the assp or not. */
 
 	outb(0, iobase+0xA4); 
 	outb(3, iobase+0xA2); 
@@ -3507,7 +3507,7 @@
 	 * 		or
 	 *		- we're not a 2e, lesser chipps seem to have problems.
 	 *		- we're not on our _very_ small whitelist.  some implemenetations
-	 *			really dont' like the pm code, others require it.
+	 *			really don't like the pm code, others require it.
 	 *			feel free to expand this as required.
 	 */
 #define SUBSYSTEM_VENDOR(x) (x&0xffff)
diff -Nru a/sound/oss/maestro3.c b/sound/oss/maestro3.c
--- a/sound/oss/maestro3.c	Tue Mar  4 19:30:13 2003
+++ b/sound/oss/maestro3.c	Tue Mar  4 19:30:13 2003
@@ -1916,8 +1916,8 @@
      * the amazingly complicated prog_dmabuf wants it.
      *
      * pci_alloc_sonsistent guarantees that it won't cross a natural
-     * boundry; the m3 hardware can't have dma cross a 64k bus
-     * address boundry.
+     * boundary; the m3 hardware can't have dma cross a 64k bus
+     * address boundary.
      */
     for (order = 16-PAGE_SHIFT; order >= 1; order--) {
         db->rawbuf = pci_alloc_consistent(pci_dev, PAGE_SIZE << order,
diff -Nru a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c
--- a/sound/oss/nec_vrc5477.c	Tue Mar  4 19:30:12 2003
+++ b/sound/oss/nec_vrc5477.c	Tue Mar  4 19:30:12 2003
@@ -1884,7 +1884,7 @@
 		goto err_dev2;
 
 #ifdef VRC5477_AC97_DEBUG
-	/* intialize the debug proc device */
+	/* initialize the debug proc device */
 	s->ps = create_proc_read_entry(VRC5477_AC97_MODULE_NAME, 0, NULL,
 				       proc_vrc5477_ac97_dump, NULL);
 #endif /* VRC5477_AC97_DEBUG */
diff -Nru a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c
--- a/sound/oss/opl3sa2.c	Tue Mar  4 19:30:03 2003
+++ b/sound/oss/opl3sa2.c	Tue Mar  4 19:30:03 2003
@@ -918,7 +918,7 @@
 		break;
 	}
 
-	/* its supposed to automute before suspending, so we wont bother */
+	/* its supposed to automute before suspending, so we won't bother */
 	opl3sa2_read(p->cfg_port, OPL3SA2_PM, &p->reg);
 	opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->reg | pm_mode);
 
diff -Nru a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
--- a/sound/oss/rme96xx.c	Tue Mar  4 19:30:07 2003
+++ b/sound/oss/rme96xx.c	Tue Mar  4 19:30:07 2003
@@ -1332,7 +1332,7 @@
                 file->f_flags |= O_NONBLOCK;
                 return 0;
 
-        case SNDCTL_DSP_GETODELAY: /* What shold this exactly do ? , 
+        case SNDCTL_DSP_GETODELAY: /* What should this exactly do ? ,
 				      ATM it is just abinfo.bytes */
 		if (!(file->f_mode & FMODE_WRITE))
 			return -EINVAL;
diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c
--- a/sound/oss/trident.c	Tue Mar  4 19:30:12 2003
+++ b/sound/oss/trident.c	Tue Mar  4 19:30:12 2003
@@ -19,6 +19,7 @@
  *	Ching-Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support 
  *	Matt Wu <mattwu@acersoftech.com.cn> ALi 5451 Audio Core Support
  *	Peter Wächtler <pwaechtler@loewe-komp.de> CyberPro5050 support
+ *      Muli Ben-Yehuda <mulix@mulix.org>
  *
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -81,7 +82,7 @@
  *  v0.14.9a
  *	Aug 6 2001 Alan Cox
  *	0.14.9 crashed on rmmod due to a timer/bh left running. Simplified
- *	the existing logic (the BH doesnt help as ac97 is lock_irqsave)
+ *	the existing logic (the BH doesn't help as ac97 is lock_irqsave)
  *	and used del_timer_sync to clean up
  *	Fixed a problem where the ALi change broke my generic card
  *  v0.14.9
@@ -201,6 +202,7 @@
 #include <linux/interrupt.h>
 #include <linux/pm.h>
 #include <linux/gameport.h>
+#include <linux/kernel.h> 
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 #include <asm/io.h>
@@ -538,8 +540,8 @@
 
 	outl(global_control, TRID_REG(card, T4D_LFO_GC_CIR));
 
-	TRDBG("trident: Enable Loop Interrupts, globctl = 0x%08X\n",
-	      inl(TRID_REG(card, T4D_LFO_GC_CIR)));
+	pr_debug("trident: Enable Loop Interrupts, globctl = 0x%08X\n",
+		 inl(TRID_REG(card, T4D_LFO_GC_CIR)));
 
 	return (TRUE);
 }
@@ -552,8 +554,8 @@
 	global_control &= ~(ENDLP_IE | MIDLP_IE);
 	outl(global_control, TRID_REG(card, T4D_LFO_GC_CIR));
 
-	TRDBG("trident: Disabled Loop Interrupts, globctl = 0x%08X\n",
-	      global_control);
+	pr_debug("trident: Disabled Loop Interrupts, globctl = 0x%08X\n",
+		 global_control);
 
 	return (TRUE);
 }
@@ -570,8 +572,8 @@
 
 #ifdef DEBUG
 	reg = inl(TRID_REG(card, addr));
-	TRDBG("trident: enabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
-	      channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
+	pr_debug("trident: enabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
+		 channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
 #endif /* DEBUG */ 
 }
 
@@ -590,8 +592,8 @@
 
 #ifdef DEBUG
 	reg = inl(TRID_REG(card, addr));
-	TRDBG("trident: disabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
-	      channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
+	pr_debug("trident: disabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
+		 channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
 #endif /* DEBUG */ 
 }
 
@@ -609,8 +611,8 @@
 
 #ifdef DEBUG 
 	reg = inl(TRID_REG(card, addr));
-	TRDBG("trident: start voice on channel %d, %s = 0x%08x(addr:%X)\n",
-	      channel, addr==T4D_START_B? "START_B":"START_A",reg,addr);
+	pr_debug("trident: start voice on channel %d, %s = 0x%08x(addr:%X)\n",
+		 channel, addr==T4D_START_B? "START_B":"START_A",reg,addr);
 #endif /* DEBUG */ 
 }
 
@@ -628,8 +630,8 @@
 
 #ifdef DEBUG
 	reg = inl(TRID_REG(card, addr));
-	TRDBG("trident: stop voice on channel %d, %s = 0x%08x(addr:%X)\n",
-	      channel, addr==T4D_STOP_B? "STOP_B":"STOP_A",reg,addr);
+	pr_debug("trident: stop voice on channel %d, %s = 0x%08x(addr:%X)\n",
+		 channel, addr==T4D_STOP_B? "STOP_B":"STOP_A",reg,addr);
 #endif /* DEBUG */ 
 }
 
@@ -647,8 +649,8 @@
 
 #ifdef DEBUG
 	if (reg & mask)
-		TRDBG("trident: channel %d has interrupt, %s = 0x%08x\n",
-		      channel,reg==T4D_AINT_B? "AINT_B":"AINT_A", reg);
+		pr_debug("trident: channel %d has interrupt, %s = 0x%08x\n",
+			 channel,reg==T4D_AINT_B? "AINT_B":"AINT_A", reg);
 #endif /* DEBUG */ 
 	return (reg & mask) ? TRUE : FALSE;
 }
@@ -665,8 +667,8 @@
 
 #ifdef DEBUG
 	reg = inl(TRID_REG(card, T4D_AINT_B));
-	TRDBG("trident: Ack channel %d interrupt, AINT_B = 0x%08x\n",
-	      channel, reg);
+	pr_debug("trident: Ack channel %d interrupt, AINT_B = 0x%08x\n",
+		 channel, reg);
 #endif /* DEBUG */ 
 }
 
@@ -914,7 +916,7 @@
 
 	trident_write_voice_regs(state);
 
-	TRDBG("trident: called trident_set_dac_rate : rate = %d\n", rate);
+	pr_debug("trident: called trident_set_dac_rate : rate = %d\n", rate);
 
 	return rate;
 }
@@ -934,7 +936,7 @@
 
 	trident_write_voice_regs(state);
 
-	TRDBG("trident: called trident_set_adc_rate : rate = %d\n", rate);
+	pr_debug("trident: called trident_set_adc_rate : rate = %d\n", rate);
 
 	return rate;
 }
@@ -978,9 +980,9 @@
 		/* stereo */
 		channel->control |= CHANNEL_STEREO;
 
-	TRDBG("trident: trident_play_setup, LBA = 0x%08x, "
-	      "Delta = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
-	      channel->lba, channel->delta, channel->eso, channel->control);
+	pr_debug("trident: trident_play_setup, LBA = 0x%08x, "
+		 "Delta = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
+		 channel->lba, channel->delta, channel->eso, channel->control);
 
 	trident_write_voice_regs(state);
 }
@@ -1064,9 +1066,9 @@
 		/* stereo */
 		channel->control |= CHANNEL_STEREO;
 	
-	TRDBG("trident: trident_rec_setup, LBA = 0x%08x, "
-	      "Delat = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
-	      channel->lba, channel->delta, channel->eso, channel->control);
+	pr_debug("trident: trident_rec_setup, LBA = 0x%08x, "
+		 "Delta = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
+		 channel->lba, channel->delta, channel->eso, channel->control);
 
 	trident_write_voice_regs(state);
 }
@@ -1101,8 +1103,8 @@
 	}
 
 	
-	TRDBG("trident: trident_get_dma_addr: chip reported channel: %d, "
-	      "cso = 0x%04x\n", dmabuf->channel->num, cso);
+	pr_debug("trident: trident_get_dma_addr: chip reported channel: %d, "
+		 "cso = 0x%04x\n", dmabuf->channel->num, cso);
 
 	/* ESO and CSO are in units of Samples, convert to byte offset */
 	cso <<= sample_shift[dmabuf->fmt];
@@ -1211,8 +1213,8 @@
 					    &dmabuf->dma_handle)))
 		return -ENOMEM;
 
-	TRDBG("trident: allocated %ld (order = %d) bytes at %p\n",
-	      PAGE_SIZE << order, order, rawbuf);
+	pr_debug("trident: allocated %ld (order = %d) bytes at %p\n",
+		 PAGE_SIZE << order, order, rawbuf);
 
 	dmabuf->ready  = dmabuf->mapped = 0;
 	dmabuf->rawbuf = rawbuf;
@@ -1349,10 +1351,11 @@
 		/* set the ready flag for the dma buffer */
 		dmabuf->ready = 1;
 
-		TRDBG("trident: prog_dmabuf(%d), sample rate = %d, format = %d, numfrag = %d, "
-		      "fragsize = %d dmasize = %d\n",
-		      dmabuf->channel->num, dmabuf->rate, dmabuf->fmt, dmabuf->numfrag,
-		      dmabuf->fragsize, dmabuf->dmasize);
+		pr_debug("trident: prog_dmabuf(%d), sample rate = %d, "
+			 "format = %d, numfrag = %d, fragsize = %d "
+			 "dmasize = %d\n", dmabuf->channel->num, dmabuf->rate, 
+			 dmabuf->fmt, dmabuf->numfrag, dmabuf->fragsize, 
+			 dmabuf->dmasize);
 	}
 	unlock_set_fmt(state);
 	return 0;
@@ -1704,7 +1707,7 @@
 	/* FIXED: read interrupt status only once */
 	irq_status=inl(TRID_REG(card, T4D_AINT_A) );
 
-	TRDBG("cyber_address_interrupt: irq_status 0x%X\n",irq_status);
+	pr_debug("cyber_address_interrupt: irq_status 0x%X\n",irq_status);
 
 	for (i = 0; i < NR_HW_CH; i++) {
 		channel = 31 - i; 
@@ -1712,7 +1715,7 @@
 			/* clear bit by writing a 1, zeroes are ignored */ 		
 			outl( (1 << channel), TRID_REG(card, T4D_AINT_A));
 		
-			TRDBG("cyber_interrupt: channel %d\n", channel);
+			pr_debug("cyber_interrupt: channel %d\n", channel);
 
 			if ((state = card->states[i]) != NULL) {
 				trident_update_ptr(state);
@@ -1735,7 +1738,7 @@
 	spin_lock(&card->lock);
 	event = inl(TRID_REG(card, T4D_MISCINT));
 
-	TRDBG("trident: trident_interrupt called, MISCINT = 0x%08x\n", event);
+	pr_debug("trident: trident_interrupt called, MISCINT = 0x%08x\n", event);
 
 	if (event & ADDRESS_IRQ) {
 		card->address_interrupt(card);
@@ -1773,7 +1776,7 @@
 	unsigned swptr;
 	int cnt;
 
-	TRDBG("trident: trident_read called, count = %d\n", count);
+	pr_debug("trident: trident_read called, count = %d\n", count);
 
 	VALIDATE_STATE(state);
 	if (ppos != &file->f_pos)
@@ -1827,7 +1830,7 @@
 			   which results in a (potential) buffer overrun. And worse, there is
 			   NOTHING we can do to prevent it. */
 			if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
-				TRDBG(KERN_ERR "trident: recording schedule timeout, "
+				pr_debug(KERN_ERR "trident: recording schedule timeout, "
 				      "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
 				      dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
 				      dmabuf->hwptr, dmabuf->swptr);
@@ -1885,7 +1888,7 @@
 	unsigned int state_cnt;
 	unsigned int copy_count;
 
-	TRDBG("trident: trident_write called, count = %d\n", count);
+	pr_debug("trident: trident_write called, count = %d\n", count);
 
 	VALIDATE_STATE(state);
 	if (ppos != &file->f_pos)
@@ -1954,7 +1957,7 @@
 			   which results in a (potential) buffer underrun. And worse, there is
 			   NOTHING we can do to prevent it. */
 			if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
-				TRDBG(KERN_ERR "trident: playback schedule timeout, "
+				pr_debug(KERN_ERR "trident: playback schedule timeout, "
 				      "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
 				      dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
 				      dmabuf->hwptr, dmabuf->swptr);
@@ -2137,7 +2140,7 @@
 	VALIDATE_STATE(state);
 	mapped = ((file->f_mode & FMODE_WRITE) && dmabuf->mapped) ||
 		((file->f_mode & FMODE_READ) && dmabuf->mapped);
-	TRDBG("trident: trident_ioctl, command = %2d, arg = 0x%08x\n",
+	pr_debug("trident: trident_ioctl, command = %2d, arg = 0x%08x\n",
 	      _IOC_NR(cmd), arg ? *(int *)arg : 0);
 
 	switch (cmd) 
@@ -2702,7 +2705,7 @@
 	state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
 	up(&card->open_sem);
 
-	TRDBG("trident: open virtual channel %d, hard channel %d\n", 
+	pr_debug("trident: open virtual channel %d, hard channel %d\n", 
               state->virt, dmabuf->channel->num);
 
 	return 0;
@@ -2724,7 +2727,7 @@
 		drain_dac(state, file->f_flags & O_NONBLOCK);
 	}
 
-	TRDBG("trident: closing virtual channel %d, hard channel %d\n", 
+	pr_debug("trident: closing virtual channel %d, hard channel %d\n", 
 	      state->virt, dmabuf->channel->num);
 
 	/* stop DMA state machine and free DMA buffers/channels */
@@ -2923,7 +2926,7 @@
 	}
 	if(!block)
 	{
-		TRDBG("accesscodecsemaphore: try unlock\n");
+		pr_debug("accesscodecsemaphore: try unlock\n");
 		block = 1;
 		goto unlock;
 	}
@@ -3002,7 +3005,7 @@
 		if(ncount <=0)
 			break;
 		if(ncount--==1) {
-			TRDBG("ali_ac97_read :try clear busy flag\n");
+			pr_debug("ali_ac97_read :try clear busy flag\n");
 			aud_reg = inl(TRID_REG(card,  ALI_AC97_WRITE));
 			outl((aud_reg & 0xffff7fff), TRID_REG(card, ALI_AC97_WRITE));
 		}
@@ -3056,12 +3059,12 @@
         ncount = 10;
 	while(1) {
 		wcontrol = inw(TRID_REG(card, ALI_AC97_WRITE));
-		if(!wcontrol & 0x8000)
+		if(!(wcontrol & 0x8000))
 			break;
 		if(ncount <= 0)
 			break;
 		if(ncount-- == 1) {
-			TRDBG("ali_ac97_set :try clear busy flag!!\n");
+			pr_debug("ali_ac97_set :try clear busy flag!!\n");
 			outw(wcontrol & 0x7fff, TRID_REG(card, ALI_AC97_WRITE));
 		}
 		udelay(10);
@@ -3933,8 +3936,10 @@
 		udelay(5000);
 	}
 
-	printk(KERN_ERR "ALi 5451 did not come out of reset.\n");
-	return 1;
+	/* This is non fatal if you have a non PM capable codec.. */
+	printk(KERN_ERR "ALi 5451 did not come out of reset "
+	       "- continuing anyway.\n");
+	return 0;
 }
 
 /* AC97 codec initialisation. */
diff -Nru a/sound/oss/trident.h b/sound/oss/trident.h
--- a/sound/oss/trident.h	Tue Mar  4 19:30:03 2003
+++ b/sound/oss/trident.h	Tue Mar  4 19:30:03 2003
@@ -360,16 +360,4 @@
 	return r;
 }
 
-#ifdef DEBUG
-
-#define TRDBG(msg, args...) do {          \
-        printk(KERN_DEBUG msg , ##args ); \
-} while (0)
-
-#else /* !defined(DEBUG) */ 
-
-#define TRDBG(msg, args...) do { } while (0)
-
-#endif /* DEBUG */ 
-
 #endif /* __TRID4DWAVE_H */
diff -Nru a/sound/oss/wavfront.c b/sound/oss/wavfront.c
--- a/sound/oss/wavfront.c	Tue Mar  4 19:30:09 2003
+++ b/sound/oss/wavfront.c	Tue Mar  4 19:30:09 2003
@@ -95,7 +95,7 @@
 
    I consider /dev/sequencer to be an anachronism, but given its
    widespread usage by various Linux MIDI software, it seems worth
-   offering support to it if its not too painful. Instead of using
+   offering support to it if it's not too painful. Instead of using
    /dev/sequencer, I recommend:
 
      for synth programming and patch loading: /dev/synthNN
@@ -1041,7 +1041,7 @@
 
 	if (header->size) {
 
-		/* XXX its a debatable point whether or not RDONLY semantics
+		/* XXX it's a debatable point whether or not RDONLY semantics
 		   on the ROM samples should cover just the sample data or
 		   the sample header. For now, it only covers the sample data,
 		   so anyone is free at all times to rewrite sample headers.
diff -Nru a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
--- a/sound/pci/ali5451/ali5451.c	Tue Mar  4 19:30:13 2003
+++ b/sound/pci/ali5451/ali5451.c	Tue Mar  4 19:30:13 2003
@@ -966,7 +966,7 @@
 
 	pchregs = &(codec->chregs);
 
-	// check if interrupt occured for channel
+	// check if interrupt occurred for channel
 	old  = pchregs->data.aint;
 	mask = ((unsigned int) 1L) << (channel & 0x1f);
 
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
--- a/sound/pci/cs46xx/cs46xx_lib.c	Tue Mar  4 19:30:04 2003
+++ b/sound/pci/cs46xx/cs46xx_lib.c	Tue Mar  4 19:30:04 2003
@@ -24,7 +24,7 @@
  *
  *  FINALLY: A credit to the developers Tom and Jordan 
  *           at Cirrus for have helping me out with the DSP, however we
- *           still dont have sufficient documentation and technical
+ *           still don't have sufficient documentation and technical
  *           references to be able to implement all fancy feutures
  *           supported by the cs46xx DSP's. 
  *           Benny <benny@hostmobility.com>
@@ -2401,7 +2401,7 @@
 		schedule_timeout(HZ/100);
 	} while (time_after_eq(end_time, jiffies));
 
-	snd_printk("CS46xx secondary codec dont respond!\n");  
+	snd_printk("CS46xx secondary codec don't respond!\n");  
 }
 #endif
 
diff -Nru a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h
--- a/sound/pci/cs46xx/dsp_spos.h	Tue Mar  4 19:30:03 2003
+++ b/sound/pci/cs46xx/dsp_spos.h	Tue Mar  4 19:30:03 2003
@@ -173,7 +173,7 @@
 #define BG_INTERVAL_TIMER_PERIOD                0x0100
 
 
-/* Only SP accesible registers */
+/* Only SP accessible registers */
 #define SP_ASER_COUNTDOWN 0x8040
 #define SP_SPDOUT_FIFO    0x0108
 #define SP_SPDIN_MI_FIFO  0x01E0
diff -Nru a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c	Tue Mar  4 19:30:13 2003
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c	Tue Mar  4 19:30:13 2003
@@ -181,7 +181,7 @@
 		      (ins->scbs + scb->index) == scb), return );
 
 #if 0
-	/* cant remove a SCB with childs before 
+	/* can't remove a SCB with childs before 
 	   removing childs first  */
 	snd_assert ( (scb->sub_list_ptr == ins->the_null_scb &&
 		      scb->next_scb_ptr == ins->the_null_scb),
@@ -1540,7 +1540,7 @@
 		cs46xx_dsp_enable_spdif_hw (chip);
 	}
 
-	/* dont touch anything if SPDIF is open */
+	/* don't touch anything if SPDIF is open */
 	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
 		/* when cs46xx_iec958_post_close(...) is called it
 		   will call this function if necessary depending on
@@ -1584,7 +1584,7 @@
 {
 	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
 
-	/* dont touch anything if SPDIF is open */
+	/* don't touch anything if SPDIF is open */
 	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
 		ins->spdif_status_out &= ~DSP_SPDIF_STATUS_OUTPUT_ENABLED;
 		return -EBUSY;
diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c
--- a/sound/pci/ens1370.c	Tue Mar  4 19:30:12 2003
+++ b/sound/pci/ens1370.c	Tue Mar  4 19:30:12 2003
@@ -161,7 +161,7 @@
 #define   ES_1370_CSTAT		(1<<10)		/* CODEC is busy or register write in progress */
 #define   ES_1370_CBUSY         (1<<9)		/* CODEC is busy */
 #define   ES_1370_CWRIP		(1<<8)		/* CODEC register write in progress */
-#define   ES_1371_SYNC_ERR	(1<<8)		/* CODEC synchronization error occured */
+#define   ES_1371_SYNC_ERR	(1<<8)		/* CODEC synchronization error occurred */
 #define   ES_1371_VC(i)         (((i)>>6)&0x03)	/* voice code from CCB module */
 #define   ES_1370_VC(i)		(((i)>>5)&0x03)	/* voice code from CCB module */
 #define   ES_1371_MPWR          (1<<5)		/* power level interrupt pending */
@@ -172,8 +172,8 @@
 #define   ES_ADC		(1<<0)		/* ADC channel interrupt pending */
 #define ES_REG_UART_DATA 0x08	/* R/W: UART data register */
 #define ES_REG_UART_STATUS 0x09	/* R/O: UART status register */
-#define   ES_RXINT		(1<<7)		/* RX interrupt occured */
-#define   ES_TXINT		(1<<2)		/* TX interrupt occured */
+#define   ES_RXINT		(1<<7)		/* RX interrupt occurred */
+#define   ES_TXINT		(1<<2)		/* TX interrupt occurred */
 #define   ES_TXRDY		(1<<1)		/* transmitter ready */
 #define   ES_RXRDY		(1<<0)		/* receiver ready */
 #define ES_REG_UART_CONTROL 0x09	/* W/O: UART control register */
diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c
--- a/sound/pci/es1968.c	Tue Mar  4 19:30:11 2003
+++ b/sound/pci/es1968.c	Tue Mar  4 19:30:11 2003
@@ -2329,7 +2329,7 @@
 	outb(0x88, iobase+0x1f);
 
 	/* it appears some maestros (dell 7500) only work if these are set,
-	   regardless of wether we use the assp or not. */
+	   regardless of whether we use the assp or not. */
 
 	outb(0, iobase + ASSP_CONTROL_B);
 	outb(3, iobase + ASSP_CONTROL_A);	/* M: Reserved bits... */
diff -Nru a/sound/sound_core.c b/sound/sound_core.c
--- a/sound/sound_core.c	Tue Mar  4 19:30:14 2003
+++ b/sound/sound_core.c	Tue Mar  4 19:30:14 2003
@@ -14,7 +14,7 @@
  *                         --------------------
  * 
  *	Top level handler for the sound subsystem. Various devices can
- *	plug into this. The fact they dont all go via OSS doesn't mean 
+ *	plug into this. The fact they don't all go via OSS doesn't mean 
  *	they don't have to implement the OSS API. There is a lot of logic
  *	to keeping much of the OSS weight out of the code in a compatibility
  *	module, but it's up to the driver to rember to load it...
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c	Tue Mar  4 19:30:11 2003
+++ b/sound/usb/usbaudio.c	Tue Mar  4 19:30:11 2003
@@ -1717,7 +1717,7 @@
 
 
 /*
- * intialize the substream instance.
+ * initialize the substream instance.
  */
 
 static void init_substream(snd_usb_stream_t *as, int stream, struct audioformat *fp)
